From e7e544ef37820b757f77b49807ee63ee100cbad7 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 4 Jul 2025 04:36:01 +0400 Subject: [PATCH 1/8] Add get_my_star_balance --- docs/source/inclusions/bot_methods.rst | 2 ++ src/telegram/_bot.py | 32 ++++++++++++++++++++++++++ src/telegram/ext/_extbot.py | 19 +++++++++++++++ tests/test_bot.py | 17 ++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/docs/source/inclusions/bot_methods.rst b/docs/source/inclusions/bot_methods.rst index d1ff3c3ac13..1915ffca661 100644 --- a/docs/source/inclusions/bot_methods.rst +++ b/docs/source/inclusions/bot_methods.rst @@ -390,6 +390,8 @@ - Used to generate an HTTP link for an invoice * - :meth:`~telegram.Bot.edit_user_star_subscription` - Used for editing a user's star subscription + * - :meth:`~telegram.Bot.get_my_star_balance` + - Used for obtaining the bot's Telegram Stars balance * - :meth:`~telegram.Bot.get_star_transactions` - Used for obtaining the bot's Telegram Stars transactions * - :meth:`~telegram.Bot.refund_star_payment` diff --git a/src/telegram/_bot.py b/src/telegram/_bot.py index 56072fbe0d6..f79b34997e4 100644 --- a/src/telegram/_bot.py +++ b/src/telegram/_bot.py @@ -11072,6 +11072,36 @@ async def remove_user_verification( api_kwargs=api_kwargs, ) + async def get_my_star_balance( + self, + *, + read_timeout: ODVInput[float] = DEFAULT_NONE, + write_timeout: ODVInput[float] = DEFAULT_NONE, + connect_timeout: ODVInput[float] = DEFAULT_NONE, + pool_timeout: ODVInput[float] = DEFAULT_NONE, + api_kwargs: Optional[JSONDict] = None, + ) -> StarAmount: + """A method to get the current Telegram Stars balance of the bot. Requires no parameters. + + .. versionadded:: NEXT.VERSION + + Returns: + :class:`telegram.StarAmount` + + Raises: + :class:`telegram.error.TelegramError` + """ + return StarAmount.de_json( + await self._post( + "getMyStarBalance", + read_timeout=read_timeout, + write_timeout=write_timeout, + connect_timeout=connect_timeout, + pool_timeout=pool_timeout, + api_kwargs=api_kwargs, + ) + ) + def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002 """See :meth:`telegram.TelegramObject.to_dict`.""" data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name} @@ -11386,3 +11416,5 @@ def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002 """Alias for :meth:`remove_chat_verification`""" removeUserVerification = remove_user_verification """Alias for :meth:`remove_user_verification`""" + getMyStarBalance = get_my_star_balance + """Alias for :meth:`get_my_star_balance`""" diff --git a/src/telegram/ext/_extbot.py b/src/telegram/ext/_extbot.py index 5781cf817bc..7c6f5ef8cb8 100644 --- a/src/telegram/ext/_extbot.py +++ b/src/telegram/ext/_extbot.py @@ -5057,6 +5057,24 @@ async def remove_user_verification( api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args), ) + async def get_my_star_balance( + self, + *, + read_timeout: ODVInput[float] = DEFAULT_NONE, + write_timeout: ODVInput[float] = DEFAULT_NONE, + connect_timeout: ODVInput[float] = DEFAULT_NONE, + pool_timeout: ODVInput[float] = DEFAULT_NONE, + api_kwargs: Optional[JSONDict] = None, + rate_limit_args: Optional[RLARGS] = None, + ) -> StarAmount: + return await super().get_my_star_balance( + read_timeout=read_timeout, + write_timeout=write_timeout, + connect_timeout=connect_timeout, + pool_timeout=pool_timeout, + api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args), + ) + # updated camelCase aliases getMe = get_me sendMessage = send_message @@ -5210,3 +5228,4 @@ async def remove_user_verification( verifyUser = verify_user removeChatVerification = remove_chat_verification removeUserVerification = remove_user_verification + getMyStarBalance = get_my_star_balance diff --git a/tests/test_bot.py b/tests/test_bot.py index 4e78cd0a449..0e6e1355e3a 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -79,6 +79,7 @@ User, WebAppInfo, ) +from telegram._payment.stars.staramount import StarAmount from telegram._utils.datetime import UTC, from_timestamp, localize, to_timestamp from telegram._utils.defaultvalue import DEFAULT_NONE from telegram._utils.strings import to_camel_case @@ -2574,6 +2575,17 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): await offline_bot.remove_chat_verification(1234) + async def test_get_my_star_balance(self, offline_bot, monkeypatch): + sa = StarAmount(1000).to_json() + + async def do_request(url, request_data: RequestData, *args, **kwargs): + assert not request_data.parameters + return 200, f'{{"ok": true, "result": {sa}}}'.encode() + + monkeypatch.setattr(offline_bot.request, "do_request", do_request) + obj = await offline_bot.get_my_star_balance() + assert isinstance(obj, StarAmount) + class TestBotWithRequest: """ @@ -4540,3 +4552,8 @@ async def test_create_edit_chat_subscription_link( assert edited_link.name == "sub_name_2" assert sub_link.subscription_period == 2592000 assert sub_link.subscription_price == 13 + + async def test_get_my_star_balance(self, bot): + balance = await bot.get_my_star_balance() + assert isinstance(balance, StarAmount) + assert balance.amount == 0 From c4457eab45a2bc4d57455b4ae5d6a88174c29d10 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 4 Jul 2025 05:14:21 +0400 Subject: [PATCH 2/8] DirectMessagePriceChanged + filters --- docs/source/telegram.at-tree.rst | 1 + .../telegram.directmessagepricechanged.rst | 6 ++ src/telegram/__init__.py | 2 + src/telegram/_directmessagepricechanged.py | 72 +++++++++++++++++ src/telegram/_message.py | 19 +++++ src/telegram/ext/filters.py | 15 ++++ tests/ext/test_filters.py | 7 +- tests/test_directmessagepricechanged.py | 81 +++++++++++++++++++ tests/test_message.py | 3 + 9 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 docs/source/telegram.directmessagepricechanged.rst create mode 100644 src/telegram/_directmessagepricechanged.py create mode 100644 tests/test_directmessagepricechanged.py diff --git a/docs/source/telegram.at-tree.rst b/docs/source/telegram.at-tree.rst index 133b3fd79d4..e248edb31e8 100644 --- a/docs/source/telegram.at-tree.rst +++ b/docs/source/telegram.at-tree.rst @@ -67,6 +67,7 @@ Available Types telegram.chatshared telegram.contact telegram.dice + telegram.directmessagepricechanged telegram.document telegram.externalreplyinfo telegram.file diff --git a/docs/source/telegram.directmessagepricechanged.rst b/docs/source/telegram.directmessagepricechanged.rst new file mode 100644 index 00000000000..64356e1a689 --- /dev/null +++ b/docs/source/telegram.directmessagepricechanged.rst @@ -0,0 +1,6 @@ +DirectMessagePriceChanged +========================= + +.. autoclass:: telegram.DirectMessagePriceChanged + :members: + :show-inheritance: \ No newline at end of file diff --git a/src/telegram/__init__.py b/src/telegram/__init__.py index f25e90b9b7e..b8632ac53b9 100644 --- a/src/telegram/__init__.py +++ b/src/telegram/__init__.py @@ -89,6 +89,7 @@ "Credentials", "DataCredentials", "Dice", + "DirectMessagePriceChanged", "Document", "EncryptedCredentials", "EncryptedPassportElement", @@ -386,6 +387,7 @@ from ._choseninlineresult import ChosenInlineResult from ._copytextbutton import CopyTextButton from ._dice import Dice +from ._directmessagepricechanged import DirectMessagePriceChanged from ._files._inputstorycontent import ( InputStoryContent, InputStoryContentPhoto, diff --git a/src/telegram/_directmessagepricechanged.py b/src/telegram/_directmessagepricechanged.py new file mode 100644 index 00000000000..4053cd64c89 --- /dev/null +++ b/src/telegram/_directmessagepricechanged.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2025 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +"""This module contains an object that represents a Direct Message Price.""" + + +from typing import Optional + +from telegram._telegramobject import TelegramObject +from telegram._utils.types import JSONDict + + +class DirectMessagePriceChanged(TelegramObject): + """ + Describes a service message about a change in the price of direct messages sent to a channel + chat. + + .. versionadded:: NEXT.VERSION + + Objects of this class are comparable in terms of equality. Two objects of this class are + considered equal, if their :attr:`are_direct_messages_enabled` are equal. + + Args: + are_direct_messages_enabled (:obj:`bool`): + :obj:`True`, if direct messages are enabled for the channel chat; :obj:`False` + otherwise. + direct_message_star_count (:obj:`int`, optional): + The new number of Telegram Stars that must be paid by users for each direct message + sent to the channel. Does not apply to users who have been exempted by administrators. + Defaults to ``0``. + + Attributes: + are_direct_messages_enabled (:obj:`bool`): + :obj:`True`, if direct messages are enabled for the channel chat; :obj:`False` + otherwise. + direct_message_star_count (:obj:`int`): + Optional. The new number of Telegram Stars that must be paid by users for each direct + message sent to the channel. Does not apply to users who have been exempted by + administrators. Defaults to ``0``. + """ + + __slots__ = ("are_direct_messages_enabled", "direct_message_star_count") + + def __init__( + self, + are_direct_messages_enabled: bool, + direct_message_star_count: Optional[int] = None, + *, + api_kwargs: Optional[JSONDict] = None, + ): + super().__init__(api_kwargs=api_kwargs) + self.are_direct_messages_enabled: bool = are_direct_messages_enabled + self.direct_message_star_count: Optional[int] = direct_message_star_count + + self._id_attrs = (self.are_direct_messages_enabled,) + + self._freeze() diff --git a/src/telegram/_message.py b/src/telegram/_message.py index 274089bff50..46d755bb71f 100644 --- a/src/telegram/_message.py +++ b/src/telegram/_message.py @@ -29,6 +29,7 @@ from telegram._chatbackground import ChatBackground from telegram._chatboost import ChatBoostAdded from telegram._dice import Dice +from telegram._directmessagepricechanged import DirectMessagePriceChanged from telegram._files.animation import Animation from telegram._files.audio import Audio from telegram._files.contact import Contact @@ -609,6 +610,11 @@ class Message(MaybeInaccessibleMessage): message about a refunded payment, information about the payment. .. versionadded:: 21.4 + direct_message_price_changed (:class:`telegram.DirectMessagePriceChanged`, optional): + Service message: the price for paid messages in the corresponding direct messages chat + of a channel has changed. + + .. versionadded:: NEXT.VERSION Attributes: message_id (:obj:`int`): Unique message identifier inside this chat. In specific instances @@ -954,6 +960,11 @@ class Message(MaybeInaccessibleMessage): message about a refunded payment, information about the payment. .. versionadded:: 21.4 + direct_message_price_changed (:class:`telegram.DirectMessagePriceChanged`): + Optional. Service message: the price for paid messages in the corresponding direct + messages chat of a channel has changed. + + .. versionadded:: NEXT.VERSION .. |custom_emoji_no_md1_support| replace:: Since custom emoji entities are not supported by :attr:`~telegram.constants.ParseMode.MARKDOWN`, this method now raises a @@ -987,6 +998,7 @@ class Message(MaybeInaccessibleMessage): "contact", "delete_chat_photo", "dice", + "direct_message_price_changed", "document", "edit_date", "effect_id", @@ -1152,6 +1164,7 @@ def __init__( unique_gift: Optional[UniqueGiftInfo] = None, paid_message_price_changed: Optional[PaidMessagePriceChanged] = None, paid_star_count: Optional[int] = None, + direct_message_price_changed: Optional[DirectMessagePriceChanged] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -1261,6 +1274,9 @@ def __init__( paid_message_price_changed ) self.paid_star_count: Optional[int] = paid_star_count + self.direct_message_price_changed: Optional[DirectMessagePriceChanged] = ( + direct_message_price_changed + ) self._effective_attachment = DEFAULT_NONE @@ -1437,6 +1453,9 @@ def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "Message": data["reply_to_story"] = de_json_optional(data.get("reply_to_story"), Story, bot) data["boost_added"] = de_json_optional(data.get("boost_added"), ChatBoostAdded, bot) data["sender_business_bot"] = de_json_optional(data.get("sender_business_bot"), User, bot) + data["direct_message_price_changed"] = de_json_optional( + data.get("direct_message_price_changed"), DirectMessagePriceChanged, bot + ) api_kwargs = {} # This is a deprecated field that TG still returns for backwards compatibility diff --git a/src/telegram/ext/filters.py b/src/telegram/ext/filters.py index 6322dafd296..914ba4fbb05 100644 --- a/src/telegram/ext/filters.py +++ b/src/telegram/ext/filters.py @@ -1947,6 +1947,7 @@ def filter(self, update: Update) -> bool: or StatusUpdate.VIDEO_CHAT_STARTED.check_update(update) or StatusUpdate.WEB_APP_DATA.check_update(update) or StatusUpdate.WRITE_ACCESS_ALLOWED.check_update(update) + or StatusUpdate.DIRECT_MESSAGE_PRICE_CHANGED.check_update(update) ) ALL = _All(name="filters.StatusUpdate.ALL") @@ -1997,6 +1998,20 @@ def filter(self, message: Message) -> bool: CONNECTED_WEBSITE = _ConnectedWebsite(name="filters.StatusUpdate.CONNECTED_WEBSITE") """Messages that contain :attr:`telegram.Message.connected_website`.""" + class _DirectMessagePriceChanged(MessageFilter): + __slots__ = () + + def filter(self, message: Message) -> bool: + return bool(message.direct_message_price_changed) + + DIRECT_MESSAGE_PRICE_CHANGED = _DirectMessagePriceChanged( + name="filters.StatusUpdate.DIRECT_MESSAGE_PRICE_CHANGED" + ) + """Messages that contain :attr:`telegram.Message.direct_message_price_changed`. + + .. versionadded:: NEXT.VERSION + """ + class _DeleteChatPhoto(MessageFilter): __slots__ = () diff --git a/tests/ext/test_filters.py b/tests/ext/test_filters.py index 6802db2a206..ca2d01dfc9e 100644 --- a/tests/ext/test_filters.py +++ b/tests/ext/test_filters.py @@ -1116,7 +1116,12 @@ def test_filters_status_update(self, update): assert filters.StatusUpdate.PAID_MESSAGE_PRICE_CHANGED.check_update(update) update.message.paid_message_price_changed = None - def test_filters_forwarded(self, update, message_origin_user): + update.message.direct_message_price_changed = "direct_message_price_changed" + assert filters.StatusUpdate.ALL.check_update(update) + assert filters.StatusUpdate.DIRECT_MESSAGE_PRICE_CHANGED.check_update(update) + update.message.direct_message_price_changed = None + + def test_filters_forwarded(self, update): assert filters.FORWARDED.check_update(update) update.message.forward_origin = MessageOriginHiddenUser(dtm.datetime.utcnow(), 1) assert filters.FORWARDED.check_update(update) diff --git a/tests/test_directmessagepricechanged.py b/tests/test_directmessagepricechanged.py new file mode 100644 index 00000000000..aaf5b9e89ea --- /dev/null +++ b/tests/test_directmessagepricechanged.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2025 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +"""This module contains an object for testing a Direct Message Price.""" + +from typing import TYPE_CHECKING + +import pytest + +from telegram import DirectMessagePriceChanged +from tests.auxil.slots import mro_slots + +if TYPE_CHECKING: + from telegram._utils.types import JSONDict + + +@pytest.fixture +def direct_message_price_changed(): + return DirectMessagePriceChanged( + are_direct_messages_enabled=True, direct_message_star_count=100 + ) + + +class DirectMessagePriceChangedTestBase: + are_direct_messages_enabled: bool = True + direct_message_star_count: int = 100 + + +class TestDirectMessagePriceChangedWithoutRequest(DirectMessagePriceChangedTestBase): + def test_slot_behaviour(self, direct_message_price_changed): + action = direct_message_price_changed + for attr in action.__slots__: + assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" + + def test_de_json(self, offline_bot): + json_dict: JSONDict = { + "are_direct_messages_enabled": self.are_direct_messages_enabled, + "direct_message_star_count": self.direct_message_star_count, + } + dmpc = DirectMessagePriceChanged.de_json(json_dict, offline_bot) + assert dmpc.api_kwargs == {} + + assert dmpc.are_direct_messages_enabled == self.are_direct_messages_enabled + assert dmpc.direct_message_star_count == self.direct_message_star_count + + def test_to_dict(self, direct_message_price_changed): + dmpc_dict = direct_message_price_changed.to_dict() + assert dmpc_dict["are_direct_messages_enabled"] == self.are_direct_messages_enabled + assert dmpc_dict["direct_message_star_count"] == self.direct_message_star_count + + def test_equality(self, direct_message_price_changed): + dmpc1 = direct_message_price_changed + dmpc2 = DirectMessagePriceChanged( + are_direct_messages_enabled=self.are_direct_messages_enabled, + direct_message_star_count=self.direct_message_star_count, + ) + assert dmpc1 == dmpc2 + assert hash(dmpc1) == hash(dmpc2) + + dmpc3 = DirectMessagePriceChanged( + are_direct_messages_enabled=False, + direct_message_star_count=self.direct_message_star_count, + ) + assert dmpc1 != dmpc3 + assert hash(dmpc1) != hash(dmpc3) diff --git a/tests/test_message.py b/tests/test_message.py index 1c5cd152859..4146fa032e0 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -76,6 +76,7 @@ Voice, WebAppData, ) +from telegram._directmessagepricechanged import DirectMessagePriceChanged from telegram._gifts import Gift, GiftInfo from telegram._uniquegift import ( UniqueGift, @@ -331,6 +332,7 @@ def message(bot): {"refunded_payment": RefundedPayment("EUR", 243, "payload", "charge_id", "provider_id")}, {"paid_star_count": 291}, {"paid_message_price_changed": PaidMessagePriceChanged(291)}, + {"direct_message_price_changed": DirectMessagePriceChanged(True, 100)}, ], ids=[ "reply", @@ -408,6 +410,7 @@ def message(bot): "refunded_payment", "paid_star_count", "paid_message_price_changed", + "direct_message_price_changed", ], ) def message_params(bot, request): From 12d5aea72093eeea63de33c895f3890c47f96147 Mon Sep 17 00:00:00 2001 From: harshil21 <37377066+harshil21@users.noreply.github.com> Date: Fri, 4 Jul 2025 01:25:34 +0000 Subject: [PATCH 3/8] Add chango fragment for PR #4851 --- changes/unreleased/4851.jGu7ZujzXWWGJATTXGxn4u.toml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changes/unreleased/4851.jGu7ZujzXWWGJATTXGxn4u.toml diff --git a/changes/unreleased/4851.jGu7ZujzXWWGJATTXGxn4u.toml b/changes/unreleased/4851.jGu7ZujzXWWGJATTXGxn4u.toml new file mode 100644 index 00000000000..f711cac4734 --- /dev/null +++ b/changes/unreleased/4851.jGu7ZujzXWWGJATTXGxn4u.toml @@ -0,0 +1,5 @@ +other = "API 9.1 General" +[[pull_requests]] +uid = "4851" +author_uid = "harshil21" +closes_threads = [] From d8a8c4d484af56ca036dc37c3ebc25db3a2d3596 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 4 Jul 2025 05:32:29 +0400 Subject: [PATCH 4/8] Copilot Review: change import, eq check --- src/telegram/_directmessagepricechanged.py | 5 +++-- tests/test_message.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/telegram/_directmessagepricechanged.py b/src/telegram/_directmessagepricechanged.py index 4053cd64c89..9d4ed925137 100644 --- a/src/telegram/_directmessagepricechanged.py +++ b/src/telegram/_directmessagepricechanged.py @@ -33,7 +33,8 @@ class DirectMessagePriceChanged(TelegramObject): .. versionadded:: NEXT.VERSION Objects of this class are comparable in terms of equality. Two objects of this class are - considered equal, if their :attr:`are_direct_messages_enabled` are equal. + considered equal, if their :attr:`are_direct_messages_enabled`, and + :attr:`direct_message_star_count` are equal. Args: are_direct_messages_enabled (:obj:`bool`): @@ -67,6 +68,6 @@ def __init__( self.are_direct_messages_enabled: bool = are_direct_messages_enabled self.direct_message_star_count: Optional[int] = direct_message_star_count - self._id_attrs = (self.are_direct_messages_enabled,) + self._id_attrs = (self.are_direct_messages_enabled, self.direct_message_star_count) self._freeze() diff --git a/tests/test_message.py b/tests/test_message.py index 4146fa032e0..805b877169a 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -33,6 +33,7 @@ ChatShared, Contact, Dice, + DirectMessagePriceChanged, Document, ExternalReplyInfo, Game, @@ -76,7 +77,6 @@ Voice, WebAppData, ) -from telegram._directmessagepricechanged import DirectMessagePriceChanged from telegram._gifts import Gift, GiftInfo from telegram._uniquegift import ( UniqueGift, From 47c38a73d2dc126088cc5df9498cf7613d4cb19b Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 4 Jul 2025 05:54:22 +0400 Subject: [PATCH 5/8] Fix test: --- src/telegram/constants.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/telegram/constants.py b/src/telegram/constants.py index 81d21e67c9a..d0a78865079 100644 --- a/src/telegram/constants.py +++ b/src/telegram/constants.py @@ -2064,6 +2064,11 @@ class MessageType(StringEnum): """:obj:`str`: Messages with :attr:`telegram.Message.delete_chat_photo`.""" DICE = "dice" """:obj:`str`: Messages with :attr:`telegram.Message.dice`.""" + DIRECT_MESSAGE_PRICE_CHANGED = "direct_message_price_changed" + """:obj:`str`: Messages with :attr:`telegram.Message.direct_message_price_changed`. + + .. versionadded:: NEXT.VERSION + """ DOCUMENT = "document" """:obj:`str`: Messages with :attr:`telegram.Message.document`.""" EFFECT_ID = "effect_id" From 468aed654f0c6633b383e6796c9c603b10e01ff9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 5 Jul 2025 00:19:20 +0400 Subject: [PATCH 6/8] Review: Add another eq test case --- tests/test_directmessagepricechanged.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_directmessagepricechanged.py b/tests/test_directmessagepricechanged.py index aaf5b9e89ea..2ca165a621f 100644 --- a/tests/test_directmessagepricechanged.py +++ b/tests/test_directmessagepricechanged.py @@ -22,7 +22,7 @@ import pytest -from telegram import DirectMessagePriceChanged +from telegram import DirectMessagePriceChanged, User from tests.auxil.slots import mro_slots if TYPE_CHECKING: @@ -79,3 +79,7 @@ def test_equality(self, direct_message_price_changed): ) assert dmpc1 != dmpc3 assert hash(dmpc1) != hash(dmpc3) + + not_a_dmpc = User(id=1, first_name="wrong", is_bot=False) + assert dmpc1 != not_a_dmpc + assert hash(dmpc1) != hash(not_a_dmpc) From dc4b71f1fad2f8878dc07ab772601065f0ee8a79 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 5 Jul 2025 05:04:52 +0400 Subject: [PATCH 7/8] Review: update constant and fixture --- src/telegram/constants.py | 2 +- tests/test_directmessagepricechanged.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/telegram/constants.py b/src/telegram/constants.py index d0a78865079..17c317b0600 100644 --- a/src/telegram/constants.py +++ b/src/telegram/constants.py @@ -3158,7 +3158,7 @@ class PollLimit(IntEnum): to the :paramref:`~telegram.Bot.send_poll.options` parameter of :meth:`telegram.Bot.send_poll`. """ - MAX_OPTION_NUMBER = 10 + MAX_OPTION_NUMBER = 12 """:obj:`int`: Maximum number of strings passed in a :obj:`list` to the :paramref:`~telegram.Bot.send_poll.options` parameter of :meth:`telegram.Bot.send_poll`. diff --git a/tests/test_directmessagepricechanged.py b/tests/test_directmessagepricechanged.py index 2ca165a621f..39d831bcfb6 100644 --- a/tests/test_directmessagepricechanged.py +++ b/tests/test_directmessagepricechanged.py @@ -32,7 +32,8 @@ @pytest.fixture def direct_message_price_changed(): return DirectMessagePriceChanged( - are_direct_messages_enabled=True, direct_message_star_count=100 + are_direct_messages_enabled=DirectMessagePriceChangedTestBase.are_direct_messages_enabled, + direct_message_star_count=DirectMessagePriceChangedTestBase.direct_message_star_count, ) From 81b047c880026e200871565d6d061fde8e293af8 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 5 Jul 2025 05:08:15 +0400 Subject: [PATCH 8/8] Add versionchanged to the constant --- src/telegram/constants.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/telegram/constants.py b/src/telegram/constants.py index 17c317b0600..7bfcbff0599 100644 --- a/src/telegram/constants.py +++ b/src/telegram/constants.py @@ -3162,6 +3162,9 @@ class PollLimit(IntEnum): """:obj:`int`: Maximum number of strings passed in a :obj:`list` to the :paramref:`~telegram.Bot.send_poll.options` parameter of :meth:`telegram.Bot.send_poll`. + + .. versionchanged:: NEXT.VERSION + This value was changed from ``10`` to ``12`` in accordance to Bot API 9.1. """ MAX_EXPLANATION_LENGTH = 200 """:obj:`int`: Maximum number of characters in a :obj:`str` passed as the