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 ¶ added in v0.3.0
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/gotd/contrib/pebble"
"github.com/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)
}
}
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"`
Metadata map[string]interface{} `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 ¶ added in v0.5.0
type PeerCollector struct {
// contains filtered or unexported fields
}
PeerCollector is a simple helper to collect peers from different sources.
func CollectPeers ¶ added in v0.5.0
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/gotd/contrib/pebble"
"github.com/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)
}
}
func (PeerCollector) Contacts ¶ added in v0.5.0
func (c PeerCollector) Contacts(ctx context.Context, contacts *tg.ContactsContacts) error
Contacts collects peers from contacts iterator.
func (PeerCollector) Participants ¶ added in v0.5.0
func (c PeerCollector) Participants(ctx context.Context, iter *participants.Iterator) error
Participants collects peers from participants iterator.
type PeerIterator ¶ added in v0.5.0
PeerIterator is a peer iterator.
type PeerKey ¶ added in v0.5.0
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/gotd/contrib/pebble"
"github.com/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)
}
}
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