package matrixbotlib import ( "os" "strings" "gopkg.in/yaml.v2" "maunium.net/go/mautrix" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" ) // NewMatrixClient returns a new logged in Mautrix Client struct func NewMatrixClient(config *MatrixClientConfig, store mautrix.Storer) (*mautrix.Client, error) { var client *mautrix.Client var err error // make sure username is lower case otherwise token login breaks uname := strings.ToLower(config.Username) if config.Token == "" { client, err = mautrix.NewClient(config.Homeserver, "", "") if err != nil { return client, err } } else { client, err = mautrix.NewClient(config.Homeserver, id.NewUserID(uname, config.Domain), config.Token) if err != nil { return client, err } } client.Store = store if config.Token == "" { loginRes, err := client.Login(&mautrix.ReqLogin{ Type: "m.login.password", Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: uname}, Password: config.Password, StoreCredentials: true, }) if err != nil { return client, err } config.Token = loginRes.AccessToken err = SyncToken(config) if err != nil { return nil, err } } return client, err } func SyncToken(config *MatrixClientConfig) error { t := make(map[string]interface{}) data, err := os.ReadFile(config.filename) if err != nil { return err } err = yaml.Unmarshal([]byte(data), &t) if err != nil { return err } t["token"] = config.Token file, err := os.OpenFile(config.filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600) if err != nil { return err } defer file.Close() enc := yaml.NewEncoder(file) err = enc.Encode(t) if err != nil { return err } return nil } // SetupAccountDataStore sets the client to use a AccountData store and filter appropriately func SetupAccountDataStore(client *mautrix.Client, token string) error { dataFilter := &mautrix.Filter{ AccountData: mautrix.FilterPart{ Limit: 20, NotTypes: []event.Type{ event.NewEventType(token), }, }, } store := mautrix.NewAccountDataStore(token, client) fID, err := client.CreateFilter(dataFilter) if err != nil { // don't want to continue if we can't keep state return err } uid := client.UserID store.SaveFilterID(uid, fID.FilterID) client.Store = store return nil }