This commit implements a comprehensive bridge-agnostic message routing system that enables real-time bidirectional message synchronization between XMPP and Mattermost platforms. Key features: - Bridge-agnostic message types and structures for extensibility - Central message bus system with publisher-subscriber pattern - Complete Bridge interface implementation for both XMPP and Mattermost - Message aggregation from multiple sources for scalability - Loop prevention mechanisms to avoid infinite message cycles - Buffered channels for high-performance message processing Architecture highlights: - Producer-consumer pattern for message routing between bridges - Thread-safe goroutine lifecycle management with context cancellation - Message handlers separated into dedicated files for maintainability - Support for future bridge implementations (Slack, Discord, etc.) - Markdown content standardization across all bridges Files added: - server/model/message.go: Core bridge-agnostic message structures - server/bridge/messagebus.go: Central message routing system - server/bridge/mattermost/message_handler.go: Mattermost-specific message processing - server/bridge/xmpp/message_handler.go: XMPP-specific message processing Files modified: - server/bridge/manager.go: Integration with message bus and routing - server/bridge/mattermost/bridge.go: Complete Bridge interface implementation - server/bridge/xmpp/bridge.go: Message aggregation and interface completion - server/model/bridge.go: Extended Bridge interface for bidirectional messaging - server/xmpp/client.go: Enhanced message listening with mellium.im/xmpp 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
88 lines
No EOL
2.8 KiB
Go
88 lines
No EOL
2.8 KiB
Go
package model
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// MessageDirection indicates the direction of message flow
|
|
type MessageDirection string
|
|
|
|
const (
|
|
DirectionIncoming MessageDirection = "incoming" // From external system to us
|
|
DirectionOutgoing MessageDirection = "outgoing" // From us to external system
|
|
)
|
|
|
|
// BridgeMessage represents a message that can be passed between any bridge types
|
|
type BridgeMessage struct {
|
|
// Source information
|
|
SourceBridge string // "xmpp", "mattermost", "slack", etc.
|
|
SourceChannelID string // Channel ID in source system
|
|
SourceUserID string // User ID in source system (JID, user ID, etc.)
|
|
SourceUserName string // Display name in source system
|
|
|
|
// Message content (standardized on Markdown)
|
|
Content string // Markdown formatted message content
|
|
MessageType string // "text", "image", "file", etc.
|
|
|
|
// Metadata
|
|
Timestamp time.Time // When message was received
|
|
MessageID string // Unique message ID from source
|
|
ThreadID string // Thread/reply ID (if applicable)
|
|
|
|
// Routing hints
|
|
TargetBridges []string // Which bridges should receive this
|
|
Metadata map[string]any // Bridge-specific metadata
|
|
}
|
|
|
|
// DirectionalMessage wraps a BridgeMessage with direction information
|
|
type DirectionalMessage struct {
|
|
*BridgeMessage
|
|
Direction MessageDirection
|
|
}
|
|
|
|
// ExternalUser represents a user from any bridge system
|
|
type ExternalUser struct {
|
|
BridgeType string // "xmpp", "slack", etc.
|
|
ExternalUserID string // JID, Slack user ID, etc.
|
|
DisplayName string // How to display this user
|
|
MattermostUserID string // Mapped Mattermost user (if exists)
|
|
}
|
|
|
|
// UserResolver handles user resolution for a specific bridge
|
|
type UserResolver interface {
|
|
// ResolveUser converts an external user ID to an ExternalUser
|
|
ResolveUser(externalUserID string) (*ExternalUser, error)
|
|
|
|
// FormatUserMention formats a user mention for Markdown content
|
|
FormatUserMention(user *ExternalUser) string
|
|
|
|
// GetDisplayName extracts display name from external user ID
|
|
GetDisplayName(externalUserID string) string
|
|
}
|
|
|
|
// MessageBus handles routing messages between bridges
|
|
type MessageBus interface {
|
|
// Subscribe returns a channel that receives messages for the specified bridge
|
|
Subscribe(bridgeName string) <-chan *DirectionalMessage
|
|
|
|
// Publish sends a message to the message bus for routing
|
|
Publish(msg *DirectionalMessage) error
|
|
|
|
// Start begins message routing
|
|
Start() error
|
|
|
|
// Stop ends message routing and cleans up resources
|
|
Stop() error
|
|
}
|
|
|
|
// MessageHandler processes incoming messages for a bridge
|
|
type MessageHandler interface {
|
|
// ProcessMessage handles an incoming message
|
|
ProcessMessage(msg *DirectionalMessage) error
|
|
|
|
// CanHandleMessage determines if this handler can process the message
|
|
CanHandleMessage(msg *BridgeMessage) bool
|
|
|
|
// GetSupportedMessageTypes returns the message types this handler supports
|
|
GetSupportedMessageTypes() []string
|
|
} |