Don't delete our reaction on Discord unless we have 0 of that reaction coming from Matrix #85

Merged
cadence merged 10 commits from ellie/out-of-your-element:ellie-fix-reacts into main 2026-06-01 04:54:39 +00:00
3 changed files with 12 additions and 10 deletions
Showing only changes of commit 28e5bd91a6 - Show all commits

deal with situations where Discord doesn't send us an emoji's name when removing it

Ellie Algase 2026-06-01 00:43:32 -04:00

View file

@ -12,7 +12,7 @@ const utils = sync.require("../../matrix/utils")
In this case, wait until the original message has finished bridging, then retrigger the passed function. In this case, wait until the original message has finished bridging, then retrigger the passed function.
*/ */
const DEBUG_RETRIGGER = true const DEBUG_RETRIGGER = false
function debugRetrigger(message) { function debugRetrigger(message) {
if (DEBUG_RETRIGGER) { if (DEBUG_RETRIGGER) {

View file

@ -383,12 +383,12 @@ module.exports = {
* @param {DiscordTypes.GatewayMessageReactionRemoveDispatchData | DiscordTypes.GatewayMessageReactionRemoveEmojiDispatchData | DiscordTypes.GatewayMessageReactionRemoveAllDispatchData} data * @param {DiscordTypes.GatewayMessageReactionRemoveDispatchData | DiscordTypes.GatewayMessageReactionRemoveEmojiDispatchData | DiscordTypes.GatewayMessageReactionRemoveAllDispatchData} data
*/ */
async onSomeReactionsRemoved(client, data) { async onSomeReactionsRemoved(client, data) {
// Don't attempt to double-bridge our own deleted reactions, this would go badly if there are race conditions // Don't attempt to double-bridge our own m2d deleted reactions back to Matrix
if ("user_id" in data && data.user_id === botID && data.emoji.name) { // sure hope data.emoji.name exists here if ("user_id" in data && data.user_id === botID) {
const encodedEmoji = encodeURIComponent(data.emoji.id ? `${data.emoji.name}:${data.emoji.id}` : data.emoji.name) const emojiIdOrName = data.emoji.id || data.emoji.name
const i = redact.ourDeletedReactions.findIndex(x => data.message_id === x.message_id && encodedEmoji === x.encoded_emoji) const i = redact.m2dDeletedReactions.findIndex(x => data.message_id === x.messageID && emojiIdOrName === x.emojiIdOrName)
if (i !== -1) { if (i !== -1) {
redact.ourDeletedReactions.splice(i, 1) redact.m2dDeletedReactions.splice(i, 1)
return return
} }
} }

View file

@ -10,8 +10,8 @@ const utils = sync.require("../../matrix/utils")
/** @type {import("../../d2m/actions/retrigger")} */ /** @type {import("../../d2m/actions/retrigger")} */
const retrigger = sync.require("../../d2m/actions/retrigger") const retrigger = sync.require("../../d2m/actions/retrigger")
/** @type {{message_id: string, encoded_emoji: string}[]} */ /** @type {{messageID: string, emojiIdOrName: string}[]} */
const ourDeletedReactions = [] const m2dDeletedReactions = []
/** /**
* @param {Ty.Event.Outer_M_Room_Redaction} event * @param {Ty.Event.Outer_M_Room_Redaction} event
@ -68,7 +68,9 @@ async function removeReaction(event) {
// See how many Matrix-side reactions there are, and delete if it's the last one // See how many Matrix-side reactions there are, and delete if it's the last one
const numberOfReactions = from("reaction").where({message_id: row.message_id, encoded_emoji: row.encoded_emoji}).pluckUnsafe("count(*)").get() const numberOfReactions = from("reaction").where({message_id: row.message_id, encoded_emoji: row.encoded_emoji}).pluckUnsafe("count(*)").get()
if (numberOfReactions === 1) { if (numberOfReactions === 1) {
ourDeletedReactions.push(row) // If a unicode emoji, the name is already the Discord preferred version because that's what was added and stored to encoded_emoji
const emojiIdOrName = decodeURIComponent(row.encoded_emoji).split(":").slice(-1)[0]
m2dDeletedReactions.push({messageID: row.message_id, emojiIdOrName})
await discord.snow.channel.deleteReactionSelf(row.reference_channel_id, row.message_id, row.encoded_emoji) await discord.snow.channel.deleteReactionSelf(row.reference_channel_id, row.message_id, row.encoded_emoji)
} }
db.prepare("DELETE FROM reaction WHERE hashed_event_id = ?").run(hash) db.prepare("DELETE FROM reaction WHERE hashed_event_id = ?").run(hash)
@ -87,4 +89,4 @@ async function handle(event) {
} }
module.exports.handle = handle module.exports.handle = handle
module.exports.ourDeletedReactions = ourDeletedReactions module.exports.m2dDeletedReactions = m2dDeletedReactions