mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-01-04 18:12:12 +01:00
API 6.3 (#3392)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
This commit is contained in:
parent
01167c805b
commit
d6c6cc231e
34 changed files with 1956 additions and 29 deletions
|
@ -14,7 +14,7 @@ repos:
|
|||
args:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
|
|
|
@ -20,7 +20,7 @@ We have a vibrant community of developers helping each other in our `Telegram gr
|
|||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.2-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.3-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ We have a vibrant community of developers helping each other in our `Telegram gr
|
|||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.2-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.3-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# serve to show the default.
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
# import telegram
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
|
@ -50,6 +51,9 @@ source_suffix = '.rst'
|
|||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# Global substitutions
|
||||
rst_prolog = (Path.cwd() / "substitutions/global.rst").read_text(encoding="utf-8")
|
||||
|
||||
# General information about the project.
|
||||
project = u'python-telegram-bot'
|
||||
copyright = u'2015-2022, Leandro Toledo'
|
||||
|
|
5
docs/source/substitutions/global.rst
Normal file
5
docs/source/substitutions/global.rst
Normal file
|
@ -0,0 +1,5 @@
|
|||
.. |message_thread_id| replace:: Unique identifier for the target message thread of the forum topic.
|
||||
|
||||
.. |message_thread_id_arg| replace:: Unique identifier for the target message thread (topic) of the forum; for forum supergroups only.
|
||||
|
||||
.. |chat_id_group| replace:: Unique identifier for the target chat or username of the target supergroup (in the format ``@supergroupusername``).
|
8
docs/source/telegram.forumtopic.rst
Normal file
8
docs/source/telegram.forumtopic.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.x/telegram/forumtopic.py
|
||||
|
||||
telegram.ForumTopic
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.ForumTopic
|
||||
:members:
|
||||
:show-inheritance:
|
8
docs/source/telegram.forumtopicclosed.rst
Normal file
8
docs/source/telegram.forumtopicclosed.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.x/telegram/forumtopic.py
|
||||
|
||||
telegram.ForumTopicClosed
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.ForumTopicClosed
|
||||
:members:
|
||||
:show-inheritance:
|
8
docs/source/telegram.forumtopiccreated.rst
Normal file
8
docs/source/telegram.forumtopiccreated.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.x/telegram/forumtopic.py
|
||||
|
||||
telegram.ForumTopicCreated
|
||||
==========================
|
||||
|
||||
.. autoclass:: telegram.ForumTopicCreated
|
||||
:members:
|
||||
:show-inheritance:
|
8
docs/source/telegram.forumtopicreopened.rst
Normal file
8
docs/source/telegram.forumtopicreopened.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.x/telegram/forumtopic.py
|
||||
|
||||
telegram.ForumTopicReopened
|
||||
===========================
|
||||
|
||||
.. autoclass:: telegram.ForumTopicReopened
|
||||
:members:
|
||||
:show-inheritance:
|
|
@ -39,6 +39,10 @@ telegram package
|
|||
telegram.error
|
||||
telegram.file
|
||||
telegram.forcereply
|
||||
telegram.forumtopic
|
||||
telegram.forumtopicclosed
|
||||
telegram.forumtopiccreated
|
||||
telegram.forumtopicreopened
|
||||
telegram.inlinekeyboardbutton
|
||||
telegram.inlinekeyboardmarkup
|
||||
telegram.inputfile
|
||||
|
|
|
@ -64,6 +64,7 @@ from .replymarkup import ReplyMarkup
|
|||
from .replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from .replykeyboardremove import ReplyKeyboardRemove
|
||||
from .forcereply import ForceReply
|
||||
from .forumtopic import ForumTopic, ForumTopicClosed, ForumTopicCreated, ForumTopicReopened
|
||||
from .error import TelegramError
|
||||
from .files.inputfile import InputFile
|
||||
from .files.file import File
|
||||
|
@ -230,6 +231,10 @@ __all__ = ( # Keep this alphabetically ordered
|
|||
'File',
|
||||
'FileCredentials',
|
||||
'ForceReply',
|
||||
'ForumTopic',
|
||||
'ForumTopicClosed',
|
||||
'ForumTopicCreated',
|
||||
'ForumTopicReopened',
|
||||
'Game',
|
||||
'GameHighScore',
|
||||
'IdDocumentData',
|
||||
|
|
465
telegram/bot.py
465
telegram/bot.py
|
@ -94,6 +94,7 @@ from telegram import (
|
|||
)
|
||||
from telegram.constants import MAX_INLINE_QUERY_RESULTS
|
||||
from telegram.error import InvalidToken, TelegramError
|
||||
from telegram.forumtopic import ForumTopic
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
from telegram.utils.helpers import (
|
||||
DEFAULT_NONE,
|
||||
|
@ -310,6 +311,7 @@ class Bot(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Union[bool, Message]:
|
||||
if reply_to_message_id is not None:
|
||||
data['reply_to_message_id'] = reply_to_message_id
|
||||
|
@ -317,6 +319,9 @@ class Bot(TelegramObject):
|
|||
if protect_content:
|
||||
data['protect_content'] = protect_content
|
||||
|
||||
if message_thread_id is not None:
|
||||
data["message_thread_id"] = message_thread_id
|
||||
|
||||
# We don't check if (DEFAULT_)None here, so that _put is able to insert the defaults
|
||||
# correctly, if necessary
|
||||
data['disable_notification'] = disable_notification
|
||||
|
@ -471,6 +476,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send text messages.
|
||||
|
||||
|
@ -492,6 +498,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
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
|
||||
|
@ -532,6 +541,7 @@ class Bot(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -547,6 +557,8 @@ class Bot(TelegramObject):
|
|||
limitations:
|
||||
|
||||
- A message can only be deleted if it was sent less than 48 hours ago.
|
||||
- Service messages about a supergroup, channel, or forum topic creation can't be
|
||||
deleted.
|
||||
- A dice message in a private chat can only be deleted if it was sent more than 24
|
||||
hours ago.
|
||||
- Bots can delete outgoing messages in private chats, groups, and supergroups.
|
||||
|
@ -590,6 +602,7 @@ class Bot(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to forward messages of any kind. Service messages can't be forwarded.
|
||||
|
||||
|
@ -613,6 +626,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
|
@ -642,6 +658,7 @@ class Bot(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -660,6 +677,7 @@ class Bot(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send photos.
|
||||
|
||||
|
@ -698,6 +716,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -739,6 +760,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -761,6 +783,7 @@ class Bot(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display them in the
|
||||
|
@ -809,6 +832,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -867,6 +893,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -887,6 +914,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send general files.
|
||||
|
@ -929,6 +957,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -983,6 +1014,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -997,6 +1029,7 @@ class Bot(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send static ``.WEBP``, animated ``.TGS``, or video ``.WEBM`` stickers.
|
||||
|
@ -1023,6 +1056,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1054,6 +1090,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1077,6 +1114,7 @@ class Bot(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send video files, Telegram clients support mp4 videos
|
||||
|
@ -1128,6 +1166,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1187,6 +1228,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1205,6 +1247,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long.
|
||||
|
@ -1243,6 +1286,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1293,6 +1339,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1315,6 +1362,7 @@ class Bot(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
|
||||
|
@ -1323,7 +1371,7 @@ class Bot(TelegramObject):
|
|||
|
||||
Note:
|
||||
``thumb`` will be ignored for small files, for which Telegram can easily
|
||||
generate thumb nails. However, this behaviour is undocumented and might be changed
|
||||
generate thumbnails. However, this behaviour is undocumented and might be changed
|
||||
by Telegram.
|
||||
|
||||
Args:
|
||||
|
@ -1369,6 +1417,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1417,6 +1468,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1436,6 +1488,7 @@ class Bot(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display the file
|
||||
|
@ -1479,6 +1532,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1522,6 +1578,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1537,6 +1594,7 @@ class Bot(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> List[Message]:
|
||||
"""Use this method to send a group of photos or videos as an album.
|
||||
|
||||
|
@ -1552,6 +1610,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1587,6 +1648,9 @@ class Bot(TelegramObject):
|
|||
if protect_content:
|
||||
data['protect_content'] = protect_content
|
||||
|
||||
if message_thread_id:
|
||||
data["message_thread_id"] = message_thread_id
|
||||
|
||||
result = self._post('sendMediaGroup', data, timeout=timeout, api_kwargs=api_kwargs)
|
||||
|
||||
return Message.de_list(result, self) # type: ignore
|
||||
|
@ -1609,6 +1673,7 @@ class Bot(TelegramObject):
|
|||
proximity_alert_radius: int = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send point on the map.
|
||||
|
||||
|
@ -1636,6 +1701,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1692,6 +1760,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1853,6 +1922,7 @@ class Bot(TelegramObject):
|
|||
google_place_type: str = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send information about a venue.
|
||||
|
||||
|
@ -1886,6 +1956,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -1950,6 +2023,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -1968,6 +2042,7 @@ class Bot(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send phone contacts.
|
||||
|
||||
|
@ -1990,6 +2065,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -2043,6 +2121,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -2057,6 +2136,7 @@ class Bot(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send a game.
|
||||
|
||||
|
@ -2070,6 +2150,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -2103,6 +2186,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -2246,9 +2330,8 @@ class Bot(TelegramObject):
|
|||
current_offset: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to send answers to an inline query. No more than 50 results per query are
|
||||
allowed.
|
||||
"""Use this method to send answers to an inline query. No more than 50 results per query
|
||||
are allowed.
|
||||
|
||||
Warning:
|
||||
In most use cases :attr:`current_offset` should not be passed manually. Instead of
|
||||
|
@ -3627,6 +3710,7 @@ class Bot(TelegramObject):
|
|||
max_tip_amount: int = None,
|
||||
suggested_tip_amounts: List[int] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""Use this method to send invoices.
|
||||
|
||||
|
@ -3705,6 +3789,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -3779,6 +3866,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -4031,6 +4119,7 @@ class Bot(TelegramObject):
|
|||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
can_manage_video_chats: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to promote or demote a user in a supergroup or a channel. The bot must be
|
||||
|
@ -4086,6 +4175,10 @@ class Bot(TelegramObject):
|
|||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
can_manage_topics (:obj:`bool`, optional): Pass :obj:`True`, if the user is
|
||||
allowed to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
@ -4125,6 +4218,8 @@ class Bot(TelegramObject):
|
|||
data['can_manage_video_chats'] = can_manage_voice_chats
|
||||
if can_manage_video_chats is not None:
|
||||
data['can_manage_video_chats'] = can_manage_video_chats
|
||||
if can_manage_topics is not None:
|
||||
data["can_manage_topics"] = can_manage_topics
|
||||
|
||||
result = self._post('promoteChatMember', data, timeout=timeout, api_kwargs=api_kwargs)
|
||||
|
||||
|
@ -5273,6 +5368,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send a native poll.
|
||||
|
@ -5315,6 +5411,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -5376,6 +5475,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -5436,6 +5536,7 @@ class Bot(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send an animated emoji that will display a random value.
|
||||
|
@ -5456,6 +5557,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -5492,6 +5596,7 @@ class Bot(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
@log
|
||||
|
@ -5813,6 +5918,7 @@ class Bot(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> MessageId:
|
||||
"""
|
||||
Use this method to copy messages of any kind. Service messages and invoice messages can't
|
||||
|
@ -5838,6 +5944,9 @@ class Bot(TelegramObject):
|
|||
forwarding and saving.
|
||||
|
||||
.. versionadded:: 13.10
|
||||
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
|
||||
original message.
|
||||
|
@ -5881,6 +5990,8 @@ class Bot(TelegramObject):
|
|||
data['reply_markup'] = reply_markup.to_json()
|
||||
else:
|
||||
data['reply_markup'] = reply_markup
|
||||
if message_thread_id:
|
||||
data["message_thread_id"] = message_thread_id
|
||||
|
||||
result = self._post('copyMessage', data, timeout=timeout, api_kwargs=api_kwargs)
|
||||
return MessageId.de_json(result, self) # type: ignore[return-value, arg-type]
|
||||
|
@ -6096,6 +6207,338 @@ class Bot(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@log
|
||||
def get_forum_topic_icon_stickers(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List[Sticker]:
|
||||
"""Use this method to get custom emoji stickers, which can be used as a forum topic
|
||||
icon by any user. Requires no parameters.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.Sticker`]
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
result = self._post(
|
||||
"getForumTopicIconStickers",
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
return Sticker.de_list(result, self) # type: ignore[return-value, arg-type]
|
||||
|
||||
@log
|
||||
def create_forum_topic(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
name: str,
|
||||
icon_color: int = None,
|
||||
icon_custom_emoji_id: str = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> ForumTopic:
|
||||
"""
|
||||
Use this method to create a topic in a forum supergroup chat. The bot must be
|
||||
an administrator in the chat for this to work and must have
|
||||
:attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights.
|
||||
|
||||
.. seealso:: :meth:`telegram.Chat.create_forum_topic`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
name (:obj:`str`): New topic name, 1-128 characters.
|
||||
icon_color (:obj:`int`, optional): Color of the topic icon in RGB format. Currently,
|
||||
must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB),
|
||||
9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)
|
||||
icon_custom_emoji_id (:obj:`str`, optional): New unique identifier of the custom emoji
|
||||
shown as the topic icon. Use :meth:`~telegram.Bot.get_forum_topic_icon_stickers`
|
||||
to get all allowed custom emoji identifiers.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ForumTopic`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"name": name,
|
||||
}
|
||||
|
||||
if icon_color is not None:
|
||||
data["icon_color"] = icon_color
|
||||
|
||||
if icon_custom_emoji_id is not None:
|
||||
data["icon_custom_emoji_id"] = icon_custom_emoji_id
|
||||
|
||||
result = self._post(
|
||||
"createForumTopic",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
return ForumTopic.de_json(result, self) # type: ignore[return-value, arg-type]
|
||||
|
||||
@log
|
||||
def edit_forum_topic(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: int,
|
||||
name: str,
|
||||
icon_custom_emoji_id: str,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
:attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights,
|
||||
unless it is the creator of the topic.
|
||||
|
||||
.. seealso:: :meth:`telegram.Message.edit_forum_topic`,
|
||||
:meth:`telegram.Chat.edit_forum_topic`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
message_thread_id (:obj:`int`): |message_thread_id|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
name (:obj:`str`): New topic name, 1-128 characters.
|
||||
icon_custom_emoji_id (:obj:`str`): New unique identifier of the custom emoji shown as
|
||||
the topic icon. Use :meth:`~telegram.Bot.get_forum_topic_icon_stickers` to get all
|
||||
allowed custom emoji identifiers.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_thread_id": message_thread_id,
|
||||
"name": name,
|
||||
"icon_custom_emoji_id": icon_custom_emoji_id,
|
||||
}
|
||||
return self._post( # type: ignore[return-value]
|
||||
"editForumTopic",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@log
|
||||
def close_forum_topic(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to close an open topic in a forum supergroup chat. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
:attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights,
|
||||
unless it is the creator of the topic.
|
||||
|
||||
.. seealso:: :meth:`telegram.Message.close_forum_topic`,
|
||||
:meth:`telegram.Chat.close_forum_topic`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
message_thread_id (:obj:`int`): |message_thread_id|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_thread_id": message_thread_id,
|
||||
}
|
||||
return self._post( # type: ignore[return-value]
|
||||
"closeForumTopic",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@log
|
||||
def reopen_forum_topic(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to reopen a closed topic in a forum supergroup chat. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
:meth:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights,
|
||||
unless it is the creator of the topic.
|
||||
|
||||
.. seealso:: :meth:`telegram.Message.reopen_forum_topic`,
|
||||
:meth:`telegram.Chat.reopen_forum_topic`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
message_thread_id (:obj:`int`): |message_thread_id|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_thread_id": message_thread_id,
|
||||
}
|
||||
return self._post( # type: ignore[return-value]
|
||||
"reopenForumTopic",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@log
|
||||
def delete_forum_topic(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to delete a forum topic along with all its messages in a forum supergroup
|
||||
chat. The bot must be an administrator in the chat for this to work and must have
|
||||
:meth:`~telegram.ChatAdministratorRights.can_delete_messages` administrator rights.
|
||||
|
||||
.. seealso:: :meth:`telegram.Message.delete_forum_topic`,
|
||||
:meth:`telegram.Chat.delete_forum_topic`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
message_thread_id (:obj:`int`): |message_thread_id|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_thread_id": message_thread_id,
|
||||
}
|
||||
return self._post( # type: ignore[return-value]
|
||||
"deleteForumTopic",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@log
|
||||
def unpin_all_forum_topic_messages(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to clear the list of pinned messages in a forum topic. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
:meth:`~telegram.ChatAdministratorRights.can_pin_messages` administrator rights
|
||||
in the supergroup.
|
||||
|
||||
.. seealso:: :meth:`telegram.Message.unpin_all_forum_topic_messages`,
|
||||
:meth:`telegram.Chat.unpin_all_forum_topic_messages`,
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
message_thread_id (:obj:`int`): |message_thread_id|
|
||||
|
||||
.. versionadded:: 13.15
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
|
||||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_thread_id": message_thread_id,
|
||||
}
|
||||
return self._post( # type: ignore[return-value]
|
||||
"unpinAllForumTopicMessages",
|
||||
data,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def to_dict(self) -> JSONDict:
|
||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data: JSONDict = {'id': self.id, 'username': self.username, 'first_name': self.first_name}
|
||||
|
@ -6292,3 +6735,17 @@ class Bot(TelegramObject):
|
|||
"""Alias for :meth:`set_my_default_administrator_rights`"""
|
||||
createInvoiceLink = create_invoice_link
|
||||
"""Alias for :meth:`create_invoice_link`"""
|
||||
getForumTopicIconStickers = get_forum_topic_icon_stickers
|
||||
"""Alias for :meth:`get_forum_topic_icon_stickers`"""
|
||||
createForumTopic = create_forum_topic
|
||||
"""Alias for :meth:`create_forum_topic`"""
|
||||
editForumTopic = edit_forum_topic
|
||||
"""Alias for :meth:`edit_forum_topic`"""
|
||||
closeForumTopic = close_forum_topic
|
||||
"""Alias for :meth:`close_forum_topic`"""
|
||||
reopenForumTopic = reopen_forum_topic
|
||||
"""Alias for :meth:`reopen_forum_topic`"""
|
||||
deleteForumTopic = delete_forum_topic
|
||||
"""Alias for :meth:`delete_forum_topic`"""
|
||||
unpinAllForumTopicMessages = unpin_all_forum_topic_messages
|
||||
"""Alias for :meth:`unpin_all_forum_topic_messages`"""
|
||||
|
|
|
@ -621,6 +621,7 @@ class CallbackQuery(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -650,6 +651,7 @@ class CallbackQuery(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: ClassVar[int] = constants.MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH
|
||||
|
|
241
telegram/chat.py
241
telegram/chat.py
|
@ -35,6 +35,7 @@ if TYPE_CHECKING:
|
|||
Bot,
|
||||
ChatMember,
|
||||
ChatInviteLink,
|
||||
ForumTopic,
|
||||
Message,
|
||||
MessageId,
|
||||
ReplyMarkup,
|
||||
|
@ -131,6 +132,21 @@ class Chat(TelegramObject):
|
|||
in the private chat. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.14
|
||||
is_forum (:obj:`bool`, optional): :obj:`True`, if the supergroup chat is a forum
|
||||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 13.15
|
||||
active_usernames (List[:obj:`str`], optional): If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels. Returned
|
||||
only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
emoji_status_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of emoji
|
||||
status of the other party in a private chat. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
|
@ -190,6 +206,23 @@ class Chat(TelegramObject):
|
|||
in the private chat. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.14
|
||||
is_forum (:obj:`bool`): Optional. :obj:`True`, if the supergroup chat is a forum
|
||||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 13.15
|
||||
active_usernames (List[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels. Returned
|
||||
only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
emoji_status_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji
|
||||
status of the other party in a private chat. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
|
@ -218,6 +251,9 @@ class Chat(TelegramObject):
|
|||
'join_to_send_messages',
|
||||
'join_by_request',
|
||||
'has_restricted_voice_and_video_messages',
|
||||
'is_forum',
|
||||
'active_usernames',
|
||||
'emoji_status_custom_emoji_id',
|
||||
'_id_attrs',
|
||||
)
|
||||
|
||||
|
@ -261,6 +297,9 @@ class Chat(TelegramObject):
|
|||
join_to_send_messages: bool = None,
|
||||
join_by_request: bool = None,
|
||||
has_restricted_voice_and_video_messages: bool = None,
|
||||
is_forum: bool = None,
|
||||
active_usernames: List[str] = None,
|
||||
emoji_status_custom_emoji_id: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
|
@ -292,6 +331,9 @@ class Chat(TelegramObject):
|
|||
self.join_to_send_messages = join_to_send_messages
|
||||
self.join_by_request = join_by_request
|
||||
self.has_restricted_voice_and_video_messages = has_restricted_voice_and_video_messages
|
||||
self.is_forum = is_forum
|
||||
self.active_usernames = active_usernames
|
||||
self.emoji_status_custom_emoji_id = emoji_status_custom_emoji_id
|
||||
|
||||
self.bot = bot
|
||||
self._id_attrs = (self.id,)
|
||||
|
@ -629,6 +671,7 @@ class Chat(TelegramObject):
|
|||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
can_manage_video_chats: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -663,6 +706,7 @@ class Chat(TelegramObject):
|
|||
can_manage_chat=can_manage_chat,
|
||||
can_manage_voice_chats=can_manage_voice_chats,
|
||||
can_manage_video_chats=can_manage_video_chats,
|
||||
can_manage_topics=can_manage_topics,
|
||||
)
|
||||
|
||||
def restrict_member(
|
||||
|
@ -836,6 +880,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -860,6 +905,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_media_group(
|
||||
|
@ -873,6 +919,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> List['Message']:
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -893,6 +940,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_chat_action(
|
||||
|
@ -935,6 +983,7 @@ class Chat(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -960,6 +1009,7 @@ class Chat(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_contact(
|
||||
|
@ -976,6 +1026,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1001,6 +1052,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_audio(
|
||||
|
@ -1021,6 +1073,7 @@ class Chat(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1050,6 +1103,7 @@ class Chat(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_document(
|
||||
|
@ -1068,6 +1122,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1095,6 +1150,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_dice(
|
||||
|
@ -1107,6 +1163,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1128,6 +1185,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_game(
|
||||
|
@ -1140,6 +1198,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1161,6 +1220,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_invoice(
|
||||
|
@ -1193,6 +1253,7 @@ class Chat(TelegramObject):
|
|||
max_tip_amount: int = None,
|
||||
suggested_tip_amounts: List[int] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1242,6 +1303,7 @@ class Chat(TelegramObject):
|
|||
max_tip_amount=max_tip_amount,
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_location(
|
||||
|
@ -1260,6 +1322,7 @@ class Chat(TelegramObject):
|
|||
proximity_alert_radius: int = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1287,6 +1350,7 @@ class Chat(TelegramObject):
|
|||
proximity_alert_radius=proximity_alert_radius,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_animation(
|
||||
|
@ -1307,6 +1371,7 @@ class Chat(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1336,6 +1401,7 @@ class Chat(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_sticker(
|
||||
|
@ -1348,6 +1414,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1369,6 +1436,7 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_venue(
|
||||
|
@ -1389,6 +1457,7 @@ class Chat(TelegramObject):
|
|||
google_place_type: str = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1418,6 +1487,7 @@ class Chat(TelegramObject):
|
|||
google_place_type=google_place_type,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_video(
|
||||
|
@ -1439,6 +1509,7 @@ class Chat(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1469,6 +1540,7 @@ class Chat(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_video_note(
|
||||
|
@ -1485,6 +1557,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1510,6 +1583,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_voice(
|
||||
|
@ -1527,6 +1601,7 @@ class Chat(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1553,6 +1628,7 @@ class Chat(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_poll(
|
||||
|
@ -1577,6 +1653,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1609,6 +1686,7 @@ class Chat(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
explanation_entities=explanation_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_copy(
|
||||
|
@ -1625,6 +1703,7 @@ class Chat(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1650,6 +1729,7 @@ class Chat(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def copy_message(
|
||||
|
@ -1666,6 +1746,7 @@ class Chat(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1691,6 +1772,7 @@ class Chat(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def export_invite_link(
|
||||
|
@ -1887,6 +1969,165 @@ class Chat(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def create_forum_topic(
|
||||
self,
|
||||
name: str,
|
||||
icon_color: int = None,
|
||||
icon_custom_emoji_id: str = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> "ForumTopic":
|
||||
"""Shortcut for::
|
||||
|
||||
bot.create_forum_topic(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.create_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ForumTopic`
|
||||
"""
|
||||
return self.bot.create_forum_topic(
|
||||
chat_id=self.id,
|
||||
name=name,
|
||||
icon_color=icon_color,
|
||||
icon_custom_emoji_id=icon_custom_emoji_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_forum_topic(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
name: str,
|
||||
icon_custom_emoji_id: str,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.edit_forum_topic(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.edit_forum_topic(
|
||||
chat_id=self.id,
|
||||
message_thread_id=message_thread_id,
|
||||
name=name,
|
||||
icon_custom_emoji_id=icon_custom_emoji_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def close_forum_topic(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.close_forum_topic(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.close_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.close_forum_topic(
|
||||
chat_id=self.id,
|
||||
message_thread_id=message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def reopen_forum_topic(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.reopen_forum_topic(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.reopen_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.reopen_forum_topic(
|
||||
chat_id=self.id,
|
||||
message_thread_id=message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def delete_forum_topic(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.delete_forum_topic(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.delete_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.delete_forum_topic(
|
||||
chat_id=self.id,
|
||||
message_thread_id=message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def unpin_all_forum_topic_messages(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.unpin_all_forum_topic_messages(chat_id=update.effective_chat.id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.unpin_all_forum_topic_messages`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.unpin_all_forum_topic_messages(
|
||||
chat_id=self.id,
|
||||
message_thread_id=message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def get_menu_button(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
|
|
@ -62,6 +62,10 @@ class ChatAdministratorRights(TelegramObject):
|
|||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Attributes:
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
|
||||
|
@ -89,6 +93,10 @@ class ChatAdministratorRights(TelegramObject):
|
|||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
|
@ -103,6 +111,7 @@ class ChatAdministratorRights(TelegramObject):
|
|||
'can_post_messages',
|
||||
'can_edit_messages',
|
||||
'can_pin_messages',
|
||||
'can_manage_topics',
|
||||
'_id_attrs',
|
||||
)
|
||||
|
||||
|
@ -119,6 +128,7 @@ class ChatAdministratorRights(TelegramObject):
|
|||
can_post_messages: bool = None,
|
||||
can_edit_messages: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
**_kwargs: Any,
|
||||
) -> None:
|
||||
# Required
|
||||
|
@ -134,6 +144,7 @@ class ChatAdministratorRights(TelegramObject):
|
|||
self.can_post_messages = can_post_messages
|
||||
self.can_edit_messages = can_edit_messages
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_manage_topics = can_manage_topics
|
||||
|
||||
self._id_attrs = (
|
||||
self.is_anonymous,
|
||||
|
@ -156,7 +167,7 @@ class ChatAdministratorRights(TelegramObject):
|
|||
:obj:`True`. This is e.g. useful when changing the bot's default administrator rights with
|
||||
:meth:`telegram.Bot.set_my_default_administrator_rights`.
|
||||
"""
|
||||
return cls(True, True, True, True, True, True, True, True, True, True, True)
|
||||
return cls(True, True, True, True, True, True, True, True, True, True, True, True)
|
||||
|
||||
@classmethod
|
||||
def no_rights(cls) -> 'ChatAdministratorRights':
|
||||
|
@ -164,4 +175,6 @@ class ChatAdministratorRights(TelegramObject):
|
|||
This method returns the :class:`ChatAdministratorRights` object with all attributes set to
|
||||
:obj:`False`.
|
||||
"""
|
||||
return cls(False, False, False, False, False, False, False, False, False, False, False)
|
||||
return cls(
|
||||
False, False, False, False, False, False, False, False, False, False, False, False
|
||||
)
|
||||
|
|
|
@ -288,6 +288,7 @@ class ChatMember(TelegramObject):
|
|||
'can_manage_voice_chats',
|
||||
'can_manage_video_chats',
|
||||
'until_date',
|
||||
'can_manage_topics',
|
||||
'_id_attrs',
|
||||
)
|
||||
|
||||
|
@ -329,6 +330,7 @@ class ChatMember(TelegramObject):
|
|||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
can_manage_video_chats: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# check before required to not waste resources if the error is raised
|
||||
|
@ -371,6 +373,7 @@ class ChatMember(TelegramObject):
|
|||
)
|
||||
self.can_manage_voice_chats = temp
|
||||
self.can_manage_video_chats = temp
|
||||
self.can_manage_topics = can_manage_topics
|
||||
|
||||
self._id_attrs = (self.user, self.status)
|
||||
|
||||
|
@ -494,6 +497,10 @@ class ChatMemberAdministrator(ChatMember):
|
|||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
|
@ -536,6 +543,10 @@ class ChatMemberAdministrator(ChatMember):
|
|||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only
|
||||
|
||||
.. versionadded:: 13.15
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
@ -557,6 +568,7 @@ class ChatMemberAdministrator(ChatMember):
|
|||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_manage_video_chats: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
super().__init__(
|
||||
|
@ -576,6 +588,7 @@ class ChatMemberAdministrator(ChatMember):
|
|||
can_invite_users=can_invite_users,
|
||||
can_pin_messages=can_pin_messages,
|
||||
can_manage_video_chats=can_manage_video_chats,
|
||||
can_manage_topics=can_manage_topics,
|
||||
)
|
||||
|
||||
|
||||
|
@ -631,6 +644,10 @@ class ChatMemberRestricted(ChatMember):
|
|||
allowed to add web page previews to their messages.
|
||||
until_date (:class:`datetime.datetime`, optional): Date when restrictions
|
||||
will be lifted for this user.
|
||||
can_manage_topics (:obj:`bool`): :obj:`True`, if the user is allowed to create
|
||||
forum topics.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
|
@ -656,6 +673,10 @@ class ChatMemberRestricted(ChatMember):
|
|||
allowed to add web page previews to their messages.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions
|
||||
will be lifted for this user.
|
||||
can_manage_topics (:obj:`bool`): :obj:`True`, if the user is allowed to create
|
||||
forum topics.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
"""
|
||||
|
||||
|
@ -674,6 +695,7 @@ class ChatMemberRestricted(ChatMember):
|
|||
can_send_other_messages: bool = None,
|
||||
can_add_web_page_previews: bool = None,
|
||||
until_date: datetime.datetime = None,
|
||||
can_manage_topics: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
super().__init__(
|
||||
|
@ -689,6 +711,7 @@ class ChatMemberRestricted(ChatMember):
|
|||
can_send_other_messages=can_send_other_messages,
|
||||
can_add_web_page_previews=can_add_web_page_previews,
|
||||
until_date=until_date,
|
||||
can_manage_topics=can_manage_topics,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class ChatPermissions(TelegramObject):
|
|||
Note:
|
||||
Though not stated explicitly in the official docs, Telegram changes not only the
|
||||
permissions that are set, but also sets all the others to :obj:`False`. However, since not
|
||||
documented, this behaviour may change unbeknown to PTB.
|
||||
documented, this behavior may change unbeknown to PTB.
|
||||
|
||||
Args:
|
||||
can_send_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send text
|
||||
|
@ -55,6 +55,11 @@ class ChatPermissions(TelegramObject):
|
|||
users to the chat.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
|
||||
messages. Ignored in public supergroups.
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create forum topics. If omitted defaults to the value of
|
||||
:attr:`can_pin_messages`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Attributes:
|
||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
|
||||
|
@ -75,6 +80,11 @@ class ChatPermissions(TelegramObject):
|
|||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
|
||||
messages. Ignored in public supergroups.
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create forum topics. If omitted defaults to the value of
|
||||
:attr:`can_pin_messages`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
"""
|
||||
|
||||
|
@ -88,6 +98,7 @@ class ChatPermissions(TelegramObject):
|
|||
'can_change_info',
|
||||
'can_pin_messages',
|
||||
'can_add_web_page_previews',
|
||||
'can_manage_topics',
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -100,6 +111,7 @@ class ChatPermissions(TelegramObject):
|
|||
can_change_info: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
|
@ -111,6 +123,7 @@ class ChatPermissions(TelegramObject):
|
|||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_manage_topics = can_manage_topics
|
||||
|
||||
self._id_attrs = (
|
||||
self.can_send_messages,
|
||||
|
|
|
@ -21,7 +21,7 @@ The following constants were extracted from the
|
|||
`Telegram Bots API <https://core.telegram.org/bots/api>`_.
|
||||
|
||||
Attributes:
|
||||
BOT_API_VERSION (:obj:`str`): `6.2`. Telegram Bot API version supported by this
|
||||
BOT_API_VERSION (:obj:`str`): `6.3`. Telegram Bot API version supported by this
|
||||
version of `python-telegram-bot`. Also available as ``telegram.bot_api_version``.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
@ -263,7 +263,7 @@ Attributes:
|
|||
"""
|
||||
from typing import List
|
||||
|
||||
BOT_API_VERSION: str = '6.2'
|
||||
BOT_API_VERSION: str = '6.3'
|
||||
MAX_MESSAGE_LENGTH: int = 4096
|
||||
MAX_CAPTION_LENGTH: int = 1024
|
||||
ANONYMOUS_ADMIN_ID: int = 1087968824
|
||||
|
|
|
@ -196,6 +196,7 @@ class ExtBot(telegram.bot.Bot):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> Union[bool, Message]:
|
||||
# We override this method to call self._replace_keyboard and self._insert_callback_data.
|
||||
# This covers most methods that have a reply_markup
|
||||
|
@ -209,6 +210,7 @@ class ExtBot(telegram.bot.Bot):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
if isinstance(result, Message):
|
||||
self._insert_callback_data(result)
|
||||
|
@ -304,6 +306,7 @@ class ExtBot(telegram.bot.Bot):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> MessageId:
|
||||
# We override this method to call self._replace_keyboard
|
||||
return super().copy_message(
|
||||
|
@ -320,6 +323,7 @@ class ExtBot(telegram.bot.Bot):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def get_chat(
|
||||
|
|
|
@ -1264,6 +1264,36 @@ officedocument.wordprocessingml.document")``.
|
|||
web_app_data = _WebAppData()
|
||||
"""Messages that contain :attr:`telegram.Message.web_app_data`."""
|
||||
|
||||
class _ForumTopicCreated(MessageFilter):
|
||||
__slots__ = ()
|
||||
name = 'Filters.status_update.forum_topic_created'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.forum_topic_created)
|
||||
|
||||
forum_topic_created = _ForumTopicCreated()
|
||||
"""Messages that contain :attr:`telegram.Message.forum_topic_created`."""
|
||||
|
||||
class _ForumTopicClosed(MessageFilter):
|
||||
__slots__ = ()
|
||||
name = 'Filters.status_update.forum_topic_closed'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.forum_topic_closed)
|
||||
|
||||
forum_topic_closed = _ForumTopicClosed()
|
||||
"""Messages that contain :attr:`telegram.Message.forum_topic_closed`."""
|
||||
|
||||
class _ForumTopicReopened(MessageFilter):
|
||||
__slots__ = ()
|
||||
name = 'Filters.status_update.forum_topic_reopened'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.forum_topic_reopened)
|
||||
|
||||
forum_topic_reopened = _ForumTopicReopened()
|
||||
"""Messages that contain :attr:`telegram.Message.forum_topic_reopened`."""
|
||||
|
||||
name = 'Filters.status_update'
|
||||
|
||||
def filter(self, message: Update) -> bool:
|
||||
|
@ -1288,6 +1318,9 @@ officedocument.wordprocessingml.document")``.
|
|||
or self.video_chat_ended(message)
|
||||
or self.video_chat_participants_invited(message)
|
||||
or self.web_app_data(message)
|
||||
or self.forum_topic_created(message)
|
||||
or self.forum_topic_closed(message)
|
||||
or self.forum_topic_reopened(message)
|
||||
)
|
||||
|
||||
status_update = _StatusUpdate()
|
||||
|
@ -1361,6 +1394,22 @@ officedocument.wordprocessingml.document")``.
|
|||
:attr:`telegram.Message.video_chat_participants_invited`.
|
||||
|
||||
.. versionadded:: 13.12
|
||||
web_app_data: Messages that contain
|
||||
:attr:`telegram.Message.web_app_data`.
|
||||
|
||||
.. versionadded:: 13.12
|
||||
forum_topic_created: Messages that contain
|
||||
:attr:`telegram.Message.forum_topic_created`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_closed: Messages that contain
|
||||
:attr:`telegram.Message.forum_topic_closed`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_reopened: Messages that contain
|
||||
:attr:`telegram.Message.forum_topic_reopened`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
"""
|
||||
|
||||
|
@ -2212,6 +2261,19 @@ officedocument.wordprocessingml.document")``.
|
|||
.. versionadded:: 13.9
|
||||
"""
|
||||
|
||||
class _IsTopicMessage(MessageFilter):
|
||||
__slots__ = ()
|
||||
name = 'Filters.is_topic_message'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.is_topic_message)
|
||||
|
||||
is_topic_message = _IsTopicMessage()
|
||||
"""Messages that contain :attr:`telegram.Message.is_topic_message`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
"""
|
||||
|
||||
class _HasProtectedContent(MessageFilter):
|
||||
__slots__ = ()
|
||||
name = 'Filters.has_protected_content'
|
||||
|
|
134
telegram/forumtopic.py
Normal file
134
telegram/forumtopic.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2022
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# 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 objects related to Telegram forum topics."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class ForumTopic(TelegramObject):
|
||||
"""
|
||||
This object represents a forum topic.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`message_thread_id`, :attr:`name` and :attr:`icon_color`
|
||||
are equal.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
message_thread_id (:obj:`int`): Unique identifier of the forum topic
|
||||
name (:obj:`str`): Name of the topic
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`, optional): Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
|
||||
Attributes:
|
||||
message_thread_id (:obj:`int`): Unique identifier of the forum topic
|
||||
name (:obj:`str`): Name of the topic
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`): Optional. Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
"""
|
||||
|
||||
__slots__ = ("message_thread_id", "name", "icon_color", "icon_custom_emoji_id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message_thread_id: int,
|
||||
name: str,
|
||||
icon_color: int,
|
||||
icon_custom_emoji_id: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
self.message_thread_id = message_thread_id
|
||||
self.name = name
|
||||
self.icon_color = icon_color
|
||||
self.icon_custom_emoji_id = icon_custom_emoji_id
|
||||
|
||||
self._id_attrs = (self.message_thread_id, self.name, self.icon_color)
|
||||
|
||||
|
||||
class ForumTopicCreated(TelegramObject):
|
||||
"""
|
||||
This object represents the content of a service message about a new forum topic created in
|
||||
the chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`name` and :attr:`icon_color` are equal.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Args:
|
||||
name (:obj:`str`): Name of the topic
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`, optional): Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
|
||||
Attributes:
|
||||
name (:obj:`str`): Name of the topic
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`): Optional. Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
"""
|
||||
|
||||
__slots__ = ("name", "icon_color", "icon_custom_emoji_id", "_id_attrs")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
icon_color: int,
|
||||
icon_custom_emoji_id: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
self.name = name
|
||||
self.icon_color = icon_color
|
||||
self.icon_custom_emoji_id = icon_custom_emoji_id
|
||||
|
||||
self._id_attrs = (self.name, self.icon_color)
|
||||
|
||||
|
||||
class ForumTopicClosed(TelegramObject):
|
||||
"""
|
||||
This object represents a service message about a forum topic closed in the chat.
|
||||
Currently holds no information.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, **_kwargs: Any): # skipcq: PTC-W0049
|
||||
pass
|
||||
|
||||
|
||||
class ForumTopicReopened(TelegramObject):
|
||||
"""
|
||||
This object represents a service message about a forum topic reopened in the chat.
|
||||
Currently holds no information.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, **_kwargs: Any): # skipcq: PTC-W0049
|
||||
pass
|
|
@ -60,6 +60,7 @@ from telegram import (
|
|||
WebAppData,
|
||||
VideoChatScheduled,
|
||||
)
|
||||
from telegram.forumtopic import ForumTopicClosed, ForumTopicCreated, ForumTopicReopened
|
||||
from telegram.utils.helpers import (
|
||||
escape_markdown,
|
||||
from_timestamp,
|
||||
|
@ -263,6 +264,26 @@ class Message(TelegramObject):
|
|||
.. versionadded:: 13.12
|
||||
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): :obj:`True`, if the message is sent to a forum
|
||||
topic.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
message_thread_id (:obj:`int`, optional): Unique identifier of a message thread to which
|
||||
the message belongs; for supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_created (:class:`telegram.ForumTopicCreated`, optional): Service message:
|
||||
forum topic created
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_closed (:class:`telegram.ForumTopicClosed`, optional): Service message:
|
||||
forum topic closed
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_reopened (:class:`telegram.ForumTopicReopened`, optional): Service message:
|
||||
forum topic reopened
|
||||
|
||||
.. versionadded:: 13.15
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
|
||||
Attributes:
|
||||
|
@ -405,6 +426,26 @@ class Message(TelegramObject):
|
|||
.. versionadded:: 13.12
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
is_topic_message (:obj:`bool`): Optional. :obj:`True`, if the message is sent to a forum
|
||||
topic.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
message_thread_id (:obj:`int`): Optional. Unique identifier of a message thread to which
|
||||
the message belongs; for supergroups only.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_created (:class:`telegram.ForumTopicCreated`): Optional. Service message:
|
||||
forum topic created
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_closed (:class:`telegram.ForumTopicClosed`): Optional. Service message:
|
||||
forum topic closed
|
||||
|
||||
.. versionadded:: 13.15
|
||||
forum_topic_reopened (:class:`telegram.ForumTopicReopened`): Optional. Service message:
|
||||
forum topic reopened
|
||||
|
||||
.. versionadded:: 13.15
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
.. |custom_emoji_formatting_note| replace:: Custom emoji entities will currently be ignored
|
||||
|
@ -478,6 +519,11 @@ class Message(TelegramObject):
|
|||
'is_automatic_forward',
|
||||
'has_protected_content',
|
||||
'web_app_data',
|
||||
'is_topic_message',
|
||||
'message_thread_id',
|
||||
'forum_topic_created',
|
||||
'forum_topic_closed',
|
||||
'forum_topic_reopened',
|
||||
'_id_attrs',
|
||||
)
|
||||
|
||||
|
@ -587,6 +633,11 @@ class Message(TelegramObject):
|
|||
video_chat_ended: VideoChatEnded = None,
|
||||
video_chat_participants_invited: VideoChatParticipantsInvited = None,
|
||||
web_app_data: WebAppData = None,
|
||||
is_topic_message: bool = None,
|
||||
message_thread_id: int = None,
|
||||
forum_topic_created: ForumTopicCreated = None,
|
||||
forum_topic_closed: ForumTopicClosed = None,
|
||||
forum_topic_reopened: ForumTopicReopened = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
if (
|
||||
|
@ -690,7 +741,11 @@ class Message(TelegramObject):
|
|||
self.voice_chat_participants_invited = temp3
|
||||
self.video_chat_participants_invited = temp3
|
||||
self.web_app_data = web_app_data
|
||||
|
||||
self.is_topic_message = is_topic_message
|
||||
self.message_thread_id = message_thread_id
|
||||
self.forum_topic_created = forum_topic_created
|
||||
self.forum_topic_closed = forum_topic_closed
|
||||
self.forum_topic_reopened = forum_topic_reopened
|
||||
self.bot = bot
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
@ -781,6 +836,13 @@ class Message(TelegramObject):
|
|||
data.get('video_chat_participants_invited'), bot
|
||||
)
|
||||
data['web_app_data'] = WebAppData.de_json(data.get('web_app_data'), bot)
|
||||
data["forum_topic_closed"] = ForumTopicClosed.de_json(data.get("forum_topic_closed"), bot)
|
||||
data["forum_topic_created"] = ForumTopicCreated.de_json(
|
||||
data.get("forum_topic_created"), bot
|
||||
)
|
||||
data["forum_topic_reopened"] = ForumTopicReopened.de_json(
|
||||
data.get("forum_topic_reopened"), bot
|
||||
)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
|
@ -893,6 +955,7 @@ class Message(TelegramObject):
|
|||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -924,6 +987,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_markdown(
|
||||
|
@ -939,6 +1003,7 @@ class Message(TelegramObject):
|
|||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -980,6 +1045,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_markdown_v2(
|
||||
|
@ -995,6 +1061,7 @@ class Message(TelegramObject):
|
|||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1032,6 +1099,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_html(
|
||||
|
@ -1047,6 +1115,7 @@ class Message(TelegramObject):
|
|||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1084,6 +1153,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_media_group(
|
||||
|
@ -1098,6 +1168,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> List['Message']:
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1127,6 +1198,7 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_photo(
|
||||
|
@ -1144,6 +1216,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1176,6 +1249,7 @@ class Message(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_audio(
|
||||
|
@ -1197,6 +1271,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1233,6 +1308,7 @@ class Message(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_document(
|
||||
|
@ -1252,6 +1328,7 @@ class Message(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1286,6 +1363,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_animation(
|
||||
|
@ -1307,6 +1385,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1343,6 +1422,7 @@ class Message(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_sticker(
|
||||
|
@ -1356,6 +1436,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1384,6 +1465,7 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_video(
|
||||
|
@ -1406,6 +1488,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1443,6 +1526,7 @@ class Message(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_video_note(
|
||||
|
@ -1460,6 +1544,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1492,6 +1577,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_voice(
|
||||
|
@ -1510,6 +1596,7 @@ class Message(TelegramObject):
|
|||
filename: str = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1543,6 +1630,7 @@ class Message(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_location(
|
||||
|
@ -1562,6 +1650,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1596,6 +1685,7 @@ class Message(TelegramObject):
|
|||
proximity_alert_radius=proximity_alert_radius,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_venue(
|
||||
|
@ -1617,6 +1707,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1653,6 +1744,7 @@ class Message(TelegramObject):
|
|||
google_place_type=google_place_type,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_contact(
|
||||
|
@ -1670,6 +1762,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1702,6 +1795,7 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_poll(
|
||||
|
@ -1726,6 +1820,7 @@ class Message(TelegramObject):
|
|||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1765,6 +1860,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
explanation_entities=explanation_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_dice(
|
||||
|
@ -1778,6 +1874,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1806,6 +1903,7 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_chat_action(
|
||||
|
@ -1844,6 +1942,7 @@ class Message(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1874,6 +1973,7 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_invoice(
|
||||
|
@ -1907,6 +2007,7 @@ class Message(TelegramObject):
|
|||
max_tip_amount: int = None,
|
||||
suggested_tip_amounts: List[int] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1965,6 +2066,7 @@ class Message(TelegramObject):
|
|||
max_tip_amount=max_tip_amount,
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def forward(
|
||||
|
@ -1974,6 +2076,7 @@ class Message(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -2005,6 +2108,7 @@ class Message(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def copy(
|
||||
|
@ -2020,6 +2124,7 @@ class Message(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -2049,6 +2154,7 @@ class Message(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def reply_copy(
|
||||
|
@ -2066,6 +2172,7 @@ class Message(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
quote: bool = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -2104,6 +2211,7 @@ class Message(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def edit_text(
|
||||
|
@ -2517,6 +2625,145 @@ class Message(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_forum_topic(
|
||||
self,
|
||||
name: str,
|
||||
icon_custom_emoji_id: str,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.edit_forum_topic(
|
||||
chat_id=message.chat_id, message_thread_id=message.message_thread_id, *args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.edit_forum_topic(
|
||||
chat_id=self.chat_id,
|
||||
message_thread_id=self.message_thread_id,
|
||||
name=name,
|
||||
icon_custom_emoji_id=icon_custom_emoji_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def close_forum_topic(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.close_forum_topic(
|
||||
chat_id=message.chat_id, message_thread_id=message.message_thread_id, *args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.close_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.close_forum_topic(
|
||||
chat_id=self.chat_id,
|
||||
message_thread_id=self.message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def reopen_forum_topic(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.reopen_forum_topic(
|
||||
chat_id=message.chat_id, message_thread_id=message.message_thread_id, *args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.reopen_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.reopen_forum_topic(
|
||||
chat_id=self.chat_id,
|
||||
message_thread_id=self.message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def delete_forum_topic(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.delete_forum_topic(
|
||||
chat_id=message.chat_id, message_thread_id=message.message_thread_id, *args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.delete_forum_topic`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.delete_forum_topic(
|
||||
chat_id=self.chat_id,
|
||||
message_thread_id=self.message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def unpin_all_forum_topic_messages(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.unpin_all_forum_topic_messages(
|
||||
chat_id=message.chat_id, message_thread_id=message.message_thread_id, *args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.unpin_all_forum_topic_messages`.
|
||||
|
||||
.. versionadded:: 13.15
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return self.bot.unpin_all_forum_topic_messages(
|
||||
chat_id=self.chat_id,
|
||||
message_thread_id=self.message_thread_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def parse_entity(self, entity: MessageEntity) -> str:
|
||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
|
||||
|
|
|
@ -360,6 +360,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -384,6 +385,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_photo(
|
||||
|
@ -400,6 +402,7 @@ class User(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -425,6 +428,7 @@ class User(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_media_group(
|
||||
|
@ -438,6 +442,7 @@ class User(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> List['Message']:
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -458,6 +463,7 @@ class User(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_audio(
|
||||
|
@ -478,6 +484,7 @@ class User(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -507,6 +514,7 @@ class User(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_chat_action(
|
||||
|
@ -549,6 +557,7 @@ class User(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -574,6 +583,7 @@ class User(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_dice(
|
||||
|
@ -586,6 +596,7 @@ class User(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -607,6 +618,7 @@ class User(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_document(
|
||||
|
@ -625,6 +637,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -652,6 +665,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_game(
|
||||
|
@ -664,6 +678,7 @@ class User(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -685,6 +700,7 @@ class User(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_invoice(
|
||||
|
@ -717,6 +733,7 @@ class User(TelegramObject):
|
|||
max_tip_amount: int = None,
|
||||
suggested_tip_amounts: List[int] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -766,6 +783,7 @@ class User(TelegramObject):
|
|||
max_tip_amount=max_tip_amount,
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_location(
|
||||
|
@ -784,6 +802,7 @@ class User(TelegramObject):
|
|||
proximity_alert_radius: int = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -811,6 +830,7 @@ class User(TelegramObject):
|
|||
proximity_alert_radius=proximity_alert_radius,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_animation(
|
||||
|
@ -831,6 +851,7 @@ class User(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -860,6 +881,7 @@ class User(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_sticker(
|
||||
|
@ -872,6 +894,7 @@ class User(TelegramObject):
|
|||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -893,6 +916,7 @@ class User(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_video(
|
||||
|
@ -914,6 +938,7 @@ class User(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -944,6 +969,7 @@ class User(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_venue(
|
||||
|
@ -964,6 +990,7 @@ class User(TelegramObject):
|
|||
google_place_type: str = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -993,6 +1020,7 @@ class User(TelegramObject):
|
|||
google_place_type=google_place_type,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_video_note(
|
||||
|
@ -1009,6 +1037,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1034,6 +1063,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_voice(
|
||||
|
@ -1051,6 +1081,7 @@ class User(TelegramObject):
|
|||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1077,6 +1108,7 @@ class User(TelegramObject):
|
|||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_poll(
|
||||
|
@ -1101,6 +1133,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1133,6 +1166,7 @@ class User(TelegramObject):
|
|||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
explanation_entities=explanation_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def send_copy(
|
||||
|
@ -1149,6 +1183,7 @@ class User(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1174,6 +1209,7 @@ class User(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def copy_message(
|
||||
|
@ -1190,6 +1226,7 @@ class User(TelegramObject):
|
|||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
protect_content: bool = None,
|
||||
message_thread_id: int = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1215,6 +1252,7 @@ class User(TelegramObject):
|
|||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
def approve_join_request(
|
||||
|
|
|
@ -29,15 +29,16 @@ from telegram.error import RetryAfter, TimedOut
|
|||
# These bots are only able to talk in our test chats, so they are quite useless for other
|
||||
# purposes than testing.
|
||||
FALLBACKS = (
|
||||
'W3sidG9rZW4iOiAiNTc5Njk0NzE0OkFBRnBLOHc2emtrVXJENHhTZVl3RjNNTzhlLTRHcm1jeTdjIiwgInBheW1lbnRfc'
|
||||
'HJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpRME5qWmxOekk1WWpKaSIsICJjaGF0X2lkIjogIjY3NTY2Nj'
|
||||
'IyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTMxMDkxMTEzNSIsICJjaGFubmVsX2lkIjogIkBweXRob250ZWxlZ3J'
|
||||
'hbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAxIiwgImJvdF91c2VybmFtZSI6ICJAcHRi'
|
||||
'X2ZhbGxiYWNrXzFfYm90In0sIHsidG9rZW4iOiAiNTU4MTk0MDY2OkFBRndEUElGbHpHVWxDYVdIdFRPRVg0UkZyWDh1O'
|
||||
'URNcWZvIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WWpFd09EUXdNVEZtTkRjeSIsIC'
|
||||
'JjaGF0X2lkIjogIjY3NTY2NjIyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTIyMTIxNjgzMCIsICJjaGFubmVsX2l'
|
||||
'kIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAyIiwgImJv'
|
||||
'dF91c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzJfYm90In1d'
|
||||
"W3sidG9rZW4iOiAiNTc5Njk0NzE0OkFBRnBLOHc2emtrVXJENHhTZVl3RjNNTzhlLTRHcm1jeTdjIiwgInBheW1lbnRfc"
|
||||
"HJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpRME5qWmxOekk1WWpKaSIsICJjaGF0X2lkIjogIjY3NTY2Nj"
|
||||
"IyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTMxMDkxMTEzNSIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTYxOTE"
|
||||
"1OTQwNCIsICJjaGFubmVsX2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0"
|
||||
"cyBmYWxsYmFjayAxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzFfYm90In0sIHsidG9rZW4iOiAiNTU4M"
|
||||
"Tk0MDY2OkFBRndEUElGbHpHVWxDYVdIdFRPRVg0UkZyWDh1OURNcWZvIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOi"
|
||||
"AiMjg0Njg1MDYzOlRFU1Q6WWpFd09EUXdNVEZtTkRjeSIsICJjaGF0X2lkIjogIjY3NTY2NjIyNCIsICJzdXBlcl9ncm9"
|
||||
"1cF9pZCI6ICItMTAwMTIyMTIxNjgzMCIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTYxOTE1OTQwNCIsICJjaGFubmVs"
|
||||
"X2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAyIiwgI"
|
||||
"mJvdF91c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzJfYm90In1d "
|
||||
)
|
||||
|
||||
GITHUB_ACTION = os.getenv('GITHUB_ACTION', None)
|
||||
|
|
|
@ -138,6 +138,11 @@ def super_group_id(bot_info):
|
|||
return bot_info['super_group_id']
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def forum_group_id(bot_info):
|
||||
return int(bot_info["forum_group_id"])
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def channel_id(bot_info):
|
||||
return bot_info['channel_id']
|
||||
|
|
|
@ -1851,6 +1851,7 @@ class TestBot:
|
|||
can_promote_members=True,
|
||||
can_manage_chat=True,
|
||||
can_manage_voice_chats=True,
|
||||
can_manage_topics=True,
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
|
@ -1892,6 +1893,7 @@ class TestBot:
|
|||
and data.get('can_promote_members') == 9
|
||||
and data.get('can_manage_chat') == 10
|
||||
and data.get('can_manage_video_chats') == 11
|
||||
and data.get("can_manage_topics") == 12
|
||||
)
|
||||
|
||||
monkeypatch.setattr(bot, '_post', make_assertion)
|
||||
|
@ -1909,6 +1911,7 @@ class TestBot:
|
|||
can_promote_members=9,
|
||||
can_manage_chat=10,
|
||||
can_manage_voice_chats=11,
|
||||
can_manage_topics=12,
|
||||
)
|
||||
|
||||
# Test that video_chats also works
|
||||
|
@ -2172,6 +2175,9 @@ class TestBot:
|
|||
# set_sticker_position_in_set, delete_sticker_from_set and get_custom_emoji_stickers
|
||||
# are tested in the test_sticker module.
|
||||
|
||||
# get_forum_topic_icon_stickers, edit_forum_topic, etc...
|
||||
# are tested in the test_forum module.
|
||||
|
||||
def test_timeout_propagation_explicit(self, monkeypatch, bot, chat_id):
|
||||
|
||||
from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout
|
||||
|
@ -2307,6 +2313,7 @@ class TestBot:
|
|||
assert my_admin_rights_ch.can_promote_members is my_rights.can_promote_members
|
||||
assert my_admin_rights_ch.can_restrict_members is my_rights.can_restrict_members
|
||||
assert my_admin_rights_ch.can_pin_messages is None # Not returned for channels
|
||||
assert my_admin_rights_ch.can_manage_topics is None # Not returned for channels
|
||||
|
||||
def test_get_set_chat_menu_button(self, bot, chat_id):
|
||||
# Test our chat menu button is commands-
|
||||
|
@ -2440,6 +2447,7 @@ class TestBot:
|
|||
assert data["disable_notification"] is True
|
||||
assert data["caption_entities"] == [MessageEntity(MessageEntity.BOLD, 0, 4)]
|
||||
assert data['protect_content'] is True
|
||||
assert data["message_thread_id"] == 1
|
||||
return data
|
||||
|
||||
monkeypatch.setattr(bot.request, 'post', post)
|
||||
|
@ -2454,6 +2462,7 @@ class TestBot:
|
|||
reply_markup=keyboard.to_json() if json_keyboard else keyboard,
|
||||
disable_notification=True,
|
||||
protect_content=True,
|
||||
message_thread_id=1,
|
||||
)
|
||||
|
||||
@flaky(3, 1)
|
||||
|
|
|
@ -46,6 +46,9 @@ def chat(bot):
|
|||
join_to_send_messages=True,
|
||||
join_by_request=True,
|
||||
has_restricted_voice_and_video_messages=True,
|
||||
is_forum=True,
|
||||
active_usernames=TestChat.active_usernames,
|
||||
emoji_status_custom_emoji_id=TestChat.emoji_status_custom_emoji_id,
|
||||
)
|
||||
|
||||
|
||||
|
@ -72,6 +75,9 @@ class TestChat:
|
|||
join_to_send_messages = True
|
||||
join_by_request = True
|
||||
has_restricted_voice_and_video_messages = True
|
||||
is_forum = True
|
||||
active_usernames = ["These", "Are", "Usernames!"]
|
||||
emoji_status_custom_emoji_id = "VeryUniqueCustomEmojiID"
|
||||
|
||||
def test_slot_behaviour(self, chat, recwarn, mro_slots):
|
||||
for attr in chat.__slots__:
|
||||
|
@ -103,6 +109,9 @@ class TestChat:
|
|||
'has_restricted_voice_and_video_messages': (
|
||||
self.has_restricted_voice_and_video_messages
|
||||
),
|
||||
"is_forum": self.is_forum,
|
||||
"active_usernames": self.active_usernames,
|
||||
"emoji_status_custom_emoji_id": self.emoji_status_custom_emoji_id,
|
||||
}
|
||||
chat = Chat.de_json(json_dict, bot)
|
||||
|
||||
|
@ -128,6 +137,9 @@ class TestChat:
|
|||
chat.has_restricted_voice_and_video_messages
|
||||
== self.has_restricted_voice_and_video_messages
|
||||
)
|
||||
assert chat.is_forum == self.is_forum
|
||||
assert chat.active_usernames == self.active_usernames
|
||||
assert chat.emoji_status_custom_emoji_id == self.emoji_status_custom_emoji_id
|
||||
|
||||
def test_to_dict(self, chat):
|
||||
chat_dict = chat.to_dict()
|
||||
|
@ -152,6 +164,9 @@ class TestChat:
|
|||
chat_dict["has_restricted_voice_and_video_messages"]
|
||||
== chat.has_restricted_voice_and_video_messages
|
||||
)
|
||||
assert chat_dict["is_forum"] == chat.is_forum
|
||||
assert chat_dict["active_usernames"] == chat.active_usernames
|
||||
assert chat_dict["emoji_status_custom_emoji_id"] == chat.emoji_status_custom_emoji_id
|
||||
|
||||
def test_link(self, chat):
|
||||
assert chat.link == f'https://t.me/{chat.username}'
|
||||
|
@ -795,6 +810,128 @@ class TestChat:
|
|||
monkeypatch.setattr(chat.bot, 'decline_chat_join_request', make_assertion)
|
||||
assert chat.decline_join_request(user_id=42)
|
||||
|
||||
def test_create_forum_topic(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == chat.id
|
||||
and kwargs["name"] == "New Name"
|
||||
and kwargs["icon_color"] == 0x6FB9F0
|
||||
and kwargs["icon_custom_emoji_id"] == "12345"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.create_forum_topic, Bot.create_forum_topic, ["chat_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.create_forum_topic,
|
||||
chat.bot,
|
||||
"create_forum_topic",
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert check_defaults_handling(chat.create_forum_topic, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "create_forum_topic", make_assertion)
|
||||
assert chat.create_forum_topic(
|
||||
name="New Name", icon_color=0x6FB9F0, icon_custom_emoji_id="12345"
|
||||
)
|
||||
|
||||
def test_edit_forum_topic(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == chat.id
|
||||
and kwargs["message_thread_id"] == 42
|
||||
and kwargs["name"] == "New Name"
|
||||
and kwargs["icon_custom_emoji_id"] == "12345"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.edit_forum_topic, Bot.edit_forum_topic, ["chat_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.edit_forum_topic, chat.bot, "edit_forum_topic", shortcut_kwargs=["chat_id"]
|
||||
)
|
||||
assert check_defaults_handling(chat.edit_forum_topic, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "edit_forum_topic", make_assertion)
|
||||
assert chat.edit_forum_topic(
|
||||
message_thread_id=42, name="New Name", icon_custom_emoji_id="12345"
|
||||
)
|
||||
|
||||
def test_close_forum_topic(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["message_thread_id"] == 42
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.close_forum_topic, Bot.close_forum_topic, ["chat_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.close_forum_topic,
|
||||
chat.bot,
|
||||
"close_forum_topic",
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert check_defaults_handling(chat.close_forum_topic, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "close_forum_topic", make_assertion)
|
||||
assert chat.close_forum_topic(message_thread_id=42)
|
||||
|
||||
def test_reopen_forum_topic(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["message_thread_id"] == 42
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.reopen_forum_topic, Bot.reopen_forum_topic, ["chat_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.reopen_forum_topic,
|
||||
chat.bot,
|
||||
"reopen_forum_topic",
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert check_defaults_handling(chat.reopen_forum_topic, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "reopen_forum_topic", make_assertion)
|
||||
assert chat.reopen_forum_topic(message_thread_id=42)
|
||||
|
||||
def test_delete_forum_topic(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["message_thread_id"] == 42
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.delete_forum_topic, Bot.delete_forum_topic, ["chat_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.delete_forum_topic,
|
||||
chat.bot,
|
||||
"delete_forum_topic",
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert check_defaults_handling(chat.delete_forum_topic, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "delete_forum_topic", make_assertion)
|
||||
assert chat.delete_forum_topic(message_thread_id=42)
|
||||
|
||||
def test_unpin_all_forum_topic_messages(self, monkeypatch, chat):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["message_thread_id"] == 42
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.unpin_all_forum_topic_messages,
|
||||
Bot.unpin_all_forum_topic_messages,
|
||||
["chat_id"],
|
||||
[],
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
chat.unpin_all_forum_topic_messages,
|
||||
chat.bot,
|
||||
"unpin_all_forum_topic_messages",
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert check_defaults_handling(chat.unpin_all_forum_topic_messages, chat.bot)
|
||||
|
||||
monkeypatch.setattr(chat.bot, "unpin_all_forum_topic_messages", make_assertion)
|
||||
assert chat.unpin_all_forum_topic_messages(message_thread_id=42)
|
||||
|
||||
def test_equality(self):
|
||||
a = Chat(self.id_, self.title, self.type_)
|
||||
b = Chat(self.id_, self.title, self.type_)
|
||||
|
|
|
@ -34,6 +34,7 @@ def chat_admin_rights():
|
|||
can_edit_messages=True,
|
||||
can_manage_chat=True,
|
||||
can_manage_video_chats=True,
|
||||
can_manage_topics=True,
|
||||
is_anonymous=True,
|
||||
)
|
||||
|
||||
|
@ -57,6 +58,7 @@ class TestChatAdministratorRights:
|
|||
'can_edit_messages': True,
|
||||
'can_manage_chat': True,
|
||||
'can_manage_video_chats': True,
|
||||
"can_manage_topics": True,
|
||||
'is_anonymous': True,
|
||||
}
|
||||
chat_administrator_rights_de = ChatAdministratorRights.de_json(json_dict, bot)
|
||||
|
@ -79,13 +81,14 @@ class TestChatAdministratorRights:
|
|||
assert admin_rights_dict['can_manage_chat'] == car.can_manage_chat
|
||||
assert admin_rights_dict['is_anonymous'] == car.is_anonymous
|
||||
assert admin_rights_dict['can_manage_video_chats'] == car.can_manage_video_chats
|
||||
assert admin_rights_dict["can_manage_topics"] == car.can_manage_topics
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatAdministratorRights(True, False, False, False, False, False, False, False)
|
||||
b = ChatAdministratorRights(True, False, False, False, False, False, False, False)
|
||||
c = ChatAdministratorRights(False, False, False, False, False, False, False, False)
|
||||
d = ChatAdministratorRights(True, True, False, False, False, False, False, False)
|
||||
e = ChatAdministratorRights(True, True, False, False, False, False, False, False)
|
||||
a = ChatAdministratorRights(True, False, False, False, False, False, False, False, False)
|
||||
b = ChatAdministratorRights(True, False, False, False, False, False, False, False, False)
|
||||
c = ChatAdministratorRights(False, False, False, False, False, False, False, False, False)
|
||||
d = ChatAdministratorRights(True, True, False, False, False, False, False, False, False)
|
||||
e = ChatAdministratorRights(True, True, False, False, False, False, False, False, False)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
@ -101,7 +104,7 @@ class TestChatAdministratorRights:
|
|||
assert hash(d) == hash(e)
|
||||
|
||||
def test_all_rights(self):
|
||||
f = ChatAdministratorRights(True, True, True, True, True, True, True, True)
|
||||
f = ChatAdministratorRights(True, True, True, True, True, True, True, True, True)
|
||||
t = ChatAdministratorRights.all_rights()
|
||||
# if the dirs are the same, the attributes will all be there
|
||||
assert dir(f) == dir(t)
|
||||
|
@ -116,7 +119,7 @@ class TestChatAdministratorRights:
|
|||
assert f != t
|
||||
|
||||
def test_no_rights(self):
|
||||
f = ChatAdministratorRights(False, False, False, False, False, False, False, False)
|
||||
f = ChatAdministratorRights(False, False, False, False, False, False, False, False, False)
|
||||
t = ChatAdministratorRights.no_rights()
|
||||
# if the dirs are the same, the attributes will all be there
|
||||
assert dir(f) == dir(t)
|
||||
|
|
|
@ -120,6 +120,7 @@ class TestChatMember:
|
|||
'can_add_web_page_previews': False,
|
||||
'can_manage_chat': True,
|
||||
'can_manage_voice_chats': True,
|
||||
'can_manage_topics': True,
|
||||
}
|
||||
chat_member_type = ChatMember.de_json(json_dict, bot)
|
||||
|
||||
|
@ -221,6 +222,7 @@ class TestChatMember:
|
|||
'can_add_web_page_previews': False,
|
||||
'can_manage_chat': True,
|
||||
'can_manage_video_chats': True,
|
||||
'can_manage_topics': True,
|
||||
}
|
||||
assert type(cls.de_json(json_dict, bot)) is cls
|
||||
|
||||
|
|
|
@ -969,6 +969,21 @@ class TestFilters:
|
|||
assert Filters.status_update.web_app_data(update)
|
||||
update.message.web_app_data = None
|
||||
|
||||
update.message.forum_topic_created = "topic"
|
||||
assert Filters.status_update(update)
|
||||
assert Filters.status_update.forum_topic_created(update)
|
||||
update.message.forum_topic_created = None
|
||||
|
||||
update.message.forum_topic_closed = "topic"
|
||||
assert Filters.status_update(update)
|
||||
assert Filters.status_update.forum_topic_closed(update)
|
||||
update.message.forum_topic_closed = None
|
||||
|
||||
update.message.forum_topic_reopened = "topic"
|
||||
assert Filters.status_update(update)
|
||||
assert Filters.status_update.forum_topic_reopened(update)
|
||||
update.message.forum_topic_reopened = None
|
||||
|
||||
def test_filters_forwarded(self, update):
|
||||
assert not Filters.forwarded(update)
|
||||
update.message.forward_date = datetime.datetime.utcnow()
|
||||
|
@ -1762,6 +1777,11 @@ class TestFilters:
|
|||
update.message.is_automatic_forward = True
|
||||
assert Filters.is_automatic_forward(update)
|
||||
|
||||
def test_filters_is_topic_message(self, update):
|
||||
assert not Filters.is_topic_message(update)
|
||||
update.message.is_topic_message = True
|
||||
assert Filters.is_topic_message(update)
|
||||
|
||||
def test_filters_has_protected_content(self, update):
|
||||
assert not Filters.has_protected_content(update)
|
||||
update.message.has_protected_content = True
|
||||
|
|
331
tests/test_forum.py
Normal file
331
tests/test_forum.py
Normal file
|
@ -0,0 +1,331 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2022
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# 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/].
|
||||
import pytest
|
||||
|
||||
from telegram import ForumTopic, ForumTopicClosed, ForumTopicCreated, ForumTopicReopened, Sticker
|
||||
|
||||
TEST_MSG_TEXT = "Topics are forever"
|
||||
TEST_TOPIC_ICON_COLOR = 0x6FB9F0
|
||||
TEST_TOPIC_NAME = "Sad bot true: real stories"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def emoji_id(bot):
|
||||
emoji_sticker_list = bot.get_forum_topic_icon_stickers()
|
||||
first_sticker = emoji_sticker_list[0]
|
||||
return first_sticker.custom_emoji_id
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def forum_topic_object(forum_group_id, emoji_id):
|
||||
return ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def real_topic(bot, emoji_id, forum_group_id):
|
||||
result = bot.create_forum_topic(
|
||||
chat_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
)
|
||||
|
||||
yield result
|
||||
|
||||
result = bot.delete_forum_topic(
|
||||
chat_id=forum_group_id, message_thread_id=result.message_thread_id
|
||||
)
|
||||
assert result is True, "Topic was not deleted"
|
||||
|
||||
|
||||
class TestForumTopic:
|
||||
def test_slot_behaviour(self, mro_slots, forum_topic_object):
|
||||
for attr in forum_topic_object.__slots__:
|
||||
assert getattr(forum_topic_object, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(forum_topic_object)) == len(
|
||||
set(mro_slots(forum_topic_object))
|
||||
), "duplicate slot"
|
||||
|
||||
def test_expected_values(self, emoji_id, forum_group_id, forum_topic_object):
|
||||
assert forum_topic_object.message_thread_id == forum_group_id
|
||||
assert forum_topic_object.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert forum_topic_object.name == TEST_TOPIC_NAME
|
||||
assert forum_topic_object.icon_custom_emoji_id == emoji_id
|
||||
|
||||
def test_de_json(self, bot, emoji_id, forum_group_id):
|
||||
assert ForumTopic.de_json(None, bot=bot) is None
|
||||
|
||||
json_dict = {
|
||||
"message_thread_id": forum_group_id,
|
||||
"name": TEST_TOPIC_NAME,
|
||||
"icon_color": TEST_TOPIC_ICON_COLOR,
|
||||
"icon_custom_emoji_id": emoji_id,
|
||||
}
|
||||
topic = ForumTopic.de_json(json_dict, bot)
|
||||
|
||||
assert topic.message_thread_id == forum_group_id
|
||||
assert topic.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert topic.name == TEST_TOPIC_NAME
|
||||
assert topic.icon_custom_emoji_id == emoji_id
|
||||
|
||||
def test_to_dict(self, emoji_id, forum_group_id, forum_topic_object):
|
||||
topic_dict = forum_topic_object.to_dict()
|
||||
|
||||
assert isinstance(topic_dict, dict)
|
||||
assert topic_dict["message_thread_id"] == forum_group_id
|
||||
assert topic_dict["name"] == TEST_TOPIC_NAME
|
||||
assert topic_dict["icon_color"] == TEST_TOPIC_ICON_COLOR
|
||||
assert topic_dict["icon_custom_emoji_id"] == emoji_id
|
||||
|
||||
def test_equality(self, emoji_id, forum_group_id):
|
||||
a = ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
)
|
||||
b = ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
)
|
||||
c = ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=f"{TEST_TOPIC_NAME}!",
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
)
|
||||
d = ForumTopic(
|
||||
message_thread_id=forum_group_id + 1,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
)
|
||||
e = ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=0xFFD67E,
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
@pytest.mark.flaky(3, 1)
|
||||
def test_create_forum_topic(self, real_topic):
|
||||
result = real_topic
|
||||
assert isinstance(result, ForumTopic)
|
||||
assert result.name == TEST_TOPIC_NAME
|
||||
assert result.message_thread_id
|
||||
assert isinstance(result.icon_color, int)
|
||||
assert isinstance(result.icon_custom_emoji_id, str)
|
||||
|
||||
def test_create_forum_topic_with_only_required_args(self, bot, forum_group_id):
|
||||
result = bot.create_forum_topic(chat_id=forum_group_id, name=TEST_TOPIC_NAME)
|
||||
assert isinstance(result, ForumTopic)
|
||||
assert result.name == TEST_TOPIC_NAME
|
||||
assert result.message_thread_id
|
||||
assert isinstance(result.icon_color, int) # color is still there though it was not passed
|
||||
assert result.icon_custom_emoji_id is None
|
||||
|
||||
result = bot.delete_forum_topic(
|
||||
chat_id=forum_group_id, message_thread_id=result.message_thread_id
|
||||
)
|
||||
assert result is True, "Failed to delete forum topic"
|
||||
|
||||
@pytest.mark.flaky(3, 1)
|
||||
def test_get_forum_topic_icon_stickers(self, bot):
|
||||
emoji_sticker_list = bot.get_forum_topic_icon_stickers()
|
||||
first_sticker = emoji_sticker_list[0]
|
||||
|
||||
assert first_sticker.emoji == "📰"
|
||||
assert first_sticker.height == 512
|
||||
assert first_sticker.width == 512
|
||||
assert first_sticker.is_animated
|
||||
assert not first_sticker.is_video
|
||||
assert first_sticker.set_name == "Topics"
|
||||
assert first_sticker.type == Sticker.CUSTOM_EMOJI
|
||||
assert first_sticker.thumb.width == 128
|
||||
assert first_sticker.thumb.height == 128
|
||||
|
||||
# The following data of first item returned has changed in the past already,
|
||||
# so check sizes loosely and ID's only by length of string
|
||||
assert first_sticker.thumb.file_size in range(2000, 7000)
|
||||
assert first_sticker.file_size in range(20000, 70000)
|
||||
assert len(first_sticker.custom_emoji_id) == 19
|
||||
assert len(first_sticker.thumb.file_unique_id) == 16
|
||||
assert len(first_sticker.file_unique_id) == 15
|
||||
|
||||
def test_edit_forum_topic(self, emoji_id, forum_group_id, bot, real_topic):
|
||||
result = bot.edit_forum_topic(
|
||||
chat_id=forum_group_id,
|
||||
message_thread_id=real_topic.message_thread_id,
|
||||
name=f"{TEST_TOPIC_NAME}_EDITED",
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
)
|
||||
assert result is True, "Failed to edit forum topic"
|
||||
# no way of checking the edited name, just the boolean result
|
||||
|
||||
@pytest.mark.flaky(3, 1)
|
||||
def test_send_message_to_topic(self, bot, forum_group_id, real_topic):
|
||||
message_thread_id = real_topic.message_thread_id
|
||||
|
||||
message = bot.send_message(
|
||||
chat_id=forum_group_id, text=TEST_MSG_TEXT, message_thread_id=message_thread_id
|
||||
)
|
||||
|
||||
assert message.text == TEST_MSG_TEXT
|
||||
assert message.is_topic_message is True
|
||||
assert message.message_thread_id == message_thread_id
|
||||
|
||||
def test_close_and_reopen_forum_topic(self, bot, forum_group_id, real_topic):
|
||||
message_thread_id = real_topic.message_thread_id
|
||||
|
||||
result = bot.close_forum_topic(
|
||||
chat_id=forum_group_id,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
assert result is True, "Failed to close forum topic"
|
||||
# bot will still be able to send a message to a closed topic, so can't test anything like
|
||||
# the inability to post to the topic
|
||||
|
||||
result = bot.reopen_forum_topic(
|
||||
chat_id=forum_group_id,
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
assert result is True, "Failed to reopen forum topic"
|
||||
|
||||
@pytest.mark.xfail(reason="Can fail due to race conditions in GH actions CI")
|
||||
def test_unpin_all_forum_topic_messages(self, bot, forum_group_id, real_topic):
|
||||
message_thread_id = real_topic.message_thread_id
|
||||
|
||||
msgs = [
|
||||
(
|
||||
bot.send_message(
|
||||
chat_id=forum_group_id, text=TEST_MSG_TEXT, message_thread_id=message_thread_id
|
||||
)
|
||||
).pin()
|
||||
for _ in range(2)
|
||||
]
|
||||
|
||||
assert all(msgs) is True, "Message(s) were not pinned"
|
||||
|
||||
# We need 2 or more pinned msgs for this to work, else we get Chat_not_modified error
|
||||
result = bot.unpin_all_forum_topic_messages(
|
||||
chat_id=forum_group_id, message_thread_id=message_thread_id
|
||||
)
|
||||
assert result is True, "Failed to unpin all the messages in forum topic"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def topic_created():
|
||||
return ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR)
|
||||
|
||||
|
||||
class TestForumTopicCreated:
|
||||
def test_slot_behaviour(self, topic_created, mro_slots):
|
||||
for attr in topic_created.__slots__:
|
||||
assert getattr(topic_created, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(topic_created)) == len(
|
||||
set(mro_slots(topic_created))
|
||||
), "duplicate slot"
|
||||
|
||||
def test_expected_values(self, topic_created):
|
||||
assert topic_created.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert topic_created.name == TEST_TOPIC_NAME
|
||||
|
||||
def test_de_json(self, bot):
|
||||
assert ForumTopicCreated.de_json(None, bot=bot) is None
|
||||
|
||||
json_dict = {"icon_color": TEST_TOPIC_ICON_COLOR, "name": TEST_TOPIC_NAME}
|
||||
action = ForumTopicCreated.de_json(json_dict, bot)
|
||||
|
||||
assert action.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert action.name == TEST_TOPIC_NAME
|
||||
|
||||
def test_to_dict(self, topic_created):
|
||||
action_dict = topic_created.to_dict()
|
||||
|
||||
assert isinstance(action_dict, dict)
|
||||
assert action_dict["name"] == TEST_TOPIC_NAME
|
||||
assert action_dict["icon_color"] == TEST_TOPIC_ICON_COLOR
|
||||
|
||||
def test_equality(self, emoji_id):
|
||||
a = ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR)
|
||||
b = ForumTopicCreated(
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
)
|
||||
c = ForumTopicCreated(name=f"{TEST_TOPIC_NAME}!", icon_color=TEST_TOPIC_ICON_COLOR)
|
||||
d = ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=0xFFD67E)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
|
||||
class TestForumTopicClosed:
|
||||
def test_slot_behaviour(self, mro_slots):
|
||||
action = ForumTopicClosed()
|
||||
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):
|
||||
action = ForumTopicClosed.de_json({}, None)
|
||||
assert isinstance(action, ForumTopicClosed)
|
||||
|
||||
def test_to_dict(self):
|
||||
action = ForumTopicClosed()
|
||||
action_dict = action.to_dict()
|
||||
assert action_dict == {}
|
||||
|
||||
|
||||
class TestForumTopicReopened:
|
||||
def test_slot_behaviour(self, mro_slots):
|
||||
action = ForumTopicReopened()
|
||||
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):
|
||||
action = ForumTopicReopened.de_json({}, None)
|
||||
assert isinstance(action, ForumTopicReopened)
|
||||
|
||||
def test_to_dict(self):
|
||||
action = ForumTopicReopened()
|
||||
action_dict = action.to_dict()
|
||||
assert action_dict == {}
|
|
@ -43,6 +43,9 @@ from .test_audio import audio, audio_file # noqa: F401
|
|||
# noinspection PyUnresolvedReferences
|
||||
from .test_document import document, document_file # noqa: F401
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .test_forum import emoji_id, real_topic # noqa: F401
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .test_photo import _photo, photo_file, photo, thumb # noqa: F401
|
||||
|
||||
|
@ -458,6 +461,19 @@ class TestSendMediaGroup:
|
|||
mes.caption_entities == [MessageEntity(MessageEntity.BOLD, 0, 5)] for mes in messages
|
||||
)
|
||||
|
||||
def test_send_media_group_with_message_thread_id(
|
||||
self, bot, real_topic, forum_group_id, media_group # noqa: F811
|
||||
):
|
||||
messages = bot.send_media_group(
|
||||
forum_group_id,
|
||||
media_group,
|
||||
message_thread_id=real_topic.message_thread_id,
|
||||
)
|
||||
assert isinstance(messages, list)
|
||||
assert len(messages) == 3
|
||||
assert all(isinstance(mes, Message) for mes in messages)
|
||||
assert all(i.message_thread_id == real_topic.message_thread_id for i in messages)
|
||||
|
||||
@flaky(3, 1)
|
||||
def test_send_media_group_all_args(self, bot, chat_id, media_group):
|
||||
m1 = bot.send_message(chat_id, text="test")
|
||||
|
|
|
@ -196,6 +196,7 @@ def message(bot):
|
|||
)
|
||||
},
|
||||
{'web_app_data': WebAppData('some_data', 'some_button_text')},
|
||||
{"message_thread_id": 123},
|
||||
],
|
||||
ids=[
|
||||
'forwarded_user',
|
||||
|
@ -252,6 +253,7 @@ def message(bot):
|
|||
'is_automatic_forward',
|
||||
'has_protected_content',
|
||||
'web_app_data',
|
||||
'message_thread_id',
|
||||
],
|
||||
)
|
||||
def message_params(bot, request):
|
||||
|
@ -1634,6 +1636,122 @@ class TestMessage:
|
|||
finally:
|
||||
message.bot.defaults = None
|
||||
|
||||
def test_edit_forum_topic(self, monkeypatch, message):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == message.chat_id
|
||||
and kwargs["message_thread_id"] == message.message_thread_id
|
||||
and kwargs["name"] == "New Name"
|
||||
and kwargs["icon_custom_emoji_id"] == "12345"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.edit_forum_topic, Bot.edit_forum_topic, ["chat_id", "message_thread_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
message.edit_forum_topic,
|
||||
message.bot,
|
||||
"edit_forum_topic",
|
||||
shortcut_kwargs=["chat_id", "message_thread_id"],
|
||||
)
|
||||
assert check_defaults_handling(message.edit_forum_topic, message.bot)
|
||||
|
||||
monkeypatch.setattr(message.bot, "edit_forum_topic", make_assertion)
|
||||
assert message.edit_forum_topic(name="New Name", icon_custom_emoji_id="12345")
|
||||
|
||||
def test_close_forum_topic(self, monkeypatch, message):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == message.chat_id
|
||||
and kwargs["message_thread_id"] == message.message_thread_id
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.close_forum_topic, Bot.close_forum_topic, ["chat_id", "message_thread_id"], []
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
message.close_forum_topic,
|
||||
message.bot,
|
||||
"close_forum_topic",
|
||||
shortcut_kwargs=["chat_id", "message_thread_id"],
|
||||
)
|
||||
assert check_defaults_handling(message.close_forum_topic, message.bot)
|
||||
|
||||
monkeypatch.setattr(message.bot, "close_forum_topic", make_assertion)
|
||||
assert message.close_forum_topic()
|
||||
|
||||
def test_reopen_forum_topic(self, monkeypatch, message):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == message.chat_id
|
||||
and kwargs["message_thread_id"] == message.message_thread_id
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.reopen_forum_topic,
|
||||
Bot.reopen_forum_topic,
|
||||
["chat_id", "message_thread_id"],
|
||||
[],
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
message.reopen_forum_topic,
|
||||
message.bot,
|
||||
"reopen_forum_topic",
|
||||
shortcut_kwargs=["chat_id", "message_thread_id"],
|
||||
)
|
||||
assert check_defaults_handling(message.reopen_forum_topic, message.bot)
|
||||
|
||||
monkeypatch.setattr(message.bot, "reopen_forum_topic", make_assertion)
|
||||
assert message.reopen_forum_topic()
|
||||
|
||||
def test_delete_forum_topic(self, monkeypatch, message):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == message.chat_id
|
||||
and kwargs["message_thread_id"] == message.message_thread_id
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.delete_forum_topic,
|
||||
Bot.delete_forum_topic,
|
||||
["chat_id", "message_thread_id"],
|
||||
[],
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
message.delete_forum_topic,
|
||||
message.bot,
|
||||
"delete_forum_topic",
|
||||
shortcut_kwargs=["chat_id", "message_thread_id"],
|
||||
)
|
||||
assert check_defaults_handling(message.delete_forum_topic, message.bot)
|
||||
|
||||
monkeypatch.setattr(message.bot, "delete_forum_topic", make_assertion)
|
||||
assert message.delete_forum_topic()
|
||||
|
||||
def test_unpin_all_forum_topic_messages(self, monkeypatch, message):
|
||||
def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == message.chat_id
|
||||
and kwargs["message_thread_id"] == message.message_thread_id
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.unpin_all_forum_topic_messages,
|
||||
Bot.unpin_all_forum_topic_messages,
|
||||
["chat_id", "message_thread_id"],
|
||||
[],
|
||||
)
|
||||
assert check_shortcut_call(
|
||||
message.unpin_all_forum_topic_messages,
|
||||
message.bot,
|
||||
"unpin_all_forum_topic_messages",
|
||||
shortcut_kwargs=["chat_id", "message_thread_id"],
|
||||
)
|
||||
assert check_defaults_handling(message.unpin_all_forum_topic_messages, message.bot)
|
||||
|
||||
monkeypatch.setattr(message.bot, "unpin_all_forum_topic_messages", make_assertion)
|
||||
assert message.unpin_all_forum_topic_messages()
|
||||
|
||||
def test_equality(self):
|
||||
id_ = 1
|
||||
a = Message(
|
||||
|
|
|
@ -174,6 +174,7 @@ def check_object(h4):
|
|||
'is_anonymous',
|
||||
'is_member',
|
||||
'until_date',
|
||||
'can_manage_topics',
|
||||
}
|
||||
if name == 'BotCommandScope':
|
||||
ignored |= {'type'} # attributes common to all subclasses
|
||||
|
|
Loading…
Reference in a new issue