musiclink/docs/design-matrix-native-routing.md

3.1 KiB

Design: Matrix-Native MusicLink Routing

Goal

Make MusicLink a native Matrix bot that listens to multiple rooms and replies in the same room that originated the message. This removes Matterbridge from the routing path and eliminates cross-room fan-out.

Background

Current deployment uses Matterbridge as an API gateway. When multiple Matrix rooms are configured in a single Matterbridge gateway, messages fan out to other rooms. This causes unintended cross-posting (including DM leakage) when MusicLink is enabled in more than one room.

Objectives

  • Correct routing: Replies must go back to the originating room (and thread when applicable).
  • Multi-room support: One MusicLink instance can monitor multiple Matrix rooms.
  • No fan-out bus: Remove Matterbridge dependency for routing.
  • Minimal operational complexity: Single service, single config, single token.

Non-Goals

  • Replacing mautrix-slack (Slack ↔ Matrix bridge remains).
  • Adding new link providers beyond current MusicLink behavior.

High-Level Architecture

Slack Room
  -> mautrix-slack (Matrix portal room)
  -> MusicLink (Matrix-native bot)
  -> same Matrix portal room (reply)
  -> mautrix-slack -> Slack thread

Proposed Implementation

1) Matrix Client

Use a Matrix SDK (mautrix-go or matrix-nio) to:

  • Login using a bot token (or access token from config).
  • Sync events from configured rooms.
  • Ignore messages from the bot itself.
  • Post replies to the same room.

2) Room Configuration

Extend config with explicit room allowlist:

[matrix]
server = "https://clarun.xyz"
accessToken = "..."
userId = "@musiclink:clarun.xyz"
rooms = [
  "!DPQveBnfuDrbgOe6dm:clarun.xyz",
  "!dT40EUcemb8e6bPiig:clarun.xyz"
]

3) Threading Support

If the incoming event references a thread (e.g., m.relates_to with rel_type=m.thread), reply into that thread; otherwise post a standard room message.

4) Message Handling

  • Parse message body for supported music links.
  • Call idonthavespotify (existing behavior).
  • Post formatted reply in the same room.

5) Loop Prevention

  • Ignore events from @musiclink.
  • Optionally ignore events without link matches.
  • Add a small delay/backoff on rate limit responses.

Migration Plan

  1. Add Matrix client support behind a feature flag (e.g., matrix.enabled).
  2. Deploy in parallel with Matterbridge to validate routing and threading.
  3. Disable Matterbridge once Matrix-native mode is verified.

Risks

  • Matrix SDK differences in threading or formatting.
  • Token handling and access permissions for the bot user.
  • Message deduplication and race conditions in sync processing.

Open Questions

  • Which Matrix SDK should we standardize on (mautrix-go vs matrix-nio)?
  • Do we need explicit thread support in Slack via mautrix-slack mapping?
  • Should we persist a small state store for sync tokens?

Appendix: Why Not Multiple Gateways?

Multiple gateways in Matterbridge solve cross-posting, but still rely on the fan-out bus model and add operational overhead. A Matrix-native bot is simpler and more correct for routing semantics.