tdlib

package module
v0.0.0-...-95efd2c Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

README

tdlib

A stateful, embeddable Telegram client library for Go — a reimplementation of the official TDLib built on top of gotd/td.

Where gotd/td is the low-level MTProto/TL client, tdlib is the layer above it: it maintains a persisted local cache of the account (users, chats, messages, files) in embedded SQLite, guarantees ordered update delivery, and exposes a high-level request/response API plus an ordered stream of updates.

It is a library: it never owns the process lifecycle, never logs to a global, and never pulls a concrete logging or telemetry framework into your build. Observability is injected through functional options with no-op defaults.

Status: v1 in progress. The full client pipeline is implemented — connection + session, authorization, options/config, the users/chats/messages caches, sending (with crash-safe binlog replay), file up/download, and live update reconciliation via the gotd/td gap engine (RFCs 0003–0013). Out of v1 scope: secret chats, channels/supergroups beyond basic caching, calls, stories, and inline bots. See docs/architecture.md and docs/rfc/0002-implementation-plan.md.

Install

go get github.com/gotd/tdlib

Example

A full-featured interactive client lives in cmd/tdlib: it drives the login flow, prints the live update stream, and exposes a REPL for chats, history, send/edit/delete, contacts, files, and options.

APP_ID=12345 APP_HASH=0123456789abcdef0123456789abcdef go run ./cmd/tdlib
# then: login +15551234567 → code 12345 → me → chats → send <chatID> hello

Usage

package main

import (
	"context"
	"log"
	"log/slog"

	"github.com/gotd/log/logslog"

	"github.com/gotd/tdlib"
)

func main() {
	ctx := context.Background()

	// Construct the client. APIID/APIHash come from https://my.telegram.org/apps.
	// New validates options but does not open the database or dial the network;
	// that happens in Run.
	client, err := tdlib.New(ctx,
		tdlib.WithAPIID(12345),
		tdlib.WithAPIHash("0123456789abcdef0123456789abcdef"),
		tdlib.WithDatabaseDirectory("./tdlib-db"),
		// Logging is a port: pass any github.com/gotd/log adapter, or omit for
		// a no-op. logslog wraps the standard library's log/slog.
		tdlib.WithLogger(logslog.New(slog.Default())),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	// Consume the ordered update stream. Updates are delivered in the exact
	// order they arrive from Telegram; the channel is closed when the client
	// stops.
	go func() {
		for u := range client.Updates() {
			switch u.Kind {
			case tdlib.UpdateKindNewMessage:
				if t := u.NewMessage.Content.Text; t != nil {
					log.Printf("message in chat %d: %s",
						u.NewMessage.ChatID, t.Text)
				}
			case tdlib.UpdateKindAuthorizationState:
				log.Printf("auth state: %d", u.AuthorizationState.Kind)
			case tdlib.UpdateKindConnectionState:
				log.Printf("connection: %s", u.ConnectionState.State)
			}
		}
	}()

	// Run starts the client and blocks until ctx is cancelled, Close is called,
	// or a fatal error occurs.
	if err := client.Run(ctx); err != nil {
		log.Fatal(err)
	}
}

Design

  • Storage: embedded SQLite via the pure-Go, CGO-free modernc.org/sqlite driver, so tdlib stays go install-able and cross-compilable with no C toolchain. A binlog table journals pending operations for crash safety.
  • Updates: the telegram/updates gap engine from gotd/td handles pts/qts/seq reconciliation; tdlib applies each update to the local cache and re-emits a normalized, ordered stream.
  • Logging: the dependency-free github.com/gotd/log port, with adapters for slog (logslog), zap (logzap), zerolog (logzerolog), and logrus (loglogrus). Import only the one you use.
  • Telemetry: OpenTelemetry TracerProvider/MeterProvider are injected via WithTracerProvider/WithMeterProvider and default to no-op; the library never calls otel.SetTracerProvider.

See docs/architecture.md for the full design.

License

MIT — do not use the Telegram name or branding for custom clients.

Documentation

Overview

Package tdlib is a stateful, embeddable Telegram client library: a Go reimplementation of the official TDLib built on top of gotd/td.

It maintains a persisted local cache of the account (users, chats, messages, files), guarantees ordered update delivery, and exposes a high-level request/response API plus an ordered stream of updates. The library never logs to a global and never imports a concrete logging or telemetry framework; observability is injected via functional options.

Index

Constants

View Source
const (
	// OptionMyID is the current user's ID (integer); read-only, set once the
	// self-user is resolved (RFC 0008).
	OptionMyID = "my_id"
	// OptionVersion is the tdlib library version string; read-only.
	OptionVersion = "version"
	// OptionUseTestDC is true when connected to a test DC; read-only.
	OptionUseTestDC = "use_test_dc"
	// OptionAPIID is the application API ID; read-only.
	OptionAPIID = "api_id"
	// OptionDeviceModel is the device model string; read-only.
	OptionDeviceModel = "device_model"
	// OptionSystemVersion is the OS version string; read-only.
	OptionSystemVersion = "system_version"
	// OptionAppVersion is the application version string; read-only.
	OptionAppVersion = "app_version"
	// OptionIsPremium is true when the account has Telegram Premium; read-only.
	OptionIsPremium = "is_premium"

	// OptionOnline controls whether the account appears online; writable.
	OptionOnline = "online"
	// OptionLanguagePackID is the active language pack identifier; writable.
	OptionLanguagePackID = "language_pack_id"
	// OptionDisableAnimatedEmoji suppresses animated emoji hints; writable.
	OptionDisableAnimatedEmoji = "disable_animated_emoji"

	// OptionMessageTextLengthMax is the server max message length; read-only.
	OptionMessageTextLengthMax = "message_text_length_max"
	// OptionMessageCaptionLengthMax is the server max caption length; read-only.
	OptionMessageCaptionLengthMax = "message_caption_length_max"
	// OptionEditTimeLimit is the message edit window in seconds; read-only.
	OptionEditTimeLimit = "edit_time_limit"
	// OptionRevokePMInbox controls whether deleting a PM removes it from both
	// sides; read-only.
	OptionRevokePMInbox = "revoke_pm_inbox"
	// OptionForwardedMessageCountMax is the max forwarded batch; read-only.
	OptionForwardedMessageCountMax = "forwarded_message_count_max"
	// OptionBasicGroupSizeMax is the max basic group member count; read-only.
	OptionBasicGroupSizeMax = "basic_group_size_max"
	// OptionSupergroupSizeMax is the max supergroup member count; read-only.
	OptionSupergroupSizeMax = "supergroup_size_max"
)

Well-known option names maintained by tdlib, mirroring TDLib's OptionManager.

Variables

View Source
var ErrClosed = errors.New("client closed")

ErrClosed is returned by Sink.Push after the Client has been closed.

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when a requested entity (user, chat, message) is absent from both the local cache and the server. It is a sentinel, so callers can check it with errors.Is.

View Source
var ErrOptionReadOnly = errors.New("option is read-only")

ErrOptionReadOnly is returned by Client.SetOption when the caller attempts to write a read-only option.

View Source
var ErrPendingMessage = errors.New("message is still pending")

ErrPendingMessage is returned when an operation that needs a server-confirmed message id (edit, delete) is called with a temporary local id.

View Source
var OptionValueEmpty = OptionValue{Kind: OptionValueKindEmpty}

OptionValueEmpty is the canonical empty OptionValue.

Functions

This section is empty.

Types

type AuthCodeType

type AuthCodeType int

AuthCodeType describes how an authentication code was delivered, trimmed to common cases; unknown types map to AuthCodeTypeUnknown.

const (
	// AuthCodeTypeUnknown is an unrecognised delivery type.
	AuthCodeTypeUnknown AuthCodeType = iota
	// AuthCodeTypeSMS is delivered by SMS.
	AuthCodeTypeSMS
	// AuthCodeTypeCall is delivered by phone call.
	AuthCodeTypeCall
	// AuthCodeTypeTelegramMessage is delivered via the Telegram app.
	AuthCodeTypeTelegramMessage
	// AuthCodeTypeFlashCall is a flash-call (missed call, code in the number).
	AuthCodeTypeFlashCall
	// AuthCodeTypeFragment is delivered via a Fragment anonymous number.
	AuthCodeTypeFragment
)

Authentication code delivery types.

type AuthorizationState

type AuthorizationState struct {
	// Kind identifies the phase.
	Kind AuthorizationStateKind
	// WaitCode is set when Kind == AuthorizationStateWaitCode.
	WaitCode *AuthorizationStateWaitCodeInfo
	// WaitPassword is set when Kind == AuthorizationStateWaitPassword.
	WaitPassword *AuthorizationStateWaitPasswordInfo
	// WaitRegistration is set when Kind == AuthorizationStateWaitRegistration.
	WaitRegistration *AuthorizationStateWaitRegistrationInfo
	// OtherDevice is set when Kind == AuthorizationStateWaitOtherDeviceConfirmation.
	OtherDevice *AuthorizationStateWaitOtherDeviceInfo
}

AuthorizationState describes the current authorization phase. It is the payload of UpdateKindAuthorizationState updates and the return value of Client.GetAuthorizationState. Exactly one of the Wait* fields is non-nil, matching Kind.

type AuthorizationStateKind

type AuthorizationStateKind int

AuthorizationStateKind enumerates authorization phases, mirroring TDLib's authorizationState* union trimmed to the v1 subset.

const (
	// AuthorizationStateWaitTdlibParameters is the transient initial state
	// before parameters are available. In tdlib New validates parameters
	// synchronously, so this is emitted once and immediately followed by the
	// real starting state.
	AuthorizationStateWaitTdlibParameters AuthorizationStateKind = iota + 1
	// AuthorizationStateWaitPhoneNumber means the caller must call
	// SetAuthenticationPhoneNumber.
	AuthorizationStateWaitPhoneNumber
	// AuthorizationStateWaitCode means a code was sent; the caller must call
	// CheckAuthenticationCode.
	AuthorizationStateWaitCode
	// AuthorizationStateWaitPassword means two-step verification is required;
	// the caller must call CheckAuthenticationPassword.
	AuthorizationStateWaitPassword
	// AuthorizationStateWaitRegistration means the phone is not registered; the
	// caller must call RegisterUser.
	AuthorizationStateWaitRegistration
	// AuthorizationStateReady means the client is fully authorized.
	AuthorizationStateReady
	// AuthorizationStateLoggingOut means LogOut was called and the request is
	// in flight.
	AuthorizationStateLoggingOut
	// AuthorizationStateClosed means the client is closed; no further auth
	// methods may be called.
	AuthorizationStateClosed
	// AuthorizationStateWaitOtherDeviceConfirmation means a QR-code login is in
	// progress; the caller must display the link/QR for the user to scan with an
	// already-authorized device. Appended after Closed to keep the persisted
	// integer values of the earlier states stable.
	AuthorizationStateWaitOtherDeviceConfirmation
)

Authorization state phase constants for the v1 scope. Deferred variants (QR login, email, premium) are added as later constants to keep these values stable.

func (AuthorizationStateKind) String

func (k AuthorizationStateKind) String() string

String returns the canonical name of the authorization phase.

type AuthorizationStateWaitCodeInfo

type AuthorizationStateWaitCodeInfo struct {
	// PhoneNumber is the number the code was sent to.
	PhoneNumber string
	// Type describes how the code was delivered.
	Type AuthCodeType
	// Timeout is the number of seconds the code remains valid.
	Timeout int
}

AuthorizationStateWaitCodeInfo carries the code-delivery metadata returned by Telegram after SetAuthenticationPhoneNumber.

type AuthorizationStateWaitOtherDeviceInfo

type AuthorizationStateWaitOtherDeviceInfo struct {
	// Link is the tg://login?token=… URL to render as a QR code for the user to
	// scan with an already-authorized device.
	Link string
}

AuthorizationStateWaitOtherDeviceInfo carries the QR-login link to display.

type AuthorizationStateWaitPasswordInfo

type AuthorizationStateWaitPasswordInfo struct {
	// PasswordHint is the user-set hint; may be empty.
	PasswordHint string
	// HasRecoveryEmailAddress reports whether a recovery email is configured.
	HasRecoveryEmailAddress bool
	// RecoveryEmailAddressPattern is the masked recovery email, e.g.
	// "ab***@example.com"; empty when no recovery email is set.
	RecoveryEmailAddressPattern string
}

AuthorizationStateWaitPasswordInfo carries 2FA password metadata.

type AuthorizationStateWaitRegistrationInfo

type AuthorizationStateWaitRegistrationInfo struct {
	// TermsOfService is the human-readable Terms of Service text to present to
	// the user.
	TermsOfService string
}

AuthorizationStateWaitRegistrationInfo carries the terms-of-service text that must be accepted before RegisterUser.

type Chat

type Chat struct {
	// ID is the Telegram chat identifier (treated as an opaque int64).
	ID ChatID
	// Type is the peer kind.
	Type ChatType
	// Title is the display name; for private chats it is the peer's full name.
	Title string
	// UserID is the peer user when Type == ChatTypePrivate; zero otherwise.
	UserID UserID
	// AccessHash is required to address Channel-backed chats; zero otherwise.
	AccessHash int64
	// LastMessageID is the id of the most recent message; zero if none.
	LastMessageID MessageID
	// LastMessageDate is the Unix timestamp of the most recent message; the
	// primary dialog-list sort key.
	LastMessageDate int64
	// Pinned reports whether the chat is pinned at the top of the main list.
	Pinned bool
	// UnreadCount is the number of unread incoming messages.
	UnreadCount int
	// LastReadInboxMessageID is the max incoming message id the user has read.
	LastReadInboxMessageID MessageID
	// LastReadOutboxMessageID is the max outgoing message id acknowledged read.
	LastReadOutboxMessageID MessageID
	// DraftText is the locally-saved draft text, or empty.
	DraftText string
}

Chat holds the cached header of a Telegram chat, trimmed to the v1 scope.

type ChatDraftUpdate

type ChatDraftUpdate struct {
	ChatID    ChatID
	DraftText string
}

ChatDraftUpdate carries a draft-message change event.

type ChatID

type ChatID int64

ChatID is a Telegram chat identifier.

type ChatLastMessageUpdate

type ChatLastMessageUpdate struct {
	ChatID          ChatID
	LastMessageID   MessageID
	LastMessageDate int64
}

ChatLastMessageUpdate carries a last-message-changed event.

type ChatList

type ChatList struct {
	// Chats is the ordered slice of chat headers (pinned first, then by
	// LastMessageDate descending).
	Chats []*Chat
	// TotalCount is the server-reported total dialog count; may exceed
	// len(Chats) when paging is incomplete.
	TotalCount int
}

ChatList is the result type returned by GetChats and LoadChats.

type ChatReadInboxUpdate

type ChatReadInboxUpdate struct {
	ChatID                 ChatID
	LastReadInboxMessageID MessageID
	UnreadCount            int
}

ChatReadInboxUpdate carries a read-inbox advancement event.

type ChatReadOutboxUpdate

type ChatReadOutboxUpdate struct {
	ChatID                  ChatID
	LastReadOutboxMessageID MessageID
}

ChatReadOutboxUpdate carries a read-outbox advancement event.

type ChatType

type ChatType int

ChatType identifies the peer kind of a Chat.

const (
	// ChatTypePrivate is a 1:1 conversation with another user.
	ChatTypePrivate ChatType = iota + 1
	// ChatTypeBasicGroup is a legacy basic group.
	ChatTypeBasicGroup
	// ChatTypeSupergroup is a supergroup or broadcast channel.
	ChatTypeSupergroup
)

Chat type constants, mirroring chatType* in td_api.tl.

type Client

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

Client is the high-level tdlib entry point. It owns the ordered update channel, delegates domain requests to internal services (added by later RFCs), and manages the lifetime of the Transport and Storage.

The zero value is not usable; construct one with New.

func New

func New(_ context.Context, opts ...Option) (*Client, error)

New creates a Client from the provided options but does not start networking or open the database; call Run to begin processing.

It returns an error when required options (APIID, APIHash) are missing. The context is reserved for option validation that may touch the filesystem or network in later RFCs; it is not retained.

func (*Client) CancelDownload

func (c *Client) CancelDownload(ctx context.Context, id FileID) error

CancelDownload cancels an active download; a no-op when none is in progress.

func (*Client) CheckAuthenticationCode

func (c *Client) CheckAuthenticationCode(ctx context.Context, code string) error

CheckAuthenticationCode checks the code delivered to the phone number. On success the state transitions to Ready, WaitPassword, or WaitRegistration.

func (*Client) CheckAuthenticationPassword

func (c *Client) CheckAuthenticationPassword(ctx context.Context, password string) error

CheckAuthenticationPassword verifies the two-step verification password. On success the state transitions to AuthorizationStateReady.

func (*Client) Close

func (c *Client) Close() error

Close signals the Client to stop, waits for Run to return if it is running, and releases the Transport and Storage. It is safe to call from any goroutine and is idempotent.

func (*Client) DeleteMessages

func (c *Client) DeleteMessages(ctx context.Context, chatID ChatID, messageIDs []MessageID, revoke bool) error

DeleteMessages permanently removes messages from chatID. When revoke is true they are deleted for all participants. The cache is updated optimistically before the RPC.

func (*Client) DownloadFile

func (c *Client) DownloadFile(ctx context.Context, id FileID, priority int, offset, limit int64, synchronous bool) (*File, error)

DownloadFile downloads (or returns an already-complete) file. priority, offset, and limit are accepted for forward compatibility; v1 downloads the whole file synchronously and emits UpdateKindFile on start and completion.

func (*Client) EditMessageText

func (c *Client) EditMessageText(ctx context.Context, chatID ChatID, messageID MessageID, newText InputMessageText) (*Message, error)

EditMessageText replaces the text of an already-sent message and emits UpdateKindMessageEdited. A pending (not-yet-confirmed) message cannot be edited.

func (*Client) GetAuthorizationState

func (c *Client) GetAuthorizationState(ctx context.Context) (*AuthorizationState, error)

GetAuthorizationState returns the current authorization state. It performs no network I/O; subscribe to Updates for live changes.

func (*Client) GetChat

func (c *Client) GetChat(ctx context.Context, id ChatID) (*Chat, error)

GetChat returns the cached header for id, or (nil, nil) when not known locally. It does not issue a network request; call LoadChats to populate the cache.

func (*Client) GetChatHistory

func (c *Client) GetChatHistory(ctx context.Context, chatID ChatID, fromMessageID MessageID, offset, limit int, onlyLocal bool) (*Messages, error)

GetChatHistory returns a page of messages for chatID, newest first. fromMessageID is the exclusive upper bound (zero = newest); offset shifts the window; limit is capped at 100. The local cache is served first; on a short page it falls back to messages.getHistory unless onlyLocal is true.

func (*Client) GetChats

func (c *Client) GetChats(ctx context.Context, limit int) (*ChatList, error)

GetChats returns the locally cached dialog list (pinned first, then by descending last-message date), capped at limit (0 means 100). It does not trigger a network request.

func (*Client) GetContacts

func (c *Client) GetContacts(ctx context.Context) ([]*User, error)

GetContacts returns the cached contact list, fetching it via contacts.getContacts when the cache is empty.

func (*Client) GetFile

func (c *Client) GetFile(ctx context.Context, id FileID) (*File, error)

GetFile returns the cached File metadata for id without starting a download.

func (*Client) GetMe

func (c *Client) GetMe(ctx context.Context) (*User, error)

GetMe returns the authenticated account's User from the local cache, fetching it via users.getUsers when the cache is cold.

func (*Client) GetMessage

func (c *Client) GetMessage(ctx context.Context, chatID ChatID, id MessageID) (*Message, error)

GetMessage returns the cached message (chatID, id) from the local cache, or (nil, nil) when not cached. It does not issue an RPC.

func (*Client) GetOption

func (c *Client) GetOption(ctx context.Context, name string) (OptionValue, error)

GetOption returns the current value of the named option, or OptionValueEmpty when it is not set.

func (*Client) GetUser

func (c *Client) GetUser(ctx context.Context, id UserID) (*User, error)

GetUser returns the cached user for id, fetching it via users.getUsers on a cache miss. It returns ErrNotFound when Telegram reports no such user.

func (*Client) GetUsers

func (c *Client) GetUsers(ctx context.Context, ids []UserID) ([]*User, error)

GetUsers returns cached users for ids, fetching unknown ones in a single users.getUsers RPC. Entries absent from both cache and Telegram are omitted.

func (*Client) ImportContacts

func (c *Client) ImportContacts(ctx context.Context, contacts []ImportContactsRequest) ([]ImportedContact, error)

ImportContacts adds phone-book contacts and returns the matched users ordered to match the input by ClientID.

func (*Client) LoadChats

func (c *Client) LoadChats(ctx context.Context, limit int) (*ChatList, error)

LoadChats fetches up to limit dialogs from the server via messages.getDialogs, applies them to the local cache, and returns the resulting list. It fetches a single page; call again with the returned cursor advanced by the server to page further.

func (*Client) LogOut

func (c *Client) LogOut(ctx context.Context) error

LogOut logs the account out, transitioning through LoggingOut to Closed, then stops the Client (Run returns). The local auth state is erased.

func (*Client) RegisterUser

func (c *Client) RegisterUser(ctx context.Context, firstName, lastName string) error

RegisterUser accepts the terms of service and registers the account with the supplied name. On success the state transitions to AuthorizationStateReady.

func (*Client) RequestQRCodeAuthentication

func (c *Client) RequestQRCodeAuthentication(ctx context.Context) error

RequestQRCodeAuthentication starts a QR-code login. It returns immediately; the authorization state transitions to AuthorizationStateWaitOtherDeviceConfirmation (carrying the link to render as a QR code for an already-authorized device to scan), then to Ready, WaitPassword (if 2FA is enabled), or back to WaitPhoneNumber on failure.

func (*Client) Resolve

func (c *Client) Resolve(ctx context.Context, username string) (*User, error)

Resolve looks up a username (without the leading "@") via contacts.resolveUsername, ingesting the result.

func (*Client) Run

func (c *Client) Run(ctx context.Context) (err error)

Run starts the Transport and blocks until ctx is cancelled, Close is called, or a fatal transport error occurs. It pumps updates pushed through the internal Sink onto the Updates channel in order.

Run may be called only once; a second call returns an error.

func (*Client) SearchUserByPhoneNumber

func (c *Client) SearchUserByPhoneNumber(ctx context.Context, phone string) (*User, error)

SearchUserByPhoneNumber resolves a phone number to a user via contacts.resolvePhone, ingesting the result.

func (*Client) SendMessage

func (c *Client) SendMessage(ctx context.Context, chatID ChatID, content InputMessageContent, opts SendMessageOptions) (*Message, error)

SendMessage sends a new message to chatID. The message is written to the cache and binlog before the RPC, so it survives a crash; the returned Message carries the real server id on success (and UpdateKindMessageSendSucceeded is emitted). On RPC failure the returned message carries a failed SendingState and a wrapped error.

func (*Client) SetAuthenticationPhoneNumber

func (c *Client) SetAuthenticationPhoneNumber(ctx context.Context, phone string) error

SetAuthenticationPhoneNumber sends an authentication code to phone, which must be in international format (e.g. "+12025550123"). On success the state transitions to AuthorizationStateWaitCode.

func (*Client) SetOption

func (c *Client) SetOption(ctx context.Context, name string, value OptionValue) error

SetOption sets a writable option, persisting it and emitting an UpdateKindOption. It returns ErrOptionReadOnly when name is read-only.

func (*Client) StageUpload

func (c *Client) StageUpload(ctx context.Context, localPath string) (*File, error)

StageUpload stages a local path for upload and returns a File with a freshly allocated FileID. The bytes are sent only when UploadFile is called (directly or via SendMessage with document content).

func (*Client) Updates

func (c *Client) Updates() <-chan Update

Updates returns the read-only channel of ordered updates. Updates are enqueued in the exact order they are pushed through the Sink; the Client performs no reordering. The channel is closed when the Client stops.

The channel is unbuffered, so the caller must consume it promptly or the Client applies back-pressure on the engine.

func (*Client) UploadFile

func (c *Client) UploadFile(ctx context.Context, id FileID) (tg.InputFileClass, error)

UploadFile performs the chunked upload for a staged file and returns the tg.InputFileClass for use in a send request.

func (*Client) ViewMessages

func (c *Client) ViewMessages(ctx context.Context, chatID ChatID, messageIDs []MessageID) error

ViewMessages marks the given messages in chatID as read, issuing the read RPC and advancing the dialog's read counters (UpdateKindChatReadInbox).

type ConnectionState

type ConnectionState int

ConnectionState mirrors the td_api.tl connectionState* union.

const (
	// ConnectionStateWaitingForNetwork indicates the client waits for the
	// network to become available.
	ConnectionStateWaitingForNetwork ConnectionState = iota
	// ConnectionStateConnecting indicates the client is establishing a
	// connection to Telegram.
	ConnectionStateConnecting
	// ConnectionStateUpdating indicates the client is catching up on missed
	// updates.
	ConnectionStateUpdating
	// ConnectionStateReady indicates the client is connected and up to date.
	ConnectionStateReady
)

Connection state values.

func (ConnectionState) String

func (s ConnectionState) String() string

String returns the canonical name of the connection state.

type ConnectionStateUpdate

type ConnectionStateUpdate struct {
	State ConnectionState
}

ConnectionStateUpdate wraps a ConnectionState change event.

type DeletedMessages

type DeletedMessages struct {
	ChatID     ChatID
	MessageIDs []MessageID
}

DeletedMessages carries the set of message IDs that were permanently removed from a chat.

type Error

type Error struct {
	// Code is the Telegram API error code.
	Code int
	// Message is the human-readable error description.
	Message string
}

Error is a structured error returned by the Telegram API, mirroring the td_api.tl error object (code:int32 message:string).

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

type File

type File struct {
	// ID is the stable local file identifier assigned by tdlib.
	ID FileID
	// Size is the known file size in bytes; 0 when unknown.
	Size int64
	// Local holds the local copy state.
	Local LocalFile
	// Remote holds the remote location state.
	Remote RemoteFile
}

File holds the metadata for a Telegram file with its local and remote state. It is delivered in UpdateKindFile and returned by the file methods. The ID is stable for the lifetime of the local database.

type FileID

type FileID int32

FileID is a Telegram file identifier.

type ImportContactsRequest

type ImportContactsRequest struct {
	// ClientID is a caller-assigned integer used to correlate results.
	ClientID int64
	// Phone is the phone number to import in international format.
	Phone string
	// FirstName is the contact's first name.
	FirstName string
	// LastName is the contact's last name; may be empty.
	LastName string
}

ImportContactsRequest describes one entry for Client.ImportContacts.

type ImportedContact

type ImportedContact struct {
	// ClientID echoes the request's ClientID.
	ClientID int64
	// User is the matched account, or nil when no match was found.
	User *User
}

ImportedContact pairs an import request with its resulting user.

type InputMessageContent

type InputMessageContent struct {
	// Kind selects the active payload field.
	Kind InputMessageContentKind
	// Text is set when Kind == InputMessageContentKindText.
	Text *InputMessageText
	// Document is set when Kind == InputMessageContentKindDocument.
	Document *InputMessageDocument
}

InputMessageContent is the input union for composing an outgoing message body.

type InputMessageContentKind

type InputMessageContentKind int

InputMessageContentKind enumerates the variants of InputMessageContent.

const (
	// InputMessageContentKindText is a plain text message.
	InputMessageContentKindText InputMessageContentKind = iota + 1
	// InputMessageContentKindDocument is a file attachment (RFC 0012 upload
	// seam; not yet implemented).
	InputMessageContentKindDocument
)

Input message content kind constants.

type InputMessageDocument

type InputMessageDocument struct {
	// FileID is the local file id from Client.StageUpload.
	FileID FileID
	// Caption is the optional text caption.
	Caption string
}

InputMessageDocument sends a staged file as a document (RFC 0012).

type InputMessageText

type InputMessageText struct {
	// Text is the message body.
	Text string
	// Entities is optional rich-text formatting; nil means none.
	Entities []MessageEntity
	// DisableWebPagePreview suppresses the link-preview box.
	DisableWebPagePreview bool
}

InputMessageText is the content for a text message send.

type LocalFile

type LocalFile struct {
	// Path is the absolute path to the local file; empty when not downloaded.
	Path string
	// CanBeDownloaded is true if the file can still be downloaded from Telegram.
	CanBeDownloaded bool
	// IsDownloadingActive is true while a DownloadFile call is in progress.
	IsDownloadingActive bool
	// IsDownloadingCompleted is true when the full file is available locally.
	IsDownloadingCompleted bool
	// DownloadedSize is the number of bytes written so far.
	DownloadedSize int64
}

LocalFile holds the local copy state of a Telegram file.

type Message

type Message struct {
	// ID is the message identifier, unique within the owning chat.
	ID MessageID
	// ChatID is the chat that contains this message.
	ChatID ChatID
	// SenderID is the user who sent it; zero for anonymous channel posts.
	SenderID UserID
	// Date is the UTC timestamp when the message was sent.
	Date time.Time
	// EditDate is the UTC timestamp of the most recent edit, or zero.
	EditDate time.Time
	// IsOutgoing reports whether the message was sent by the authenticated user.
	IsOutgoing bool
	// ReplyTo identifies the replied-to message, or nil.
	ReplyTo *MessageReplyTo
	// Content holds the typed message body.
	Content MessageContent
	// SendingState is non-nil for outgoing messages awaiting server
	// confirmation (RFC 0011); nil for incoming or delivered messages.
	SendingState *MessageSendingState
}

Message holds a single cached Telegram message, trimmed to the v1 scope. Message ids are per-dialog: always pair a MessageID with its ChatID.

type MessageContent

type MessageContent struct {
	// Kind identifies which payload field is set.
	Kind MessageContentKind
	// Text is set when Kind == MessageContentKindText.
	Text *MessageText
}

MessageContent is the tagged union for message body variants. Exactly one payload field is non-nil, identified by Kind.

type MessageContentKind

type MessageContentKind int

MessageContentKind enumerates the variants of a MessageContent.

const (
	// MessageContentKindText is a plain text message; mirrors messageText.
	MessageContentKindText MessageContentKind = iota + 1
	// MessageContentKindUnsupported is a placeholder for content types not yet
	// handled in v1 (photos, documents, stickers, …). RFC 0012 replaces it.
	MessageContentKindUnsupported
)

Message content kind constants.

type MessageEntity

type MessageEntity struct {
	// Type is the entity kind (bold, italic, code, mention, …).
	Type string
	// Offset is the UTF-16 code-unit start of the span.
	Offset int
	// Length is the UTF-16 code-unit length of the span.
	Length int
}

MessageEntity is a formatting annotation over a span of text (reserved; nil in v1).

type MessageID

type MessageID int64

MessageID is a Telegram message identifier, scoped to a chat.

type MessageReplyTo

type MessageReplyTo struct {
	// ChatID is the chat containing the original message; zero when the reply
	// is in the same chat.
	ChatID ChatID
	// MessageID is the id of the message being replied to.
	MessageID MessageID
}

MessageReplyTo identifies the message being replied to.

type MessageSendFailed

type MessageSendFailed struct {
	// Message is the message as stored locally (still using the temp id).
	Message *Message
	// OldMessageID is the temporary local id.
	OldMessageID MessageID
	// Error is the RPC error that caused the failure.
	Error *Error
}

MessageSendFailed is the payload for UpdateKindMessageSendFailed.

type MessageSendSucceeded

type MessageSendSucceeded struct {
	// Message is the final message with its real server-assigned id.
	Message *Message
	// OldMessageID is the temporary local id it replaced.
	OldMessageID MessageID
}

MessageSendSucceeded is the payload for UpdateKindMessageSendSucceeded.

type MessageSendingState

type MessageSendingState struct {
	// Kind identifies whether the message is pending or failed.
	Kind MessageSendingStateKind
	// Error is set when Kind == MessageSendingStateFailed.
	Error *Error
}

MessageSendingState holds the send state of an outgoing message. It is nil for incoming or successfully-delivered messages.

type MessageSendingStateKind

type MessageSendingStateKind int

MessageSendingStateKind enumerates the sending state of an outgoing message.

const (
	// MessageSendingStatePending means the message is inserted locally but not
	// yet confirmed by the server.
	MessageSendingStatePending MessageSendingStateKind = iota + 1
	// MessageSendingStateFailed means the send RPC failed and will not be
	// retried automatically.
	MessageSendingStateFailed
)

Sending state constants.

type MessageText

type MessageText struct {
	// Text is the message body as a plain string.
	Text string
	// Entities is reserved for rich-text formatting; nil in v1.
	Entities []MessageEntity
}

MessageText holds the body of a text message.

type Messages

type Messages struct {
	// Items is the ordered page, newest first (descending by id).
	Items []*Message
	// TotalCount is the server-reported total; zero when served from cache.
	TotalCount int
}

Messages is the result type returned by GetChatHistory.

type Option

type Option func(*options)

Option is a functional option for Client construction.

func WithAPIHash

func WithAPIHash(hash string) Option

WithAPIHash sets the Telegram application hash (required). Obtain it from https://my.telegram.org/apps.

func WithAPIID

func WithAPIID(id int) Option

WithAPIID sets the Telegram application ID (required). Obtain it from https://my.telegram.org/apps.

func WithAppVersion

func WithAppVersion(version string) Option

WithAppVersion sets the application version string reported to Telegram.

func WithDatabaseDirectory

func WithDatabaseDirectory(dir string) Option

WithDatabaseDirectory sets the directory holding the local SQLite database file. It defaults to "." when empty.

func WithDeviceModel

func WithDeviceModel(model string) Option

WithDeviceModel sets the device model string reported to Telegram. It defaults to the OS name when empty.

func WithFilesDirectory

func WithFilesDirectory(dir string) Option

WithFilesDirectory sets the directory where downloaded files are stored. It defaults to "files" under the database directory when empty.

func WithLogger

func WithLogger(l log.Logger) Option

WithLogger sets the logger the Client and its services write to. A nil value (the default) discards all log records via log.Nop.

func WithMeterProvider

func WithMeterProvider(mp metric.MeterProvider) Option

WithMeterProvider sets the OpenTelemetry MeterProvider. It defaults to the no-op provider.

func WithSystemVersion

func WithSystemVersion(version string) Option

WithSystemVersion sets the OS version string reported to Telegram.

func WithTestDC

func WithTestDC(dc int) Option

WithTestDC overrides the initial DC index for test-server connections. Pass 1, 2, or 3 to target the Telegram test environment. Zero (the default) uses the production DC.

func WithTracerProvider

func WithTracerProvider(tp trace.TracerProvider) Option

WithTracerProvider sets the OpenTelemetry TracerProvider. It defaults to the no-op provider so the library never calls otel.SetTracerProvider.

type OptionValue

type OptionValue struct {
	// Kind identifies which payload field is active.
	Kind OptionValueKind
	// Boolean is set when Kind == OptionValueKindBoolean.
	Boolean bool
	// Integer is set when Kind == OptionValueKindInteger.
	Integer int64
	// String is set when Kind == OptionValueKindString.
	String string
}

OptionValue is a sealed tagged union over Empty, Boolean, Integer, and String. Exactly one payload field matches Kind; the others are zero.

func OptionValueBool

func OptionValueBool(v bool) OptionValue

OptionValueBool returns an OptionValue wrapping v.

func OptionValueInt

func OptionValueInt(v int64) OptionValue

OptionValueInt returns an OptionValue wrapping v.

func OptionValueStr

func OptionValueStr(v string) OptionValue

OptionValueStr returns an OptionValue wrapping v.

type OptionValueKind

type OptionValueKind int

OptionValueKind enumerates the variants of an OptionValue.

const (
	// OptionValueKindEmpty is the absence of a value.
	OptionValueKindEmpty OptionValueKind = iota
	// OptionValueKindBoolean corresponds to optionValueBoolean.
	OptionValueKindBoolean
	// OptionValueKindInteger corresponds to optionValueInteger.
	OptionValueKindInteger
	// OptionValueKindString corresponds to optionValueString.
	OptionValueKindString
)

Option value kind constants, mirroring td_api.tl optionValue*.

type PendingSendEntry

type PendingSendEntry struct {
	// BinlogID is the binlog row id; used to confirm the entry on success.
	BinlogID int64 `json:"-"`
	// ChatID identifies the chat.
	ChatID ChatID `json:"chat_id"`
	// TempMessageID is the temporary local id of the pending message.
	TempMessageID MessageID `json:"temp_id"`
	// RandomID is the random_id used for server-side deduplication.
	RandomID int64 `json:"random_id"`
	// Text is the message body to re-send.
	Text string `json:"text"`
	// ReplyToMessageID is non-zero when the message is a reply.
	ReplyToMessageID MessageID `json:"reply_to,omitempty"`
}

PendingSendEntry is the JSON binlog payload for a "send_message" operation, carrying everything needed to re-issue the RPC after a crash.

type RemoteFile

type RemoteFile struct {
	// ID is the opaque remote file identifier usable across restarts.
	ID string
	// UniqueID is the stable content identifier shared across users.
	UniqueID string
	// IsUploadingActive is true while an UploadFile call is in progress.
	IsUploadingActive bool
	// IsUploadingCompleted is true after a successful upload.
	IsUploadingCompleted bool
	// UploadedSize is the number of bytes confirmed uploaded so far.
	UploadedSize int64
}

RemoteFile holds the remote location of a Telegram file.

type SendMessageOptions

type SendMessageOptions struct {
	// ReplyToMessageHolder is the message id to reply to; zero means no reply.
	ReplyToMessageID MessageID
}

SendMessageOptions carries per-send flags.

type Sink

type Sink interface {
	// Push enqueues one update for delivery to the caller. It returns an error
	// only when the Client has been closed or ctx is cancelled.
	Push(ctx context.Context, u Update) error
}

Sink is the update-intake boundary between the network engine (RFC 0013) and the Client's ordered fan-out. The engine calls Push for each normalised update in the order it was received; the Client serialises these onto the caller-facing Updates channel.

Push must not be assumed to be non-blocking: it applies back-pressure when the caller is slow. Implementations must be safe for concurrent use.

type Transport

type Transport interface {
	// Run starts the underlying MTProto session and blocks until ctx is
	// cancelled or a fatal error occurs.
	Run(ctx context.Context) error
	// API returns the raw TL client for issuing MTProto RPCs. Safe for
	// concurrent use.
	API() *tg.Client
	// Self blocks until authentication completes and returns the authorized
	// user.
	Self(ctx context.Context) (*tg.User, error)
	// Close gracefully shuts down the transport.
	Close() error
}

Transport is the gotd/td client port. The Client drives its lifecycle (Run/Close); services issue MTProto RPCs through API and resolve the authorized account through Self. The real implementation lives in internal/td (*td.Conn); tests use the generated moq fake.

Implementations must be safe for concurrent use by multiple goroutines.

type Update

type Update struct {
	// Kind identifies which payload field is set.
	Kind UpdateKind

	// AuthorizationState is set when Kind == UpdateKindAuthorizationState.
	AuthorizationState *AuthorizationState
	// NewMessage is set when Kind == UpdateKindNewMessage.
	NewMessage *Message
	// DeletedMessages is set when Kind == UpdateKindDeleteMessages.
	DeletedMessages *DeletedMessages
	// User is set when Kind == UpdateKindUser.
	User *User
	// Chat is set when Kind == UpdateKindChat.
	Chat *Chat
	// ConnectionState is set when Kind == UpdateKindConnectionState.
	ConnectionState *ConnectionStateUpdate
	// File is set when Kind == UpdateKindFile.
	File *File
	// Option is set when Kind == UpdateKindOption.
	Option *UpdateOption
	// ChatReadInbox is set when Kind == UpdateKindChatReadInbox.
	ChatReadInbox *ChatReadInboxUpdate
	// ChatReadOutbox is set when Kind == UpdateKindChatReadOutbox.
	ChatReadOutbox *ChatReadOutboxUpdate
	// ChatLastMessage is set when Kind == UpdateKindChatLastMessage.
	ChatLastMessage *ChatLastMessageUpdate
	// ChatDraftMessage is set when Kind == UpdateKindChatDraftMessage.
	ChatDraftMessage *ChatDraftUpdate
	// SendSucceeded is set when Kind == UpdateKindMessageSendSucceeded.
	SendSucceeded *MessageSendSucceeded
	// SendFailed is set when Kind == UpdateKindMessageSendFailed.
	SendFailed *MessageSendFailed
	// EditedMessage is set when Kind == UpdateKindMessageEdited.
	EditedMessage *Message
}

Update is one item on the ordered update stream the Client delivers to the caller. Exactly one payload field is non-nil; Kind identifies which one.

type UpdateKind

type UpdateKind int

UpdateKind enumerates the variants of an Update.

const (
	// UpdateKindAuthorizationState is sent whenever the authorization state
	// changes; mirrors updateAuthorizationState.
	UpdateKindAuthorizationState UpdateKind = iota + 1
	// UpdateKindNewMessage is sent when a new message is received; mirrors
	// updateNewMessage.
	UpdateKindNewMessage
	// UpdateKindDeleteMessages is sent when messages are permanently deleted;
	// mirrors updateDeleteMessages.
	UpdateKindDeleteMessages
	// UpdateKindUser is sent when a user object changes; mirrors updateUser.
	UpdateKindUser
	// UpdateKindChat is sent when a chat header changes; mirrors
	// updateNewChat / updateChatTitle and related constructors.
	UpdateKindChat
	// UpdateKindConnectionState is sent when the network state changes;
	// mirrors updateConnectionState.
	UpdateKindConnectionState
	// UpdateKindFile is sent when a file transfer progresses; mirrors
	// updateFile.
	UpdateKindFile
	// UpdateKindOption is sent when a named option changes; mirrors
	// updateOption.
	UpdateKindOption
	// UpdateKindChatReadInbox is sent when the read-inbox high-water mark
	// advances; mirrors updateChatReadInbox.
	UpdateKindChatReadInbox
	// UpdateKindChatReadOutbox mirrors updateChatReadOutbox.
	UpdateKindChatReadOutbox
	// UpdateKindChatLastMessage mirrors updateChatLastMessage.
	UpdateKindChatLastMessage
	// UpdateKindChatDraftMessage mirrors updateChatDraftMessage.
	UpdateKindChatDraftMessage
	// UpdateKindMessageSendSucceeded is emitted when the server confirms an
	// outgoing message; mirrors updateMessageSendSucceeded.
	UpdateKindMessageSendSucceeded
	// UpdateKindMessageSendFailed is emitted when the server rejects an
	// outgoing message; mirrors updateMessageSendFailed.
	UpdateKindMessageSendFailed
	// UpdateKindMessageEdited is emitted when a message is edited.
	UpdateKindMessageEdited
)

Update kind constants for the v1 scope. New variants are appended as later RFCs expand the surface.

type UpdateOption

type UpdateOption struct {
	// Name is the option name, e.g. "my_id", "version".
	Name string
	// Value is the new value.
	Value OptionValue
}

UpdateOption carries a named option change. A Value with Kind OptionValueKindEmpty means the option was cleared.

type User

type User struct {
	// ID is the Telegram user identifier.
	ID UserID
	// AccessHash is the opaque token required to address this user in MTProto
	// RPCs via tg.InputUser. It is persisted and never overwritten with zero
	// once known.
	AccessHash int64
	// FirstName is the user's first name.
	FirstName string
	// LastName is the user's last name; may be empty.
	LastName string
	// Username is the primary username without the leading "@"; may be empty.
	Username string
	// Usernames holds all active usernames; the primary one is first.
	Usernames []string
	// Phone is the international-format phone number; set only when accessible.
	Phone string
	// Status is the last known online presence.
	Status UserStatus
	// IsBot is true when the account belongs to a bot.
	IsBot bool
	// IsContact is true when this user is in the account's contact list.
	IsContact bool
	// IsMutualContact is true when the contact relationship is mutual.
	IsMutualContact bool
	// IsSelf is true when this user is the authenticated account itself.
	IsSelf bool
	// IsMin is true when the object was received as a "min" user (incomplete,
	// without a usable access_hash).
	IsMin bool
}

User holds the cached profile of a Telegram account, trimmed to the v1 scope.

type UserID

type UserID int64

UserID is a Telegram user identifier.

type UserStatus

type UserStatus struct {
	// Kind is the presence variant.
	Kind UserStatusKind
	// Expires is the online-window close time when Kind == UserStatusKindOnline.
	Expires time.Time
	// WasOnline is the last-seen time when Kind == UserStatusKindOffline.
	WasOnline time.Time
}

UserStatus holds the cached online presence of a Telegram user.

type UserStatusKind

type UserStatusKind int

UserStatusKind enumerates online-presence variants, mirroring td_api.tl userStatus* constructors.

const (
	// UserStatusKindUnknown is the zero value; status has not been received.
	UserStatusKindUnknown UserStatusKind = iota
	// UserStatusKindOnline means the user is currently online.
	UserStatusKindOnline
	// UserStatusKindOffline means the user was last seen at a specific time.
	UserStatusKindOffline
	// UserStatusKindRecently means the user was recently online.
	UserStatusKindRecently
	// UserStatusKindLastWeek means the user was online within the last week.
	UserStatusKindLastWeek
	// UserStatusKindLastMonth means the user was online within the last month.
	UserStatusKindLastMonth
)

User status kind constants.

Directories

Path Synopsis
cmd
tdlib command
Command tdlib is a full-featured interactive example client for the tdlib library.
Command tdlib is a full-featured interactive example client for the tdlib library.
internal
db
Package db implements the SQLite storage engine backing every stateful feature in tdlib.
Package db implements the SQLite storage engine backing every stateful feature in tdlib.
obs
Package obs provides the OTEL provider bundle injected into tdlib components.
Package obs provides the OTEL provider bundle injected into tdlib components.
td
Package td implements the tdlib network transport over gotd/td's telegram.Client.
Package td implements the tdlib network transport over gotd/td's telegram.Client.

Jump to

Keyboard shortcuts

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