Documentation
¶
Overview ¶
Package user is a batteries-included bootstrap for user accounts (userbots, archivers, services) on top of telegram.Client.
One call connects, signs in if needed, and wires what a long-running user client needs and is easy to get wrong by hand:
- the session in Options.Dir, so that the account keeps its authorization across restarts: an authorized session is never signed in again;
- the session is checked: a bot session, or another account than Options.UserID, fails with ErrSessionMismatch;
- an unauthorized session is signed in with Options.Auth (phone code or QR), or Start fails with ErrNotAuthorized; FLOOD_WAIT on sign in is waited out, up to Options.MaxLoginWait;
- the updates manager (telegram/updates) with its state and the access hashes of channels and users in Options.Dir, so that updates sent while the client was stopped are delivered after the restart, gaps are recovered, and known channels need no extra getDifference;
- the peer manager (telegram/peers) with an entity cache, fed with the entities of every update, including the ones of getDifference.
Usage:
d := tg.NewUpdateDispatcher()
u, err := user.New(appID, appHash, user.Options{
Dir: "state",
Handler: d,
Auth: user.Phone(auth.Constant(phone, password, codeAuth), auth.SendCodeOptions{}),
})
if err != nil {
return err
}
d.OnNewMessage(func(ctx context.Context, e tg.Entities, upd *tg.UpdateNewMessage) error {
// ...
return nil
})
if err := u.Start(ctx); err != nil {
return err
}
defer func() { _ = u.Close() }()
return u.Wait(ctx)
Index ¶
- Constants
- Variables
- type Authenticator
- type Options
- type QROptions
- type User
- func (u *User) API() *tg.Client
- func (u *User) Client() *telegram.Client
- func (u *User) Close() error
- func (u *User) Done() <-chan struct{}
- func (u *User) ID() int64
- func (u *User) Peers() *peers.Manager
- func (u *User) Self() *tg.User
- func (u *User) Sender() *message.Sender
- func (u *User) Shutdown(ctx context.Context) error
- func (u *User) Start(ctx context.Context, so ...telegram.StartOption) error
- func (u *User) Stop()
- func (u *User) Updates() *updates.Manager
- func (u *User) Wait(ctx context.Context) error
Constants ¶
const ( // SessionFile is the name of the session file in Options.Dir. SessionFile = bootstrap.SessionFile // UpdatesFile is the name of the update state file in Options.Dir. UpdatesFile = bootstrap.UpdatesFile )
File names in Options.Dir.
Variables ¶
var ( // ErrSessionMismatch is returned by Start if the stored or signed in // account is a bot, or another user than Options.UserID. Use another // Options.Dir, or remove the session to sign in again. ErrSessionMismatch = errors.New("session belongs to another account") // ErrNotAuthorized is returned by Start if the session is not authorized // and Options.Auth is nil. Nothing is sent to sign in. ErrNotAuthorized = errors.New("session is not authorized and no authenticator is set") )
Functions ¶
This section is empty.
Types ¶
type Authenticator ¶
type Authenticator interface {
// contains filtered or unexported methods
}
Authenticator signs in an unauthorized session: Phone, QR or AuthFunc.
It is called at most once per Start, plus once more after each FLOOD_WAIT (bounded by Options.MaxLoginWait); other errors fail Start.
func AuthFunc ¶
AuthFunc is an Authenticator calling f, e.g. for a custom sign in with client.Auth().
func Phone ¶
func Phone(a auth.UserAuthenticator, opt auth.SendCodeOptions) Authenticator
Phone signs in with a phone code (and the 2FA password if the account has one), see auth.NewFlow.
A FLOOD_WAIT is waited out (up to Options.MaxLoginWait) only before a code was requested from the authenticator: after that, signing in again would send a new code, so the error is returned to the caller.
func QR ¶
func QR(opt QROptions) Authenticator
QR signs in by a login token accepted on another device, see qrlogin.QR.Auth. Tokens accepted by an account of another DC are imported there.
type Options ¶
type Options struct {
// Client is the options of the telegram.Client.
//
// Client.UpdateHandler must be nil: the updates manager is the update
// handler of the client, use Handler instead. If Client.SessionStorage
// is nil and Dir is set, the session is kept in Dir.
Client telegram.Options
// Dir is the directory for the session (SessionFile) and the update
// state with access hashes (UpdatesFile). It is created if needed. Empty
// means memory only: every start needs a sign in, and updates sent while
// stopped are not delivered.
//
// Use one Dir per account, and never share it by running processes.
Dir string
// Handler is called with the updates after gap recovery, with the
// entities of every update applied to the peer manager first (optional).
//
// Handlers run inside the client: they may use the User, but must not
// call Close or Shutdown (use Stop).
Handler telegram.UpdateHandler
// Updates is the base configuration of the updates manager (optional).
// Handler is set from Handler above. Storage and AccessHasher default to
// an updates.FileStorage in Dir (memory without Dir); the file storage
// also keeps user access hashes. MaxChannelDifferenceConcurrency
// defaults to 10. BeforeRunPass (the zero value) is replaced by
// BeforeRunBuffer, so updates received during sign in are not lost.
Updates updates.Config
// Peers is the options of the peer manager (optional). The entity cache
// is in memory by default.
Peers peers.Options
// Auth signs in an unauthorized session (optional): Phone or QR. If nil,
// Start fails with ErrNotAuthorized instead of signing in, e.g. for a
// service that must only run with an existing session.
Auth Authenticator
// UserID is the expected account (optional). If set, a session of
// another user fails with ErrSessionMismatch.
UserID int64
// MaxLoginWait is the maximum total FLOOD_WAIT to wait out on sign in
// before Start fails. Defaults to 5 minutes; negative means do not wait.
MaxLoginWait time.Duration
}
Options of a User.
type QROptions ¶
type QROptions struct {
// Show displays the login token, e.g. as a QR code of token.URL() to scan
// with Telegram on another device (Settings > Devices > Link Desktop
// Device). It is called again with a new token when the shown one
// expires. Required.
Show func(ctx context.Context, token qrlogin.Token) error
// Password returns the 2FA password of the account, if it has one
// (optional; without it an account with 2FA fails with
// SESSION_PASSWORD_NEEDED).
Password func(ctx context.Context) (string, error)
}
QROptions are options of QR.
type User ¶
type User struct {
// contains filtered or unexported fields
}
User is a started user account: a telegram.Client with an updates manager and a peer manager.
func New ¶
New creates a User without connecting, so that handlers can be set up with the User before Start.
func Start ¶
func Start(ctx context.Context, appID int, appHash string, opt Options, so ...telegram.StartOption) (*User, error)
Start creates a User with New and starts it with User.Start.
func (*User) Close ¶
Close is Shutdown without a deadline. Never call it from handlers, use Stop there.
func (*User) Done ¶
func (u *User) Done() <-chan struct{}
Done returns a channel that is closed when the client stops.
func (*User) Shutdown ¶
Shutdown stops the client and waits until it and the updates manager are stopped or ctx is done. It returns the error that stopped the client before Shutdown was called, nil if Shutdown stopped it or if Start failed, or the wrapped ctx.Err().
Never call it from handlers, use Stop there.
func (*User) Start ¶
Start connects, signs in if needed and starts the updates manager. It returns once the account is signed in and the update state is loaded, so missed updates are being fetched; they are passed to Options.Handler in the background.
The ctx bounds the startup only (including an interactive sign in), see telegram.Client.Start, which gets the StartOptions. An authorized session is never signed in again. If it is a bot or another user than Options.UserID, Start fails with ErrSessionMismatch; if it is not authorized and Options.Auth is nil, with ErrNotAuthorized. On error the client is fully stopped.
A User can be started once.
func (*User) Stop ¶
func (u *User) Stop()
Stop stops the client without waiting, see telegram.Client.Stop. It is safe to call from handlers.