Documentation ¶
Overview ¶
Package storage contains common structures for iterating over peer storage.
Index ¶
- Constants
- Variables
- func ForEach(ctx context.Context, iterator PeerIterator, cb func(Peer) error) error
- func UpdateHook(next telegram.UpdateHandler, storage PeerStorage) telegram.UpdateHandler
- type Peer
- func (p Peer) AsInputChannel() (*tg.InputChannel, bool)
- func (p Peer) AsInputPeer() tg.InputPeerClass
- func (p Peer) AsInputUser() (*tg.InputUser, bool)
- func (p *Peer) FromChat(chat tg.ChatClass) bool
- func (p *Peer) FromInputPeer(input tg.InputPeerClass) error
- func (p *Peer) FromUser(user tg.UserClass) bool
- func (p *Peer) Keys() []string
- type PeerCollector
- type PeerIterator
- type PeerKey
- type PeerStorage
- type ResolverCache
Examples ¶
Constants ¶
const LatestVersion = 1
LatestVersion is a latest supported version of data.
Variables ¶
var ErrPeerNotFound = errors.New("peer not found")
ErrPeerNotFound is a special error to return when peer not found.
var PeerKeyPrefix = []byte("peer") // nolint:gochecknoglobals
PeerKeyPrefix is a key prefix of peer key.
Functions ¶
func UpdateHook ¶
func UpdateHook(next telegram.UpdateHandler, storage PeerStorage) telegram.UpdateHandler
UpdateHook creates update hook, to collect peer data from updates.
Example ¶
package main import ( "context" "fmt" "os" "os/signal" pebbledb "github.com/cockroachdb/pebble" "github.com/go-faster/errors" "github.com/gotd/td/telegram" "github.com/gotd/td/telegram/message" "github.com/gotd/td/tg" "github.com/johnnyipcom/gotd-contrib/pebble" "github.com/johnnyipcom/gotd-contrib/storage" ) func updatesHook(ctx context.Context) error { db, err := pebbledb.Open("pebble.db", &pebbledb.Options{}) if err != nil { return errors.Errorf("create pebble storage: %w", err) } s := pebble.NewPeerStorage(db) dispatcher := tg.NewUpdateDispatcher() handler := storage.UpdateHook(dispatcher, s) client, err := telegram.ClientFromEnvironment(telegram.Options{ UpdateHandler: handler, }) if err != nil { return errors.Errorf("create client: %w", err) } raw := tg.NewClient(client) sender := message.NewSender(raw) dispatcher.OnNewMessage(func(ctx context.Context, e tg.Entities, update *tg.UpdateNewMessage) error { msg, ok := update.Message.(*tg.Message) if !ok { return nil } // Use PeerID to find peer because *Short updates does not contain any entities, so it necessary to // store some entities. // Storage can be filled using PeerCollector. p, err := storage.FindPeer(ctx, s, msg.GetPeerID()) if err != nil { return err } _, err = sender.To(p.AsInputPeer()).Text(ctx, msg.GetMessage()) return err }) return client.Run(ctx, func(ctx context.Context) error { return telegram.RunUntilCanceled(ctx, client) }) } func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() if err := updatesHook(ctx); err != nil { _, _ = fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(1) } }
Output:
Types ¶
type Peer ¶
type Peer struct { Version int Key dialogs.DialogKey CreatedAt int64 User *tg.User `json:",omitempty"` Chat *tg.Chat `json:",omitempty"` Channel *tg.Channel `json:",omitempty"` }
Peer is abstraction for peer object.
func (Peer) AsInputChannel ¶
func (p Peer) AsInputChannel() (*tg.InputChannel, bool)
AsInputChannel tries to convert peer to *tg.InputChannel.
func (Peer) AsInputPeer ¶
func (p Peer) AsInputPeer() tg.InputPeerClass
AsInputPeer tries to convert peer to tg.InputPeerClass.
func (Peer) AsInputUser ¶
AsInputUser tries to convert peer to *tg.InputUser.
func (*Peer) FromInputPeer ¶
func (p *Peer) FromInputPeer(input tg.InputPeerClass) error
FromInputPeer fills Peer object using given tg.InputPeerClass.
type PeerCollector ¶
type PeerCollector struct {
// contains filtered or unexported fields
}
PeerCollector is a simple helper to collect peers from different sources.
func CollectPeers ¶
func CollectPeers(storage PeerStorage) PeerCollector
CollectPeers creates new PeerCollector.
Example ¶
package main import ( "context" "fmt" "os" "os/signal" pebbledb "github.com/cockroachdb/pebble" "github.com/go-faster/errors" "github.com/gotd/td/telegram" "github.com/gotd/td/telegram/query" "github.com/gotd/td/tg" "github.com/johnnyipcom/gotd-contrib/pebble" "github.com/johnnyipcom/gotd-contrib/storage" ) func peerCollector(ctx context.Context) error { db, err := pebbledb.Open("pebble.db", &pebbledb.Options{}) if err != nil { return errors.Errorf("create pebble storage: %w", err) } s := pebble.NewPeerStorage(db) collector := storage.CollectPeers(s) client, err := telegram.ClientFromEnvironment(telegram.Options{}) if err != nil { return errors.Errorf("create client: %w", err) } raw := tg.NewClient(client) return client.Run(ctx, func(ctx context.Context) error { // Fills storage with user dialogs peers metadata. return collector.Dialogs(ctx, query.GetDialogs(raw).Iter()) }) } func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() if err := peerCollector(ctx); err != nil { _, _ = fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(1) } }
Output:
func (PeerCollector) Contacts ¶
func (c PeerCollector) Contacts(ctx context.Context, contacts *tg.ContactsContacts) error
Contacts collects peers from contacts iterator.
func (PeerCollector) Participants ¶
func (c PeerCollector) Participants(ctx context.Context, iter *participants.Iterator) error
Participants collects peers from participants iterator.
type PeerIterator ¶
PeerIterator is a peer iterator.
type PeerKey ¶
PeerKey is unique key of peer object.
type PeerStorage ¶
type PeerStorage interface { // Add adds given peer to the storage. Add(ctx context.Context, value Peer) error // Find finds peer using given key. // If peer not found, it returns ErrPeerNotFound error. Find(ctx context.Context, key PeerKey) (Peer, error) // Assign adds given peer to the storage and associates it to the given key. Assign(ctx context.Context, key string, value Peer) error // Resolve finds peer using associated key. // If peer not found, it returns ErrPeerNotFound error. Resolve(ctx context.Context, key string) (Peer, error) // Iterate creates and returns new PeerIterator. Iterate(ctx context.Context) (PeerIterator, error) }
PeerStorage is abstraction for peer storage.
type ResolverCache ¶
type ResolverCache struct {
// contains filtered or unexported fields
}
ResolverCache is a peer.Resolver cache implemented using peer storage.
Example ¶
package main import ( "context" "fmt" "os" "os/signal" pebbledb "github.com/cockroachdb/pebble" "github.com/go-faster/errors" "github.com/gotd/td/telegram/message" "github.com/gotd/td/telegram/message/peer" "github.com/gotd/td/tg" "github.com/gotd/td/telegram" "github.com/johnnyipcom/gotd-contrib/pebble" "github.com/johnnyipcom/gotd-contrib/storage" ) func resolverCache(ctx context.Context) error { db, err := pebbledb.Open("pebble.db", &pebbledb.Options{}) if err != nil { return errors.Errorf("create pebble storage: %w", err) } client, err := telegram.ClientFromEnvironment(telegram.Options{}) if err != nil { return errors.Errorf("create client: %w", err) } return client.Run(ctx, func(ctx context.Context) error { raw := tg.NewClient(client) resolver := storage.NewResolverCache(peer.Plain(raw), pebble.NewPeerStorage(db)) s := message.NewSender(raw).WithResolver(resolver) _, err := s.Resolve("durov").Text(ctx, "Hi!") return err }) } func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() if err := resolverCache(ctx); err != nil { _, _ = fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(1) } }
Output:
func NewResolverCache ¶
func NewResolverCache(next peer.Resolver, storage PeerStorage) ResolverCache
NewResolverCache creates new ResolverCache.
func (ResolverCache) ResolveDomain ¶
func (r ResolverCache) ResolveDomain(ctx context.Context, domain string) (tg.InputPeerClass, error)
ResolveDomain implements peer.Resolver
func (ResolverCache) ResolvePhone ¶
func (r ResolverCache) ResolvePhone(ctx context.Context, phone string) (tg.InputPeerClass, error)
ResolvePhone implements peer.Resolver