v0.0.0-...-0cf6527 Latest Latest

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

Go to latest
Published: Dec 27, 2023 License: MPL-2.0 Imports: 32 Imported by: 0




View Source
const (
	WebsocketCloseConnReplaced       = 4001
	WebsocketCloseTxnNotAcknowledged = 4002
View Source
const DoublePuppetKey = "fi.mau.double_puppet_source"
View Source
const WebsocketCommandHTTPProxy = "http_proxy"


View Source
var (
	ErrWebsocketManualStop   = errors.New("the websocket was disconnected manually")
	ErrWebsocketOverridden   = errors.New("a new call to StartWebsocket overrode the previous connection")
	ErrWebsocketUnknownError = errors.New("an unknown error occurred")

	ErrWebsocketNotConnected = errors.New("websocket not connected")
	ErrWebsocketClosed       = errors.New("websocket closed before response received")
View Source
var EventChannelSize = 64

EventChannelSize is the size for the Events channel in Appservice instances.

View Source
var OTKChannelSize = 4


func Respond

func Respond(w http.ResponseWriter, data interface{}) error

Respond responds to a HTTP request with a JSON object.

func WriteBlankOK

func WriteBlankOK(w http.ResponseWriter)

WriteBlankOK writes a blank OK message as a reply to a HTTP request.


type AppService

type AppService struct {
	HomeserverDomain string

	Host HostConfig

	Registration *Registration
	Log          zerolog.Logger

	Events         chan *event.Event
	ToDeviceEvents chan *event.Event
	DeviceLists    chan *mautrix.DeviceLists
	OTKCounts      chan *mautrix.OTKCount
	QueryHandler   QueryHandler
	StateStore     StateStore

	Router    *mux.Router
	UserAgent string

	HTTPClient *http.Client

	DefaultHTTPRetries int

	Live  bool
	Ready bool

	StopWebsocket func(error)

	// ProcessID is an identifier sent to the websocket proxy for debugging connections
	ProcessID string

	DoublePuppetValue string
	GetProfile        func(userID id.UserID, roomID id.RoomID) *event.MemberEventContent
	// contains filtered or unexported fields

AppService is the main config for all appservices. It also serves as the appservice instance struct.

func Create

func Create() *AppService

Create a blank appservice instance.

func (*AppService) BotClient

func (as *AppService) BotClient() *mautrix.Client

func (*AppService) BotIntent

func (as *AppService) BotIntent() *IntentAPI

func (*AppService) BotMXID

func (as *AppService) BotMXID() id.UserID

func (*AppService) CheckServerToken

func (as *AppService) CheckServerToken(w http.ResponseWriter, r *http.Request) (isValid bool)

CheckServerToken checks if the given request originated from the Matrix homeserver.

func (*AppService) Client

func (as *AppService) Client(userID id.UserID) *mautrix.Client

func (*AppService) GetLive

func (as *AppService) GetLive(w http.ResponseWriter, r *http.Request)

func (*AppService) GetReady

func (as *AppService) GetReady(w http.ResponseWriter, r *http.Request)

func (*AppService) GetRoom

func (as *AppService) GetRoom(w http.ResponseWriter, r *http.Request)

GetRoom handles a /rooms GET call from the homeserver.

func (*AppService) GetUser

func (as *AppService) GetUser(w http.ResponseWriter, r *http.Request)

GetUser handles a /users GET call from the homeserver.

func (*AppService) HasWebsocket

func (as *AppService) HasWebsocket() bool

func (*AppService) Intent

func (as *AppService) Intent(userID id.UserID) *IntentAPI

func (*AppService) NewExternalMautrixClient

func (as *AppService) NewExternalMautrixClient(userID id.UserID, token string, homeserverURL string) (*mautrix.Client, error)

func (*AppService) NewIntentAPI

func (as *AppService) NewIntentAPI(localpart string) *IntentAPI

func (*AppService) NewMautrixClient

func (as *AppService) NewMautrixClient(userID id.UserID) *mautrix.Client

func (*AppService) PostPing

func (as *AppService) PostPing(w http.ResponseWriter, r *http.Request)

func (*AppService) PrepareWebsocket

func (as *AppService) PrepareWebsocket()

func (*AppService) PutTransaction

func (as *AppService) PutTransaction(w http.ResponseWriter, r *http.Request)

PutTransaction handles a /transactions PUT call from the homeserver.

func (*AppService) RequestWebsocket

func (as *AppService) RequestWebsocket(ctx context.Context, cmd *WebsocketRequest, response interface{}) error

func (*AppService) Save

func (as *AppService) Save(path string) error

Save saves this config into a file at the given path.

func (*AppService) SendWebsocket

func (as *AppService) SendWebsocket(cmd *WebsocketRequest) error

func (*AppService) SetHomeserverURL

func (as *AppService) SetHomeserverURL(homeserverURL string) error

func (*AppService) SetWebsocketCommandHandler

func (as *AppService) SetWebsocketCommandHandler(cmd string, handler WebsocketHandler)

func (*AppService) Start

func (as *AppService) Start()

Start starts the HTTP server that listens for calls from the Matrix homeserver.

func (*AppService) StartWebsocket

func (as *AppService) StartWebsocket(baseURL string, onConnect func()) error

func (*AppService) Stop

func (as *AppService) Stop()

func (*AppService) WebsocketHTTPProxy

func (as *AppService) WebsocketHTTPProxy(cmd WebsocketCommand) (bool, interface{})

func (*AppService) YAML

func (as *AppService) YAML() (string, error)

YAML returns the config in YAML format.

type CloseCommand

type CloseCommand struct {
	Code    int                    `json:"-"`
	Command string                 `json:"command"`
	Status  MeowWebsocketCloseCode `json:"status"`

func (CloseCommand) Error

func (cc CloseCommand) Error() string

type DeviceListHandler

type DeviceListHandler = func(lists *mautrix.DeviceLists, since string)

type EnsureJoinedParams

type EnsureJoinedParams struct {
	IgnoreCache bool
	BotOverride *mautrix.Client

type Error

type Error struct {
	HTTPStatus int       `json:"-"`
	ErrorCode  ErrorCode `json:"errcode"`
	Message    string    `json:"error"`

Error represents a Matrix protocol error.

func (Error) Write

func (err Error) Write(w http.ResponseWriter)

type ErrorCode

type ErrorCode string

ErrorCode is the machine-readable code in an Error.

const (
	ErrUnknownToken ErrorCode = "M_UNKNOWN_TOKEN"
	ErrBadJSON      ErrorCode = "M_BAD_JSON"
	ErrNotJSON      ErrorCode = "M_NOT_JSON"
	ErrUnknown      ErrorCode = "M_UNKNOWN"

Native ErrorCodes

const (

Custom ErrorCodes

type ErrorResponse

type ErrorResponse struct {
	Code    string `json:"code"`
	Message string `json:"message"`

func (*ErrorResponse) Error

func (er *ErrorResponse) Error() string

type EventHandler

type EventHandler = func(evt *event.Event)

type EventListener

type EventListener func(evt *event.Event)

EventListener is a function that receives events.

type EventProcessor

type EventProcessor struct {
	ExecMode ExecMode
	// contains filtered or unexported fields

func NewEventProcessor

func NewEventProcessor(as *AppService) *EventProcessor

func (*EventProcessor) Dispatch

func (ep *EventProcessor) Dispatch(evt *event.Event)

func (*EventProcessor) DispatchDeviceList

func (ep *EventProcessor) DispatchDeviceList(dl *mautrix.DeviceLists)

func (*EventProcessor) DispatchOTK

func (ep *EventProcessor) DispatchOTK(otk *mautrix.OTKCount)

func (*EventProcessor) On

func (ep *EventProcessor) On(evtType event.Type, handler EventHandler)

func (*EventProcessor) OnDeviceList

func (ep *EventProcessor) OnDeviceList(handler DeviceListHandler)

func (*EventProcessor) OnOTK

func (ep *EventProcessor) OnOTK(handler OTKHandler)

func (*EventProcessor) PrependHandler

func (ep *EventProcessor) PrependHandler(evtType event.Type, handler EventHandler)

func (*EventProcessor) Start

func (ep *EventProcessor) Start()

func (*EventProcessor) Stop

func (ep *EventProcessor) Stop()

type ExecMode

type ExecMode uint8
const (
	AsyncHandlers ExecMode = iota

type FallbackKeyMap

type FallbackKeyMap = map[id.UserID]map[id.DeviceID][]id.KeyAlgorithm

type HTTPProxyRequest

type HTTPProxyRequest struct {
	Method  string          `json:"method"`
	Path    string          `json:"path"`
	Query   string          `json:"query"`
	Headers http.Header     `json:"headers"`
	Body    json.RawMessage `json:"body"`

type HTTPProxyResponse

type HTTPProxyResponse struct {
	Status  int             `json:"status"`
	Headers http.Header     `json:"headers"`
	Body    json.RawMessage `json:"body"`
	// contains filtered or unexported fields

func (*HTTPProxyResponse) Header

func (p *HTTPProxyResponse) Header() http.Header

func (*HTTPProxyResponse) Write

func (p *HTTPProxyResponse) Write(bytes []byte) (int, error)

func (*HTTPProxyResponse) WriteHeader

func (p *HTTPProxyResponse) WriteHeader(statusCode int)

type HostConfig

type HostConfig struct {
	Hostname string `yaml:"hostname"`
	Port     uint16 `yaml:"port"`
	TLSKey   string `yaml:"tls_key,omitempty"`
	TLSCert  string `yaml:"tls_cert,omitempty"`

HostConfig contains info about how to host the appservice.

func (*HostConfig) Address

func (hc *HostConfig) Address() string

Address gets the whole address of the Appservice.

func (*HostConfig) IsConfigured

func (hc *HostConfig) IsConfigured() bool

func (*HostConfig) IsUnixSocket

func (hc *HostConfig) IsUnixSocket() bool

type IntentAPI

type IntentAPI struct {

	Localpart string
	UserID    id.UserID

	IsCustomPuppet bool
	// contains filtered or unexported fields

func (*IntentAPI) AddDoublePuppetValue

func (intent *IntentAPI) AddDoublePuppetValue(into interface{}) interface{}

func (*IntentAPI) BanUser

func (intent *IntentAPI) BanUser(roomID id.RoomID, req *mautrix.ReqBanUser, extraContent[string]interface{}) (resp *mautrix.RespBanUser, err error)

func (*IntentAPI) EnsureInvited

func (intent *IntentAPI) EnsureInvited(roomID id.RoomID, userID id.UserID) error

func (*IntentAPI) EnsureJoined

func (intent *IntentAPI) EnsureJoined(roomID id.RoomID, extra ...EnsureJoinedParams) error

func (*IntentAPI) EnsureRegistered

func (intent *IntentAPI) EnsureRegistered() error

func (*IntentAPI) InviteUser

func (intent *IntentAPI) InviteUser(roomID id.RoomID, req *mautrix.ReqInviteUser, extraContent[string]interface{}) (resp *mautrix.RespInviteUser, err error)

func (*IntentAPI) JoinRoomByID

func (intent *IntentAPI) JoinRoomByID(roomID id.RoomID, extraContent[string]interface{}) (resp *mautrix.RespJoinRoom, err error)

func (*IntentAPI) KickUser

func (intent *IntentAPI) KickUser(roomID id.RoomID, req *mautrix.ReqKickUser, extraContent[string]interface{}) (resp *mautrix.RespKickUser, err error)

func (*IntentAPI) LeaveRoom

func (intent *IntentAPI) LeaveRoom(roomID id.RoomID, extra ...interface{}) (resp *mautrix.RespLeaveRoom, err error)

func (*IntentAPI) Member

func (intent *IntentAPI) Member(roomID id.RoomID, userID id.UserID) *event.MemberEventContent

func (*IntentAPI) PowerLevels

func (intent *IntentAPI) PowerLevels(roomID id.RoomID) (pl *event.PowerLevelsEventContent, err error)

func (*IntentAPI) RedactEvent

func (intent *IntentAPI) RedactEvent(roomID id.RoomID, eventID id.EventID, extra ...mautrix.ReqRedact) (*mautrix.RespSendEvent, error)

func (*IntentAPI) Register

func (intent *IntentAPI) Register() error

func (*IntentAPI) SendCustomMembershipEvent

func (intent *IntentAPI) SendCustomMembershipEvent(roomID id.RoomID, target id.UserID, membership event.Membership, reason string, extraContent[string]interface{}) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendMassagedMessageEvent

func (intent *IntentAPI) SendMassagedMessageEvent(roomID id.RoomID, eventType event.Type, contentJSON interface{}, ts int64) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendMassagedStateEvent

func (intent *IntentAPI) SendMassagedStateEvent(roomID id.RoomID, eventType event.Type, stateKey string, contentJSON interface{}, ts int64) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendMessageEvent

func (intent *IntentAPI) SendMessageEvent(roomID id.RoomID, eventType event.Type, contentJSON interface{}) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendNotice

func (intent *IntentAPI) SendNotice(roomID id.RoomID, text string) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendStateEvent

func (intent *IntentAPI) SendStateEvent(roomID id.RoomID, eventType event.Type, stateKey string, contentJSON interface{}) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SendText

func (intent *IntentAPI) SendText(roomID id.RoomID, text string) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SetAvatarURL

func (intent *IntentAPI) SetAvatarURL(avatarURL id.ContentURI) error

func (*IntentAPI) SetDisplayName

func (intent *IntentAPI) SetDisplayName(displayName string) error

func (*IntentAPI) SetPowerLevel

func (intent *IntentAPI) SetPowerLevel(roomID id.RoomID, userID id.UserID, level int) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SetPowerLevels

func (intent *IntentAPI) SetPowerLevels(roomID id.RoomID, levels *event.PowerLevelsEventContent) (resp *mautrix.RespSendEvent, err error)

func (*IntentAPI) SetRoomAvatar

func (intent *IntentAPI) SetRoomAvatar(roomID id.RoomID, avatarURL id.ContentURI) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SetRoomName

func (intent *IntentAPI) SetRoomName(roomID id.RoomID, roomName string) (*mautrix.RespSendEvent, error)

func (*IntentAPI) SetRoomTopic

func (intent *IntentAPI) SetRoomTopic(roomID id.RoomID, topic string) (*mautrix.RespSendEvent, error)

func (*IntentAPI) State

func (intent *IntentAPI) State(roomID id.RoomID) (mautrix.RoomStateMap, error)

func (*IntentAPI) StateEvent

func (intent *IntentAPI) StateEvent(roomID id.RoomID, eventType event.Type, stateKey string, outContent interface{}) error

func (*IntentAPI) UnbanUser

func (intent *IntentAPI) UnbanUser(roomID id.RoomID, req *mautrix.ReqUnbanUser, extraContent[string]interface{}) (resp *mautrix.RespUnbanUser, err error)

func (*IntentAPI) Whoami

func (intent *IntentAPI) Whoami() (*mautrix.RespWhoami, error)

type MeowWebsocketCloseCode

type MeowWebsocketCloseCode string
const (
	MeowServerShuttingDown MeowWebsocketCloseCode = "server_shutting_down"
	MeowConnectionReplaced MeowWebsocketCloseCode = "conn_replaced"
	MeowTxnNotAcknowledged MeowWebsocketCloseCode = "transactions_not_acknowledged"

func (MeowWebsocketCloseCode) String

func (mwcc MeowWebsocketCloseCode) String() string

type Namespace

type Namespace struct {
	Regex     string `yaml:"regex" json:"regex"`
	Exclusive bool   `yaml:"exclusive" json:"exclusive"`

Namespace is a reserved namespace in any area.

type NamespaceList

type NamespaceList []Namespace

func (*NamespaceList) Register

func (nsl *NamespaceList) Register(regex *regexp.Regexp, exclusive bool)

type Namespaces

type Namespaces struct {
	UserIDs     NamespaceList `yaml:"users,omitempty" json:"users,omitempty"`
	RoomAliases NamespaceList `yaml:"aliases,omitempty" json:"aliases,omitempty"`
	RoomIDs     NamespaceList `yaml:"rooms,omitempty" json:"rooms,omitempty"`

Namespaces contains the three areas that appservices can reserve parts of.

type OTKCountMap

type OTKCountMap = map[id.UserID]map[id.DeviceID]mautrix.OTKCount

type OTKHandler

type OTKHandler = func(otk *mautrix.OTKCount)

type QueryHandler

type QueryHandler interface {
	QueryAlias(alias string) bool
	QueryUser(userID id.UserID) bool

QueryHandler handles room alias and user ID queries from the homeserver.

type QueryHandlerStub

type QueryHandlerStub struct{}

func (*QueryHandlerStub) QueryAlias

func (qh *QueryHandlerStub) QueryAlias(alias string) bool

func (*QueryHandlerStub) QueryUser

func (qh *QueryHandlerStub) QueryUser(userID id.UserID) bool

type Registration

type Registration struct {
	ID              string     `yaml:"id" json:"id"`
	URL             string     `yaml:"url" json:"url"`
	AppToken        string     `yaml:"as_token" json:"as_token"`
	ServerToken     string     `yaml:"hs_token" json:"hs_token"`
	SenderLocalpart string     `yaml:"sender_localpart" json:"sender_localpart"`
	RateLimited     *bool      `yaml:"rate_limited,omitempty" json:"rate_limited,omitempty"`
	Namespaces      Namespaces `yaml:"namespaces" json:"namespaces"`
	Protocols       []string   `yaml:"protocols,omitempty" json:"protocols,omitempty"`

	SoruEphemeralEvents bool `yaml:"de.sorunome.msc2409.push_ephemeral,omitempty" json:"de.sorunome.msc2409.push_ephemeral,omitempty"`
	EphemeralEvents     bool `yaml:"push_ephemeral,omitempty" json:"push_ephemeral,omitempty"`

Registration contains the data in a Matrix appservice registration. See

func CreateRegistration

func CreateRegistration() *Registration

CreateRegistration creates a Registration with random appservice and homeserver tokens.

func LoadRegistration

func LoadRegistration(path string) (*Registration, error)

LoadRegistration loads a YAML file and turns it into a Registration.

func (*Registration) Save

func (reg *Registration) Save(path string) error

Save saves this Registration into a file at the given path.

func (*Registration) YAML

func (reg *Registration) YAML() (string, error)

YAML returns the registration in YAML format.

type StateStore

type StateStore interface {

	IsRegistered(userID id.UserID) bool
	MarkRegistered(userID id.UserID)

	GetPowerLevel(roomID id.RoomID, userID id.UserID) int
	GetPowerLevelRequirement(roomID id.RoomID, eventType event.Type) int
	HasPowerLevel(roomID id.RoomID, userID id.UserID, eventType event.Type) bool

type Transaction

type Transaction struct {
	Events          []*event.Event `json:"events"`
	EphemeralEvents []*event.Event `json:"ephemeral,omitempty"`
	ToDeviceEvents  []*event.Event `json:"to_device,omitempty"`

	DeviceLists    *mautrix.DeviceLists `json:"device_lists,omitempty"`
	DeviceOTKCount OTKCountMap          `json:"device_one_time_keys_count,omitempty"`
	FallbackKeys   FallbackKeyMap       `json:"device_unused_fallback_key_types,omitempty"`

	MSC2409EphemeralEvents []*event.Event       `json:"de.sorunome.msc2409.ephemeral,omitempty"`
	MSC2409ToDeviceEvents  []*event.Event       `json:"de.sorunome.msc2409.to_device,omitempty"`
	MSC3202DeviceLists     *mautrix.DeviceLists `json:"org.matrix.msc3202.device_lists,omitempty"`
	MSC3202DeviceOTKCount  OTKCountMap          `json:"org.matrix.msc3202.device_one_time_keys_count,omitempty"`
	MSC3202FallbackKeys    FallbackKeyMap       `json:"org.matrix.msc3202.device_unused_fallback_key_types,omitempty"`

Transaction contains a list of events.

func (*Transaction) ContentString

func (txn *Transaction) ContentString() string

func (*Transaction) MarshalZerologObject

func (txn *Transaction) MarshalZerologObject(ctx *zerolog.Event)

type TransactionIDCache

type TransactionIDCache struct {
	// contains filtered or unexported fields

func NewTransactionIDCache

func NewTransactionIDCache(size int) *TransactionIDCache

func (*TransactionIDCache) IsProcessed

func (txnIDC *TransactionIDCache) IsProcessed(txnID string) bool

func (*TransactionIDCache) MarkProcessed

func (txnIDC *TransactionIDCache) MarkProcessed(txnID string)

type WebsocketCommand

type WebsocketCommand struct {
	ReqID   int             `json:"id,omitempty"`
	Command string          `json:"command"`
	Data    json.RawMessage `json:"data"`

	Ctx context.Context `json:"-"`

func (*WebsocketCommand) MakeResponse

func (wsc *WebsocketCommand) MakeResponse(ok bool, data interface{}) *WebsocketRequest

type WebsocketHandler

type WebsocketHandler func(WebsocketCommand) (ok bool, data interface{})

type WebsocketMessage

type WebsocketMessage struct {

type WebsocketRequest

type WebsocketRequest struct {
	ReqID   int         `json:"id,omitempty"`
	Command string      `json:"command"`
	Data    interface{} `json:"data"`

	Deadline time.Duration `json:"-"`

type WebsocketTransaction

type WebsocketTransaction struct {
	Status string `json:"status"`
	TxnID  string `json:"txn_id"`

type WebsocketTransactionResponse

type WebsocketTransactionResponse struct {
	TxnID string `json:"txn_id"`

Jump to

Keyboard shortcuts

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