Documentation ¶
Index ¶
- Constants
- Variables
- func FormatHelp(ce *CommandEvent) string
- type AliasedCommandHandler
- type Avatar
- type Bridge
- func (br *Bridge) GetAllUserLogins(ctx context.Context) ([]*UserLogin, error)
- func (br *Bridge) GetCachedUserLoginByID(id networkid.UserLoginID) *UserLogin
- func (br *Bridge) GetExistingPortalByID(ctx context.Context, id networkid.PortalKey) (*Portal, error)
- func (br *Bridge) GetExistingUserByMXID(ctx context.Context, userID id.UserID) (*User, error)
- func (br *Bridge) GetGhostByID(ctx context.Context, id networkid.UserID) (*Ghost, error)
- func (br *Bridge) GetGhostByMXID(ctx context.Context, mxid id.UserID) (*Ghost, error)
- func (br *Bridge) GetPortalByID(ctx context.Context, id networkid.PortalKey) (*Portal, error)
- func (br *Bridge) GetPortalByMXID(ctx context.Context, mxid id.RoomID) (*Portal, error)
- func (br *Bridge) GetUserByMXID(ctx context.Context, userID id.UserID) (*User, error)
- func (br *Bridge) GetUserLoginsInPortal(ctx context.Context, portal networkid.PortalKey) ([]*UserLogin, error)
- func (br *Bridge) NewBridgeStateQueue(user status.BridgeStateFiller) *BridgeStateQueue
- func (br *Bridge) QueueMatrixEvent(ctx context.Context, evt *event.Event)
- func (br *Bridge) QueueRemoteEvent(login *UserLogin, evt RemoteEvent)
- func (br *Bridge) SendGlobalBridgeState(state status.BridgeState)
- func (br *Bridge) Start() error
- type BridgeName
- type BridgeStateQueue
- type CommandEvent
- type CommandHandler
- type CommandProcessor
- type CommandState
- type ConfigValidatingNetwork
- type ConvertedEdit
- type ConvertedEditPart
- type ConvertedMessage
- type ConvertedMessagePart
- type DBUpgradeError
- type EventSender
- type FullHandler
- type Ghost
- func (ghost *Ghost) IntentFor(portal *Portal) MatrixAPI
- func (ghost *Ghost) UpdateAvatar(ctx context.Context, avatar *Avatar) bool
- func (ghost *Ghost) UpdateContactInfo(ctx context.Context, identifiers []string, isBot *bool) bool
- func (ghost *Ghost) UpdateInfo(ctx context.Context, info *UserInfo)
- func (ghost *Ghost) UpdateInfoIfNecessary(ctx context.Context, source *UserLogin)
- func (ghost *Ghost) UpdateName(ctx context.Context, name string) bool
- type HelpMeta
- type HelpSection
- type HelpfulHandler
- type LoginCompleteParams
- type LoginCookiesParams
- type LoginDisplayAndWaitParams
- type LoginDisplayType
- type LoginFlow
- type LoginInputDataField
- type LoginInputFieldType
- type LoginProcess
- type LoginProcessCookies
- type LoginProcessDisplayAndWait
- type LoginProcessUserInput
- type LoginStep
- type LoginStepType
- type LoginSubmit
- type LoginUserInputParams
- type MatrixAPI
- type MatrixConnector
- type MatrixEdit
- type MatrixEventBase
- type MatrixMessage
- type MatrixMessageRemove
- type MatrixReaction
- type MatrixReactionPreResponse
- type MatrixReactionRemove
- type MatrixReadReceipt
- type MatrixTyping
- type MaxFileSizeingNetwork
- type MessageStatus
- func (ms MessageStatus) Error() string
- func (ms *MessageStatus) ToCheckpoint(evt *MessageStatusEventInfo) *status.MessageCheckpoint
- func (ms *MessageStatus) ToMSSEvent(evt *MessageStatusEventInfo) *event.BeeperMessageStatusEventContent
- func (ms *MessageStatus) ToNoticeEvent(evt *MessageStatusEventInfo) *event.MessageEventContent
- func (ms MessageStatus) Unwrap() error
- func (ms MessageStatus) WithErrorAsMessage() MessageStatus
- func (ms MessageStatus) WithErrorReason(reason event.MessageStatusReason) MessageStatus
- func (ms MessageStatus) WithIsCertain(certain bool) MessageStatus
- func (ms MessageStatus) WithMessage(msg string) MessageStatus
- func (ms MessageStatus) WithSendNotice(send bool) MessageStatus
- func (ms MessageStatus) WithStatus(status event.MessageStatus) MessageStatus
- func (ms MessageStatus) WithStep(step status.MessageCheckpointStep) MessageStatus
- type MessageStatusEventInfo
- type MinimalCommandHandler
- type MinimalCommandHandlerFunc
- type NetworkAPI
- type NetworkConnector
- type OrigSender
- type Portal
- func (portal *Portal) CreateMatrixRoom(ctx context.Context, source *UserLogin) error
- func (portal *Portal) FindPreferredLogin(ctx context.Context, user *User, allowRelay bool) (*UserLogin, *database.UserPortal, error)
- func (portal *Portal) GetTopLevelParent() *Portal
- func (portal *Portal) SyncParticipants(ctx context.Context, members []networkid.UserID, source *UserLogin) ([]id.UserID, []id.UserID, error)
- func (portal *Portal) UpdateAvatar(ctx context.Context, avatar *Avatar, sender *Ghost, ts time.Time) bool
- func (portal *Portal) UpdateBridgeInfo(ctx context.Context)
- func (portal *Portal) UpdateInfo(ctx context.Context, info *PortalInfo, sender *Ghost, ts time.Time)
- func (portal *Portal) UpdateName(ctx context.Context, name string, sender *Ghost, ts time.Time) bool
- func (portal *Portal) UpdateTopic(ctx context.Context, topic string, sender *Ghost, ts time.Time) bool
- type PortalInfo
- type RemoteEdit
- type RemoteEvent
- type RemoteEventThatMayCreatePortal
- type RemoteEventType
- type RemoteEventWithTargetMessage
- type RemoteEventWithTargetPart
- type RemoteEventWithTimestamp
- type RemoteMessage
- type RemoteMessageRemove
- type RemoteReaction
- type RemoteReactionRemove
- type RemoteReactionWithMeta
- type RemoteReceipt
- type RemoteTyping
- type SimpleRemoteEvent
- func (sre *SimpleRemoteEvent[T]) AddLogContext(c zerolog.Context) zerolog.Context
- func (sre *SimpleRemoteEvent[T]) ConvertEdit(ctx context.Context, portal *Portal, intent MatrixAPI, ...) (*ConvertedEdit, error)
- func (sre *SimpleRemoteEvent[T]) ConvertMessage(ctx context.Context, portal *Portal, intent MatrixAPI) (*ConvertedMessage, error)
- func (sre *SimpleRemoteEvent[T]) GetID() networkid.MessageID
- func (sre *SimpleRemoteEvent[T]) GetPortalKey() networkid.PortalKey
- func (sre *SimpleRemoteEvent[T]) GetReactionDBMetadata() map[string]any
- func (sre *SimpleRemoteEvent[T]) GetReactionEmoji() (string, networkid.EmojiID)
- func (sre *SimpleRemoteEvent[T]) GetRemovedEmojiID() networkid.EmojiID
- func (sre *SimpleRemoteEvent[T]) GetSender() EventSender
- func (sre *SimpleRemoteEvent[T]) GetTargetMessage() networkid.MessageID
- func (sre *SimpleRemoteEvent[T]) GetTimestamp() time.Time
- func (sre *SimpleRemoteEvent[T]) GetType() RemoteEventType
- func (sre *SimpleRemoteEvent[T]) ShouldCreatePortal() bool
- type User
- func (user *User) DoublePuppet(ctx context.Context) MatrixAPI
- func (user *User) LoginDoublePuppet(ctx context.Context, token string) error
- func (user *User) LogoutDoublePuppet(ctx context.Context)
- func (user *User) NewLogin(ctx context.Context, data *database.UserLogin, client NetworkAPI) (*UserLogin, error)
- func (user *User) Save(ctx context.Context) error
- type UserInfo
- type UserLogin
- func (ul *UserLogin) GetMXID() id.UserID
- func (ul *UserLogin) GetRemoteID() string
- func (ul *UserLogin) GetRemoteName() string
- func (ul *UserLogin) Logout(ctx context.Context)
- func (ul *UserLogin) MarkAsPreferredIn(ctx context.Context, portal *Portal) error
- func (ul *UserLogin) Save(ctx context.Context) error
Constants ¶
const PortalEventBuffer = 64
Variables ¶
var ( // Deprecated: this should be used as a placeholder that needs to be fixed HelpSectionUnclassified = HelpSection{"Unclassified", -1} HelpSectionGeneral = HelpSection{"General", 0} HelpSectionAuth = HelpSection{"Authentication", 10} HelpSectionAdmin = HelpSection{"Administration", 50} )
var ( ErrNoPortal error = WrapErrorInStatus(errors.New("room is not a portal")).WithIsCertain(true).WithSendNotice(false) ErrIgnoringReactionFromRelayedUser error = WrapErrorInStatus(errors.New("ignoring reaction event from relayed user")).WithIsCertain(true).WithSendNotice(false) ErrUnexpectedParsedContentType error = WrapErrorInStatus(errors.New("unexpected parsed content type")).WithErrorAsMessage().WithIsCertain(true).WithSendNotice(true) ErrDatabaseError error = WrapErrorInStatus(errors.New("database error")).WithMessage("internal database error").WithIsCertain(true).WithSendNotice(true) ErrTargetMessageNotFound error = WrapErrorInStatus(errors.New("target message not found")).WithErrorAsMessage().WithIsCertain(true).WithSendNotice(false) )
var CommandCancel = &FullHandler{ Func: func(ce *CommandEvent) { state := ce.User.CommandState.Swap(nil) if state != nil { action := state.Action if action == "" { action = "Unknown action" } if state.Cancel != nil { state.Cancel() } ce.Reply("%s cancelled.", action) } else { ce.Reply("No ongoing command.") } }, Name: "cancel", Help: HelpMeta{ Section: HelpSectionGeneral, Description: "Cancel an ongoing action.", }, }
var CommandHelp = &FullHandler{ Func: func(ce *CommandEvent) { ce.Reply(FormatHelp(ce)) }, Name: "help", Help: HelpMeta{ Section: HelpSectionGeneral, Description: "Show this help message.", }, }
var CommandLogin = &FullHandler{ Func: fnLogin, Name: "login", Help: HelpMeta{ Section: HelpSectionAuth, Description: "Log into the bridge", Args: "[_flow ID_]", }, }
var CommandLogout = &FullHandler{ Func: fnLogout, Name: "logout", Help: HelpMeta{ Section: HelpSectionAuth, Description: "Log out of the bridge", Args: "<_login ID_>", }, }
var CommandSetPreferredLogin = &FullHandler{ Func: fnSetPreferredLogin, Name: "set-preferred-login", Aliases: []string{"prefer"}, Help: HelpMeta{ Section: HelpSectionAuth, Description: "Set the preferred login ID for sending messages to this portal (only relevant when logged into multiple accounts via the bridge)", Args: "<_login ID_>", }, RequiresPortal: true, }
var ErrNotLoggedIn = errors.New("not logged in")
Functions ¶
func FormatHelp ¶
func FormatHelp(ce *CommandEvent) string
Types ¶
type AliasedCommandHandler ¶
type AliasedCommandHandler interface { CommandHandler GetAliases() []string }
type Avatar ¶
type Bridge ¶
type Bridge struct { ID networkid.BridgeID DB *database.Database Log zerolog.Logger Matrix MatrixConnector Bot MatrixAPI Network NetworkConnector Commands *CommandProcessor Config *bridgeconfig.BridgeConfig // contains filtered or unexported fields }
func NewBridge ¶
func NewBridge(bridgeID networkid.BridgeID, db *dbutil.Database, log zerolog.Logger, cfg *bridgeconfig.BridgeConfig, matrix MatrixConnector, network NetworkConnector) *Bridge
func (*Bridge) GetAllUserLogins ¶
func (*Bridge) GetCachedUserLoginByID ¶
func (br *Bridge) GetCachedUserLoginByID(id networkid.UserLoginID) *UserLogin
func (*Bridge) GetExistingPortalByID ¶
func (*Bridge) GetExistingUserByMXID ¶
func (*Bridge) GetGhostByID ¶
func (*Bridge) GetGhostByMXID ¶
func (*Bridge) GetPortalByID ¶
func (*Bridge) GetPortalByMXID ¶
func (*Bridge) GetUserByMXID ¶
func (*Bridge) GetUserLoginsInPortal ¶
func (*Bridge) NewBridgeStateQueue ¶
func (br *Bridge) NewBridgeStateQueue(user status.BridgeStateFiller) *BridgeStateQueue
func (*Bridge) QueueMatrixEvent ¶
func (*Bridge) QueueRemoteEvent ¶
func (br *Bridge) QueueRemoteEvent(login *UserLogin, evt RemoteEvent)
func (*Bridge) SendGlobalBridgeState ¶
func (br *Bridge) SendGlobalBridgeState(state status.BridgeState)
type BridgeName ¶
type BridgeName struct { // The displayname of the network, e.g. `Discord` DisplayName string // The URL to the website of the network, e.g. `https://discord.com` NetworkURL string // The icon of the network as a mxc:// URI NetworkIcon id.ContentURIString // An identifier uniquely identifying the network, e.g. `discord` NetworkID string // An identifier uniquely identifying the bridge software, e.g. `discordgo` BeeperBridgeType string // The default appservice port to use in the example config, defaults to 8080 if unset DefaultPort uint16 // The default command prefix to use in the example config, defaults to NetworkID if unset. Must include the ! prefix. DefaultCommandPrefix string }
BridgeName contains information about the network that a connector bridges to.
func (BridgeName) AsBridgeInfoSection ¶
func (bn BridgeName) AsBridgeInfoSection() event.BridgeInfoSection
type BridgeStateQueue ¶
type BridgeStateQueue struct {
// contains filtered or unexported fields
}
func (*BridgeStateQueue) GetPrev ¶
func (bsq *BridgeStateQueue) GetPrev() status.BridgeState
func (*BridgeStateQueue) Send ¶
func (bsq *BridgeStateQueue) Send(state status.BridgeState)
func (*BridgeStateQueue) SetPrev ¶
func (bsq *BridgeStateQueue) SetPrev(prev status.BridgeState)
type CommandEvent ¶
type CommandEvent struct { Bot MatrixAPI Bridge *Bridge Portal *Portal Processor *CommandProcessor Handler MinimalCommandHandler RoomID id.RoomID EventID id.EventID User *User Command string Args []string RawArgs string ReplyTo id.EventID Ctx context.Context Log *zerolog.Logger }
CommandEvent stores all data which might be used to handle commands
func (*CommandEvent) MarkRead ¶
func (ce *CommandEvent) MarkRead()
MarkRead marks the command event as read.
func (*CommandEvent) React ¶
func (ce *CommandEvent) React(key string)
React sends a reaction to the command.
func (*CommandEvent) Redact ¶
func (ce *CommandEvent) Redact(req ...mautrix.ReqRedact)
Redact redacts the command.
func (*CommandEvent) Reply ¶
func (ce *CommandEvent) Reply(msg string, args ...any)
Reply sends a reply to command as notice, with optional string formatting and automatic $cmdprefix replacement.
func (*CommandEvent) ReplyAdvanced ¶
func (ce *CommandEvent) ReplyAdvanced(msg string, allowMarkdown, allowHTML bool)
ReplyAdvanced sends a reply to command as notice. It allows using HTML and disabling markdown, but doesn't have built-in string formatting.
type CommandHandler ¶
type CommandHandler interface { MinimalCommandHandler GetName() string }
type CommandProcessor ¶
type CommandProcessor struct {
// contains filtered or unexported fields
}
func NewProcessor ¶
func NewProcessor(bridge *Bridge) *CommandProcessor
NewProcessor creates a CommandProcessor
func (*CommandProcessor) AddHandler ¶
func (proc *CommandProcessor) AddHandler(handler CommandHandler)
func (*CommandProcessor) AddHandlers ¶
func (proc *CommandProcessor) AddHandlers(handlers ...CommandHandler)
type CommandState ¶
type CommandState struct { Next MinimalCommandHandler Action string Meta any Cancel func() }
type ConfigValidatingNetwork ¶
type ConfigValidatingNetwork interface { NetworkConnector ValidateConfig() error }
ConfigValidatingNetwork is an optional interface that network connectors can implement to validate config fields before the bridge is started.
When the ValidateConfig method is called, the config data will already be unmarshaled into the object returned by [NetworkConnector.GetConfig].
This mechanism is usually used to refuse bridge startup if a mandatory field has an invalid value.
type ConvertedEdit ¶
type ConvertedEdit struct { ModifiedParts []*ConvertedEditPart DeletedParts []*database.Message }
type ConvertedEditPart ¶
type ConvertedEditPart struct { Part *database.Message Type event.Type // The Content and Extra fields will be put inside `m.new_content` automatically. // SetEdit must NOT be called by the network connector. Content *event.MessageEventContent Extra map[string]any // TopLevelExtra can be used to specify custom fields at the top level of the content rather than inside `m.new_content`. TopLevelExtra map[string]any }
type ConvertedMessage ¶
type ConvertedMessage struct { ReplyTo *networkid.MessageOptionalPartID ThreadRoot *networkid.MessageOptionalPartID Parts []*ConvertedMessagePart }
type ConvertedMessagePart ¶
type DBUpgradeError ¶
func (DBUpgradeError) Error ¶
func (e DBUpgradeError) Error() string
func (DBUpgradeError) Unwrap ¶
func (e DBUpgradeError) Unwrap() error
type EventSender ¶
type EventSender struct { IsFromMe bool SenderLogin networkid.UserLoginID Sender networkid.UserID }
type FullHandler ¶
type FullHandler struct { Func func(*CommandEvent) Name string Aliases []string Help HelpMeta RequiresAdmin bool RequiresPortal bool RequiresLogin bool RequiresEventLevel event.Type }
func (*FullHandler) GetAliases ¶
func (fh *FullHandler) GetAliases() []string
func (*FullHandler) GetHelp ¶
func (fh *FullHandler) GetHelp() HelpMeta
func (*FullHandler) GetName ¶
func (fh *FullHandler) GetName() string
func (*FullHandler) Run ¶
func (fh *FullHandler) Run(ce *CommandEvent)
func (*FullHandler) ShowInHelp ¶
func (fh *FullHandler) ShowInHelp(ce *CommandEvent) bool
type Ghost ¶
type Ghost struct { *database.Ghost Bridge *Bridge Log zerolog.Logger Intent MatrixAPI MXID id.UserID }
func (*Ghost) UpdateAvatar ¶
func (*Ghost) UpdateContactInfo ¶
func (*Ghost) UpdateInfoIfNecessary ¶
type HelpMeta ¶
type HelpMeta struct { Command string Section HelpSection Description string Args string }
type HelpSection ¶
type HelpfulHandler ¶
type HelpfulHandler interface { CommandHandler GetHelp() HelpMeta ShowInHelp(*CommandEvent) bool }
type LoginCompleteParams ¶
type LoginCompleteParams struct {
UserLoginID networkid.UserLoginID `json:"user_login_id"`
}
type LoginCookiesParams ¶
type LoginCookiesParams struct { URL string `json:"url"` UserAgent string `json:"user_agent,omitempty"` CookieDomain string `json:"cookie_domain,omitempty"` CookieKeys []string `json:"cookie_keys,omitempty"` LocalStorageKeys []string `json:"local_storage_keys,omitempty"` SpecialKeys []string `json:"special_keys,omitempty"` SpecialExtractJS string `json:"special_extract_js,omitempty"` }
type LoginDisplayAndWaitParams ¶
type LoginDisplayAndWaitParams struct { // The type of thing to display (QR, emoji or text code) Type LoginDisplayType `json:"type"` // The thing to display (raw data for QR, unicode emoji for emoji, plain string for code) Data string `json:"data"` // An image containing the thing to display. If present, this is recommended over using data directly. // For emojis, the URL to the canonical image representation of the emoji ImageURL string `json:"image_url,omitempty"` }
type LoginDisplayType ¶
type LoginDisplayType string
const ( LoginDisplayTypeQR LoginDisplayType = "qr" LoginDisplayTypeEmoji LoginDisplayType = "emoji" LoginDisplayTypeCode LoginDisplayType = "code" )
type LoginInputDataField ¶
type LoginInputDataField struct { // The type of input field as a hint for the client. Type LoginInputFieldType `json:"type"` // The ID of the field to be used as the key in the map that is submitted to the connector. ID string `json:"id"` // The name of the field shown to the user. Name string `json:"name"` // The description of the field shown to the user. Description string `json:"description"` // A regex pattern that the client can use to validate input client-side. Pattern string `json:"pattern,omitempty"` // A function that validates the input and optionally cleans it up before it's submitted to the connector. Validate func(string) (string, error) `json:"-"` }
func (*LoginInputDataField) FillDefaultValidate ¶
func (f *LoginInputDataField) FillDefaultValidate()
type LoginInputFieldType ¶
type LoginInputFieldType string
const ( LoginInputFieldTypeUsername LoginInputFieldType = "username" LoginInputFieldTypePassword LoginInputFieldType = "password" LoginInputFieldTypePhoneNumber LoginInputFieldType = "phone_number" LoginInputFieldTypeEmail LoginInputFieldType = "email" LoginInputFieldType2FACode LoginInputFieldType = "2fa_code" )
type LoginProcess ¶
type LoginProcess interface { // Start starts the process and returns the first step. // // For example, a network using QR login may connect to the network, fetch a QR code, // and return a DisplayAndWait-type step. // // This will only ever be called once. Start(ctx context.Context) (*LoginStep, error) // Cancel stops the login process and cleans up any resources. // No other methods will be called after cancel. // // Cancel will not be called if any other method returned an error: // errors are always treated as fatal and the process is assumed to be automatically cancelled. Cancel() }
LoginProcess represents a single occurrence of a user logging into the remote network.
type LoginProcessCookies ¶
type LoginProcessDisplayAndWait ¶
type LoginProcessDisplayAndWait interface { LoginProcess Wait(ctx context.Context) (*LoginStep, error) }
type LoginProcessUserInput ¶
type LoginStep ¶
type LoginStep struct { // The type of login step Type LoginStepType `json:"type"` // A unique ID for this step. The ID should be same for every login using the same flow, // but it should be different for different bridges and step types. // // For example, Telegram's QR scan followed by a 2-factor password // might use the IDs `fi.mau.telegram.qr` and `fi.mau.telegram.2fa_password`. StepID string `json:"step_id"` // Instructions contains human-readable instructions for completing the login step. Instructions string `json:"instructions"` DisplayAndWaitParams *LoginDisplayAndWaitParams `json:"display_and_wait"` CookiesParams *LoginCookiesParams `json:"cookies"` UserInputParams *LoginUserInputParams `json:"user_input"` CompleteParams *LoginCompleteParams `json:"complete"` }
type LoginStepType ¶
type LoginStepType string
const ( LoginStepTypeUserInput LoginStepType = "user_input" LoginStepTypeCookies LoginStepType = "cookies" LoginStepTypeDisplayAndWait LoginStepType = "display_and_wait" LoginStepTypeComplete LoginStepType = "complete" )
type LoginSubmit ¶
type LoginSubmit struct { }
type LoginUserInputParams ¶
type LoginUserInputParams struct { // The fields that the user needs to fill in. Fields []LoginInputDataField `json:"fields"` }
type MatrixAPI ¶
type MatrixAPI interface { GetMXID() id.UserID SendMessage(ctx context.Context, roomID id.RoomID, eventType event.Type, content *event.Content, ts time.Time) (*mautrix.RespSendEvent, error) SendState(ctx context.Context, roomID id.RoomID, eventType event.Type, stateKey string, content *event.Content, ts time.Time) (*mautrix.RespSendEvent, error) MarkRead(ctx context.Context, roomID id.RoomID, eventID id.EventID, ts time.Time) error DownloadMedia(ctx context.Context, uri id.ContentURIString, file *event.EncryptedFileInfo) ([]byte, error) UploadMedia(ctx context.Context, roomID id.RoomID, data []byte, fileName, mimeType string) (url id.ContentURIString, file *event.EncryptedFileInfo, err error) SetDisplayName(ctx context.Context, name string) error SetAvatarURL(ctx context.Context, avatarURL id.ContentURIString) error SetExtraProfileMeta(ctx context.Context, data any) error CreateRoom(ctx context.Context, req *mautrix.ReqCreateRoom) (id.RoomID, error) DeleteRoom(ctx context.Context, roomID id.RoomID) error InviteUser(ctx context.Context, roomID id.RoomID, userID id.UserID) error EnsureJoined(ctx context.Context, roomID id.RoomID) error }
type MatrixConnector ¶
type MatrixConnector interface { Init(*Bridge) Start(ctx context.Context) error ParseGhostMXID(userID id.UserID) (networkid.UserID, bool) FormatGhostMXID(userID networkid.UserID) id.UserID GhostIntent(userID id.UserID) MatrixAPI NewUserIntent(ctx context.Context, userID id.UserID, accessToken string) (MatrixAPI, string, error) BotIntent() MatrixAPI SendBridgeStatus(ctx context.Context, state *status.BridgeState) error SendMessageStatus(ctx context.Context, status *MessageStatus, evt *MessageStatusEventInfo) GetMembers(ctx context.Context, roomID id.RoomID) (map[id.UserID]*event.MemberEventContent, error) GetMemberInfo(ctx context.Context, roomID id.RoomID, userID id.UserID) (*event.MemberEventContent, error) ServerName() string }
type MatrixEdit ¶
type MatrixEdit struct { MatrixEventBase[*event.MessageEventContent] EditTarget *database.Message }
type MatrixEventBase ¶
type MatrixEventBase[ContentType any] struct { // The raw event being bridged. Event *event.Event // The parsed content struct of the event. Custom fields can be found in Event.Content.Raw. Content ContentType // The room where the event happened. Portal *Portal // The original sender user ID. Only present in case the event is being relayed (and Sender is not the same user). OrigSender *OrigSender }
type MatrixMessage ¶
type MatrixMessage struct { MatrixEventBase[*event.MessageEventContent] ThreadRoot *database.Message ReplyTo *database.Message }
type MatrixMessageRemove ¶
type MatrixMessageRemove struct { MatrixEventBase[*event.RedactionEventContent] TargetMessage *database.Message }
type MatrixReaction ¶
type MatrixReaction struct { MatrixEventBase[*event.ReactionEventContent] TargetMessage *database.Message PreHandleResp *MatrixReactionPreResponse // When MaxReactions is >0 in the pre-response, this is the list of previous reactions that should be preserved. ExistingReactionsToKeep []*database.Reaction }
type MatrixReactionRemove ¶
type MatrixReactionRemove struct { MatrixEventBase[*event.RedactionEventContent] TargetReaction *database.Reaction }
type MatrixReadReceipt ¶
type MatrixReadReceipt struct { Portal *Portal // The event ID that the receipt is targeting EventID id.EventID // The exact message that was read. This may be nil if the event ID isn't a message. ExactMessage *database.Message // The timestamp that the user has read up to. This is either the timestamp of the message // (if one is present) or the timestamp of the receipt. ReadUpTo time.Time // The ReadUpTo timestamp of the previous message LastRead time.Time // The receipt metadata. Receipt event.ReadReceipt }
type MatrixTyping ¶
type MatrixTyping struct{}
type MaxFileSizeingNetwork ¶
type MaxFileSizeingNetwork interface { NetworkConnector SetMaxFileSize(maxSize int64) }
MaxFileSizeingNetwork is an optional interface that network connectors can implement to find out the maximum file size that can be uploaded to Matrix.
The SetMaxFileSize will be called asynchronously soon after startup. Before the function is called, the connector may assume a default limit of 50 MiB.
type MessageStatus ¶
type MessageStatus struct { Step status.MessageCheckpointStep RetryNum int Status event.MessageStatus ErrorReason event.MessageStatusReason DeliveredTo []id.UserID InternalError error // Internal error to be tracked in message checkpoints Message string // Human-readable message shown to users ErrorAsMessage bool IsCertain bool SendNotice bool DisableMSS bool }
func WrapErrorInStatus ¶
func WrapErrorInStatus(err error) MessageStatus
func (MessageStatus) Error ¶
func (ms MessageStatus) Error() string
func (*MessageStatus) ToCheckpoint ¶
func (ms *MessageStatus) ToCheckpoint(evt *MessageStatusEventInfo) *status.MessageCheckpoint
func (*MessageStatus) ToMSSEvent ¶
func (ms *MessageStatus) ToMSSEvent(evt *MessageStatusEventInfo) *event.BeeperMessageStatusEventContent
func (*MessageStatus) ToNoticeEvent ¶
func (ms *MessageStatus) ToNoticeEvent(evt *MessageStatusEventInfo) *event.MessageEventContent
func (MessageStatus) Unwrap ¶
func (ms MessageStatus) Unwrap() error
func (MessageStatus) WithErrorAsMessage ¶
func (ms MessageStatus) WithErrorAsMessage() MessageStatus
func (MessageStatus) WithErrorReason ¶
func (ms MessageStatus) WithErrorReason(reason event.MessageStatusReason) MessageStatus
func (MessageStatus) WithIsCertain ¶
func (ms MessageStatus) WithIsCertain(certain bool) MessageStatus
func (MessageStatus) WithMessage ¶
func (ms MessageStatus) WithMessage(msg string) MessageStatus
func (MessageStatus) WithSendNotice ¶
func (ms MessageStatus) WithSendNotice(send bool) MessageStatus
func (MessageStatus) WithStatus ¶
func (ms MessageStatus) WithStatus(status event.MessageStatus) MessageStatus
func (MessageStatus) WithStep ¶
func (ms MessageStatus) WithStep(step status.MessageCheckpointStep) MessageStatus
type MessageStatusEventInfo ¶
type MessageStatusEventInfo struct { RoomID id.RoomID EventID id.EventID EventType event.Type MessageType event.MessageType Sender id.UserID ThreadRoot id.EventID }
func StatusEventInfoFromEvent ¶
func StatusEventInfoFromEvent(evt *event.Event) *MessageStatusEventInfo
type MinimalCommandHandler ¶
type MinimalCommandHandler interface {
Run(*CommandEvent)
}
type MinimalCommandHandlerFunc ¶
type MinimalCommandHandlerFunc func(*CommandEvent)
func (MinimalCommandHandlerFunc) Run ¶
func (mhf MinimalCommandHandlerFunc) Run(ce *CommandEvent)
type NetworkAPI ¶
type NetworkAPI interface { Connect(ctx context.Context) error IsLoggedIn() bool LogoutRemote(ctx context.Context) IsThisUser(ctx context.Context, userID networkid.UserID) bool GetChatInfo(ctx context.Context, portal *Portal) (*PortalInfo, error) GetUserInfo(ctx context.Context, ghost *Ghost) (*UserInfo, error) HandleMatrixMessage(ctx context.Context, msg *MatrixMessage) (message *database.Message, err error) HandleMatrixEdit(ctx context.Context, msg *MatrixEdit) error PreHandleMatrixReaction(ctx context.Context, msg *MatrixReaction) (MatrixReactionPreResponse, error) HandleMatrixReaction(ctx context.Context, msg *MatrixReaction) (reaction *database.Reaction, err error) HandleMatrixReactionRemove(ctx context.Context, msg *MatrixReactionRemove) error HandleMatrixMessageRemove(ctx context.Context, msg *MatrixMessageRemove) error HandleMatrixReadReceipt(ctx context.Context, msg *MatrixReadReceipt) error }
NetworkAPI is an interface representing a remote network client for a single user login.
type NetworkConnector ¶
type NetworkConnector interface { // Init is called when the bridge is initialized. The connector should store the bridge instance for later use. // This should not do any network calls or other blocking operations. Init(*Bridge) // Start is called when the bridge is starting. // The connector should do any non-user-specific startup actions necessary. // User logins will be loaded separately, so the connector should not load them here. Start(context.Context) error // LoadUserLogin is called when a UserLogin is loaded from the database in order to fill the [UserLogin.Client] field. // // This is called within the bridge's global cache lock, so it must not do any slow operations, // such as connecting to the network. Instead, connecting should happen when [NetworkAPI.Connect] is called later. LoadUserLogin(ctx context.Context, login *UserLogin) error GetName() BridgeName // GetConfig returns all the parts of the network connector's config file. Specifically: // - example: a string containing an example config file // - data: an interface to unmarshal the actual config into // - upgrader: a config upgrader to ensure all fields are present and to do any migrations from old configs GetConfig() (example string, data any, upgrader configupgrade.Upgrader) // GetLoginFlows returns a list of login flows that the network supports. GetLoginFlows() []LoginFlow // CreateLogin is called when a user wants to log in to the network. // // This should generally not do any work, it should just return a LoginProcess that remembers // the user and will execute the requested flow. The actual work should start when [LoginProcess.Start] is called. CreateLogin(ctx context.Context, user *User, flowID string) (LoginProcess, error) }
NetworkConnector is the main interface that a network connector must implement.
type OrigSender ¶
type OrigSender struct { User *User event.MemberEventContent }
type Portal ¶
type Portal struct { *database.Portal Bridge *Bridge Log zerolog.Logger Parent *Portal Relay *UserLogin // contains filtered or unexported fields }
func (*Portal) CreateMatrixRoom ¶
func (*Portal) FindPreferredLogin ¶
func (*Portal) GetTopLevelParent ¶
func (*Portal) SyncParticipants ¶
func (*Portal) UpdateAvatar ¶
func (*Portal) UpdateBridgeInfo ¶
func (*Portal) UpdateInfo ¶
func (*Portal) UpdateName ¶
type PortalInfo ¶
type RemoteEdit ¶
type RemoteEdit interface { RemoteEventWithTargetMessage ConvertEdit(ctx context.Context, portal *Portal, intent MatrixAPI, existing []*database.Message) (*ConvertedEdit, error) }
type RemoteEvent ¶
type RemoteEvent interface { GetType() RemoteEventType GetPortalKey() networkid.PortalKey AddLogContext(c zerolog.Context) zerolog.Context GetSender() EventSender }
RemoteEvent represents a single event from the remote network, such as a message or a reaction.
When a NetworkAPI receives an event from the remote network, it should convert it into a RemoteEvent and pass it to the bridge for processing using Bridge.QueueRemoteEvent.
type RemoteEventThatMayCreatePortal ¶
type RemoteEventThatMayCreatePortal interface { RemoteEvent ShouldCreatePortal() bool }
type RemoteEventType ¶
type RemoteEventType int
const ( RemoteEventUnknown RemoteEventType = iota RemoteEventMessage RemoteEventEdit RemoteEventReaction RemoteEventReactionRemove RemoteEventMessageRemove RemoteEventReadReceipt RemoteEventDeliveryReceipt RemoteEventTyping )
type RemoteEventWithTargetMessage ¶
type RemoteEventWithTargetMessage interface { RemoteEvent GetTargetMessage() networkid.MessageID }
type RemoteEventWithTargetPart ¶
type RemoteEventWithTargetPart interface { RemoteEventWithTargetMessage GetTargetMessagePart() networkid.PartID }
type RemoteEventWithTimestamp ¶
type RemoteEventWithTimestamp interface { RemoteEvent GetTimestamp() time.Time }
type RemoteMessage ¶
type RemoteMessage interface { RemoteEvent GetID() networkid.MessageID ConvertMessage(ctx context.Context, portal *Portal, intent MatrixAPI) (*ConvertedMessage, error) }
type RemoteMessageRemove ¶
type RemoteMessageRemove interface { RemoteEventWithTargetMessage }
type RemoteReaction ¶
type RemoteReaction interface { RemoteEventWithTargetMessage GetReactionEmoji() (string, networkid.EmojiID) }
type RemoteReactionRemove ¶
type RemoteReactionRemove interface { RemoteEventWithTargetMessage GetRemovedEmojiID() networkid.EmojiID }
type RemoteReactionWithMeta ¶
type RemoteReactionWithMeta interface { RemoteReaction GetReactionDBMetadata() map[string]any }
type RemoteReceipt ¶
type RemoteReceipt interface { RemoteEvent GetLastReceiptTarget() networkid.MessageID GetReceiptTargets() []networkid.MessageID }
type RemoteTyping ¶
type RemoteTyping interface { RemoteEvent GetTimeout() time.Duration }
type SimpleRemoteEvent ¶
type SimpleRemoteEvent[T any] struct { Type RemoteEventType LogContext func(c zerolog.Context) zerolog.Context PortalKey networkid.PortalKey Data T CreatePortal bool ID networkid.MessageID Sender EventSender TargetMessage networkid.MessageID EmojiID networkid.EmojiID Emoji string ReactionDBMeta map[string]any Timestamp time.Time ConvertMessageFunc func(ctx context.Context, portal *Portal, intent MatrixAPI, data T) (*ConvertedMessage, error) ConvertEditFunc func(ctx context.Context, portal *Portal, intent MatrixAPI, existing []*database.Message, data T) (*ConvertedEdit, error) }
SimpleRemoteEvent is a simple implementation of RemoteEvent that can be used with struct fields and some callbacks.
func (*SimpleRemoteEvent[T]) AddLogContext ¶
func (sre *SimpleRemoteEvent[T]) AddLogContext(c zerolog.Context) zerolog.Context
func (*SimpleRemoteEvent[T]) ConvertEdit ¶
func (sre *SimpleRemoteEvent[T]) ConvertEdit(ctx context.Context, portal *Portal, intent MatrixAPI, existing []*database.Message) (*ConvertedEdit, error)
func (*SimpleRemoteEvent[T]) ConvertMessage ¶
func (sre *SimpleRemoteEvent[T]) ConvertMessage(ctx context.Context, portal *Portal, intent MatrixAPI) (*ConvertedMessage, error)
func (*SimpleRemoteEvent[T]) GetID ¶
func (sre *SimpleRemoteEvent[T]) GetID() networkid.MessageID
func (*SimpleRemoteEvent[T]) GetPortalKey ¶
func (sre *SimpleRemoteEvent[T]) GetPortalKey() networkid.PortalKey
func (*SimpleRemoteEvent[T]) GetReactionDBMetadata ¶
func (sre *SimpleRemoteEvent[T]) GetReactionDBMetadata() map[string]any
func (*SimpleRemoteEvent[T]) GetReactionEmoji ¶
func (sre *SimpleRemoteEvent[T]) GetReactionEmoji() (string, networkid.EmojiID)
func (*SimpleRemoteEvent[T]) GetRemovedEmojiID ¶
func (sre *SimpleRemoteEvent[T]) GetRemovedEmojiID() networkid.EmojiID
func (*SimpleRemoteEvent[T]) GetSender ¶
func (sre *SimpleRemoteEvent[T]) GetSender() EventSender
func (*SimpleRemoteEvent[T]) GetTargetMessage ¶
func (sre *SimpleRemoteEvent[T]) GetTargetMessage() networkid.MessageID
func (*SimpleRemoteEvent[T]) GetTimestamp ¶
func (sre *SimpleRemoteEvent[T]) GetTimestamp() time.Time
func (*SimpleRemoteEvent[T]) GetType ¶
func (sre *SimpleRemoteEvent[T]) GetType() RemoteEventType
func (*SimpleRemoteEvent[T]) ShouldCreatePortal ¶
func (sre *SimpleRemoteEvent[T]) ShouldCreatePortal() bool
type User ¶
type User struct { *database.User Bridge *Bridge Log zerolog.Logger CommandState atomic.Pointer[CommandState] // contains filtered or unexported fields }
func (*User) LoginDoublePuppet ¶
func (*User) LogoutDoublePuppet ¶
type UserLogin ¶
type UserLogin struct { *database.UserLogin Bridge *Bridge User *User Log zerolog.Logger Client NetworkAPI BridgeState *BridgeStateQueue }
func (*UserLogin) GetRemoteID ¶
func (*UserLogin) GetRemoteName ¶
func (*UserLogin) MarkAsPreferredIn ¶
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
mxmain
Package mxmain contains initialization code for a single-network Matrix bridge using the bridgev2 package.
|
Package mxmain contains initialization code for a single-network Matrix bridge using the bridgev2 package. |
Package networkid contains string types used to represent different kinds of identifiers on remote networks.
|
Package networkid contains string types used to represent different kinds of identifiers on remote networks. |