imbridge

package
v0.35.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const TelegramDefaultBaseURL = "https://api.telegram.org"

Variables

This section is empty.

Functions

func MatrixSendImage

func MatrixSendImage(ctx context.Context, homeserverURL, accessToken, roomID string, imageData []byte, caption string) error

MatrixSendImage uploads an image to the Matrix content repository and sends an m.image event to a room. If caption is non-empty, it is used as the body text of the image event.

func MatrixSendText

func MatrixSendText(ctx context.Context, homeserverURL, accessToken, roomID, text string) error

MatrixSendText sends a text message to a Matrix room.

func MatrixSendTyping

func MatrixSendTyping(ctx context.Context, homeserverURL, accessToken, userID, roomID string, typing bool, timeoutMs int) error

MatrixSendTyping sends a typing indicator to a Matrix room. userID is the bot's own Matrix user ID (needed for the typing endpoint URL path).

func MatrixWhoami

func MatrixWhoami(ctx context.Context, homeserverURL, accessToken string) (string, error)

MatrixWhoami validates a Matrix access token and returns the authenticated user ID.

func TelegramGetFile

func TelegramGetFile(ctx context.Context, baseURL, botToken, fileID string) ([]byte, error)

TelegramGetFile retrieves the file path for a file_id, then downloads the file content.

func TelegramSendChatAction

func TelegramSendChatAction(ctx context.Context, baseURL, botToken string, chatID int64, action string) error

TelegramSendChatAction sends a typing indicator to a chat.

func TelegramSendMessage

func TelegramSendMessage(ctx context.Context, baseURL, botToken string, chatID int64, text string) error

TelegramSendMessage sends a text message to a chat.

func TelegramSendPhoto

func TelegramSendPhoto(ctx context.Context, baseURL, botToken string, chatID int64, photoData []byte, caption string) error

TelegramSendPhoto sends a photo to a chat via multipart upload.

Types

type Bridge

type Bridge struct {
	// contains filtered or unexported fields
}

Bridge manages per-binding poll goroutines for all IM providers.

func NewBridge

func NewBridge(db BridgeDB, resolver SandboxResolver, exec ExecCommander, providers []Provider) *Bridge

NewBridge creates a new Bridge instance with the given providers.

func (*Bridge) FindProviderByJID

func (b *Bridge) FindProviderByJID(jid string) Provider

FindProviderByJID matches a JID suffix to a provider. Returns nil if no provider matches.

func (*Bridge) GetProvider

func (b *Bridge) GetProvider(name string) Provider

GetProvider returns the provider with the given name, or nil if not found.

func (*Bridge) Providers

func (b *Bridge) Providers() []Provider

Providers returns all registered providers.

func (*Bridge) SetChannelRequireMention added in v0.27.1

func (b *Bridge) SetChannelRequireMention(channelID string, requireMention bool)

SetChannelRequireMention updates the in-memory require_mention setting for a channel.

func (*Bridge) StartPoller

func (b *Bridge) StartPoller(binding BridgeBinding)

StartPoller starts a long-poll goroutine for a channel. If a poller already exists for this channel, it is stopped first.

func (*Bridge) StopAllPollers

func (b *Bridge) StopAllPollers()

StopAllPollers stops all polling goroutines and typing sessions.

func (*Bridge) StopPoller

func (b *Bridge) StopPoller(channelID string)

StopPoller stops the polling goroutine for a specific channel.

func (*Bridge) StopTyping

func (b *Bridge) StopTyping(channelID, userID string)

StopTyping stops the typing indicator for a user in a channel. It first tries an exact match on channelID:userID, then falls back to stopping all typing sessions for the channel (needed for group chats where the reply's to_user_id is the room, not the sender).

type BridgeBinding

type BridgeBinding struct {
	Provider    Provider
	Credentials Credentials
	ChannelID   string // workspace_im_channels.id
	Cursor      string
}

BridgeBinding holds the info needed to run a poller for one IM channel. The sandbox to forward messages to is resolved dynamically from the channel ID.

type BridgeDB

type BridgeDB interface {
	UpdateIMChannelCursor(channelID, cursor string) error
	UpsertChannelMeta(channelID, userID, key, value string) error
	GetChannelMeta(channelID, userID, key string) (string, error)
	GetAllChannelMeta(channelID, userID string) (map[string]string, error)
	GetSandboxForChannel(channelID string) (sandboxID, podIP, bridgeSecret, assistantName string, err error)
}

BridgeDB is the DB interface needed by the bridge.

type ConfigurableProvider

type ConfigurableProvider interface {
	ValidateCredentials(ctx context.Context, baseURL, token string) (botID string, err error)
}

ConfigurableProvider validates credentials during configure. Returns the botID derived from the provider's validation response.

type Credentials

type Credentials struct {
	ChannelID string // workspace_im_channels.id
	BotID     string
	BotToken  string
	BaseURL   string
}

Credentials holds the authentication info needed to talk to an IM API.

type DisconnectProvider

type DisconnectProvider interface {
	Disconnect(sandboxID, botID string)
}

DisconnectProvider handles cleanup when a binding is explicitly disconnected.

type ExecCommander

type ExecCommander interface {
	ExecSimple(ctx context.Context, sandboxID string, command []string) (string, error)
}

ExecCommander can execute a command inside a sandbox pod.

type ImageSendProvider

type ImageSendProvider interface {
	SendImage(ctx context.Context, creds *Credentials, toUserID string, imageData []byte, caption string) error
}

ImageSendProvider is an optional interface for providers that support sending images.

type InboundMessage

type InboundMessage struct {
	FromUserID    string
	SenderName    string
	Text          string
	IsGroup       bool              // true for group/supergroup chats
	Metadata      map[string]string // provider-specific state (e.g., weixin context_token)
	MediaData     []byte            // optional: downloaded media (image/file) binary data
	MediaType     string            // optional: "image", "voice", "file", "video"
	MediaFilename string            // optional: original filename for file attachments
}

InboundMessage represents a single incoming message from the IM platform.

type InitializableProvider

type InitializableProvider interface {
	InitProvider(dbURL string) error
}

InitializableProvider can be initialized with server-level configuration.

type MatrixCryptoClient

type MatrixCryptoClient struct {
	// contains filtered or unexported fields
}

MatrixCryptoClient wraps a long-lived mautrix client with E2EE support.

func (*MatrixCryptoClient) SendImage

func (cc *MatrixCryptoClient) SendImage(ctx context.Context, roomID string, imageData []byte, caption string) error

SendImage uploads an image and sends it to a room, auto-encrypting if E2EE.

func (*MatrixCryptoClient) SendText

func (cc *MatrixCryptoClient) SendText(ctx context.Context, roomID, text string) error

SendText sends a text message to a room, auto-encrypting if the room is E2EE.

func (*MatrixCryptoClient) SendTyping

func (cc *MatrixCryptoClient) SendTyping(ctx context.Context, roomID string, typing bool, timeoutMs int) error

SendTyping sends a typing indicator to a room.

func (*MatrixCryptoClient) SyncAndDecrypt

func (cc *MatrixCryptoClient) SyncAndDecrypt(ctx context.Context, selfUserID string, since string, timeoutSec int, initialSync bool) ([]MatrixMessage, string, error)

SyncAndDecrypt performs a Matrix /sync, processes crypto key exchanges, and decrypts any encrypted messages. When initialSync is true, message decryption is skipped (only crypto state and cursor are processed).

type MatrixCryptoManager

type MatrixCryptoManager struct {
	// contains filtered or unexported fields
}

MatrixCryptoManager manages long-lived E2EE Matrix clients per device.

func NewMatrixCryptoManager

func NewMatrixCryptoManager(mainDBURL string, encKey []byte) *MatrixCryptoManager

NewMatrixCryptoManager creates a manager for E2EE Matrix clients. mainDBURL is the PostgreSQL connection URL for the main database. The crypto database (agentserver_matrix) is derived from it and created if it doesn't exist.

func (*MatrixCryptoManager) GetOrCreate

func (m *MatrixCryptoManager) GetOrCreate(ctx context.Context, creds *Credentials, recoveryKey string) (*MatrixCryptoClient, error)

GetOrCreate returns an existing crypto client or creates a new one. Clients are keyed by botID:deviceID so each access token (with its unique device) gets its own Olm account. Sandboxes using the same token share the same client. If recoveryKey is non-empty, it's used to self-verify the device via SSSS cross-signing.

func (*MatrixCryptoManager) Remove

func (m *MatrixCryptoManager) Remove(sandboxID, botID string)

Remove closes and removes all crypto clients for a bot (all devices).

type MatrixMessage

type MatrixMessage struct {
	RoomID        string
	EventID       string
	SenderID      string
	Text          string
	Timestamp     int64
	Mentioned     bool // true if the bot was @-mentioned
	IsDM          bool // true if the room has only 2 members (direct message)
	MediaData     []byte
	MediaType     string
	MediaFilename string
}

MatrixMessage represents a message received from a Matrix room.

func MatrixSync

func MatrixSync(ctx context.Context, homeserverURL, accessToken, selfUserID, since string, timeoutSec int) ([]MatrixMessage, string, error)

MatrixSync performs a single /sync request, returns messages from joined rooms and the next_batch token. It automatically joins any rooms the bot is invited to. Messages sent by selfUserID are filtered out. selfUserID should be the bot's own Matrix user ID (e.g. "@bot:example.com"), available from creds.BotID.

type MatrixProvider

type MatrixProvider struct {
	CryptoManager *MatrixCryptoManager
}

MatrixProvider implements Provider, TypingProvider, ImageSendProvider, ConfigurableProvider, and DisconnectProvider for the Matrix protocol.

func (*MatrixProvider) ConfigureE2EE

func (p *MatrixProvider) ConfigureE2EE(ctx context.Context, creds *Credentials, recoveryKey string) error

ConfigureE2EE initializes E2EE with the given recovery key for self-verification.

func (*MatrixProvider) Disconnect

func (p *MatrixProvider) Disconnect(sandboxID, botID string)

Disconnect implements DisconnectProvider — closes the E2EE client when a binding is disconnected.

func (*MatrixProvider) InitProvider

func (p *MatrixProvider) InitProvider(dbURL string) error

InitProvider implements InitializableProvider — sets up the E2EE crypto manager.

func (*MatrixProvider) JIDSuffix

func (p *MatrixProvider) JIDSuffix() string

func (*MatrixProvider) Name

func (p *MatrixProvider) Name() string

func (*MatrixProvider) Poll

func (p *MatrixProvider) Poll(ctx context.Context, creds *Credentials, cursor string) (*PollResult, error)

func (*MatrixProvider) Send

func (p *MatrixProvider) Send(ctx context.Context, creds *Credentials, toUserID, text string, meta map[string]string) error

func (*MatrixProvider) SendImage

func (p *MatrixProvider) SendImage(ctx context.Context, creds *Credentials, toUserID string, imageData []byte, caption string) error

SendImage implements ImageSendProvider for Matrix.

func (*MatrixProvider) StartTyping

func (p *MatrixProvider) StartTyping(ctx context.Context, creds *Credentials, userID string, meta map[string]string,
	sendError func(text string))

StartTyping implements TypingProvider for Matrix.

func (*MatrixProvider) ValidateCredentials

func (p *MatrixProvider) ValidateCredentials(ctx context.Context, baseURL, token string) (string, error)

ValidateCredentials implements ConfigurableProvider. Calls Matrix /whoami and initializes E2EE if CryptoManager is set. The token parameter is the access token; baseURL is the homeserver URL. options may contain "recovery_key" for E2EE self-verification.

type PollResult

type PollResult struct {
	Messages      []InboundMessage
	NewCursor     string
	ShouldBackoff time.Duration // >0 means pause before next poll
}

PollResult is returned by Provider.Poll.

type Provider

type Provider interface {
	// Name returns the provider identifier: "weixin", "telegram", "matrix".
	Name() string

	// JIDSuffix returns the suffix used to construct chat JIDs: "@im.wechat", "@tg", "@matrix".
	JIDSuffix() string

	// Poll long-polls the IM API for new messages.
	// cursor is opaque state from the previous poll (empty string on first call).
	Poll(ctx context.Context, creds *Credentials, cursor string) (*PollResult, error)

	// Send sends a text message to a user via the IM API.
	// meta carries provider-specific state (e.g., WeChat context_token). May be nil.
	Send(ctx context.Context, creds *Credentials, toUserID, text string, meta map[string]string) error
}

Provider defines the contract for an IM platform integration.

type RateLimitError

type RateLimitError struct {
	RetryAfter time.Duration
}

RateLimitError is returned when Telegram returns HTTP 429.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

type SandboxResolver

type SandboxResolver interface {
	GetPodIP(sandboxID string) string
}

SandboxResolver looks up the current state of a sandbox.

type TelegramBotInfo

type TelegramBotInfo struct {
	ID        int64  `json:"id"`
	IsBot     bool   `json:"is_bot"`
	FirstName string `json:"first_name"`
	Username  string `json:"username"`
}

TelegramBotInfo is the response from Telegram's getMe API.

func TelegramGetMe

func TelegramGetMe(ctx context.Context, baseURL, botToken string) (*TelegramBotInfo, error)

TelegramGetMe validates a bot token and returns bot info.

type TelegramChat

type TelegramChat struct {
	ID   int64  `json:"id"`
	Type string `json:"type"` // "private", "group", "supergroup", "channel"
}

TelegramChat represents a Telegram chat.

type TelegramDocument

type TelegramDocument struct {
	FileID       string `json:"file_id"`
	FileUniqueID string `json:"file_unique_id"`
	FileName     string `json:"file_name"`
	MimeType     string `json:"mime_type"`
	FileSize     int    `json:"file_size"`
}

TelegramDocument represents a document/file in a Telegram message.

type TelegramMessage

type TelegramMessage struct {
	MessageID int64             `json:"message_id"`
	From      *TelegramUser     `json:"from"`
	Chat      TelegramChat      `json:"chat"`
	Text      string            `json:"text"`
	Caption   string            `json:"caption"`
	Photo     []TelegramPhoto   `json:"photo"`
	Document  *TelegramDocument `json:"document"`
}

TelegramMessage represents a Telegram message.

type TelegramPhoto

type TelegramPhoto struct {
	FileID       string `json:"file_id"`
	FileUniqueID string `json:"file_unique_id"`
	Width        int    `json:"width"`
	Height       int    `json:"height"`
	FileSize     int    `json:"file_size"`
}

TelegramPhoto represents a photo size in a Telegram message.

type TelegramProvider

type TelegramProvider struct{}

TelegramProvider implements Provider for Telegram Bot API.

func (*TelegramProvider) DefaultBaseURL

func (p *TelegramProvider) DefaultBaseURL() string

DefaultBaseURL returns the default Telegram Bot API base URL.

func (*TelegramProvider) JIDSuffix

func (p *TelegramProvider) JIDSuffix() string

func (*TelegramProvider) Name

func (p *TelegramProvider) Name() string

func (*TelegramProvider) Poll

func (p *TelegramProvider) Poll(ctx context.Context, creds *Credentials, cursor string) (*PollResult, error)

func (*TelegramProvider) Send

func (p *TelegramProvider) Send(ctx context.Context, creds *Credentials, toUserID, text string, meta map[string]string) error

func (*TelegramProvider) SendImage

func (p *TelegramProvider) SendImage(ctx context.Context, creds *Credentials, toUserID string, imageData []byte, caption string) error

SendImage implements ImageSendProvider for Telegram.

func (*TelegramProvider) StartTyping

func (p *TelegramProvider) StartTyping(ctx context.Context, creds *Credentials, userID string, meta map[string]string,
	sendError func(text string))

StartTyping implements TypingProvider for Telegram. Sends "typing" chat action every 5s (Telegram auto-cancels after ~5s). On timeout (5min), sends error notice and stops.

func (*TelegramProvider) ValidateCredentials

func (p *TelegramProvider) ValidateCredentials(ctx context.Context, baseURL, token string) (string, error)

ValidateCredentials implements ConfigurableProvider for Telegram. Calls the Telegram getMe API and returns the bot username as botID.

type TelegramUpdate

type TelegramUpdate struct {
	UpdateID int64            `json:"update_id"`
	Message  *TelegramMessage `json:"message"`
}

TelegramUpdate represents a single update from Telegram's getUpdates API.

func TelegramGetUpdates

func TelegramGetUpdates(ctx context.Context, baseURL, botToken string, offset int64, timeout int) ([]TelegramUpdate, error)

TelegramGetUpdates long-polls for new updates.

type TelegramUser

type TelegramUser struct {
	ID        int64  `json:"id"`
	IsBot     bool   `json:"is_bot"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
}

TelegramUser represents a Telegram user.

type TypingProvider

type TypingProvider interface {
	StartTyping(ctx context.Context, creds *Credentials, userID string, meta map[string]string,
		sendError func(text string))
}

TypingProvider is an optional interface for providers that support typing indicators.

type WeixinProvider

type WeixinProvider struct{}

WeixinProvider implements Provider for WeChat via iLink API.

func (*WeixinProvider) ClearSession

func (p *WeixinProvider) ClearSession(sandboxID string)

ClearSession removes the QR login session for a sandbox.

func (*WeixinProvider) DefaultBaseURL

func (p *WeixinProvider) DefaultBaseURL() string

DefaultBaseURL returns the default iLink API base URL.

func (*WeixinProvider) GetSession

func (p *WeixinProvider) GetSession(sandboxID string) *weixin.Session

GetSession retrieves the current QR login session for a sandbox.

func (*WeixinProvider) JIDSuffix

func (p *WeixinProvider) JIDSuffix() string

func (*WeixinProvider) Name

func (p *WeixinProvider) Name() string

func (*WeixinProvider) Poll

func (p *WeixinProvider) Poll(ctx context.Context, creds *Credentials, cursor string) (*PollResult, error)

func (*WeixinProvider) PollQRLogin

func (p *WeixinProvider) PollQRLogin(ctx context.Context, qrCode string) (*weixin.StatusResult, error)

PollQRLogin polls for the QR code scan status.

func (*WeixinProvider) Send

func (p *WeixinProvider) Send(ctx context.Context, creds *Credentials, toUserID, text string, meta map[string]string) error

func (*WeixinProvider) SendImage

func (p *WeixinProvider) SendImage(ctx context.Context, creds *Credentials, toUserID string, imageData []byte, caption string) error

SendImage implements ImageSendProvider for WeChat. Uploads the image to CDN and sends it, then sends the caption as a separate text message.

func (*WeixinProvider) SetSession

func (p *WeixinProvider) SetSession(sandboxID string, session *weixin.Session)

SetSession stores a QR login session for a sandbox.

func (*WeixinProvider) StartQRLogin

func (p *WeixinProvider) StartQRLogin(ctx context.Context) (*weixin.Session, error)

StartQRLogin initiates a WeChat QR code login flow.

func (*WeixinProvider) StartTyping

func (p *WeixinProvider) StartTyping(ctx context.Context, creds *Credentials, userID string, meta map[string]string,
	sendError func(text string))

StartTyping implements TypingProvider for WeChat. It fetches a typing_ticket via GetConfig, then sends typing keepalives every 5s. On timeout (5min), it sends an error notice to the user and stops.

func (*WeixinProvider) TakeSession

func (p *WeixinProvider) TakeSession(sandboxID string) *weixin.Session

TakeSession atomically retrieves and removes the QR login session.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL