Skip to content

Conversation

@ggazzo
Copy link
Member

@ggazzo ggazzo commented Sep 22, 2025

  • Added MessageType to fileTypes for better type safety.
  • Simplified message handling logic by destructuring content and refining relation checks.
  • Improved readability and maintainability of the message processing code.

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Added explicit support for generic file messages, improving handling of non-image/video/audio attachments.
  • Bug Fixes

    • Improved reliability of threads, replies, quotes, and edited messages in Matrix rooms for correct linking and updates.
    • More consistent resolution of referenced messages and media, reducing errors and mismatches.
  • Refactor

    • Centralized message relation handling for more stable and predictable Matrix interactions.
  • Chores

    • Minor integration cleanups to aid external tooling compatibility.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Sep 22, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Sep 22, 2025

⚠️ No Changeset found

Latest commit: 3af8527

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Walkthrough

Replaces a local Matrix file-type alias with the shared FileMessageType and adds file: 'm.file' to mappings in FederationMatrix; centralizes relation extraction in message handling to derive threads, quotes, and edits from content['m.relates_to'], updates types and relation-driven lookup logic.

Changes

Cohort / File(s) Summary
File message typing update
ee/packages/federation-matrix/src/FederationMatrix.ts
Replace local MatrixFileTypes usage with imported FileMessageType; change fileTypes typing to Record<string, FileMessageType> and add file: 'm.file'; update getMatrixMessageType return type and imports accordingly.
Relation-driven message handling
ee/packages/federation-matrix/src/events/message.ts
Centralize relation = content['m.relates_to']; use typed EventID for thread lookup and MessageType for msgtype; compute isThreadMessage, threadRootEventId, and quoteMessageEventId from relation; defer getThreadMessageId until thread root present; replace direct relation accesses with the unified relation variable across edit, quote, and original-message lookup flows; adjust URL construction and logging to use relation-based IDs.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant HS as Homeserver
  participant Handler as message() handler
  participant Store as Message Store
  participant Room as Room Lookup

  HS->>Handler: receive Matrix event (data)
  Handler->>Handler: const { content } = data\nrelation = content['m.relates_to']
  alt relation.rel_type == "m.thread"
    Handler->>Handler: threadRootEventId = relation.event_id
    Handler->>Store: getThreadMessageId(threadRootEventId)  %% async lookup
  end
  opt reply present
    Handler->>Handler: quoteMessageEventId = relation['m.in_reply_to']?.event_id
    Handler->>Store: resolve quoted/original message by quoteMessageEventId
  end
  alt relation.rel_type == "m.replace" (edit)
    Handler->>Store: originalEventId = relation.event_id
    Handler->>Handler: newContent = content['m.new_content']
    Handler->>Store: update original message with newContent
  else new/regular message
    Handler->>Room: optional room metadata fetch
    Handler->>Store: create/save new message (media handling typed)
  end
  Handler-->>HS: ack/complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • sampaiodiego

Poem

I nibble on relations, hop through each thread,
Map files and replies where event-IDs spread.
Types tidy the burrow, mappings now neat,
edits and quotes scurry to find their seat.
Thump-thump — the federation warren is complete. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title succinctly describes the primary bugfix — replies mapped incorrectly when the thread id was empty — and matches the changes in events/message.ts that centralize relation handling and adjust threadRootEventId resolution. It is a short, single sentence and focuses on the most important behavioral change from the developer’s perspective. The title omits secondary typing refactors (file/message type changes) but that is acceptable because titles need not list every change.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/missing-typings

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5fb801e and 3af8527.

📒 Files selected for processing (2)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (3 hunks)
  • ee/packages/federation-matrix/src/events/message.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • ee/packages/federation-matrix/src/events/message.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build

Comment @coderabbitai help to get the list of available commands and usage tips.

@ggazzo ggazzo changed the title fix: empty thread fix(federation): empty thread id leads to wrong reply Sep 22, 2025
@ggazzo ggazzo added this to the 7.11.0 milestone Sep 22, 2025
@ggazzo ggazzo force-pushed the fix/missing-typings branch from 9ebbf1c to 1d1915c Compare September 22, 2025 15:51
@ggazzo ggazzo marked this pull request as ready for review September 22, 2025 16:56
@ggazzo ggazzo force-pushed the fix/missing-typings branch from 1d1915c to a856d76 Compare September 22, 2025 16:58
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
ee/packages/federation-matrix/src/FederationMatrix.ts (2)

33-38: Harden the mapping against accidental mutation.

Make fileTypes readonly to avoid accidental writes at runtime.

-export const fileTypes: Record<string, MessageType> = {
+export const fileTypes: Readonly<Record<string, MessageType>> = {
   image: 'm.image',
   video: 'm.video',
   audio: 'm.audio',
   file: 'm.file',
 };

99-99: Env flag always true due to || true.

process.env.MEDIA_ENABLE_THUMBNAILS === 'true' || true always evaluates to true. Respect the env var and default to true only when unset.

- enableThumbnails: process.env.MEDIA_ENABLE_THUMBNAILS === 'true' || true,
+ enableThumbnails:
+   process.env.MEDIA_ENABLE_THUMBNAILS === undefined
+     ? true
+     : process.env.MEDIA_ENABLE_THUMBNAILS === 'true',
ee/packages/federation-matrix/src/events/message.ts (2)

221-224: Guard media filename to avoid crashes when body is absent.

Some media events can miss body. handleMediaMessage uses encodeURIComponent(fileName), which will throw on undefined.

- const messageBody = content?.body?.toString();
+ const messageBody = content?.body?.toString() ?? content?.filename ?? 'file';

267-274: Fallback to room.fname when room.name is absent.

Federated rooms/DMs may lack name. Use room.name || room.fname to avoid skipping quote formatting.

- const messageToReplyToUrl = await MeteorService.getMessageURLToReplyTo(
-   room.t as string,
-   room._id,
-   room.name,
-   originalMessage._id,
- );
+ const messageToReplyToUrl = await MeteorService.getMessageURLToReplyTo(
+   room.t as string,
+   room._id,
+   room.name || (room as any).fname || '',
+   originalMessage._id,
+ );

Apply the same change to the non‑edit quote branch.

Also applies to: 315-316

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e7247a4 and a856d76.

📒 Files selected for processing (2)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (2 hunks)
  • ee/packages/federation-matrix/src/events/message.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ee/packages/federation-matrix/src/events/message.ts (2)
ee/packages/federation-matrix/src/FederationMatrix.ts (1)
  • fileTypes (33-38)
packages/models/src/index.ts (1)
  • Messages (184-184)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (1)
ee/packages/federation-matrix/src/events/message.ts (1)

242-248: LGTM: centralizing relation parsing prevents empty-thread-id replies.

Using a single relation object and short‑circuiting falsy event_id ensures empty thread IDs don’t misroute replies. This addresses the PR’s core issue.

Please confirm with a test that an event carrying rel_type: 'm.thread' and event_id: '' results in a non-threaded message save (no tmid), as intended.

Comment on lines 240 to 247
const relation = content['m.relates_to'];

const isThreadMessage = relation && relation.rel_type === 'm.thread';
const threadRootEventId = isThreadMessage && relation.event_id;

const quoteMessageEventId = relation && 'm.in_reply_to' in relation && relation['m.in_reply_to']?.event_id;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Edited replies: also read reply target from m.new_content.m.relates_to.

In edits (m.replace), some HS place m.in_reply_to inside m.new_content.m.relates_to. Current logic only checks top‑level relation, so edited replies can lose their reply context.

- const relation = content['m.relates_to'];
+ const relation = content['m.relates_to'];
+ const newContentRelation = content['m.new_content']?.['m.relates_to'];
- const quoteMessageEventId = relation && 'm.in_reply_to' in relation && relation['m.in_reply_to']?.event_id;
+ const quoteMessageEventId =
+   relation?.['m.in_reply_to']?.event_id ??
+   newContentRelation?.['m.in_reply_to']?.event_id;

Also applies to: 251-253

🤖 Prompt for AI Agents
In ee/packages/federation-matrix/src/events/message.ts around lines 240-246 (and
similarly around 251-253), the code only reads relation info from
content['m.relates_to'] so edited replies whose reply target is moved into
m.new_content.m.relates_to (during an m.replace edit) lose their reply/thread
context; update the logic to first check for
content['m.new_content']?.['m.relates_to'] and fall back to
content['m.relates_to'], then derive isThreadMessage, threadRootEventId and
quoteMessageEventId from that chosen relation object (apply the same change to
the other occurrence at lines 251-253).

@ggazzo ggazzo force-pushed the fix/missing-typings branch from a856d76 to b480def Compare September 22, 2025 17:07
- Added MessageType to fileTypes for better type safety.
- Simplified message handling logic by destructuring content and refining relation checks.
- Improved readability and maintainability of the message processing code.
@ggazzo ggazzo force-pushed the fix/missing-typings branch from b480def to 5fb801e Compare September 22, 2025 17:20
@codecov
Copy link

codecov bot commented Sep 22, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.34%. Comparing base (4b1ac41) to head (3af8527).
⚠️ Report is 4 commits behind head on chore/federation-backup.

Additional details and impacted files

Impacted file tree graph

@@                   Coverage Diff                    @@
##           chore/federation-backup   #37023   +/-   ##
========================================================
  Coverage                    67.33%   67.34%           
========================================================
  Files                         3342     3342           
  Lines                       113397   113401    +4     
  Branches                     20704    20666   -38     
========================================================
+ Hits                         76361    76375   +14     
+ Misses                       34435    34427    -8     
+ Partials                      2601     2599    -2     
Flag Coverage Δ
e2e 56.97% <ø> (+0.03%) ⬆️
unit 71.26% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ricardogarim ricardogarim self-requested a review September 22, 2025 18:02
- Updated fileTypes to use FileMessageType for improved type safety.
- Refined getMatrixMessageType to return FileMessageType.
- Adjusted message handling to ensure consistent type usage across the federation module.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants