Layer 102, Storage Engines, New Text Parser and much more#
New Features and Enhancements#
API schema updated to Layer 102.
TgCrypto updated to v1.2.0.
Goodbye JSON-based session files, you served very well, but is now time for Storage Engines. This version brings two built-in implementations based on SQLite: File Storage and Memory Storage. Extra storage engines for different storage options (such as Redis, MySQL, MongoDB, …) can be easily implemented as well. (proposal by @bakatrouble, which provided an implementation in #220 that got refactored).
Added export_session_string() method to export a session string. Session strings are useful when you want to run authorized Pyrogram clients completely in-memory on platforms like Heroku, where their ephemeral filesystems makes it much harder for a file-based storage engine to properly work as intended.
Text Formatting re-done from scratch. You can now style message texts and captions using extra styles like underline and strikethrough styles, in both Markdown and HTML. You can nest and combine multiple styles together on the same text too, such as in this example (bold, italic and strikethrough text) and also disable the parser completely by passing
Noneas argument to the parse_mode parameter.
Added archive_chats() and unarchive_chats() methods to archive and unarchive your chats.
unarchive()bound methods to User and Chat types as convenience shortcuts for
Added new methods to edit messages sent by inline bots: edit_inline_text(), edit_inline_caption(), edit_inline_media() and edit_inline_reply_markup(). The reason behind having 4+4 methods for editing normal messages and messages sent by inline bots is because of Telegram requiring a special inline_message_id that is mutually exclusive with the usual pair of chat_id+message_id.
Added new CallbackQuery bound-methods for editing messages:
Added friendly methods to block and unblock users: block_user() and unblock_user() (contributed by @ColinTheShark in #256).
Added new Chat bound-methods:
promote_member()(contributed by @mendelmaleh in #260).
Added some new FAQs about: DC migration, DC IP addresses, library stability and reliability.
Added a bunch of new errors:
GameHighScorestypes. These types were just annoying wrappers around bare lists and removing them means that now you get a simple list of objects:
Messages→ List of Message objects.
ChatMembers→ List of ChatMember objects.
Dialogs→ List of Dialog objects.
ProfilePhotos→ List of Photo objects.
GameHighScores→ List of GameHighScore objects.
Dealing with methods which returned such types has also become easier. Instead of doing the following:
history = app.get_history("pyrogramchat") print(history.messages)
you can omit
.messagesbecause the returned type is a simple list:
history = app.get_history("pyrogramchat") print(history)
To get the total count of items each old type contained, you have to use the respective methods: get_history_count(), get_chat_members_count(), get_dialogs_count(), get_profile_photos_count().
Unknown errors with known error codes are now raised by their category error instead of
520 UnknownError. For example, an unknown error that has the known error code
400will be raised as
BadRequest. Totally unknown errors (with both unknown message and error code) will still be raised as
Error messages now contain information about which raw method caused the RPC error. For example: [400 MESSAGE_EMPTY]: The message sent is empty (caused by “messages.SendMessage”).
Fixed get_profile_photos() method not working when passing
Fixed plugins not getting reloaded properly when restarting a client.
Fixed download_media() ignoring the
file_nameargument which also lead to files being saved with random names generated by the framework.
Fixed script executions not working outside the current directory (addressed #41).
Fixed texts being sliced incorrectly when trying to use the offsets and lengths from message entities.
Fixed delete_profile_photos() not working since that last update (addressed #259).
Fixed objects failing to print in case there’s no __slots__ attribute.
GameHighScorestypes are now gone and replaced with simple lists of objects (as explained in the section above).
nameargument of Filters.create() is now optional and moved behind. The simplest custom filter you can create will now look like this:
flt = Filters.create(lambda _, m: ...).