summaryrefslogtreecommitdiffstats
path: root/vendor/maunium.net/go/mautrix/syncstore.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maunium.net/go/mautrix/syncstore.go')
-rw-r--r--vendor/maunium.net/go/mautrix/syncstore.go149
1 files changed, 149 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/syncstore.go b/vendor/maunium.net/go/mautrix/syncstore.go
new file mode 100644
index 00000000..a3611e5e
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/syncstore.go
@@ -0,0 +1,149 @@
+package mautrix
+
+import (
+ "maunium.net/go/mautrix/id"
+)
+
+// SyncStore is an interface which must be satisfied to store client data.
+//
+// You can either write a struct which persists this data to disk, or you can use the
+// provided "MemorySyncStore" which just keeps data around in-memory which is lost on
+// restarts.
+type SyncStore interface {
+ SaveFilterID(userID id.UserID, filterID string)
+ LoadFilterID(userID id.UserID) string
+ SaveNextBatch(userID id.UserID, nextBatchToken string)
+ LoadNextBatch(userID id.UserID) string
+}
+
+// Deprecated: renamed to SyncStore
+type Storer = SyncStore
+
+// MemorySyncStore implements the Storer interface.
+//
+// Everything is persisted in-memory as maps. It is not safe to load/save filter IDs
+// or next batch tokens on any goroutine other than the syncing goroutine: the one
+// which called Client.Sync().
+type MemorySyncStore struct {
+ Filters map[id.UserID]string
+ NextBatch map[id.UserID]string
+}
+
+// SaveFilterID to memory.
+func (s *MemorySyncStore) SaveFilterID(userID id.UserID, filterID string) {
+ s.Filters[userID] = filterID
+}
+
+// LoadFilterID from memory.
+func (s *MemorySyncStore) LoadFilterID(userID id.UserID) string {
+ return s.Filters[userID]
+}
+
+// SaveNextBatch to memory.
+func (s *MemorySyncStore) SaveNextBatch(userID id.UserID, nextBatchToken string) {
+ s.NextBatch[userID] = nextBatchToken
+}
+
+// LoadNextBatch from memory.
+func (s *MemorySyncStore) LoadNextBatch(userID id.UserID) string {
+ return s.NextBatch[userID]
+}
+
+// NewMemorySyncStore constructs a new MemorySyncStore.
+func NewMemorySyncStore() *MemorySyncStore {
+ return &MemorySyncStore{
+ Filters: make(map[id.UserID]string),
+ NextBatch: make(map[id.UserID]string),
+ }
+}
+
+// AccountDataStore uses account data to store the next batch token, and stores the filter ID in memory
+// (as filters can be safely recreated every startup).
+type AccountDataStore struct {
+ FilterID string
+ EventType string
+ client *Client
+}
+
+type accountData struct {
+ NextBatch string `json:"next_batch"`
+}
+
+func (s *AccountDataStore) SaveFilterID(userID id.UserID, filterID string) {
+ if userID.String() != s.client.UserID.String() {
+ panic("AccountDataStore must only be used with a single account")
+ }
+ s.FilterID = filterID
+}
+
+func (s *AccountDataStore) LoadFilterID(userID id.UserID) string {
+ if userID.String() != s.client.UserID.String() {
+ panic("AccountDataStore must only be used with a single account")
+ }
+ return s.FilterID
+}
+
+func (s *AccountDataStore) SaveNextBatch(userID id.UserID, nextBatchToken string) {
+ if userID.String() != s.client.UserID.String() {
+ panic("AccountDataStore must only be used with a single account")
+ }
+
+ data := accountData{
+ NextBatch: nextBatchToken,
+ }
+
+ err := s.client.SetAccountData(s.EventType, data)
+ if err != nil {
+ s.client.Log.Warn().Err(err).Msg("Failed to save next batch token to account data")
+ }
+}
+
+func (s *AccountDataStore) LoadNextBatch(userID id.UserID) string {
+ if userID.String() != s.client.UserID.String() {
+ panic("AccountDataStore must only be used with a single account")
+ }
+
+ data := &accountData{}
+
+ err := s.client.GetAccountData(s.EventType, data)
+ if err != nil {
+ s.client.Log.Warn().Err(err).Msg("Failed to load next batch token from account data")
+ return ""
+ }
+
+ return data.NextBatch
+}
+
+// NewAccountDataStore returns a new AccountDataStore, which stores
+// the next_batch token as a custom event in account data in the
+// homeserver.
+//
+// AccountDataStore is only appropriate for bots, not appservices.
+//
+// The event type should be a reversed DNS name like tld.domain.sub.internal and
+// must be unique for a client. The data stored in it is considered internal
+// and must not be modified through outside means. You should also add a filter
+// for account data changes of this event type, to avoid ending up in a sync
+// loop:
+//
+// filter := mautrix.Filter{
+// AccountData: mautrix.FilterPart{
+// Limit: 20,
+// NotTypes: []event.Type{
+// event.NewEventType(eventType),
+// },
+// },
+// }
+// // If you use a custom Syncer, set the filter there, not like this
+// client.Syncer.(*mautrix.DefaultSyncer).FilterJSON = &filter
+// client.Store = mautrix.NewAccountDataStore("com.example.mybot.store", client)
+// go func() {
+// err := client.Sync()
+// // don't forget to check err
+// }()
+func NewAccountDataStore(eventType string, client *Client) *AccountDataStore {
+ return &AccountDataStore{
+ EventType: eventType,
+ client: client,
+ }
+}