The Gateway System
Relevant source files
The following files were used as context for generating this wiki page:
The Gateway System is the core routing engine of Matterbridge, responsible for interconnecting multiple chat protocols and managing the flow of messages between them. It acts as a bridge-aggregator that allows messages from one platform (e.g., IRC, Slack, or Discord) to be synchronized across others based on defined configurations. The system handles complex tasks such as message transformation, user spoofing, attachment handling, and protocol-specific event translation.
At its high level, a Gateway defines the relationship between different "accounts" and "channels," specifying whether communication is one-way (In/Out) or bidirectional (InOut). It ensures that a message received on one side is correctly formatted and delivered to all valid destinations within the same gateway context.
Sources: gateway/gateway.go:21-40, README.md:121-140
Architecture and Components
The gateway architecture revolves around the Gateway struct, which manages the lifecycle of bridges and the routing of messages. It relies on a Router to handle the physical message channel and maintains its own set of channels and bridge instances.
Core Data Structures
| Structure | Description |
|---|---|
Gateway | The main controller for a specific bridge configuration, holding bridge instances and channel mappings. |
BrMsgID | A mapping structure used to track message IDs across different protocols for threading and edits. |
ChannelInfo | Stores metadata about a specific channel, including its direction (in/out/inout) and options. |
Sources: gateway/gateway.go:21-39, gateway/gateway.go:42-46
System Workflow
The following diagram illustrates how the Gateway system initializes and processes messages between protocols.
Message Routing Logic
Routing is determined by the direction defined in the configuration. The system differentiates between in, out, and inout channels to prevent message loops and ensure controlled synchronization.
Directional Mapping
- In: Messages are only received from this channel and forwarded to others.
- Out: Messages are only sent to this channel from other "in" sources.
- InOut: Bidirectional communication; acts as both a source and a destination.
The mapChannelConfig function handles the normalization of these paths, including specific logic for protocols like IRC (lowercasing channels) and Mattermost (handling leading hash characters).
Sources: gateway/gateway.go:151-188
Destination Resolution
The getDestChannel function calculates the final delivery targets. It checks:
- If the source channel is configured as an "in" or "inout" source.
- If the destination bridge is part of the same gateway.
SameChannellogic: If enabled, messages are routed to channels with identical names on other protocols.- API-specific constraints to ensure messages originating from the API bridge only route to the intended gateway.
Sources: gateway/gateway.go:195-233
Message Transformation and Filtering
Before a message is sent to a destination, it undergoes several transformation phases to match the destination's format and the user's preferences.
Modification Pipeline
- Ignore Filtering: Messages can be ignored based on "IgnoreNicks" or "IgnoreMessages" regex patterns. Empty messages are also dropped unless they contain attachments or typing events.
- Tengo Integration: Users can provide
.tengoscripts viaInMessageandOutMessageconfiguration settings to programmatically modify message text, usernames, or drop messages entirely. - Username Spoofing: The
modifyUsernamefunction appliesRemoteNickFormat, replaces nicks via regex, and can inject a "No-Ping" character to prevent accidental mentions. - Emoji Translation: The system replaces
:emoji:strings with their Unicode equivalents using theemojilibrary.
Sources: gateway/gateway.go:261-279, gateway/gateway.go:297-347, gateway/gateway.go:487-515
Transformation Sequence
API Interface
The Gateway system includes a dedicated API protocol (apiProtocol = "api") allowing external applications to interact with the bridge. The API supports posting messages to specific gateways and streaming incoming messages in real-time.
API Capabilities
| Endpoint | Method | Description |
|---|---|---|
/message | POST | Send an OutgoingMessage to a gateway. |
/messages | GET | List new messages from the bridge. |
/stream | GET | Real-time stream of IncomingMessage objects via JSON stream. |
Sources: contrib/api.yaml:15-60, gateway/gateway.go:46
The API bridge is treated as a "fixed" protocol where the account name usually starts with api.. Unlike standard bridges, it requires the gateway field in the message payload to identify the target routing context.
Sources: gateway/gateway.go:200-203, contrib/api.yaml:135-145
Threading and Message ID Tracking
To support message edits, deletions, and threading, the Gateway maintains an LRU (Least Recently Used) cache of message IDs.
- Canonical IDs: When a message is received, it is stored using a canonical ID format:
protocol + " " + messageID. - ID Mapping: The
getDestMsgIDfunction looks up this cache to find the corresponding ID on a destination platform. This allows an edit on Slack to correctly update the previously sent message on Discord. - Parent Tracking: For threaded conversations, the system attempts to resolve the
ParentID. If a parent message is not found in the cache, it is marked with aParentIDNotFoundconstant.
Sources: gateway/gateway.go:61-79, gateway/gateway.go:235-247, gateway/gateway.go:417-429
The Gateway System serves as the intelligent intermediary of Matterbridge. By combining strict directional routing with flexible scriptable transformations and cross-protocol ID tracking, it enables seamless communication across disparate chat ecosystems while maintaining context such as threading and user identity.