From 6bf2a2621ce6288363a8a8fae9bc558eaf4aca7b Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 26 Mar 2026 17:57:07 +0100 Subject: [PATCH] fix(federation): skip broadcasting relay messages to source-instance users When Instance 2 receives a relay from Instance 1, it no longer broadcasts dm_message_created to members whose home instance is Instance 1. Those users already have the original message via their home WS connection. This prevents duplicate messages from appearing in the sender's chat. --- packages/server/src/routes/federation.ts | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/server/src/routes/federation.ts b/packages/server/src/routes/federation.ts index 118741ca..bcfc6cea 100644 --- a/packages/server/src/routes/federation.ts +++ b/packages/server/src/routes/federation.ts @@ -1078,11 +1078,30 @@ function processCreateEvent( } } - // Broadcast to local WebSocket clients — use getDmMessageWithUser to pick up - // the attachment rows we just created (with remote URLs as filenames) + // Broadcast to local WebSocket clients, but skip members whose home instance + // is the source instance — they already have the original message via their + // home instance's WebSocket connection. const fullMessage = getDmMessageWithUser(localMessageId); if (fullMessage) { - broadcastDmMessage(localDmChannelId, fullMessage); + const dmMembers = db.select() + .from(schema.dmMembers) + .where(eq(schema.dmMembers.dmChannelId, localDmChannelId)) + .all(); + + for (const member of dmMembers) { + const memberUser = db.select() + .from(schema.users) + .where(eq(schema.users.id, member.userId)) + .get(); + + // Skip members whose home instance is the source — they already have this message + if (memberUser?.homeInstance === sourceInstance) continue; + + connectionManager.sendToUser(member.userId, { + type: 'dm_message_created', + message: fullMessage, + }); + } } accepted.push(event.messageId);