opentele-ng¶
PyPI package name: opentele-ng.
The GitHub repository is called opentele, the package it publishes is
opentele-ng, and the import path stays opentele. Same project.
Modern fork of thedemons/opentele. Python 3.10–3.14 • pure-Python runtime, no Qt dependency • reads tdata from current Telegram Desktop, no version gate • drop-in
import opentelecompatibility.
Install¶
30-second tour¶
Inspect a tdata folder:
Convert it to a Telethon session:
For programmatic use:
import asyncio
from opentele.api import API, CreateNewSession
from opentele.td import TDesktop
async def main():
td = TDesktop("/path/to/Telegram/tdata")
client = await td.ToTelethon(
session="me.session",
flag=CreateNewSession,
api=API.TelegramDesktop.Generate(),
)
me = await client.get_me()
print(me.id, me.username)
asyncio.run(main())
Why this fork¶
Upstream thedemons/opentele last shipped to PyPI in January 2022 and last committed in July 2024; it started silently breaking on tdata from current Telegram Desktop because Telegram added several lskType keys that desync the stream on read. opentele-ng ships the missing wire-format fixes plus a pure-Python QDataStream so you don't need to install Qt — see the README for the full breakdown.
Which Telegram Desktop versions can it read?¶
Verified against Telegram Desktop 7.0.9 (2026-08-06), and nothing in the reader turns a folder away for being newer than that.
Storage.ReadFile checks the TDF$ magic and the MD5 trailer, then treats the version field in the header as information — it becomes TDesktop.AppVersion — not as something to accept or reject. There is no floor and no ceiling. Compatibility is decided by the contents instead:
- The
lskTypeenum intd/configs.pymatches TDesktop's own instorage_account.cppentry for entry,0x00–0x1E. One name lags:0x11is stilllskTrustedBotshere, renamedlskTrustedPeersupstream. Same ID, so it reads fine. - The account-map reader dispatches
lskDraft(0x01) throughlskPrefs(0x1E).lskUserMap(0x00) names the map file itself and is not written as a block by either side. - An unrecognised key fails closed with a clear exception instead of desyncing the stream (behaviour introduced in 1.3.0). You get an error naming the key and its offset, not silently truncated data.
- In the MTProto path the one hard equality is
MTP.Config.kVersion == 1.DcOptionsreads whatever positive version it finds and only writeskVersion = 2.
So a later Telegram Desktop could still require work here — if it adds a block type, changes the layout of an existing one, or bumps MTP.Config — but a version bump on its own does not.
Where next¶
- CLI quick start — common one-shot workflows
- Programmatic examples
- Security policy
- Changelog
- Benchmarks