From b6f7946d07c1b28251708b97da5120e328b61726 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Sun, 6 Nov 2022 15:37:50 +0300 Subject: [PATCH 1/7] feat(Bot, ExtBot) add param `message_thread_id` * haven't added this param to shortcuts yet * testing doesn't seem to be possible before ForumTopic class is implemented --- telegram/_bot.py | 119 ++++++++++++++++++++++++++++++++++++++++ telegram/ext/_extbot.py | 40 ++++++++++++++ 2 files changed, 159 insertions(+) diff --git a/telegram/_bot.py b/telegram/_bot.py index f526101164c..5ea6ca0eb81 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -433,6 +433,7 @@ async def _send_message( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -452,6 +453,9 @@ async def _send_message( if reply_markup is not None: data["reply_markup"] = reply_markup + if message_thread_id is not None: + data["message_thread_id"] = message_thread_id + result = await self._post( endpoint, data, @@ -669,6 +673,7 @@ async def send_message( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -709,6 +714,10 @@ async def send_message( :class:`ReplyKeyboardRemove` | :class:`ForceReply`, optional): Additional interface options. An object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 Keyword Args: read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to @@ -751,6 +760,7 @@ async def send_message( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -836,6 +846,7 @@ async def forward_message( message_id: int, disable_notification: DVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -869,6 +880,10 @@ async def forward_message( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 Keyword Args: read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to @@ -905,6 +920,7 @@ async def forward_message( data, disable_notification=disable_notification, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -925,6 +941,7 @@ async def send_photo( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -965,6 +982,8 @@ async def send_photo( receive a notification with no sound. protect_content (:obj:`bool`, optional): Protects the contents of the sent message from forwarding and saving. + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. .. versionadded:: 13.10 @@ -1024,6 +1043,7 @@ async def send_photo( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1048,6 +1068,7 @@ async def send_audio( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1101,6 +1122,10 @@ async def send_audio( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1175,6 +1200,7 @@ async def send_audio( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1197,6 +1223,7 @@ async def send_document( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1249,6 +1276,10 @@ async def send_document( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1317,6 +1348,7 @@ async def send_document( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1334,6 +1366,7 @@ async def send_sticker( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -1367,6 +1400,10 @@ async def send_sticker( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1408,6 +1445,7 @@ async def send_sticker( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1433,6 +1471,7 @@ async def send_video( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1491,6 +1530,10 @@ async def send_video( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1566,6 +1609,7 @@ async def send_video( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1586,6 +1630,7 @@ async def send_video_note( thumb: FileInput = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1633,6 +1678,10 @@ async def send_video_note( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1699,6 +1748,7 @@ async def send_video_note( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1723,6 +1773,7 @@ async def send_animation( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1785,6 +1836,10 @@ async def send_animation( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1849,6 +1904,7 @@ async def send_animation( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1870,6 +1926,7 @@ async def send_voice( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1922,6 +1979,10 @@ async def send_voice( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -1981,6 +2042,7 @@ async def send_voice( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1999,6 +2061,7 @@ async def send_media_group( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -2032,6 +2095,10 @@ async def send_media_group( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -2105,6 +2172,9 @@ async def send_media_group( if reply_to_message_id: data["reply_to_message_id"] = reply_to_message_id + if message_thread_id: + data["message_thread_id"] = message_thread_id + result = await self._post( "sendMediaGroup", data, @@ -2132,6 +2202,7 @@ async def send_location( proximity_alert_radius: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, location: Location = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2171,6 +2242,10 @@ async def send_location( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -2238,6 +2313,7 @@ async def send_location( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2447,6 +2523,7 @@ async def send_venue( google_place_type: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, venue: Venue = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2489,6 +2566,10 @@ async def send_venue( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -2571,6 +2652,7 @@ async def send_venue( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2591,6 +2673,7 @@ async def send_contact( vcard: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, contact: Contact = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2623,6 +2706,10 @@ async def send_contact( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -2694,6 +2781,7 @@ async def send_contact( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2711,6 +2799,7 @@ async def send_game( reply_markup: InlineKeyboardMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2733,6 +2822,10 @@ async def send_game( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -2775,6 +2868,7 @@ async def send_game( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -4845,6 +4939,7 @@ async def send_invoice( max_tip_amount: int = None, suggested_tip_amounts: List[int] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -4938,6 +5033,10 @@ async def send_invoice( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -5018,6 +5117,7 @@ async def send_invoice( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -7146,6 +7246,7 @@ async def send_poll( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -7201,6 +7302,10 @@ async def send_poll( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -7268,6 +7373,7 @@ async def send_poll( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -7349,6 +7455,7 @@ async def send_dice( emoji: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -7391,6 +7498,10 @@ async def send_dice( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 Keyword Args: read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to @@ -7427,6 +7538,7 @@ async def send_dice( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -7897,6 +8009,7 @@ async def copy_message( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -7933,6 +8046,10 @@ async def copy_message( forwarding and saving. .. versionadded:: 13.10 + message_thread_id (:obj:`int`, optional): Unique identifier for the target message + thread (topic) of the forum; for forum supergroups only. + + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. @@ -7983,6 +8100,8 @@ async def copy_message( data["reply_to_message_id"] = reply_to_message_id if reply_markup: data["reply_markup"] = reply_markup + if message_thread_id: + data["message_thread_id"] = message_thread_id result = await self._post( "copyMessage", diff --git a/telegram/ext/_extbot.py b/telegram/ext/_extbot.py index a344123f965..6a68f5a9971 100644 --- a/telegram/ext/_extbot.py +++ b/telegram/ext/_extbot.py @@ -460,6 +460,7 @@ async def _send_message( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -477,6 +478,7 @@ async def _send_message( reply_markup=self._replace_keyboard(reply_markup), allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -624,6 +626,7 @@ async def copy_message( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -645,6 +648,7 @@ async def copy_message( allow_sending_without_reply=allow_sending_without_reply, reply_markup=self._replace_keyboard(reply_markup), protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1395,6 +1399,7 @@ async def forward_message( message_id: int, disable_notification: DVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1409,6 +1414,7 @@ async def forward_message( message_id=message_id, disable_notification=disable_notification, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1876,6 +1882,7 @@ async def send_animation( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1900,6 +1907,7 @@ async def send_animation( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -1924,6 +1932,7 @@ async def send_audio( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1948,6 +1957,7 @@ async def send_audio( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -1990,6 +2000,7 @@ async def send_contact( vcard: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, contact: Contact = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2010,6 +2021,7 @@ async def send_contact( vcard=vcard, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, contact=contact, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2027,6 +2039,7 @@ async def send_dice( emoji: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2043,6 +2056,7 @@ async def send_dice( emoji=emoji, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2064,6 +2078,7 @@ async def send_document( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2086,6 +2101,7 @@ async def send_document( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2103,6 +2119,7 @@ async def send_game( reply_markup: InlineKeyboardMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2119,6 +2136,7 @@ async def send_game( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2155,6 +2173,7 @@ async def send_invoice( max_tip_amount: int = None, suggested_tip_amounts: List[int] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2191,6 +2210,7 @@ async def send_invoice( max_tip_amount=max_tip_amount, suggested_tip_amounts=suggested_tip_amounts, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2212,6 +2232,7 @@ async def send_location( proximity_alert_radius: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, location: Location = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2234,6 +2255,7 @@ async def send_location( proximity_alert_radius=proximity_alert_radius, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, location=location, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2252,6 +2274,7 @@ async def send_media_group( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -2270,6 +2293,7 @@ async def send_media_group( reply_to_message_id=reply_to_message_id, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2292,6 +2316,7 @@ async def send_message( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2308,6 +2333,7 @@ async def send_message( disable_web_page_preview=disable_web_page_preview, disable_notification=disable_notification, protect_content=protect_content, + message_thread_id=message_thread_id, reply_to_message_id=reply_to_message_id, allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, @@ -2330,6 +2356,7 @@ async def send_photo( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2350,6 +2377,7 @@ async def send_photo( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2378,6 +2406,7 @@ async def send_poll( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2405,6 +2434,7 @@ async def send_poll( allow_sending_without_reply=allow_sending_without_reply, explanation_entities=explanation_entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2421,6 +2451,7 @@ async def send_sticker( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -2437,6 +2468,7 @@ async def send_sticker( reply_markup=reply_markup, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2460,6 +2492,7 @@ async def send_venue( google_place_type: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, venue: Venue = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2484,6 +2517,7 @@ async def send_venue( google_place_type=google_place_type, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, venue=venue, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2509,6 +2543,7 @@ async def send_video( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2534,6 +2569,7 @@ async def send_video( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2554,6 +2590,7 @@ async def send_video_note( thumb: FileInput = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2574,6 +2611,7 @@ async def send_video_note( thumb=thumb, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, @@ -2595,6 +2633,7 @@ async def send_voice( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2616,6 +2655,7 @@ async def send_voice( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, filename=filename, read_timeout=read_timeout, write_timeout=write_timeout, From 56f223c4a27c54f66633d5c4bda7c65341a89374 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:25:43 +0300 Subject: [PATCH 2/7] fix(Bot.send_photo docstring) `versionadded` --- telegram/_bot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/telegram/_bot.py b/telegram/_bot.py index 5ea6ca0eb81..7094cd0044e 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -982,10 +982,12 @@ async def send_photo( receive a notification with no sound. protect_content (:obj:`bool`, optional): Protects the contents of the sent message from forwarding and saving. + + .. versionadded:: 13.10 message_thread_id (:obj:`int`, optional): Unique identifier for the target message thread (topic) of the forum; for forum supergroups only. - .. versionadded:: 13.10 + .. versionadded:: 20.0 reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. From e6eba1f1d15338a00324c8923fb66e0de25bca7b Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:49:05 +0300 Subject: [PATCH 3/7] fix(code) `black`'s notes on Chat and TestChat, unrelated to my changes --- telegram/_chat.py | 2 +- tests/test_chat.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram/_chat.py b/telegram/_chat.py index 6cbedb2037b..fee14a20441 100644 --- a/telegram/_chat.py +++ b/telegram/_chat.py @@ -266,7 +266,7 @@ class Chat(TelegramObject): "has_restricted_voice_and_video_messages", "is_forum", "active_usernames", - "emoji_status_custom_emoji_id" + "emoji_status_custom_emoji_id", ) SENDER: ClassVar[str] = constants.ChatType.SENDER diff --git a/tests/test_chat.py b/tests/test_chat.py index 8422148c0fb..4f2305180b8 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -106,7 +106,7 @@ def test_de_json(self, bot): ), "is_forum": self.is_forum, "active_usernames": self.active_usernames, - "emoji_status_custom_emoji_id": self.emoji_status_custom_emoji_id + "emoji_status_custom_emoji_id": self.emoji_status_custom_emoji_id, } chat = Chat.de_json(json_dict, bot) From d5d85fd8c6f62bb236c0e458d3d07005c8b32783 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:50:35 +0300 Subject: [PATCH 4/7] feat: add `message_thread_id` to methods in `Chat`, `Message`, `User` + minor in Bot: delete one line break --- telegram/_bot.py | 1 - telegram/_chat.py | 42 ++++++++++++++++++++++++++++++++++++++++ telegram/_message.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ telegram/_user.py | 38 ++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) diff --git a/telegram/_bot.py b/telegram/_bot.py index 7094cd0044e..d1c0f3710ef 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -988,7 +988,6 @@ async def send_photo( thread (topic) of the forum; for forum supergroups only. .. versionadded:: 20.0 - reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the original message. allow_sending_without_reply (:obj:`bool`, optional): Pass :obj:`True`, if the message diff --git a/telegram/_chat.py b/telegram/_chat.py index fee14a20441..79fe3b07cd6 100644 --- a/telegram/_chat.py +++ b/telegram/_chat.py @@ -1225,6 +1225,7 @@ async def send_message( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1253,6 +1254,7 @@ async def send_message( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1269,6 +1271,7 @@ async def send_media_group( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -1301,6 +1304,7 @@ async def send_media_group( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, @@ -1350,6 +1354,7 @@ async def send_photo( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1380,6 +1385,7 @@ async def send_photo( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1398,6 +1404,7 @@ async def send_contact( vcard: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, contact: "Contact" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1433,6 +1440,7 @@ async def send_contact( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_audio( @@ -1450,6 +1458,7 @@ async def send_audio( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1484,6 +1493,7 @@ async def send_audio( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1504,6 +1514,7 @@ async def send_document( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1541,6 +1552,7 @@ async def send_document( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_dice( @@ -1551,6 +1563,7 @@ async def send_dice( emoji: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1581,6 +1594,7 @@ async def send_dice( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_game( @@ -1591,6 +1605,7 @@ async def send_game( reply_markup: "InlineKeyboardMarkup" = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1621,6 +1636,7 @@ async def send_game( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_invoice( @@ -1651,6 +1667,7 @@ async def send_invoice( max_tip_amount: int = None, suggested_tip_amounts: List[int] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1711,6 +1728,7 @@ async def send_invoice( max_tip_amount=max_tip_amount, suggested_tip_amounts=suggested_tip_amounts, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_location( @@ -1726,6 +1744,7 @@ async def send_location( proximity_alert_radius: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, location: "Location" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1763,6 +1782,7 @@ async def send_location( proximity_alert_radius=proximity_alert_radius, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_animation( @@ -1780,6 +1800,7 @@ async def send_animation( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1819,6 +1840,7 @@ async def send_animation( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_sticker( @@ -1829,6 +1851,7 @@ async def send_sticker( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -1859,6 +1882,7 @@ async def send_sticker( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_venue( @@ -1876,6 +1900,7 @@ async def send_venue( google_place_type: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, venue: "Venue" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1915,6 +1940,7 @@ async def send_venue( google_place_type=google_place_type, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_video( @@ -1933,6 +1959,7 @@ async def send_video( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1973,6 +2000,7 @@ async def send_video( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_video_note( @@ -1986,6 +2014,7 @@ async def send_video_note( thumb: FileInput = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2021,6 +2050,7 @@ async def send_video_note( allow_sending_without_reply=allow_sending_without_reply, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_voice( @@ -2035,6 +2065,7 @@ async def send_voice( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2071,6 +2102,7 @@ async def send_voice( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_poll( @@ -2092,6 +2124,7 @@ async def send_poll( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2133,6 +2166,7 @@ async def send_poll( allow_sending_without_reply=allow_sending_without_reply, explanation_entities=explanation_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_copy( @@ -2147,6 +2181,7 @@ async def send_copy( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2181,6 +2216,7 @@ async def send_copy( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def copy_message( @@ -2195,6 +2231,7 @@ async def copy_message( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2229,6 +2266,7 @@ async def copy_message( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def forward_from( @@ -2237,6 +2275,7 @@ async def forward_from( message_id: int, disable_notification: DVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2269,6 +2308,7 @@ async def forward_from( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def forward_to( @@ -2277,6 +2317,7 @@ async def forward_to( message_id: int, disable_notification: DVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2309,6 +2350,7 @@ async def forward_to( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def export_invite_link( diff --git a/telegram/_message.py b/telegram/_message.py index 86d40a1a355..a6a2865621d 100644 --- a/telegram/_message.py +++ b/telegram/_message.py @@ -775,6 +775,7 @@ async def reply_text( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -810,6 +811,7 @@ async def reply_text( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -827,6 +829,7 @@ async def reply_markdown( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -872,6 +875,7 @@ async def reply_markdown( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -889,6 +893,7 @@ async def reply_markdown_v2( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -930,6 +935,7 @@ async def reply_markdown_v2( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -947,6 +953,7 @@ async def reply_html( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -988,6 +995,7 @@ async def reply_html( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1004,6 +1012,7 @@ async def reply_media_group( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1046,6 +1055,7 @@ async def reply_media_group( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, @@ -1062,6 +1072,7 @@ async def reply_photo( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1099,6 +1110,7 @@ async def reply_photo( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1121,6 +1133,7 @@ async def reply_audio( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1162,6 +1175,7 @@ async def reply_audio( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -1182,6 +1196,7 @@ async def reply_document( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1226,6 +1241,7 @@ async def reply_document( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_animation( @@ -1243,6 +1259,7 @@ async def reply_animation( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1290,6 +1307,7 @@ async def reply_animation( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_sticker( @@ -1300,6 +1318,7 @@ async def reply_sticker( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1337,6 +1356,7 @@ async def reply_sticker( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_video( @@ -1355,6 +1375,7 @@ async def reply_video( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1402,6 +1423,7 @@ async def reply_video( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_video_note( @@ -1415,6 +1437,7 @@ async def reply_video_note( thumb: FileInput = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1458,6 +1481,7 @@ async def reply_video_note( allow_sending_without_reply=allow_sending_without_reply, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_voice( @@ -1472,6 +1496,7 @@ async def reply_voice( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, quote: bool = None, @@ -1516,6 +1541,7 @@ async def reply_voice( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_location( @@ -1531,6 +1557,7 @@ async def reply_location( proximity_alert_radius: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, location: Location = None, quote: bool = None, @@ -1575,6 +1602,7 @@ async def reply_location( proximity_alert_radius=proximity_alert_radius, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_venue( @@ -1592,6 +1620,7 @@ async def reply_venue( google_place_type: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, venue: Venue = None, quote: bool = None, @@ -1638,6 +1667,7 @@ async def reply_venue( google_place_type=google_place_type, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_contact( @@ -1651,6 +1681,7 @@ async def reply_contact( vcard: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, contact: Contact = None, quote: bool = None, @@ -1693,6 +1724,7 @@ async def reply_contact( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_poll( @@ -1714,6 +1746,7 @@ async def reply_poll( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1762,6 +1795,7 @@ async def reply_poll( allow_sending_without_reply=allow_sending_without_reply, explanation_entities=explanation_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_dice( @@ -1772,6 +1806,7 @@ async def reply_dice( emoji: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1809,6 +1844,7 @@ async def reply_dice( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_chat_action( @@ -1851,6 +1887,7 @@ async def reply_game( reply_markup: "InlineKeyboardMarkup" = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1890,6 +1927,7 @@ async def reply_game( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_invoice( @@ -1920,6 +1958,7 @@ async def reply_invoice( max_tip_amount: int = None, suggested_tip_amounts: List[int] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1989,6 +2028,7 @@ async def reply_invoice( max_tip_amount=max_tip_amount, suggested_tip_amounts=suggested_tip_amounts, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def forward( @@ -1996,6 +2036,7 @@ async def forward( chat_id: Union[int, str], disable_notification: DVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2032,6 +2073,7 @@ async def forward( message_id=self.message_id, disable_notification=disable_notification, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -2050,6 +2092,7 @@ async def copy( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2090,6 +2133,7 @@ async def copy( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def reply_copy( @@ -2104,6 +2148,7 @@ async def reply_copy( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, quote: bool = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -2152,6 +2197,7 @@ async def reply_copy( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def edit_text( diff --git a/telegram/_user.py b/telegram/_user.py index 01bf0d93a87..015ec93234e 100644 --- a/telegram/_user.py +++ b/telegram/_user.py @@ -376,6 +376,7 @@ async def send_message( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -404,6 +405,7 @@ async def send_message( allow_sending_without_reply=allow_sending_without_reply, entities=entities, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -422,6 +424,7 @@ async def send_photo( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -452,6 +455,7 @@ async def send_photo( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -468,6 +472,7 @@ async def send_media_group( reply_to_message_id: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -500,6 +505,7 @@ async def send_media_group( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, @@ -520,6 +526,7 @@ async def send_audio( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -554,6 +561,7 @@ async def send_audio( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, read_timeout=read_timeout, write_timeout=write_timeout, connect_timeout=connect_timeout, @@ -605,6 +613,7 @@ async def send_contact( vcard: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, contact: "Contact" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -640,6 +649,7 @@ async def send_contact( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_dice( @@ -650,6 +660,7 @@ async def send_dice( emoji: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -680,6 +691,7 @@ async def send_dice( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_document( @@ -695,6 +707,7 @@ async def send_document( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -732,6 +745,7 @@ async def send_document( allow_sending_without_reply=allow_sending_without_reply, caption_entities=caption_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_game( @@ -742,6 +756,7 @@ async def send_game( reply_markup: "InlineKeyboardMarkup" = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -772,6 +787,7 @@ async def send_game( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_invoice( @@ -802,6 +818,7 @@ async def send_invoice( max_tip_amount: int = None, suggested_tip_amounts: List[int] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -862,6 +879,7 @@ async def send_invoice( max_tip_amount=max_tip_amount, suggested_tip_amounts=suggested_tip_amounts, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_location( @@ -877,6 +895,7 @@ async def send_location( proximity_alert_radius: int = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, location: "Location" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -914,6 +933,7 @@ async def send_location( proximity_alert_radius=proximity_alert_radius, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_animation( @@ -931,6 +951,7 @@ async def send_animation( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -970,6 +991,7 @@ async def send_animation( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_sticker( @@ -980,6 +1002,7 @@ async def send_sticker( reply_markup: ReplyMarkup = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = 20, @@ -1010,6 +1033,7 @@ async def send_sticker( api_kwargs=api_kwargs, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_video( @@ -1028,6 +1052,7 @@ async def send_video( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1068,6 +1093,7 @@ async def send_video( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_venue( @@ -1085,6 +1111,7 @@ async def send_venue( google_place_type: str = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, venue: "Venue" = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1124,6 +1151,7 @@ async def send_venue( google_place_type=google_place_type, allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_video_note( @@ -1137,6 +1165,7 @@ async def send_video_note( thumb: FileInput = None, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1172,6 +1201,7 @@ async def send_video_note( allow_sending_without_reply=allow_sending_without_reply, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_voice( @@ -1186,6 +1216,7 @@ async def send_voice( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, filename: str = None, read_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1222,6 +1253,7 @@ async def send_voice( caption_entities=caption_entities, filename=filename, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_poll( @@ -1243,6 +1275,7 @@ async def send_poll( allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1284,6 +1317,7 @@ async def send_poll( allow_sending_without_reply=allow_sending_without_reply, explanation_entities=explanation_entities, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def send_copy( @@ -1298,6 +1332,7 @@ async def send_copy( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1332,6 +1367,7 @@ async def send_copy( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def copy_message( @@ -1346,6 +1382,7 @@ async def copy_message( allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE, reply_markup: ReplyMarkup = None, protect_content: ODVInput[bool] = DEFAULT_NONE, + message_thread_id: int = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -1380,6 +1417,7 @@ async def copy_message( pool_timeout=pool_timeout, api_kwargs=api_kwargs, protect_content=protect_content, + message_thread_id=message_thread_id, ) async def approve_join_request( From 7cf63ea7d3df373e4dc97e8fd3904fdc58bdf0e6 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Mon, 7 Nov 2022 21:29:59 +0300 Subject: [PATCH 5/7] feat: add `is_topic_message`, `message_thread_id` to `Message` --- telegram/_message.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/telegram/_message.py b/telegram/_message.py index a6a2865621d..cbbbfc3b581 100644 --- a/telegram/_message.py +++ b/telegram/_message.py @@ -247,6 +247,13 @@ class Message(TelegramObject): .. versionadded:: 20.0 reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. ``login_url`` buttons are represented as ordinary url buttons. + is_topic_message (:obj:`bool`, optional): True, if the message is sent to a forum topic. + + .. versionadded:: 20.0 + message_thread_id (:obj:`int`, optional): Unique identifier of a message thread to which + the message belongs; for supergroups only. + + .. versionadded:: 20.0 Attributes: message_id (:obj:`int`): Unique message identifier inside this chat. @@ -367,6 +374,13 @@ class Message(TelegramObject): .. versionadded:: 20.0 reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. + is_topic_message (:obj:`bool`, optional): True, if the message is sent to a forum topic. + + .. versionadded:: 20.0 + message_thread_id (:obj:`int`, optional): Unique identifier of a message thread to which + the message belongs; for supergroups only. + + .. versionadded:: 20.0 .. |custom_emoji_formatting_note| replace:: Custom emoji entities will currently be ignored by this function. Instead, the supplied replacement for the emoji will be used. @@ -434,6 +448,8 @@ class Message(TelegramObject): "is_automatic_forward", "has_protected_content", "web_app_data", + "is_topic_message", + "message_thread_id", ) def __init__( @@ -497,6 +513,8 @@ def __init__( is_automatic_forward: bool = None, has_protected_content: bool = None, web_app_data: WebAppData = None, + is_topic_message: bool = None, + message_thread_id: int = None, *, api_kwargs: JSONDict = None, ): @@ -563,6 +581,8 @@ def __init__( self.video_chat_participants_invited = video_chat_participants_invited self.reply_markup = reply_markup self.web_app_data = web_app_data + self.is_topic_message = is_topic_message + self.message_thread_id = message_thread_id self._effective_attachment = DEFAULT_NONE From 8822d6b0ee1f4578169267b9f8b269d67873cc55 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Mon, 7 Nov 2022 21:31:26 +0300 Subject: [PATCH 6/7] add test for `Bot.send_message` with topic --- tests/test_bot.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_bot.py b/tests/test_bot.py index 0189763799a..2a15775d357 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2494,6 +2494,31 @@ async def test_send_message_entities(self, bot, chat_id): assert message.text == test_string assert message.entities == entities + @flaky(3, 1) + async def test_send_message_to_topic(self, bot, forum_group_id): + test_string = "Topics are forever" + + result = await bot._post( + "createForumTopic", + {"chat_id": forum_group_id, "name": "Is just a yellow lemon tree"}, + ) + + message_thread_id = result["message_thread_id"] + + message = await bot.send_message( + chat_id=forum_group_id, text=test_string, message_thread_id=message_thread_id + ) + + assert message.text == test_string + assert message.is_topic_message is True + assert message.message_thread_id == message_thread_id + + result = await bot._post( + "deleteForumTopic", + {"chat_id": forum_group_id, "message_thread_id": message_thread_id}, + ) + assert result is True + @flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_message_default_parse_mode(self, default_bot, chat_id): From 6fc90c835e06113d03099e2f69b33e02a108cce0 Mon Sep 17 00:00:00 2001 From: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Date: Tue, 8 Nov 2022 13:46:15 +0300 Subject: [PATCH 7/7] add TODO to test to mark that it's only a proof of concept --- tests/test_bot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_bot.py b/tests/test_bot.py index 2a15775d357..e6655fdefe4 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2496,6 +2496,7 @@ async def test_send_message_entities(self, bot, chat_id): @flaky(3, 1) async def test_send_message_to_topic(self, bot, forum_group_id): + # TODO rework when new methods and attributes become available test_string = "Topics are forever" result = await bot._post(