updates

package
v0.157.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 15 Imported by: 45

Documentation

Overview

Package updates provides a Telegram's internalState synchronization manager.

It guarantees that all internalState-sensitive updates will be performed in correct order.

Limitations:

  1. Manager cannot verify stateless types of updates (tg.UpdatesClass without Seq, or tg.UpdateClass without Pts or Qts).

  2. Due to the fact that updates.getDifference and updates.getChannelDifference do not return event sequences, manager cannot guarantee the correctness of these operations. We rely on the server here.

  3. Manager cannot recover the channel gap if there is a ChannelDifferenceTooLong error. Restoring the internalState in such situation is not the prerogative of this manager. See: https://core.telegram.org/constructor/updates.channelDifferenceTooLong

TODO: Write implementation details.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type API added in v0.80.0

type API interface {
	UpdatesGetState(ctx context.Context) (*tg.UpdatesState, error)
	UpdatesGetDifference(ctx context.Context, request *tg.UpdatesGetDifferenceRequest) (tg.UpdatesDifferenceClass, error)
	UpdatesGetChannelDifference(ctx context.Context, request *tg.UpdatesGetChannelDifferenceRequest) (tg.UpdatesChannelDifferenceClass, error)
}

API is the interface which contains Telegram RPC methods used by manager for internalState synchronization.

type AuthOptions added in v0.80.0

type AuthOptions struct {
	IsBot   bool
	Forget  bool
	OnStart func(ctx context.Context)
}

type ChannelAccessHasher added in v0.51.0

type ChannelAccessHasher interface {
	SetChannelAccessHash(ctx context.Context, userID, channelID, accessHash int64) error
	GetChannelAccessHash(ctx context.Context, userID, channelID int64) (accessHash int64, found bool, err error)
}

ChannelAccessHasher stores users channel access hashes.

type Config

type Config struct {
	// Handler where updates will be passed.
	Handler telegram.UpdateHandler
	// Callback called if manager cannot
	// recover channel gap (optional).
	OnChannelTooLong func(channelID int64)
	// Callback called when the manager loses access to a channel, detected via
	// CHANNEL_PRIVATE on updates.getChannelDifference (e.g. the account was
	// kicked/banned or the channel was deleted). The channel is removed from
	// the update manager after this call (optional).
	OnChannelInaccessible func(channelID int64)
	// Callback called if manager cannot recover
	// common state gap, i.e. on updates.differenceTooLong (optional).
	OnTooLong func()
	// Callback called when the manager fails to load the locally stored user
	// state during Run with forget=false (no state found), so the state is
	// fetched from the server and a full resynchronization is performed.
	//
	// Useful to detect that updates missed while offline may need to be fetched
	// manually, e.g. via messages.getHistory (optional).
	OnLoadUserStateFailed func()
	// Callback called when the manager fails to load the locally stored state of
	// a channel during Run with forget=false (its access hash is missing), so
	// the channel is skipped.
	//
	// Useful to detect that the channel may need to be resynchronized manually
	// (optional).
	OnLoadChannelStateFailed func(channelID int64)
	// State storage.
	// In-mem used if not provided.
	Storage StateStorage
	// Channel access hash storage.
	// In-mem used if not provided.
	AccessHasher ChannelAccessHasher
	// User access hash storage.
	// In-mem used if not provided.
	UserAccessHasher UserAccessHasher
	// Logger (optional).
	Logger log.Logger
	// TracerProvider (optional).
	TracerProvider trace.TracerProvider
}

Config of the manager.

type Manager added in v0.51.0

type Manager struct {
	// contains filtered or unexported fields
}

Manager deals with gaps.

Important: Updates produced by this manager may contain negative Pts/Qts/Seq values in tg.UpdateClass/tg.UpdatesClass (does not affects to the tg.MessageClass).

This is because telegram server does not return these sequences for getDifference/getChannelDifference results. You SHOULD NOT use them in update handlers at all.

func New

func New(cfg Config) *Manager

New creates new manager.

func (*Manager) Handle added in v0.51.0

func (m *Manager) Handle(ctx context.Context, u tg.UpdatesClass) error

Handle handles updates.

Important: If Run method not called, all updates will be passed to the provided handler as-is without any order verification or short updates transformation.

func (*Manager) HandleAffected added in v0.157.0

func (m *Manager) HandleAffected(ctx context.Context, channelID int64, pts, ptsCount int) error

HandleAffected applies the pts increment carried by a messages.affectedMessages or messages.affectedHistory RPC result, keeping the local pts in sync after a self-initiated read or delete (e.g. messages.readHistory, messages.deleteMessages).

Without this, such results silently advance the server pts while the local pts stays behind, so the next genuine update looks like a gap and is postponed until the next pts-changing update or a getDifference (see issue #1382).

channelID must be the channel the result belongs to, or 0 for the common (user/basic-group) sequence. The affected pts for a channel is applied only when that channel is already tracked. It is a no-op before Run is called.

Most callers should not call this directly: use the hook middleware in telegram/updates/hook, which wires it from RPC results automatically.

func (*Manager) Reset added in v0.80.0

func (m *Manager) Reset()

Reset notifies manager about user logout.

func (*Manager) Run added in v0.80.0

func (m *Manager) Run(ctx context.Context, api API, userID int64, opt AuthOptions) error

Run notifies manager about user authentication on the telegram server.

If forget is true, local internalState (if exist) will be overwritten with remote internalState.

type State

type State struct {
	Pts, Qts, Date, Seq int
}

State is the user internalState.

type StateStorage added in v0.51.0

type StateStorage interface {
	GetState(ctx context.Context, userID int64) (state State, found bool, err error)
	SetState(ctx context.Context, userID int64, state State) error
	SetPts(ctx context.Context, userID int64, pts int) error
	SetQts(ctx context.Context, userID int64, qts int) error
	SetDate(ctx context.Context, userID int64, date int) error
	SetSeq(ctx context.Context, userID int64, seq int) error
	SetDateSeq(ctx context.Context, userID int64, date, seq int) error
	GetChannelPts(ctx context.Context, userID, channelID int64) (pts int, found bool, err error)
	SetChannelPts(ctx context.Context, userID, channelID int64, pts int) error
	ForEachChannels(ctx context.Context, userID int64, f func(ctx context.Context, channelID int64, pts int) error) error
}

StateStorage is the users internalState storage.

Note: SetPts, SetQts, SetDate, SetSeq, SetDateSeq should return error if user internalState does not exist.

type UserAccessHasher added in v0.150.0

type UserAccessHasher interface {
	SetUserAccessHash(ctx context.Context, userID, targetUserID, accessHash int64) error
	GetUserAccessHash(ctx context.Context, userID, targetUserID int64) (accessHash int64, found bool, err error)
}

UserAccessHasher stores user access hashes observed by the updates manager so it can decide whether an incoming update references a user it already knows. Mirrors ChannelAccessHasher. In-mem used if not provided to Config.

Directories

Path Synopsis
Package hook contains telegram update hook middleware.
Package hook contains telegram update hook middleware.
internal
e2e
Package e2e contains end-to-end updates processing test.
Package e2e contains end-to-end updates processing test.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL