Skip to content

Releases: LonamiWebs/Telethon

Changelog moved

19 Jan 19:51
Choose a tag to compare
Changelog moved Pre-release

Please refer to Read The Docs - Changelog (Version History) for the changelog from now on! You should read it every time you update the library, a considerable amount of effort is put into it and should save you from some "my code worked but not anymore".

Sessions as sqlite databases

28 Dec 11:58
Choose a tag to compare

In the beginning, session files used to be pickle. This proved to be bad as soon as one wanted to add more fields. For this reason, they were migrated to use JSON instead. But this proved to be bad as soon as one wanted to save things like entities (usernames, their ID and hash), so now it properly uses sqlite3, which has been well tested, to save the session files! Calling .get_input_entity using a username no longer will need to fetch it first, so it's really 0 calls again. Calling .get_entity will always fetch the most up to date version.

Furthermore, nearly everything has been documented, thus preparing the library for Read the Docs (although there are a few things missing I'd like to polish first), and the logging are now better placed.

Breaking changes

  • .get_dialogs() now returns a single list instead a tuple consisting of a custom class that should make everything easier to work with.
  • .get_message_history() also returns a single list instead a tuple, with the Message instances modified to make them more convenient.

Both lists have a .total attribute so you can still know how many dialogs/messages are in total.

New stuff

  • The mentioned use of sqlite3 for the session file.
  • .get_entity() now supports lists too, and it will make as little API calls as possible if you feed it InputPeer types. Usernames will always be resolved, since they may have changed.
  • .set_proxy() method, to avoid having to create a new TelegramClient.
  • More date types supported to represent a date parameter.

Bug fixes

  • Empty strings weren't working when they were a flag parameter (e.g., setting no last name).
  • Fix invalid assertion regarding flag parameters as well.
  • Avoid joining the background thread on disconnect, as it would be None due to a race condition.
  • Correctly handle None dates when downloading media.
  • .download_profile_photo was failing for some channels.
  • .download_media wasn't handling Photo.

Internal changes

  • date was being serialized as local date, but that was wrong.
  • date was being represented as a float instead of an int.
  • .tl parser wasn't stripping inline comments.
  • Removed some redundant checks on
  • Use a synchronized queue instead a hand crafted version.
  • Use signed integers consistently (e.g. salt).
  • Always read the corresponding TLObject from API responses, except for some special cases still.
  • A few more except low level to correctly wrap errors.
  • More accurate exception types.
  • invokeWithLayer(initConnection(X)) now wraps every first request after .connect().

As always, report if you have issues with some of the changes!

IPv6 support

16 Nov 18:24
Choose a tag to compare
IPv6 support Pre-release
Scheme layer used: 73

It's here, it has come! The library now supports IPv6! Just pass use_ipv6=True when creating a TelegramClient. Note that I could not test this feature because my machine doesn't have IPv6 setup. If you know IPv6 works in your machine but the library doesn't, please refer to #425.


  • IPv6 support.
  • New method to extract the text surrounded by MessageEntity's, in the extensions.markdown module.


  • Markdown parsing is Done Right.
  • Reconnection on failed invoke. Should avoid "number of retries reached 0" (#270).
  • Some missing autocast to Input* types.
  • The library uses the NullHandler for logging as it should have always done.
  • TcpClient.is_connected() is now more reliable.

Bug fixes

  • Getting an entity using their phone wasn't actually working.
  • Full entities aren't saved unless they have an access_hash, to avoid some None errors.
  • .get_message_history was failing when retrieving items that had messages forwarded from a channel.

General enhancements

04 Nov 12:41
Choose a tag to compare
General enhancements Pre-release
Scheme layer used: 72

This update brings a few general enhancements that are enough to deserve a new release, with a new feature: beta markdown-like parsing for .send_message()!


  • .send_message() supports parse_mode='md' for Markdown! It works in a similar fashion to the official clients (defaults to double underscore/asterisk, like **this**). Please report any issues with emojies or enhancements for the parser!
  • New .idle() method so your main thread can do useful job (listen for updates).
  • Add missing .to_dict(), __str__ and .stringify() for TLMessage and MessageContainer.

Bug fixes

  • The list of known peers could end "corrupted" and have users with access_hash=None, resulting in struct error for it not being an integer. You shouldn't encounter this issue anymore.
  • The warning for "added update handler but no workers set" wasn't actually working.
  • .get_input_peer was ignoring a case for InputPeerSelf.
  • There used to be an exception when logging exceptions (whoops) on update handlers.
  • "Downloading contacts" would produce strange output if they had semicolons (;) in their name.
  • Fix some cyclic imports and installing dependencies from the git repository.
  • Code generation was using f-strings, which are only supported on Python ≥3.6.

Other changes

  • The auth_key generation has been moved from .connect() to .invoke(). There were some issues were .connect() failed and the auth_key was None so this will ensure to have a valid auth_key when needed, even if BrokenAuthKeyError is raised.
  • Support for higher limits on .get_history() and .get_dialogs().
  • Much faster integer factorization when generating the required auth_key. Thanks @delivrance for making me notice this, and for the pull request.

Bug fixes with updates

20 Oct 21:40
Choose a tag to compare

Hopefully a very ungrateful bug has been removed. When you used to invoke some request through update handlers, it could potentially enter an infinite loop. This has been mitigated and it's now safe to invoke things again! A lot of updates were being dropped (all those gzipped), and this has been fixed too.

More bug fixes include a correct parsing of certain TLObjects thanks to @stek29, and some wrong calls that would cause the library to crash thanks to @andr-04, and the ReadThread not re-starting if you were already authorized.

Internally, the .to_bytes() function has been replaced with __bytes__ so now you can do bytes(tlobject).

Bug fixes and new small features

14 Oct 10:14
Choose a tag to compare

This release primarly focuses on a few bug fixes and enhancements. Although more stuff may have broken along the way.

Bug fixes:

  • .get_input_entity was failing for IDs and other cases, also making more requests than it should.
  • Use basename instead abspath when sending a file. You can now also override the attributes.
  • EntityDatabase.__delitem__ wasn't working.
  • .send_message() was failing with channels.
  • .get_dialogs(limit=None) should now return all the dialogs correctly.
  • Temporary fix for abusive duplicated updates.


  • You will be warned if you call .add_update_handler with no update_workers.
  • New customizable threshold value on the session to determine when to automatically sleep on flood waits. See client.session.flood_sleep_threshold.
  • New .get_drafts() method with a custom Draft class by @JosXa.
  • Join all threads when calling .disconnect(), to assert no dangling thread is left alive.
  • Larger chunk when downloading files should result in faster downloads.
  • You can use a callable key for the EntityDatabase, so it can be any filter you need.

Internal changes:

  • MsgsAck is now sent in a container rather than its own request.
  • .get_input_photo is now used in the generated code.
  • .process_entities was being called from more places than only __call__.
  • MtProtoSender now relies more on the generated code to read responses.

Custom Entity Database

05 Oct 12:05
Choose a tag to compare

The main feature of this release is that Telethon now has a custom database for all the entities you encounter, instead depending on @lru_cache on the .get_entity() method.

The EntityDatabase will, by default, cache all the users, chats and channels you find in memory for as long as the program is running. The session will, by default, save all key-value pairs of the entity identifiers and their hashes (since Telegram may send an ID that it thinks you already know about, we need to save this information).

You can prevent the EntityDatabase from saving users by setting client.session.entities.enabled = False, and prevent the Session from saving input entities at all by setting client.session.save_entities = False. You can also clear the cache for a certain user through client.session.entities.clear_cache(entity=None), which will clear all if no entity is given.

More things:

  • .sign_in accepts phones as integers.
  • .get_dialogs() doesn't fail on Windows anymore, and returns the right amount of dialogs.
  • New method to .delete_messages().
  • New ChannelPrivateError class
  • Changing the IP to which you connect to is as simple as client.session.server_address = 'ip', since now the server address is always queried from the session.
  • GeneralProxyError should be passed to the main thread again, so that you can handle it.

Updates Overhaul Update

01 Oct 15:41
Choose a tag to compare

After hundreds of lines changed on a major refactor, it's finally here. It's the Updates Overhaul Update; let's get right into it!

New stuff and enhancements

  • You can invoke requests from update handlers. And any other thread. A new temporary will be made, so that you can be sending even several requests at the same time!
  • Several worker threads for your updates! By default, None will spawn. I recommend you to work with update_workers=4 to get started, these will be polling constantly for updates.
  • You can also change the number of workers at any given time.
  • The library can now run in a single thread again, if you don't need to spawn any at all. Simply set spawn_read_thread=False when creating the TelegramClient!
  • You can specify limit=None on .get_dialogs() to get all of them[1].
  • Updates are expanded, so you don't need to check if the update has .updates or an inner .update anymore.
  • All InputPeer entities are saved in the session file, but you can disable this by setting save_entities=False.
  • New .get_input_entity method, which makes use of the above feature. You should use this when a request needs a InputPeer, rather than the whole entity (although both work).

Less important enhancements

  • Assert that either all or None dependent-flag parameters are set before sending the request.
  • Phone numbers can have dashes, spaces, or parenthesis. They'll be removed before making the request.
  • You can override the phone and its hash on .sign_in(), if you're creating a new TelegramClient on two different places.

Compatibility breaks

  • .create_new_connection() is gone for good. No need to deal with this manually since new connections are now handled on demand by the library itself.

Bugs fixed

  • .log_out() was consuming all retries. It should work just fine now.
  • The session would fail to load if the auth_key had been removed manually.
  • Updates.check_error was popping wrong side, although it's been completely removed.
  • ServerError's will be ignored, and the request will immediately be retried.
  • Cross-thread safety when saving the session file.
  • Some things changed on a matter of when to reconnect, so please report any bugs!

Internal changes

  • TelegramClient is now only an abstraction over the TelegramBareClient, which can only do basic things, such as invoking requests, working with files, etc. If you don't need any of the abstractions the TelegramClient, you can now use the TelegramBareClient in a much more comfortable way.
  • MtProtoSender is not thread-safe, but it doesn't need to be since a new connection will be spawned when needed.
  • New connections used to be cached and then reused. Now only their sessions are saved, as temporary connections are spawned only when needed.
  • Added more RPC errors to the list.

[1]: Broken due to a condition which should had been the opposite (sigh), fixed 4 commits ahead on 62ea77c.

That's pretty much it, although there's more work to be done to make the overall experience of working with updates even better. Stay tuned!

Serialization bug fixes

29 Sep 11:18
Choose a tag to compare

Two bug fixes, one of them quite important, related to the serialization. Every object or request that had to serialize a True/False type was always being serialized as false!

Another bug that didn't allow you to leave as None flag parameters that needed a list has been fixed.

Other internal changes include a somewhat more readable .to_bytes() function and pre-computing the flag instead using bit shifting. The TLObject.constructor_id has been renamed to TLObject.CONSTRUCTOR_ID, and .subclass_of_id is also uppercase now.

Farewell, BinaryWriter

28 Sep 10:06
Choose a tag to compare

Version v0.14 had started working on the new .to_bytes() method to dump the BinaryWriter and its usage on the .on_send() when serializing TLObjects, and this release finally removes it. The speed up when serializing things to bytes should now be over twice as fast wherever it's needed.

Other internal changes include using proper classes (including the generated code) for generating authorization keys and to write out TLMessage's.

For bug fixes, this version is again compatible with Python 3.x versions below 3.5 (there was a method call that was Python 3.5 and above).