diff --git a/src/bot.ts b/src/bot.ts
index 1666f13b6da22b350f240a7befac0adc668c689b..782bb2abb3b4b24ef774bf182987697fa8892cba 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 c89a0cd0dce04c38bc305ee548c0ca136ac226de..9c9e469d264d8d78122c22ca172f5862e7365a01 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);
             }