Elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots
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 None
as argument to the parse_mode parameter.
Added archive_chats() and unarchive_chats() methods to archive and unarchive your chats.
Added archive()
and unarchive()
bound methods to User and Chat types as convenience shortcuts for archive_chats()
and unarchive_chats()
.
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: edit_message_text()
, edit_message_caption()
, edit_message_media()
and edit_message_reply_markup()
.
Added friendly methods to block and unblock users: block_user() and unblock_user() (contributed by @ColinTheShark in #256).
Added new Chat bound-methods: set_title()
, set_description()
, set_photo()
, kick_member()
, unban_member()
, restrict_member()
and 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: FOLDER_DEAC_AUTOFIX_ALL
, FOLDER_ID_INVALID
, MEGAGROUP_PREHISTORY_HIDDEN
, CHAT_LINK_EXISTS
, LINK_NOT_MODIFIED
, BROADCAST_ID_INVALID
and MEGAGROUP_ID_INVALID
, START_PARAM_INVALID
, MSGID_DECREASE_RETRY
.
Removed Messages
, ChatMembers
, Dialogs
, ProfilePhotos
and GameHighScores
types. 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[0])
you can omit .messages
because the returned type is a simple list:
history = app.get_history("pyrogramchat")
print(history[0])
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 400
will be raised as BadRequest
. Totally unknown errors (with both unknown message and error code) will still be raised as UnknownError
.
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 me
or self
as argument.
Fixed plugins not getting reloaded properly when restarting a client.
Fixed download_media() ignoring the file_name
argument 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.
ChatMembers
, Dialogs
, ProfilePhotos
, Messages
and GameHighScores
types are now gone and replaced with simple lists of objects (as explained in the section above).
The name
argument 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: ...)
.
.tgs
format. Note: this is still an experimental feature, not even all official clients properly support animated stickers and Telegram has not announced anything yet about this new feature.unsave
parameter to send_animation(). Pass True in order to remove the GIF animation from your own collection (the server automatically adds them).[1, 2, 3, 4, 5]
when coming from the Telegram raw API are now printed nicely.PhotoSize
type has been replaced by Thumbnail, a much more interesting and useful name.message.photo.sizes[-1].file_id
, you can now simply use message.photo.file_id
to get the highest quality available, all the other sizes are kept as a list of thumbnails in the thumbs
attribute.thumbs
attribute to store all the available thumbnails (there can be more than one, sorted by ascending size).*
. E.g. 391234567890
→ ************
. Date attributes are shown as human-readable dates instead of a unix timestamps. E.g. 1559742628
→ 2019-06-05 15:50:28
. Note this is just a visual modification, when accessing the inner attributes, you will still get the same values (full number, unix timestamp).is_verified
is_restricted
is_scam
is_support
(user only).UserProfilePhotos
to just ProfilePhotos for brevity, but also because such object can now store profile photos from both users and chats.delete_user_profile_photos()
→ delete_profile_photos()
get_user_profile_photos()
→ get_profile_photos()
set_user_profile_photo()
→ set_profile_photo()
get_user_profile_photos_count()
→ get_profile_photos_count()
This version features a massive overhaul of the documentation structure and a shiny new domain name: https://pyrogram.org. After well over a week spent working solely on the documentation website, here's what's new:
That's all about the documentation, for now. I hope you enjoy it! Let's now go ahead with listing the new features this version brings in the library itself:
bot
chat type. We now have "private", "bot", "group", "supergroup" and "channel" Chat
types.is_member
attribute to the ChatMember type to check wether a restricted user is still a member of a chat.callback_data
(with inline buttons and callback query respectively) has gained back support for strings. If you pass strings for which you are 100% sure they will be valid UTF-8 texts, you can rely on the library reporting back string types, otherwise you'll get a bytes type. This is due to how Telegram handles callback queries data (only bytes allowed) and it's a matter of convenience to allow strings as well.supports_streaming
attribute to the Video type.timeout
parameter to Message.click()
False
in case they fail to delete (they used to always return True due to how Telegram handles this method; the server doesn't raise any error).replies
parameter. Up to unlimited replies.close_poll()
was renamed to stop_poll().forward_from_name
of Message was renamed to forward_sender_name
.ParseMode
module was removed. It was pretty much useless, better just use "markdown" and "html" string literals.ChatAction
module was removed too, same reason of ParseMode
.get_chat_preview()
method, get_chat() will take care of both Chat and ChatPreview objects.bot_token
Client parameter to start a bot session (contributed by @bakatrouble in #221).__slots__
in every single type to help reduce the memory footprint.send_*
methods dealing with media messages (audio, document, animation, etc...) will now always send the correct Telegram media kind, regardless of the uploaded file.str
.print(message)
) will now display UTF-8 characters instead of ASCII representations of their code points.as_copy
parameter in forward_messages() method and Message.forward() bound method (contributed by @bakatrouble in #227 ).forward_from_name
attribute of a Message will contain the user first name only (as string) of the author as opposed to a full User object.errors
package has been moved; it is now importable with from pyrogram import errors
, and the Error
exception has been renamed to RPCError.no_updates
Client parameter. Pass True
in order to completely disable incoming updates from Telegram. Useful in batch programs, for example, when you want to broadcast a message to many users and have no need to handle incoming messages or other updates whatsoever.takeout
Client parameter. Pass True
in order to use a special takeout session instead of a normal one. Useful for exporting your Telegram data; methods invoked inside a takeout session (such as get_history, download_media, ...) are less prone to throw FloodWait exceptions.str
. This makes possible to send objects that implement a string representation without having to manually cast, for example:
app.send_message(chat_id, 123456)
sends "123456" (int) text message as string.message.reply(message)
replies with the message (Message) itself.Filters.user("me")
.game
and game_high_score
attributes inside Message as well as Filters.game, Filters.game_score filters and send_game, set_game_score, get_game_high_scores methods.phone_number
, password
, first_name
and last_name
can now be callback functions.date
, inviter_by
, promoted_by
and restricted_by
.develop
installation for pip. Thanks @bakatrouble for the hint!reversed
parameter has been renamed to reverse
because it was colliding with the built-in "reversed" function.Notice: Python 3.5.2 is bugged and breaks with Pyrogram. More info at https://t.me/PyrogramChat/49171
This last update of the year turns out to be the biggest ever made, featuring quite important internal changes – which worth mentioning – as well as lots of new additions. More updates will come in the future, such as the work-in-progress inline mode. Keep Pyrogramming!
hide_via
argument for send_inline_bot_result used to hide via @bot captions (currently doesn't work as official clients or the server itself seem to ignore this).reversed
parameters set to True (contributed by @YoilyL in #94).future
branch is now gone, all changes have been merged into the default develop
branch, meaning this update contains all of them!bytes
instead of str
, because of Telegram API actually allowing clients to send arbitrary bytes; forcing the decoding to turn bytes data into strings could lead to errors.offset_date
as integer instead of a Dialog chunk as offset....
@app1.on_message(...)
@app2.on_message(...)
@app3.on_message(...)
def on_message(client, message):
...
MESSAGE_IDS_EMPTY
error raised in case of a message replying to another was pinned and the replied message was deleted at the same time.AttributeError: 'ChannelForbidden' object has no attribute 'restriction_reason'
.MESSAGE_IDS_EMPTY
error.UnicodeDecodeError
raised by invalid UTF-8 data inside inline buttons callback data.ChatMember.total_count
not being available when fetching members from supergroups and channels.InlineKeyboardButton.callback_data
type is now bytes
instead of str
in order to fix the bug above.Pyrogram Proxy Telegram
[IPv4] <---> [IPv4] -X- [IPv4]
[IPv6] -X- [IPv6] <---> [IPv6]
delete_profile_photos
has been renamed to delete_user_profile_photos.fast
:
pip3 install -U pyrogram[fast]
.