Message Routing & Mapping
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Message Routing & Mapping system is the core architectural component of Matterbridge, responsible for orchestrating the flow of communication between disparate chat protocols. It facilitates the ingestion of messages from one platform (e.g., Slack), determines their validity and destination based on predefined gateway rules, and dispatches them to target platforms (e.g., Discord or IRC). This system ensures that user identities, message content, and media attachments are correctly translated and distributed across all connected bridges.
The primary logic resides within the Gateway and Router components, which manage bridge instances, channel mappings, and message transformation rules. By utilizing a central message channel and a routing table, the system can handle complex multi-way synchronization, message edits, and deletions while maintaining protocol-specific nuances like IRC notices or Discord join/leave events.
Architecture and Components
The Router and Gateway Relationship
The routing architecture is built on a hierarchical structure where a Router manages multiple Gateway instances. Each Gateway acts as a logical grouping of bridges and channels that should be synchronized.
| Component | Description |
|---|---|
| Router | Orchestrates the high-level message flow and maintains the global mapping of bridge instances (BridgeMap). |
| Gateway | A specific configuration of interconnected accounts and channels. It handles the specific routing logic for messages within its scope. |
| Bridge | An abstraction of a specific account on a chat protocol (e.g., irc.libera). |
| ChannelInfo | Contains metadata about a specific channel, including its ID, direction (in, out, or inout), and account association. |
Sources: gateway/gateway.go:21-48, gateway/gateway.go:136-168
Logic Flow for Incoming Messages
When a message is received by a bridge, it is sent to the central Router channel. The router then identifies which gateways are interested in that message.
The flowchart above illustrates the high-level path a message takes from ingestion to redistribution.
Sources: gateway/gateway.go:21-48, gateway/gateway.go:170-205
Channel Mapping and Directionality
Channels are mapped within a gateway using three primary directions, which dictate how messages flow between the bridge and the gateway.
- in: Messages are only received from this channel and routed elsewhere.
- out: Messages from other "in" or "inout" channels are sent to this channel.
- inout: Full bidirectional synchronization.
Configuration Structure
Gateways are defined in the configuration (TOML) using these directions. A single gateway can link multiple accounts.
[[gateway]]
name="mygateway"
enable=true
[[gateway.inout]]
account="irc.libera"
channel="#testing"
[[gateway.inout]]
account="mattermost.work"
channel="off-topic"
Sources: README.md:195-214, gateway/gateway.go:136-168
Internal ID Generation
The system generates a unique internal ID for every channel to avoid collisions between bridges using the same channel name. The format used is ChannelName + AccountName.
ID := br.Channel + br.Account
Sources: gateway/gateway.go:148-150, gateway/gateway.go:375-377
Message Modification and Translation
Before a message is dispatched to a destination bridge, it undergoes several transformations to ensure identity preservation and formatting compatibility.
Identity Spoofing and Formatting
The modifyUsername function handles how a sender's name appears on the remote side. This is controlled by the RemoteNickFormat setting, which supports various placeholders.
| Placeholder | Replaced With |
|---|---|
{NICK} | The original sender's username. |
{PROTOCOL} | The protocol name of the source (e.g., slack). |
{BRIDGE} | The name of the source bridge. |
{GATEWAY} | The name of the active gateway. |
{NOPINGNICK} | The username with a zero-width space to prevent pings. |
Sources: gateway/gateway.go:240-281
Message Filtering (Ignore Rules)
The gateway evaluates several "ignore" criteria to prevent loops or unwanted content:
- IgnoreNicks: Drops messages from specific users.
- IgnoreMessages: Drops messages matching specific regex patterns.
- Text Empty: Messages with no text and no attachments (excluding typing events) are ignored.
Sources: gateway/gateway.go:207-224
Logic for Message IDs and Threading
Matterbridge maintains a message ID cache (lru.Cache) to track messages across different platforms. This is critical for features like message edits, deletions, and preserving thread replies.
The sequence diagram shows how the system uses cached IDs to ensure that modifications target the correct message on the remote platform.
Sources: gateway/gateway.go:58-76, gateway/gateway.go:200-205
API Routing
The system includes a specialized api protocol. Messages sent via the API must specify a target gateway. The routing logic verifies the Gateway field in the incoming API message before processing.
API Message Properties
| Field | Type | Description |
|---|---|---|
gateway | string | Required. The name of the target gateway. |
username | string | Required. The display name for the message. |
text | string | Required. The content of the message. |
Sources: contrib/api.yaml:65-98, gateway/gateway.go:173-176
Conclusion
The Message Routing & Mapping system in Matterbridge provides a robust framework for cross-platform communication. By abstracting bridges and channels into logical gateways, it enables flexible synchronization patterns ranging from simple two-way bridges to complex multi-protocol networks. Its internal ID management and identity formatting ensure that while messages move between different environments, the context and origin remain clear to the end users.