Documentation
¶
Overview ¶
Package storage defines the interfaces and domain types used by mtgo Telegram clients to persist session data, peer cache entries, and conversation state.
The primary interface is Adapter, which combines SessionStore and PeerStore. Implementations that also support the conversations plugin should satisfy ConversationStore as well.
Built-in adapters are provided as sub-modules:
- github.com/mtgo-labs/storage/sqlite — SQLite (pure-Go, no CGO)
- github.com/mtgo-labs/storage/postgres — PostgreSQL
- github.com/mtgo-labs/storage/mongodb — MongoDB
To create a custom adapter, implement the Adapter interface (and optionally ConversationStore). See the ExampleCustomStorage type in this package for a minimal in-memory implementation.
Wiring an adapter into a client ¶
store, _ := sqlite.Open("session.db")
client, _ := telegram.NewClient(apiID, apiHash, telegram.WithStorage(store))
Implementing a custom adapter ¶
A custom adapter must implement SessionStore, PeerStore, and [Close]. To support the conversations plugin, also implement ConversationStore. Use the test suite in github.com/mtgo-labs/storage/internal/suite to verify correctness:
func TestMyAdapter(t *testing.T) {
a := NewMyAdapter()
suite.Run(t, a)
}
Index ¶
- func ExportSessionString(sess *Session) (string, error)
- func MustMarshal(v interface{}) []byte
- func MustUnmarshal(data []byte, v interface{})
- func NewAdapter(a Adapter) *adapterWrapper
- type Adapter
- type ChannelUpdateState
- type Conversation
- type ConversationStore
- type DCAuthEntry
- type DCAuthStore
- type DurableUpdate
- type Peer
- type PeerCache
- type PeerEntry
- type PeerStore
- type PeerType
- type Session
- type SessionIDAware
- type SessionStore
- type Storage
- type UpdateState
- type UpdateStateStore
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExportSessionString ¶
ExportSessionString encodes session data into a portable string. This is a convenience function for memory-based adapters.
func MustMarshal ¶
func MustMarshal(v interface{}) []byte
MustMarshal marshals v to JSON, panicking on error.
func MustUnmarshal ¶
func MustUnmarshal(data []byte, v interface{})
MustUnmarshal unmarshals data into v, panicking on error. If data is empty, it is a no-op.
func NewAdapter ¶
func NewAdapter(a Adapter) *adapterWrapper
NewAdapter wraps a github.com/mtgo-labs/storage.Adapter so it can be used as Config.Storage in the Telegram client.
Types ¶
type Adapter ¶
type Adapter interface {
SessionStore
PeerStore
Close() error
}
Adapter combines session and peer storage. ConversationStore is optional; adapters that support it should also implement ConversationStore.
type ChannelUpdateState ¶
type Conversation ¶
type Conversation struct {
ChatID int64 `json:"chat_id"`
UserID int64 `json:"user_id"`
Name string `json:"name"`
Step int `json:"step"`
Data []byte `json:"data,omitempty"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
Conversation holds plugin conversation state.
type ConversationStore ¶
type ConversationStore interface {
SaveConversation(c *Conversation) error
LoadConversation(chatID, userID int64) (*Conversation, error)
DeleteConversation(chatID, userID int64) error
}
ConversationStore persists plugin conversation state. Implementations should create their backing table lazily on first use.
type DCAuthEntry ¶
type DCAuthStore ¶
type DCAuthStore interface {
SaveDCAuth(entry DCAuthEntry) error
LoadDCAuth(dcID int) (DCAuthEntry, error)
}
type DurableUpdate ¶
type Peer ¶
type Peer struct {
ID int64 `json:"id"`
Type PeerType `json:"type"`
AccessHash int64 `json:"access_hash"`
Username string `json:"username"`
Usernames string `json:"usernames,omitempty"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number,omitempty"`
IsBot bool `json:"is_bot,omitempty"`
PhotoID int64 `json:"photo_id,omitempty"`
Language string `json:"language,omitempty"`
LastUpdated int64 `json:"last_updated"`
}
Peer holds cached peer information.
type PeerCache ¶
type PeerCache interface {
SavePeers([]Peer) error
LoadPeers() ([]Peer, error)
SavePeer(Peer) error
DeletePeer(id int64) error
}
PeerCache is an optional interface that Storage implementations can satisfy to persist peer entries for the Telegram client's peer cache.
type PeerEntry ¶
type PeerEntry struct {
ID int64 `json:"id"`
Type PeerType `json:"type"`
AccessHash int64 `json:"access_hash"`
Username string `json:"username"`
Usernames string `json:"usernames,omitempty"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number,omitempty"`
IsBot bool `json:"is_bot,omitempty"`
PhotoID int64 `json:"photo_id,omitempty"`
Language string `json:"language,omitempty"`
LastUpdated int64 `json:"last_updated,omitempty"`
}
type PeerStore ¶
type PeerStore interface {
SavePeer(p *Peer) error
GetPeer(id int64) (*Peer, error)
GetPeerByUsername(username string) (*Peer, error)
LoadPeers() ([]*Peer, error)
DeletePeer(id int64) error
}
PeerStore persists peer cache entries.
type Session ¶
type Session struct {
SessionID string `json:"session_id"`
DC int `json:"dc"`
APIID int32 `json:"api_id"`
APIHash string `json:"api_hash"`
TestMode bool `json:"test_mode"`
AuthKey []byte `json:"auth_key"`
State []byte `json:"state"`
UserID int64 `json:"user_id"`
IsBot bool `json:"is_bot"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
Date int `json:"date"`
Addr string `json:"addr"`
Port int `json:"port"`
}
Session holds MTProto session data.
type SessionIDAware ¶
type SessionIDAware interface {
SetSessionName(name string)
}
SessionIDAware is an optional interface that adapters can implement to receive the session name from the client. The client calls SetSessionName early in connectTransport, before any data access, so the adapter can scope its queries accordingly.
type SessionStore ¶
SessionStore persists MTProto session data.
type Storage ¶
type Storage interface {
SessionID() (string, error)
SetSessionID(string) error
DCID() (int, error)
SetDCID(int) error
APIID() (int32, error)
SetAPIID(int32) error
APIHash() (string, error)
SetAPIHash(string) error
TestMode() (bool, error)
SetTestMode(bool) error
AuthKey() ([]byte, error)
SetAuthKey([]byte) error
UserID() (int64, error)
SetUserID(int64) error
IsBot() (bool, error)
SetIsBot(bool) error
FirstName() (string, error)
SetFirstName(string) error
LastName() (string, error)
SetLastName(string) error
Username() (string, error)
SetUsername(string) error
Date() (int, error)
SetDate(int) error
ServerAddress() (string, error)
SetServerAddress(string) error
Port() (int, error)
SetPort(int) error
State() ([]byte, error)
SetState([]byte) error
// ExportSessionString encodes the session state into a portable string
// using the Telethon/Pyrogram/Kurigram format:
//
// "1" + base64url( dc_id[1B] + ip[4B|16B] + port[2B big-endian] + auth_key[256B] )
//
// WARNING: the returned string contains the full 256-byte authorization key
// in plaintext. Anyone who obtains this string can fully impersonate the
// session.
ExportSessionString() (string, error)
Close() error
}
Storage is the interface the Telegram client uses to read and write session fields. Implementations must also implement PeerCache for peer persistence and [Close] for cleanup.
Built-in implementations:
- [MemoryStorage] — in-memory, for testing
- [SQLiteStorage] — SQLite-backed, created via [NewSQLiteStorage]
Third-party adapters (sqlite, mongodb, postgres) can be bridged via NewAdapter:
store, _ := sqlite.Open("bot.db")
client, _ := tg.NewClient(apiID, apiHash, &tg.Config{
Storage: storage.NewAdapter(store),
})
type UpdateState ¶
type UpdateStateStore ¶
type UpdateStateStore interface {
LoadUpdateState(sessionID string) (*UpdateState, error)
SaveUpdateState(state *UpdateState) error
LoadChannelUpdateState(sessionID string, channelID int64) (*ChannelUpdateState, error)
LoadAllChannelUpdateStates(sessionID string) ([]*ChannelUpdateState, error)
SaveChannelUpdateState(state *ChannelUpdateState) error
SaveUpdateDedupKey(sessionID string, key string) (bool, error)
UpdateDedupKeyExists(sessionID string, key string) (bool, error)
EnqueueDurableUpdate(update *DurableUpdate) error
DeleteDurableUpdate(sessionID string, id string) error
LoadDurableUpdates(sessionID string, limit int) ([]*DurableUpdate, error)
MarkDurableUpdateFailed(sessionID string, id string, attempts int, lastErr string) error
}