From 369d9141562c244cc143bfee9735e2d87e609e59 Mon Sep 17 00:00:00 2001
From: salixor <salixor@pm.me>
Date: Thu, 2 May 2024 21:10:30 +0200
Subject: [PATCH] Revert handling reactions in the Discord -> Matrix way

---
 README.md               |   2 -
 changelog.d/862.feature |   1 -
 src/bot.ts              | 155 ----------------------------------------
 src/db/dbdataevent.ts   |   2 -
 test/mocks/message.ts   |   2 +-
 test/mocks/reaction.ts  |  16 -----
 test/test_discordbot.ts |  80 ---------------------
 7 files changed, 1 insertion(+), 257 deletions(-)
 delete mode 100644 changelog.d/862.feature
 delete mode 100644 test/mocks/reaction.ts

diff --git a/README.md b/README.md
index 28664f6..934ed5f 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,6 @@ In a vague order of what is coming up next
      - [x] Audio/Video content
      - [ ] Typing notifs (**Not supported, requires syncing**)
      - [x] User Profiles
-     - [ ] Reactions
  - Discord -> Matrix
      - [x] Text content
      - [x] Image content
@@ -153,7 +152,6 @@ In a vague order of what is coming up next
      - [x] User Profiles
      - [x] Presence
      - [x] Per-guild display names.
-     - [x] Reactions
  - [x] Group messages
  - [ ] Third Party Lookup
     - [x] Rooms
diff --git a/changelog.d/862.feature b/changelog.d/862.feature
deleted file mode 100644
index a693baa..0000000
--- a/changelog.d/862.feature
+++ /dev/null
@@ -1 +0,0 @@
-Adds one-way reaction support from Discord -> Matrix. Thanks to @SethFalco!
diff --git a/src/bot.ts b/src/bot.ts
index 8e0ccfb..f5cd93c 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -263,21 +263,6 @@ export class DiscordBot {
                 await this.channelSync.OnGuildDelete(guild);
             } catch (err) { log.error("Exception thrown while handling \"guildDelete\" event", err); }
         });
-        client.on("messageReactionAdd", async (reaction, user) => {
-            try {
-                await this.OnMessageReactionAdd(reaction, user);
-            } catch (err) { log.error("Exception thrown while handling \"messageReactionAdd\" event", err); }
-        });
-        client.on("messageReactionRemove", async (reaction, user) => {
-            try {
-                await this.OnMessageReactionRemove(reaction, user);
-            } catch (err) { log.error("Exception thrown while handling \"messageReactionRemove\" event", err); }
-        });
-        client.on("messageReactionRemoveAll", async (message) => {
-            try {
-                await this.OnMessageReactionRemoveAll(message);
-            } catch (err) { log.error("Exception thrown while handling \"messageReactionRemoveAll\" event", err); }
-        });
 
         // Due to messages often arriving before we get a response from the send call,
         // messages get delayed from discord. We use Util.DelayedPromise to handle this.
@@ -1221,146 +1206,6 @@ export class DiscordBot {
         await this.OnMessage(newMsg);
     }
 
-    public async OnMessageReactionAdd(reaction: Discord.MessageReaction, user: Discord.User | Discord.PartialUser) {
-        const message = reaction.message;
-        const reactionName = reaction.emoji.name;
-        log.verbose(`Got message reaction add event for ${message.id} with ${reactionName}`);
-
-        let rooms: string[];
-
-        try {
-            rooms = await this.channelSync.GetRoomIdsFromChannel(message.channel);
-        } catch (err) {
-            log.verbose(`No bridged rooms to forward reaction to. Reaction Event: ${reaction}`);
-            MetricPeg.get.requestOutcome(message.id, true, "dropped");
-            return;
-        }
-
-        const intent = this.GetIntentFromDiscordMember(user);
-        await intent.ensureRegistered();
-        this.userActivity.updateUserActivity(intent.userId);
-
-        const storeEvent = await this.store.Get(DbEvent, {
-            discord_id: message.id
-        });
-
-        if (!storeEvent?.Result) {
-            log.verbose(`Received add reaction event for untracked message. Dropping! Reaction Event: ${reaction}`);
-            return;
-        }
-
-        while (storeEvent.Next()) {
-            const matrixIds = storeEvent.MatrixId.split(";");
-
-            for (const room of rooms) {
-                const reactionEventId = await intent.underlyingClient.unstableApis.addReactionToEvent(
-                    room,
-                    matrixIds[0],
-                    reaction.emoji.id ? `:${reactionName}:` : reactionName
-                );
-
-                const event = new DbEvent();
-                event.MatrixId = `${reactionEventId};${room}`;
-                event.DiscordId = message.id;
-                event.ChannelId = message.channel.id;
-                if (message.guild) {
-                    event.GuildId = message.guild.id;
-                }
-
-                await this.store.Insert(event);
-            }
-        }
-    }
-
-    public async OnMessageReactionRemove(reaction: Discord.MessageReaction, user: Discord.User | Discord.PartialUser) {
-        const message = reaction.message;
-        log.verbose(`Got message reaction remove event for ${message.id} with ${reaction.emoji.name}`);
-
-        const intent = this.GetIntentFromDiscordMember(user);
-        await intent.ensureRegistered();
-        this.userActivity.updateUserActivity(intent.userId);
-
-        const storeEvent = await this.store.Get(DbEvent, {
-            discord_id: message.id,
-        });
-
-        if (!storeEvent?.Result) {
-            log.verbose(`Received remove reaction event for untracked message. Dropping! Reaction Event: ${reaction}`);
-            return;
-        }
-
-        while (storeEvent.Next()) {
-            const [ eventId, roomId ] = storeEvent.MatrixId.split(";");
-            const underlyingClient = intent.underlyingClient;
-
-            const { chunk } = await underlyingClient.unstableApis.getRelationsForEvent(
-                roomId,
-                eventId,
-                "m.annotation"
-            );
-
-            const event = chunk.find((event) => {
-                if (event.sender !== intent.userId) {
-                    return false;
-                }
-
-                return event.content["m.relates_to"].key === reaction.emoji.name;
-            });
-
-            if (!event) {
-                log.verbose(`Received remove reaction event for tracked message where the add reaction event was not bridged. Dropping! Reaction Event: ${reaction}`);
-                return;
-            }
-
-            const { room_id, event_id } = event;
-
-            try {
-                await underlyingClient.redactEvent(room_id, event_id);
-            } catch (ex) {
-                log.warn(`Failed to delete ${storeEvent.DiscordId}, retrying as bot`);
-                try {
-                    await this.bridge.botIntent.underlyingClient.redactEvent(room_id, event_id);
-                } catch (ex) {
-                    log.warn(`Failed to delete ${event_id}, giving up`);
-                }
-            }
-        }
-    }
-
-    public async OnMessageReactionRemoveAll(message: Discord.Message | Discord.PartialMessage) {
-        log.verbose(`Got message reaction remove all event for ${message.id}`);
-
-        const storeEvent = await this.store.Get(DbEvent, {
-            discord_id: message.id,
-        });
-
-        if (!storeEvent?.Result) {
-            log.verbose(`Received remove all reaction event for untracked message. Dropping! Event: ${message}`);
-            return;
-        }
-
-        while (storeEvent.Next()) {
-            const [ eventId, roomId ] = storeEvent.MatrixId.split(";");
-            const underlyingClient = this.bridge.botIntent.underlyingClient;
-
-            const { chunk } = await underlyingClient.unstableApis.getRelationsForEvent(
-                roomId,
-                eventId,
-                "m.annotation"
-            );
-
-            const filteredChunk = chunk.filter((event) => event.sender === this.bridge.botUserId);
-
-            await Promise.all(filteredChunk.map(async (event) => {
-                try {
-                    return await underlyingClient.redactEvent(event.room_id, event.event_id);
-                } catch (ex) {
-                    log.warn(`Failed to delete ${event.event_id}, giving up`);
-                }
-            }));
-        }
-    }
-
     private async DeleteDiscordMessage(msg: Discord.Message) {
         log.info(`Got delete event for ${msg.id}`);
         const storeEvent = await this.store.Get(DbEvent, {discord_id: msg.id});
diff --git a/src/db/dbdataevent.ts b/src/db/dbdataevent.ts
index 5d8fd9e..d3fc58f 100644
--- a/src/db/dbdataevent.ts
+++ b/src/db/dbdataevent.ts
@@ -19,9 +19,7 @@ import { IDbDataMany } from "./dbdatainterface";
 import { ISqlCommandParameters } from "./connector";
 
 export class DbEvent implements IDbDataMany {
-    /** ID associated with the event in the format "MatrixID:RoomID". */
     public MatrixId: string;
-    /** Discord ID of the relevant message associated with this event. */
     public DiscordId: string;
     public GuildId: string;
     public ChannelId: string;
diff --git a/test/mocks/message.ts b/test/mocks/message.ts
index 9393f42..bfd7ac5 100644
--- a/test/mocks/message.ts
+++ b/test/mocks/message.ts
@@ -24,7 +24,7 @@ import { MockCollection } from "./collection";
 export class MockMessage {
     public attachments = new MockCollection<string, any>();
     public embeds: any[] = [];
-    public content: string;
+    public content = "";
     public channel: Discord.TextChannel | undefined;
     public guild: Discord.Guild | undefined;
     public author: MockUser;
diff --git a/test/mocks/reaction.ts b/test/mocks/reaction.ts
deleted file mode 100644
index 7ca8555..0000000
--- a/test/mocks/reaction.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { MockTextChannel } from './channel';
-import { MockEmoji } from './emoji';
-import { MockMessage } from './message';
-
-/* tslint:disable:no-unused-expression max-file-line-count no-any */
-export class MockReaction {
-    public message: MockMessage;
-    public emoji: MockEmoji;
-    public channel: MockTextChannel;
-
-    constructor(message: MockMessage, emoji: MockEmoji, channel: MockTextChannel) {
-        this.message = message;
-        this.emoji = emoji;
-        this.channel = channel;
-    }
-}
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index 009157d..e5834d4 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -26,8 +26,6 @@ import { Util } from "../src/util";
 import { AppserviceMock } from "./mocks/appservicemock";
 import { MockUser } from "./mocks/user";
 import { MockTextChannel } from "./mocks/channel";
-import { MockReaction } from './mocks/reaction';
-import { MockEmoji } from './mocks/emoji';
 
 // we are a test file and thus need those
 /* tslint:disable:no-unused-expression max-file-line-count no-any */
@@ -535,82 +533,4 @@ describe("DiscordBot", () => {
             expect(expected).to.eq(ITERATIONS);
         });
     });
-    describe("OnMessageReactionAdd", () => {
-        const channel = new MockTextChannel();
-        const author = new MockUser("11111");
-        const message = new MockMessage(channel, "Hello, World!", author);
-        const emoji = new MockEmoji("", "🤔");
-        const reaction = new MockReaction(message, emoji, channel);
-
-        function getDiscordBot() {
-            mockBridge.cleanup();
-            const discord = new modDiscordBot.DiscordBot(
-                config,
-                mockBridge,
-                {},
-            );
-            discord.channelSync = {
-                GetRoomIdsFromChannel: async () => ["!asdf:localhost"],
-            };
-            discord.store = {
-                Get: async () => {
-                    let storeMockResults = 0;
-
-                    return {
-                        Result: true,
-                        MatrixId: "$mAKet_w5WYFCgh1WaHVOvyn9LJLbolFeuELTKVfm0Po;!asdf:localhost",
-                        Next: () => storeMockResults++ === 0
-                    }
-                },
-                Insert: async () => { },
-            };
-            discord.userActivity = {
-                updateUserActivity: () => { }
-            };
-            discord.GetIntentFromDiscordMember = () => {
-                return mockBridge.getIntent(author.id);
-            }
-            return discord;
-        }
-
-        it("Adds reaction from Discord → Matrix", async () => {
-            discordBot = getDiscordBot();
-            await discordBot.OnMessageReactionAdd(reaction, author);
-            mockBridge.getIntent(author.id).underlyingClient.unstableApis.wasCalled(
-                "addReactionToEvent",
-                true,
-                "!asdf:localhost",
-                "$mAKet_w5WYFCgh1WaHVOvyn9LJLbolFeuELTKVfm0Po",
-                "🤔"
-            );
-        });
-
-        it("Removes reaction from Discord → Matrix", async () => {
-            discordBot = getDiscordBot();
-            const intent = mockBridge.getIntent(author.id);
-
-            intent.underlyingClient.unstableApis.getRelationsForEvent = async () => {
-                return {
-                    chunk: [
-                        {
-                            sender: "11111",
-                            room_id: "!asdf:localhost",
-                            event_id: "$mAKet_w5WYFCgh1WaHVOvyn9LJLbolFeuELTKVfm0Po",
-                            content: {
-                                "m.relates_to": { key: "🤔" }
-                            }
-                        }
-                    ]
-                }
-            }
-
-            await discordBot.OnMessageReactionRemove(reaction, author);
-            intent.underlyingClient.wasCalled(
-                "redactEvent",
-                false,
-                "!asdf:localhost",
-                "$mAKet_w5WYFCgh1WaHVOvyn9LJLbolFeuELTKVfm0Po",
-            );
-        });
-    });
 });
-- 
GitLab