fix(federation): fix reaction relay using wrong ID for message lookup

Reaction outbox events used reactionId (add) or a composite dedup key
(remove) as the event messageId. The receiver looked up dm_messages by
sourceMessageId = event.messageId, which never matched because it was
searching for a reactionId, not the actual message ID.

Fix: include the actual DM messageId in the reaction payload JSON.
The receiver now uses event.reaction.messageId for the lookup, with
fallback to event.messageId for backward compatibility.
This commit is contained in:
Jannis Braun
2026-03-26 14:27:48 +01:00
parent 086195aa7c
commit a21243256e
3 changed files with 11 additions and 4 deletions
+8 -4
View File
@@ -1252,14 +1252,16 @@ function processReactionAddEvent(
return; return;
} }
// Find the local message corresponding to the source message // Find the local message — use the actual message ID from the reaction payload,
// not event.messageId which is the outbox dedup key (reactionId)
const sourceMessageId = event.reaction.messageId ?? event.messageId;
const localMsg = db const localMsg = db
.select() .select()
.from(schema.dmMessages) .from(schema.dmMessages)
.where( .where(
and( and(
eq(schema.dmMessages.sourceInstance, sourceInstance), eq(schema.dmMessages.sourceInstance, sourceInstance),
eq(schema.dmMessages.sourceMessageId, event.messageId), eq(schema.dmMessages.sourceMessageId, sourceMessageId),
), ),
) )
.get(); .get();
@@ -1337,14 +1339,16 @@ function processReactionRemoveEvent(
return; return;
} }
// Find the local message // Find the local message — use the actual message ID from the reaction payload,
// not event.messageId which is the outbox dedup key (composite string)
const sourceMessageId = event.reaction.messageId ?? event.messageId;
const localMsg = db const localMsg = db
.select() .select()
.from(schema.dmMessages) .from(schema.dmMessages)
.where( .where(
and( and(
eq(schema.dmMessages.sourceInstance, sourceInstance), eq(schema.dmMessages.sourceInstance, sourceInstance),
eq(schema.dmMessages.sourceMessageId, event.messageId), eq(schema.dmMessages.sourceMessageId, sourceMessageId),
), ),
) )
.get(); .get();
+2
View File
@@ -1135,6 +1135,7 @@ function handleReactionAdd(event: Record<string, unknown>, userId: string): void
})); }));
queueOutboxEvent(reactionId, dmMsg.dmChannelId, 'reaction_add', JSON.stringify({ queueOutboxEvent(reactionId, dmMsg.dmChannelId, 'reaction_add', JSON.stringify({
reaction: { reaction: {
messageId,
userId, userId,
homeUserId: reactionUser?.homeUserId || userId, homeUserId: reactionUser?.homeUserId || userId,
emoji, emoji,
@@ -1212,6 +1213,7 @@ function handleReactionRemove(event: Record<string, unknown>, userId: string): v
'reaction_remove', 'reaction_remove',
JSON.stringify({ JSON.stringify({
reaction: { reaction: {
messageId,
userId, userId,
homeUserId: removingUser?.homeUserId || userId, homeUserId: removingUser?.homeUserId || userId,
emoji, emoji,
+1
View File
@@ -744,6 +744,7 @@ export interface FederationRelayEvent {
} }
export interface FederationRelayReaction { export interface FederationRelayReaction {
messageId?: string;
userId: string; userId: string;
homeUserId: string; homeUserId: string;
emoji: string; emoji: string;