opentele2.td
Telegram Desktop folders and their accounts and keys, read and written by opentele2._native.
from opentele2.td import Account, AuthKey, AuthKeyType, TDesktopTDesktop
A Telegram Desktop client: the accounts of one tdata folder, loaded and saved by the core.
class TDesktop:
kMaxAccounts: int = TData.MAX_ACCOUNTS # 6
kDefaultKeyFile: str = "data"
kPerformanceMode: bool = True
def __init__(
self,
basePath: str | None = None,
api: type[APIData] | APIData = API.TelegramDesktop,
passcode: str | None = None,
keyFile: str | None = None,
) -> None: ...With a basePath the folder is loaded at once; without one the instance is empty until
LoadTData or until accounts are added through FromTelethon.
Methods
def isLoaded(self) -> bool: ...
def LoadTData(self, basePath: str | None = None, passcode: str | None = None,
keyFile: str | None = None) -> None: ...
def SaveTData(self, basePath: str | None = None, passcode: str | None = None,
keyFile: str | None = None, *, draws: Iterable[bytes] | None = None) -> bool: ...
async def ToTelethon(self, session: str | Session | None = None,
flag: type[LoginFlag] = CreateNewSession,
api: type[APIData] | APIData = API.TelegramDesktop,
password: str | None = None,
**kwargs: Unpack[TelethonClientKwargs]) -> tl.TelegramClient: ...
@staticmethod
async def FromTelethon(telethonClient: tl.TelegramClient,
flag: type[LoginFlag] = CreateNewSession,
api: type[APIData] | APIData = API.TelegramDesktop,
password: str | None = None) -> TDesktop: ...
@staticmethod
async def FromSessionJson(session_path: str, json_path: str | None = None,
flag: type[LoginFlag] = UseCurrentSession,
api: type[APIData] | APIData | None = None,
password: str | None = None) -> TDesktop: ...
async def SaveSessionJson(self, session_path: str, api: type[APIData] | APIData | None = None,
fetch_user_info: bool = False) -> tuple[str, str]: ...
@classmethod
def PerformanceMode(cls, enabled: bool = True) -> None: ...| Method | Description |
|---|---|
isLoaded() | Whether accounts have been loaded from tdata, or a local key was made for new ones. |
LoadTData(...) | Loads the accounts of the folder at basePath; raises TDataBadDecryptKey for a missing or wrong passcode and TFileNotFound without a key file. |
SaveTData(...) | Writes the accounts listed in accounts to a folder; a new passcode, or a folder never loaded, gets a new local key, and a pre-7.3 key file is migrated once. Raises TDataSaveFailed. |
ToTelethon(...) | The main account as a TelegramClient; see Telegram. |
FromTelethon(...) | A new TDesktop holding the client’s account: its own session with UseCurrentSession, a new QR-login session with CreateNewSession. |
FromSessionJson(...) | A TDesktop from a .session + .json pair; api defaults to the profile stored in the .json. |
SaveSessionJson(...) | Writes the main account’s session as a .session + .json pair and returns both paths. |
Performance | Sets kPerformanceMode: fixed keys for a new local key without a passcode, and no configs files on save. |
draws, a testing hook, replays recorded os.urandom draws for one save instead of the OS random
source, so a save can be compared byte for byte with a reference folder.
Properties
| Property | Type | Description |
|---|---|---|
api | type[APIData] or APIData | The API profile of the folder; setting it sets every account’s. |
basePath | str or None | The absolute folder path. |
passcode | str | The local passcode, "" for none. |
keyFile | str | The key file data name, "data" by default. |
passcodeKey | AuthKey or None | The open or passcode key the local key is wrapped under. |
localKey | AuthKey or None | The local key every file but the key file is encrypted with. |
AppVersion | int or None | The Telegram Desktop version in the key file header, for example 7003001. |
accountsCount | int | How many accounts are listed. |
accounts | list[Account] | The accounts; removing one from the list or appending one is saved. |
mainAccount | Account or None | The account at the active index. |
Account
One account of a Telegram Desktop folder, owned by a TDesktop.
class Account:
kWideIdsTag: int = ~0
def __init__(
self,
owner: TDesktop,
basePath: str | None = None,
api: type[APIData] | APIData = API.TelegramDesktop,
keyFile: str | None = None,
index: int = 0,
) -> None: ...
def isAuthorized(self) -> bool: ...
def isLoaded(self) -> bool: ...
def SaveTData(self, basePath: str | None = None, passcode: str | None = None,
keyFile: str | None = None, *, draws: Iterable[bytes] | None = None) -> None: ...
async def ToTelethon(self, session: str | Session | None = None,
flag: type[LoginFlag] = CreateNewSession,
api: type[APIData] | APIData = API.TelegramDesktop,
password: str | None = None,
**kwargs: Unpack[TelethonClientKwargs]) -> tl.TelegramClient: ...
@staticmethod
async def FromTelethon(telethonClient: tl.TelegramClient,
flag: type[LoginFlag] = CreateNewSession,
api: type[APIData] | APIData = API.TelegramDesktop,
password: str | None = None,
owner: TDesktop | None = None) -> Account: ...| Name | Description |
|---|---|
isLoaded() | Whether the account was loaded from a folder or built from a client. |
isAuthorized() | The account object’s authorization flag, which loading and conversion leave False. |
SaveTData(...) | Saves the owner’s folder; see TDesktop.SaveTData. |
ToTelethon(...) | This account as a TelegramClient; raises TDAccountNotLoaded before loading. |
FromTelethon(...) | Adds the client’s account to owner (a new TDesktop without one) at the lowest free index; raises MaxAccountLimit for a full folder. |
| Property | Type | Description |
|---|---|---|
owner | TDesktop | The folder the account belongs to. |
api | type[APIData] or APIData | The account’s API profile; setting it sets the owner’s. |
basePath | str | The absolute folder path. |
keyFile | str | The key file data name; settable. |
localKey | AuthKey or None | The folder’s local key; settable. |
authKey | AuthKey or None | The auth key of the main DC. |
UserId | int | The Telegram user id. |
MainDcId | int | The main DC id. |
index | int | The index of the account in the folder. |
MtpConfig | MtpConfigView | The account’s stored MTP config, read only. |
MtpConfigView
Account.MtpConfig: the MTP config of one loaded account as the core parses it, or the production
default when the folder stores none or it does not parse. Every read returns a new copy, so editing
a result changes nothing that is saved.
class MtpConfigView:
@property
def environment(self) -> Literal["production", "test"]: ...
def isTestMode(self) -> bool: ...
@property
def dcOptions(self) -> dict[int, list[Endpoint]]: ...
@property
def cdnPublicKeys(self) -> list[RsaPublicKey]: ...
@property
def fields(self) -> MtpConfigFields: ...
def endpoints(self, dcId: int = 0) -> Endpoints: ...| Name | Description |
|---|---|
environment | "production" or "test". |
isTestMode() | Whether the environment is not production. |
dcOptions | The endpoints of every DC, by DC id, in the stored order. |
cdnPublicKeys | The CDN RSA keys as {"dc_id", "n", "e"} dicts. |
fields | The scalar config fields (chat_size_max, edit_time_limit, internal_links_domain and the rest). |
endpoints(dcId) | The endpoints of dcId by family and protocol: "ipv4" and "ipv6", each with "tcp" and "http", plus "selected_ipv4" and "selected_ipv6". Raises TDataDcIdNotFound for a DC the config does not list; the default 0 is never listed. |
An Endpoint is a dict with id, flags, ip, port and secret; the flag bits are the
MTP_FLAG_* constants of opentele2._native.
AuthKey
An MTProto auth key, its id and its old-MTP AES key derivation.
class AuthKeyType(IntEnum):
Generated = 0
Temporary = 1
ReadFromFile = 2
Local = 3
class AuthKey:
kSize = 256
def __init__(self, key: bytes = b"", type: AuthKeyType = AuthKeyType.Generated,
dcId: int = 0) -> None: ...
@property
def dcId(self) -> int: ...
@property
def type(self) -> AuthKeyType: ...
@property
def key(self) -> bytes: ...
@property
def keyId(self) -> int: ...
def prepareAES_oldmtp(self, msgKey: bytes, send: bool) -> tuple[bytes, bytes]: ...| Name | Description |
|---|---|
dcId | The DC the key belongs to; 0 for none. |
type | How the key was made. |
key | The 256 key bytes. |
keyId | The low 64 bits of SHA-1 of the key, little endian; a key of another size raises ValueError. |
prepare | The MTProto 1.0 AES key and IV for the first 16 bytes of msgKey; send picks the client-to-server half. Raises on a bad key or msg_key length. |
TDataDcIdNotFound
class TDataDcIdNotFound(OpenTeleException):
def __init__(self, dcId: int, stack_index: int = 2) -> None: ...
dcId: intRaised by MtpConfigView.endpoints for a DC the config does not list.
AuthKey.key, TDesktop.localKey and TDesktop.passcodeKey are raw key material. Never print
or log them.