Releases: usernein/pyromod
v3.1.0: register_next_step_handler and more...
Breaking changes
Client.stop_listening
is now an async function, so you must await it if you're calling it on your code. If you don't use stop_listening, there is no breaking changes for you.
Highlights of this release
register_next_step_handler
is finally here!
A lot of people that asks for conversation handling on Pyrogram (and don't know pyromod yet) actually wants something like pyTelegramBotApi does withregister_next_step_handler
. Well, finally you can use it in Pyrogram, with pyromod! And it's not based on Futures likelisten
andask
are, so those who don't like pyromod might like this new feature.
The difference from pyTelegramBotApi's approach is that with pyromod, your callback will actually receive the Client object and the received Message (or CallbackQuery). In pyTelegramBotApi, the callback receives only the Message. Also, you don't need to call any other function than register_next_step_handler
. You just call it passing your callback and that's all! Check the example below:
- Now pyromod accepts lists of values for
chat_id
,user_id
,message_id
andinline_message_id
.
- Now pyromod accepts usernames for
chat_id
anduser_id
, so the example above could also be:
Other changes
- Thanks to @jusidama18 with #34, now pyromod will also work if you use sync filters.
Full Changelog: v3.0.0...v3.1.0
v3.0.0: pyromod easier than ever
What's Changed
-
The classes Client, Message, Chat and User now inherit from their respective classes in Pyrogram. This mean you can use them as if they were the original classes from Pyrogram. This is super useful for the IDEs to provide code completion and type checking of the pyromod features.
-
Since we can now use pyromod's Client just like the original Client, there is a new way of initilizing pyromod. Before, you needed to import pyromod anywhere in your code before importing pyrogram. Now you can simply import Client from pyromod instead of pyrogram and you are good to go.
-
The tuple identifiers that divided opinions have been removed. Now you can specify the data directly to the listen and ask methods as keyword arguments. Thanks for the suggestion, @Eikosa! (#12)
-
Added support for inline_message_id in the listen and ask methods.
-
pyromod will now check if the CallbackQuery.chat exists before trying to get its id, since chat will be null on inline messages.
-
The order of the arguments of Client.ask has been changed. Now the first argument is the chat_id and the second is the text to send, following the same order as Client.send_message.
-
The internal login of listeners got a lot more simple and robust. It has been hugely refactored and now it's a lot easier to understand and maintain.
-
The internal logic of the listeners state has been refactored. Now it uses Listener objects instead of a bunch of positional variables and dicts.
-
The whole code got type hints. This means that the IDEs can now provide code completion and type checking of the pyromod features.
-
The decorators patch and patchable have been renamed to patch_into and should_patch respectively, making them more descriptive.
-
@Jusidama-Bot made a huge contribution to the project, making the monkeypatching utils so much more powerful. Awesome!
-
The classes Client, Chat, User, Message, MessageHandler and CallbackQueryHAndler, that were previously in the listen.py file were split into their own files into the listen subpackage.
-
The classes ListenerStopped and ListenerTimeout, that were previously in the listen.py file were moved to the exceptions subpackage.
-
The class PyrogramConfig, that was previously in the utils.py file was moved to the config subpackage. It's now called config and it's a SimpleNamespace object instead of a class.
-
The enum ListenerTypes, that was previously in the listen.py file was moved to the brand new types subpackage.
-
Now the ask method will only send a message if the specified text is not empty. Thanks for that, @Eikosa!
-
The attribute request of the Message object returned by the ask method has been renamed to sent_message, much more descriptive. Thanks again, @Eikosa!
-
@tofikdn has added support for Message.message_id, when available, like in Pyrogram v1. Thanks for that!
-
The project structure has been completely refactored. Now it's more organized and a lot easier to maintain.
pyromod/
├── __init__.py
├── helpers
│ ├── helpers.py
│ └── __init__.py
├── listen
│ ├── __init__.py
│ └── listen.py (used to contain Client, Message, Chat, User, MessageHandler, CallbackQueryHandler, ListenerStopped, ListenerTimeout and ListenerTypes)
├── nav
│ ├── __init__.py
│ └── pagination.py
└── utils
├── __init__.py
└── utils.py (used to contain PyromodConfig and the functions patch and patchable)
Now it has the following structure:
pyromod/
├── __init__.py
├── config
│ └── __init__.py (contains the config object, formerly PyrogramConfig)
├── exceptions
│ ├── __init__.py
│ ├── listener_stopped.py
│ └── listener_timeout.py
├── helpers
│ ├── __init__.py
│ └── helpers.py
├── listen
│ ├── __init__.py
│ ├── callback_query_handler.py
│ ├── chat.py
│ ├── client.py
│ ├── message_handler.py
│ ├── message.py
│ └── user.py
├── nav
│ ├── __init__.py
│ └── pagination.py
├── types
│ ├── __init__.py
│ ├── identifier.py
│ ├── listener.py
│ └── listener_types.py
└── utils
├── __init__.py
└── patch.py (now contains the functions patch_into and should_patch)
- Now pyromod has documentation! You can access it at https://pyromod.pauxis.dev
New Contributors
- @tofikdn made their first contribution in #11
- @Eikosa made their first contribution in #13
- @Jusidama-Bot made their first contribution in #17
Full Changelog: v2.1.0...v3.0.0
v2.1.0
What's Changed
- fix listen does not check if message.from_user.id exists or not. Caus… by @WhaleFell in #30
New Contributors
- @WhaleFell made their first contribution in #30
Full Changelog: v2.0.0...v2.1.0
v2.0.0: the era of buttons
- It became easier to create simple inline keyboards. You can now pass a string as button, which will be used as text and callback_data:
keyboard = ikb([
["Earth", "Mars", "Venus"],
["Saturn", "Jupyter"]
])
-
Added support for listening for buttons. You can use await
Message.wait_for_click()
to await for any click on any button on that message. By passing anuser_id
into the parameterfrom_user_id
, you can restrict from which users should the bot accept the click. Any other user will see an alert (i.e. query.answer()) informing they are not supposed to click the button. You can pass a custom text to the paramalert
or can pass False to disable it, so no text will be shown at all.
-
To support both messages and callback queries, a parameter named
listener_type
has been added. Its value must be one of the enumpyromod.ListenerTypes
-
The method cancel_listener has been renamed to
stop_listening
-
Pyromod now uses "identifiers" in all its methods instead of the good old chat_id. Identifiers are basically tuples with ordered data about the messages that the listeners should listen for. It must follow this order:
(chat_id, user_id, message_id)
. If you pass None as value, it will act as a wildcard, matching any value. Examples:-
(1029384756, 276145711, None)
means "any message sent by 276145711 in the chat 1029384756" -
(1029384756, None, None)
means "any message sent in the chat 1029384756, from any user" -
(None, 276145711, None)
means "any message from 276145711 on any chat" -
message_id is only used when waiting for button clicks:
(1029384756, 276145711, 1123)
means "a click done by 276145711 on a button on the message 1123 on the chat 1029384756"(1029384756, None, 1123)
means "a click on a button on the message 1123 on the chat 1029384756, done by any user"
The listeners are used as patterns for matching against the received update data. A listener with the identifier/pattern(1029384756, 276145711, None)
will match if the message data is(1029384756, 276145711, 728)
, but won't do if the message data is(1029384756, 200097591, 729)
, because the identifier specified which user_id it wants and it′s not matching.
If you use mostly the bound methods, you don′t need to worry about it, since they will automatically compose the identifier for you.
-
m.chat.listen will compose
(m.chat.id, None, None)
-
m.from_user.listen will compose
(None, m.from_user.id, None)
-
m.from_user.ask will compose
(m.from_user.id, m.from_user.id, None)
-
m.wait_for_click(from_user_id=276145711) will compose
(m.chat.id, 276145711, m.id)
Be aware that User.listen does not create a listener for messages sent by the user on the chat of the message. If using
User.ask
, it asks on the private chat with the user and creates a listener for messages sent by the user on the private conversation. This may change in the future to whatever makes more sense. If usingUser.listen
, it will listen for any message from that user, anywhere.
-
-
Pyromod now raises
pyromod.ListenerTimeout(timeout)
instead of asyncio.TimeoutError -
New exception
pyromod.ListenerStopped
. It raises when any listener is stopped byClient.stop_listening
-
New class
pyromod.PyromodConfig
. It′s a class with some static properties that hold some tweaks and error handlers.timeout_handler
: a callback that gets executed instead of raising asyncio.TimeoutError (nowpyromod.ListenerTimeout
). It receives(identifier, listener_data, timeout)
as arguments.stopped_handler
: a callback that gets executed when a listener is stopped bystop_listening()
throw_exceptions
: Boolean, defaults to True. If False, pyromod won't raise none ofpyromod.ListenerTimeout
andpyromod.ListenerStopped
. The functions should just return None instead.unallowed_user_alert
: Boolean, defaults to True. If False, no text will be responded to unwanted user clicks.unallowed_user_alert_text
: the default text for unallowed user alerts.
-
Before this release, pyromod would block other commands to work if there is a listener on the chat, but the filters doesn't match (i.e. a listener with filters.photo, but the message is just text). Now, if there′s a listener but the filters doesn't match, the message will keep propagating to other handlers. The same happens when you use a restrictive identifier, specifying the user_id. In this case, all other users will still be able to use the bot, while the bot keeps awaiting for a message from the wanted user. As it should be.
-
The parameters for
stop_listening
(formerly cancel_listener) has changed, due to the addition of identifiers. Before this release, you could pass the chat_id of the listener to stop and delete it. Now, with identifiers, you can either pass a message data as(chat_id, user_id, message_id)
to stop the first matching listener or pass aidentifier_pattern
to stop the first matching listeners.To explain the difference between these two, let′s suppose you want to stop a listener that has
(1029384756, 276145711, 19876)
as identifier, but you only know the chat_id, so you can't pass the message data to match.
In this case, you can passidentifier_pattern=(1029384756, None, None)
.
This also may change in the near future, I honestly don't know why there is two ways, where identifier_pattern could handle both situations. I was sleepy.
Full Changelog: v1.5...v2.0.0
v.1.5: Basically stable
Merge pull request #2 from jonatan1609/patch-1 Fix an issue with removing old listeners