From 1cd4ddb4bb7c6eb4bfca37dd87cdb9aad94d4b57 Mon Sep 17 00:00:00 2001
From: Seth Falco <seth@falco.fun>
Date: Thu, 6 Jul 2023 01:13:30 +0100
Subject: [PATCH] fix: join room on reaction events

Signed-off-by: Seth Falco <seth@falco.fun>
---
 src/bot.ts              | 34 ++++++++++++++++++++++++++--------
 test/test_discordbot.ts |  3 +++
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/bot.ts b/src/bot.ts
index 1666f13..782bb2a 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -1211,10 +1211,6 @@ export class DiscordBot {
         const reactionName = reaction.emoji.name;
         log.verbose(`Got message reaction add event for ${message.id} with ${reactionName}`);
 
-        const intent = this.GetIntentFromDiscordMember(user);
-        await intent.ensureRegistered();
-        this.userActivity.updateUserActivity(intent.userId);
-
         const storeEvent = await this.store.Get(DbEvent, {
             discord_id: message.id
         });
@@ -1224,8 +1220,21 @@ export class DiscordBot {
             return;
         }
 
+        const intent = this.GetIntentFromDiscordMember(user);
+        await intent.ensureRegistered();
+        this.userActivity.updateUserActivity(intent.userId);
+
         while (storeEvent.Next()) {
             const [ eventId, roomId ] = storeEvent.MatrixId.split(";");
+
+            // If the user is partial, only forward the event for rooms they're already in.
+            if (user.partial) {
+                log.warn(`Skipping reaction add for user with Discord ID ${user.id} in ${roomId}. User was partial.`);
+                continue;
+            }
+
+            await this.userSync.JoinRoom(user, roomId);
+
             const reactionEventId = await intent.underlyingClient.unstableApis.addReactionToEvent(
                 roomId,
                 eventId,
@@ -1248,10 +1257,6 @@ export class DiscordBot {
         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,
         });
@@ -1261,8 +1266,21 @@ export class DiscordBot {
             return;
         }
 
+        const intent = this.GetIntentFromDiscordMember(user);
+        await intent.ensureRegistered();
+        this.userActivity.updateUserActivity(intent.userId);
+
         while (storeEvent.Next()) {
             const [ eventId, roomId ] = storeEvent.MatrixId.split(";");
+
+            // If the user is partial, only forward the event for rooms they're already in.
+            if (user.partial) {
+                log.warn(`Skipping reaction remove for user with Discord ID ${user.id} in ${roomId}. User was partial.`);
+                continue;
+            }
+
+            await this.userSync.JoinRoom(user, roomId);
+
             const underlyingClient = intent.underlyingClient;
 
             const { chunk } = await underlyingClient.unstableApis.getRelationsForEvent(
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index c89a0cd..9c9e469 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -476,6 +476,9 @@ describe("DiscordBot", () => {
             discord.userActivity = {
                 updateUserActivity: () => { }
             };
+            discord.userSync = {
+                JoinRoom: async () => { },
+            };
             discord.GetIntentFromDiscordMember = () => {
                 return mockBridge.getIntent(author.id);
             }
-- 
GitLab