mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-01-03 09:49:21 +01:00
API 6.5 (#3530)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
This commit is contained in:
parent
9953216980
commit
23a685335b
33 changed files with 1228 additions and 35 deletions
|
@ -14,7 +14,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.4-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.5-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **6.4** are supported.
|
||||
All types and methods of the Telegram Bot API **6.5** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.4-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.5-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **6.4** are supported.
|
||||
All types and methods of the Telegram Bot API **6.5** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
|
|
@ -31,6 +31,7 @@ Available Types
|
|||
telegram.chatmemberupdated
|
||||
telegram.chatpermissions
|
||||
telegram.chatphoto
|
||||
telegram.chatshared
|
||||
telegram.contact
|
||||
telegram.dice
|
||||
telegram.document
|
||||
|
@ -54,6 +55,8 @@ Available Types
|
|||
telegram.inputmediavideo
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
telegram.keyboardbuttonrequestchat
|
||||
telegram.keyboardbuttonrequestuser
|
||||
telegram.location
|
||||
telegram.loginurl
|
||||
telegram.menubutton
|
||||
|
@ -76,6 +79,7 @@ Available Types
|
|||
telegram.update
|
||||
telegram.user
|
||||
telegram.userprofilephotos
|
||||
telegram.usershared
|
||||
telegram.venue
|
||||
telegram.video
|
||||
telegram.videochatended
|
||||
|
|
6
docs/source/telegram.chatshared.rst
Normal file
6
docs/source/telegram.chatshared.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
ChatShared
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.ChatShared
|
||||
:members:
|
||||
:show-inheritance:
|
6
docs/source/telegram.keyboardbuttonrequestchat.rst
Normal file
6
docs/source/telegram.keyboardbuttonrequestchat.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
KeyboardButtonRequestChat
|
||||
==================================
|
||||
|
||||
.. autoclass:: telegram.KeyboardButtonRequestChat
|
||||
:members:
|
||||
:show-inheritance:
|
6
docs/source/telegram.keyboardbuttonrequestuser.rst
Normal file
6
docs/source/telegram.keyboardbuttonrequestuser.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
KeyboardButtonRequestUser
|
||||
==================================
|
||||
|
||||
.. autoclass:: telegram.KeyboardButtonRequestUser
|
||||
:members:
|
||||
:show-inheritance:
|
6
docs/source/telegram.usershared.rst
Normal file
6
docs/source/telegram.usershared.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
UserShared
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.UserShared
|
||||
:members:
|
||||
:show-inheritance:
|
|
@ -54,6 +54,7 @@ __all__ = ( # Keep this alphabetically ordered
|
|||
"ChatMemberUpdated",
|
||||
"ChatPermissions",
|
||||
"ChatPhoto",
|
||||
"ChatShared",
|
||||
"ChosenInlineResult",
|
||||
"constants",
|
||||
"Contact",
|
||||
|
@ -118,6 +119,8 @@ __all__ = ( # Keep this alphabetically ordered
|
|||
"Invoice",
|
||||
"KeyboardButton",
|
||||
"KeyboardButtonPollType",
|
||||
"KeyboardButtonRequestChat",
|
||||
"KeyboardButtonRequestUser",
|
||||
"LabeledPrice",
|
||||
"Location",
|
||||
"LoginUrl",
|
||||
|
@ -167,6 +170,7 @@ __all__ = ( # Keep this alphabetically ordered
|
|||
"Update",
|
||||
"User",
|
||||
"UserProfilePhotos",
|
||||
"UserShared",
|
||||
"Venue",
|
||||
"Video",
|
||||
"VideoChatEnded",
|
||||
|
@ -282,6 +286,7 @@ from ._inline.inputtextmessagecontent import InputTextMessageContent
|
|||
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
|
||||
from ._keyboardbutton import KeyboardButton
|
||||
from ._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||
from ._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||
from ._loginurl import LoginUrl
|
||||
from ._menubutton import MenuButton, MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
|
||||
from ._message import Message
|
||||
|
@ -325,6 +330,7 @@ from ._proximityalerttriggered import ProximityAlertTriggered
|
|||
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
from ._sentwebappmessage import SentWebAppMessage
|
||||
from ._shared import ChatShared, UserShared
|
||||
from ._telegramobject import TelegramObject
|
||||
from ._update import Update
|
||||
from ._user import User
|
||||
|
|
|
@ -4467,6 +4467,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
user_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
until_date: Union[int, datetime] = None,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4493,6 +4494,21 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
used.
|
||||
permissions (:class:`telegram.ChatPermissions`): An object for new user
|
||||
permissions.
|
||||
use_independent_chat_permissions (:obj:`bool`, optional): Pass :obj:`True` if chat
|
||||
permissions are set independently. Otherwise, the
|
||||
:attr:`~telegram.ChatPermissions.can_send_other_messages` and
|
||||
:attr:`~telegram.ChatPermissions.can_add_web_page_previews` permissions will imply
|
||||
the :attr:`~telegram.ChatPermissions.can_send_messages`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_audios`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_documents`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_photos`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_videos`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_video_notes`, and
|
||||
:attr:`~telegram.ChatPermissions.can_send_voice_notes` permissions; the
|
||||
:attr:`~telegram.ChatPermissions.can_send_polls` permission will imply the
|
||||
:attr:`~telegram.ChatPermissions.can_send_messages` permission.
|
||||
|
||||
.. versionadded: 20.1
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
@ -4505,6 +4521,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
"user_id": user_id,
|
||||
"permissions": permissions,
|
||||
"until_date": until_date,
|
||||
"use_independent_chat_permissions": use_independent_chat_permissions,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
|
@ -4633,6 +4650,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
self,
|
||||
chat_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4648,6 +4666,21 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
permissions (:class:`telegram.ChatPermissions`): New default chat permissions.
|
||||
use_independent_chat_permissions (:obj:`bool`, optional): Pass :obj:`True` if chat
|
||||
permissions are set independently. Otherwise, the
|
||||
:attr:`~telegram.ChatPermissions.can_send_other_messages` and
|
||||
:attr:`~telegram.ChatPermissions.can_add_web_page_previews` permissions will imply
|
||||
the :attr:`~telegram.ChatPermissions.can_send_messages`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_audios`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_documents`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_photos`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_videos`,
|
||||
:attr:`~telegram.ChatPermissions.can_send_video_notes`, and
|
||||
:attr:`~telegram.ChatPermissions.can_send_voice_notes` permissions; the
|
||||
:attr:`~telegram.ChatPermissions.can_send_polls` permission will imply the
|
||||
:attr:`~telegram.ChatPermissions.can_send_messages` permission.
|
||||
|
||||
.. versionadded: 20.1
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
@ -4656,7 +4689,11 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {"chat_id": chat_id, "permissions": permissions}
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"permissions": permissions,
|
||||
"use_independent_chat_permissions": use_independent_chat_permissions,
|
||||
}
|
||||
result = await self._post(
|
||||
"setChatPermissions",
|
||||
data,
|
||||
|
|
|
@ -943,6 +943,7 @@ class Chat(TelegramObject):
|
|||
user_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
until_date: Union[int, datetime] = None,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -959,6 +960,9 @@ class Chat(TelegramObject):
|
|||
|
||||
.. versionadded:: 13.2
|
||||
|
||||
.. versionadded:: 20.1
|
||||
Added :paramref:`~telegram.Bot.restrict_chat_member.use_independent_chat_permissions`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
|
@ -968,6 +972,7 @@ class Chat(TelegramObject):
|
|||
user_id=user_id,
|
||||
permissions=permissions,
|
||||
until_date=until_date,
|
||||
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -978,6 +983,7 @@ class Chat(TelegramObject):
|
|||
async def set_permissions(
|
||||
self,
|
||||
permissions: ChatPermissions,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -992,6 +998,9 @@ class Chat(TelegramObject):
|
|||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.set_chat_permissions`.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
Added :paramref:`~telegram.Bot.set_chat_permissions.use_independent_chat_permissions`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
|
@ -999,6 +1008,7 @@ class Chat(TelegramObject):
|
|||
return await self.get_bot().set_chat_permissions(
|
||||
chat_id=self.id,
|
||||
permissions=permissions,
|
||||
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
|
|
@ -39,17 +39,32 @@ class ChatJoinRequest(TelegramObject):
|
|||
considered equal, if their :attr:`chat`, :attr:`from_user` and :attr:`date` are equal.
|
||||
|
||||
Note:
|
||||
Since Bot API 5.5, bots are allowed to contact users who sent a join request to a chat
|
||||
* Since Bot API 5.5, bots are allowed to contact users who sent a join request to a chat
|
||||
where the bot is an administrator with the
|
||||
:attr:`~telegram.ChatMemberAdministrator.can_invite_users` administrator right – even if
|
||||
the user never interacted with the bot before.
|
||||
:attr:`~telegram.ChatMemberAdministrator.can_invite_users` administrator right – even
|
||||
if the user never interacted with the bot before.
|
||||
* Telegram does not guarantee that :attr:`from_user.id <from_user>` coincides with the
|
||||
``chat_id`` of the user. Please use :attr:`user_chat_id` to contact the user in
|
||||
response to their join request.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
.. versionchanged:: 20.1
|
||||
In Bot API 6.5 the argument :paramref:`user_chat_id` was added, which changes the position
|
||||
of the optional arguments :paramref:`bio` and :paramref:`invite_link`.
|
||||
|
||||
Args:
|
||||
chat (:class:`telegram.Chat`): Chat to which the request was sent.
|
||||
from_user (:class:`telegram.User`): User that sent the join request.
|
||||
date (:class:`datetime.datetime`): Date the request was sent.
|
||||
user_chat_id (:obj:`int`): Identifier of a private chat with the user who sent the join
|
||||
request. This number may have more than 32 significant bits and some programming
|
||||
languages may have difficulty/silent defects in interpreting it. But it has at most 52
|
||||
significant bits, so a 64-bit integer or double-precision float type are safe for
|
||||
storing this identifier. The bot can use this identifier for 24 hours to send messages
|
||||
until the join request is processed, assuming no other administrator contacted the
|
||||
user.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
bio (:obj:`str`, optional): Bio of the user.
|
||||
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link that was used
|
||||
by the user to send the join request.
|
||||
|
@ -58,19 +73,29 @@ class ChatJoinRequest(TelegramObject):
|
|||
chat (:class:`telegram.Chat`): Chat to which the request was sent.
|
||||
from_user (:class:`telegram.User`): User that sent the join request.
|
||||
date (:class:`datetime.datetime`): Date the request was sent.
|
||||
user_chat_id (:obj:`int`): Identifier of a private chat with the user who sent the join
|
||||
request. This number may have more than 32 significant bits and some programming
|
||||
languages may have difficulty/silent defects in interpreting it. But it has at most 52
|
||||
significant bits, so a 64-bit integer or double-precision float type are safe for
|
||||
storing this identifier. The bot can use this identifier for 24 hours to send messages
|
||||
until the join request is processed, assuming no other administrator contacted the
|
||||
user.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
bio (:obj:`str`): Optional. Bio of the user.
|
||||
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link that was used
|
||||
by the user to send the join request.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("chat", "from_user", "date", "bio", "invite_link")
|
||||
__slots__ = ("chat", "from_user", "date", "bio", "invite_link", "user_chat_id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
chat: Chat,
|
||||
from_user: User,
|
||||
date: datetime.datetime,
|
||||
user_chat_id: int,
|
||||
bio: str = None,
|
||||
invite_link: ChatInviteLink = None,
|
||||
*,
|
||||
|
@ -81,6 +106,7 @@ class ChatJoinRequest(TelegramObject):
|
|||
self.chat: Chat = chat
|
||||
self.from_user: User = from_user
|
||||
self.date: datetime.datetime = date
|
||||
self.user_chat_id: int = user_chat_id
|
||||
|
||||
# Optionals
|
||||
self.bio: Optional[str] = bio
|
||||
|
|
|
@ -354,8 +354,8 @@ class ChatMemberRestricted(ChatMember):
|
|||
|
||||
.. versionadded:: 13.7
|
||||
.. versionchanged:: 20.0
|
||||
The argument :paramref:`can_manage_topics` was added, which changes the position of the
|
||||
optional argument :paramref:`until_date`.
|
||||
All arguments were made positional and their order was changed.
|
||||
The argument can_manage_topics was added.
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
|
@ -368,9 +368,12 @@ class ChatMemberRestricted(ChatMember):
|
|||
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send text messages, contacts, locations and venues.
|
||||
to send text messages, contacts, invoices, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this argument with granular media settings.
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
|
@ -383,6 +386,26 @@ class ChatMemberRestricted(ChatMember):
|
|||
.. versionadded:: 20.0
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
|
@ -400,6 +423,9 @@ class ChatMemberRestricted(ChatMember):
|
|||
to send text messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this attribute with granular media settings.
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
|
@ -412,6 +438,26 @@ class ChatMemberRestricted(ChatMember):
|
|||
.. versionadded:: 20.0
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
"""
|
||||
|
||||
|
@ -427,6 +473,12 @@ class ChatMemberRestricted(ChatMember):
|
|||
"can_add_web_page_previews",
|
||||
"can_manage_topics",
|
||||
"until_date",
|
||||
"can_send_audios",
|
||||
"can_send_documents",
|
||||
"can_send_photos",
|
||||
"can_send_videos",
|
||||
"can_send_video_notes",
|
||||
"can_send_voice_notes",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -443,6 +495,12 @@ class ChatMemberRestricted(ChatMember):
|
|||
can_add_web_page_previews: bool,
|
||||
can_manage_topics: bool,
|
||||
until_date: datetime.datetime,
|
||||
can_send_audios: bool,
|
||||
can_send_documents: bool,
|
||||
can_send_photos: bool,
|
||||
can_send_videos: bool,
|
||||
can_send_video_notes: bool,
|
||||
can_send_voice_notes: bool,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -459,6 +517,12 @@ class ChatMemberRestricted(ChatMember):
|
|||
self.can_add_web_page_previews: bool = can_add_web_page_previews
|
||||
self.can_manage_topics: bool = can_manage_topics
|
||||
self.until_date: datetime.datetime = until_date
|
||||
self.can_send_audios: bool = can_send_audios
|
||||
self.can_send_documents: bool = can_send_documents
|
||||
self.can_send_photos: bool = can_send_photos
|
||||
self.can_send_videos: bool = can_send_videos
|
||||
self.can_send_video_notes: bool = can_send_video_notes
|
||||
self.can_send_voice_notes: bool = can_send_voice_notes
|
||||
|
||||
|
||||
class ChatMemberLeft(ChatMember):
|
||||
|
|
|
@ -21,6 +21,8 @@ from typing import Optional
|
|||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
|
||||
class ChatPermissions(TelegramObject):
|
||||
|
@ -35,6 +37,11 @@ class ChatPermissions(TelegramObject):
|
|||
.. versionchanged:: 20.0
|
||||
:attr:`can_manage_topics` is considered as well when comparing objects of
|
||||
this type in terms of equality.
|
||||
.. deprecated:: 20.1
|
||||
:attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
|
||||
:attr:`can_send_videos`, :attr:`can_send_video_notes` and :attr:`can_send_voice_notes`
|
||||
will be considered as well when comparing objects of this type in terms of equality in
|
||||
V21.
|
||||
|
||||
Note:
|
||||
Though not stated explicitly in the official docs, Telegram changes not only the
|
||||
|
@ -47,6 +54,9 @@ class ChatPermissions(TelegramObject):
|
|||
can_send_media_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this argument with granular media settings.
|
||||
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
|
@ -65,6 +75,26 @@ class ChatPermissions(TelegramObject):
|
|||
:attr:`can_pin_messages`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Attributes:
|
||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
|
||||
|
@ -72,6 +102,9 @@ class ChatPermissions(TelegramObject):
|
|||
can_send_media_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this attribute with granular media settings.
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
|
@ -90,6 +123,26 @@ class ChatPermissions(TelegramObject):
|
|||
:attr:`can_pin_messages`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
|
||||
notes.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
"""
|
||||
|
||||
|
@ -103,6 +156,12 @@ class ChatPermissions(TelegramObject):
|
|||
"can_pin_messages",
|
||||
"can_add_web_page_previews",
|
||||
"can_manage_topics",
|
||||
"can_send_audios",
|
||||
"can_send_documents",
|
||||
"can_send_photos",
|
||||
"can_send_videos",
|
||||
"can_send_video_notes",
|
||||
"can_send_voice_notes",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -116,6 +175,12 @@ class ChatPermissions(TelegramObject):
|
|||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_manage_topics: bool = None,
|
||||
can_send_audios: bool = None,
|
||||
can_send_documents: bool = None,
|
||||
can_send_photos: bool = None,
|
||||
can_send_videos: bool = None,
|
||||
can_send_video_notes: bool = None,
|
||||
can_send_voice_notes: bool = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -130,6 +195,12 @@ class ChatPermissions(TelegramObject):
|
|||
self.can_invite_users: Optional[bool] = can_invite_users
|
||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
||||
self.can_send_audios: Optional[bool] = can_send_audios
|
||||
self.can_send_documents: Optional[bool] = can_send_documents
|
||||
self.can_send_photos: Optional[bool] = can_send_photos
|
||||
self.can_send_videos: Optional[bool] = can_send_videos
|
||||
self.can_send_video_notes: Optional[bool] = can_send_video_notes
|
||||
self.can_send_voice_notes: Optional[bool] = can_send_voice_notes
|
||||
|
||||
self._id_attrs = (
|
||||
self.can_send_messages,
|
||||
|
@ -145,6 +216,19 @@ class ChatPermissions(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
warn(
|
||||
"In v21, granular media settings will be considered as well when comparing"
|
||||
" ChatPermissions instances.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return super().__eq__(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
# Intend: Added so support the own __eq__ function (which otherwise breaks hashing)
|
||||
return super().__hash__()
|
||||
|
||||
@classmethod
|
||||
def all_permissions(cls) -> "ChatPermissions":
|
||||
"""
|
||||
|
@ -155,7 +239,7 @@ class ChatPermissions(TelegramObject):
|
|||
.. versionadded:: 20.0
|
||||
|
||||
"""
|
||||
return cls(True, True, True, True, True, True, True, True, True)
|
||||
return cls(*(15 * (True,)))
|
||||
|
||||
@classmethod
|
||||
def no_permissions(cls) -> "ChatPermissions":
|
||||
|
@ -165,4 +249,4 @@ class ChatPermissions(TelegramObject):
|
|||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
return cls(False, False, False, False, False, False, False, False, False)
|
||||
return cls(*(15 * (False,)))
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||
from telegram._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._webappinfo import WebAppInfo
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
@ -31,12 +34,12 @@ if TYPE_CHECKING:
|
|||
|
||||
class KeyboardButton(TelegramObject):
|
||||
"""
|
||||
This object represents one button of the reply keyboard. For simple text buttons String can be
|
||||
used instead of this object to specify text of the button.
|
||||
This object represents one button of the reply keyboard. For simple text buttons, :obj:`str`
|
||||
can be used instead of this object to specify text of the button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`text`, :attr:`request_contact`, :attr:`request_location`,
|
||||
:attr:`request_poll` and :attr:`web_app` are equal.
|
||||
:attr:`request_poll`, :attr:`web_app`, :attr:`request_user` and :attr:`request_chat` are equal.
|
||||
|
||||
Note:
|
||||
* Optional fields are mutually exclusive.
|
||||
|
@ -46,10 +49,16 @@ class KeyboardButton(TelegramObject):
|
|||
January, 2020. Older clients will display unsupported message.
|
||||
* :attr:`web_app` option will only work in Telegram versions released after 16 April, 2022.
|
||||
Older clients will display unsupported message.
|
||||
* :attr:`request_user` and :attr:`request_chat` options will only work in Telegram
|
||||
versions released after 3 February, 2023. Older clients will display unsupported
|
||||
message.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
:attr:`web_app` is considered as well when comparing objects of this type in terms of
|
||||
equality.
|
||||
.. deprecated:: 20.1
|
||||
:paramref:`request_user` and :paramref:`request_chat` will be considered as well when
|
||||
comparing objects of this type in terms of equality in V21.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): Text of the button. If none of the optional fields are used, it will be
|
||||
|
@ -67,6 +76,18 @@ class KeyboardButton(TelegramObject):
|
|||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
request_user (:class:`KeyboardButtonRequestUser`, optional): If specified, pressing the
|
||||
button will open a list of suitable users. Tapping on any user will send its
|
||||
identifier to the bot in a :attr:`telegram.Message.user_shared` service message.
|
||||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
request_chat (:class:`KeyboardButtonRequestChat`, optional): If specified, pressing the
|
||||
button will open a list of suitable chats. Tapping on a chat will send its
|
||||
identifier to the bot in a :attr:`telegram.Message.chat_shared` service message.
|
||||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
Attributes:
|
||||
text (:obj:`str`): Text of the button. If none of the optional fields are used, it will be
|
||||
sent to the bot as a message when the button is pressed.
|
||||
|
@ -83,9 +104,29 @@ class KeyboardButton(TelegramObject):
|
|||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
request_user (:class:`KeyboardButtonRequestUser`): Optional. If specified, pressing the
|
||||
button will open a list of suitable users. Tapping on any user will send its
|
||||
identifier to the bot in a :attr:`telegram.Message.user_shared` service message.
|
||||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
request_chat (:class:`KeyboardButtonRequestChat`): Optional. If specified, pressing the
|
||||
button will open a list of suitable chats. Tapping on a chat will send its
|
||||
identifier to the bot in a :attr:`telegram.Message.chat_shared` service message.
|
||||
Available in private chats only.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
"""
|
||||
|
||||
__slots__ = ("request_location", "request_contact", "request_poll", "text", "web_app")
|
||||
__slots__ = (
|
||||
"request_location",
|
||||
"request_contact",
|
||||
"request_poll",
|
||||
"text",
|
||||
"web_app",
|
||||
"request_user",
|
||||
"request_chat",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -94,6 +135,8 @@ class KeyboardButton(TelegramObject):
|
|||
request_location: bool = None,
|
||||
request_poll: KeyboardButtonPollType = None,
|
||||
web_app: WebAppInfo = None,
|
||||
request_user: KeyboardButtonRequestUser = None,
|
||||
request_chat: KeyboardButtonRequestChat = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -105,6 +148,8 @@ class KeyboardButton(TelegramObject):
|
|||
self.request_location: Optional[bool] = request_location
|
||||
self.request_poll: Optional[KeyboardButtonPollType] = request_poll
|
||||
self.web_app: Optional[WebAppInfo] = web_app
|
||||
self.request_user: Optional[KeyboardButtonRequestUser] = request_user
|
||||
self.request_chat: Optional[KeyboardButtonRequestChat] = request_chat
|
||||
|
||||
self._id_attrs = (
|
||||
self.text,
|
||||
|
@ -116,6 +161,19 @@ class KeyboardButton(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
warn(
|
||||
"In v21, granular media settings will be considered as well when comparing"
|
||||
" ChatPermissions instances.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return super().__eq__(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
# Intend: Added so support the own __eq__ function (which otherwise breaks hashing)
|
||||
return super().__hash__()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["KeyboardButton"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -125,6 +183,8 @@ class KeyboardButton(TelegramObject):
|
|||
return None
|
||||
|
||||
data["request_poll"] = KeyboardButtonPollType.de_json(data.get("request_poll"), bot)
|
||||
data["request_user"] = KeyboardButtonRequestUser.de_json(data.get("request_user"), bot)
|
||||
data["request_chat"] = KeyboardButtonRequestChat.de_json(data.get("request_chat"), bot)
|
||||
data["web_app"] = WebAppInfo.de_json(data.get("web_app"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
|
197
telegram/_keyboardbuttonrequest.py
Normal file
197
telegram/_keyboardbuttonrequest.py
Normal file
|
@ -0,0 +1,197 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 two objects to request chats/users."""
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chatadministratorrights import ChatAdministratorRights
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class KeyboardButtonRequestUser(TelegramObject):
|
||||
"""This object defines the criteria used to request a suitable user. The identifier of the
|
||||
selected user will be shared with the bot when the corresponding button is pressed.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`request_id` is equal.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Signed 32-bit identifier of the request, which will be received
|
||||
back in the :class:`telegram.UserShared` object. Must be unique within the message.
|
||||
user_is_bot (:obj:`bool`, optional): Pass :obj:`True` to request a bot, pass :obj:`False`
|
||||
to request a regular user. If not specified, no additional restrictions are applied.
|
||||
user_is_premium (:obj:`bool`, optional): Pass :obj:`True` to request a premium user, pass
|
||||
:obj:`False` to request a non-premium user. If not specified, no additional
|
||||
restrictions are applied.
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
user_is_bot (:obj:`bool`): Optional. Pass :obj:`True` to request a bot, pass :obj:`False`
|
||||
to request a regular user. If not specified, no additional restrictions are applied.
|
||||
user_is_premium (:obj:`bool`): Optional. Pass :obj:`True` to request a premium user, pass
|
||||
:obj:`False` to request a non-premium user. If not specified, no additional
|
||||
restrictions are applied.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"request_id",
|
||||
"user_is_bot",
|
||||
"user_is_premium",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
user_is_bot: bool = None,
|
||||
user_is_premium: bool = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None, # skipcq: PYL-W0622
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.request_id: int = request_id
|
||||
|
||||
# Optionals
|
||||
self.user_is_bot: Optional[bool] = user_is_bot
|
||||
self.user_is_premium: Optional[bool] = user_is_premium
|
||||
|
||||
self._id_attrs = (self.request_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class KeyboardButtonRequestChat(TelegramObject):
|
||||
"""This object defines the criteria used to request a suitable chat. The identifier of the
|
||||
selected user will be shared with the bot when the corresponding button is pressed.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`request_id` is equal.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Signed 32-bit identifier of the request, which will be received
|
||||
back in the :class:`telegram.ChatShared` object. Must be unique within the message.
|
||||
chat_is_channel (:obj:`bool`): Pass :obj:`True` to request a channel chat, pass
|
||||
:obj:`False` to request a group or a supergroup chat.
|
||||
chat_is_forum (:obj:`bool`, optional): Pass :obj:`True` to request a forum supergroup, pass
|
||||
:obj:`False` to request a non-forum chat. If not specified, no additional
|
||||
restrictions are applied.
|
||||
chat_has_username (:obj:`bool`, optional): Pass :obj:`True` to request a supergroup or a
|
||||
channel with a username, pass :obj:`False` to request a chat without a username. If
|
||||
not specified, no additional restrictions are applied.
|
||||
chat_is_created (:obj:`bool`, optional): Pass :obj:`True` to request a chat owned by the
|
||||
user. Otherwise, no additional restrictions are applied.
|
||||
user_administrator_rights (:class:`ChatAdministratorRights`, optional): Specifies the
|
||||
required administrator rights of the user in the chat. If not specified, no additional
|
||||
restrictions are applied.
|
||||
bot_administrator_rights (:class:`ChatAdministratorRights`, optional): Specifies the
|
||||
required administrator rights of the bot in the chat. The rights must be a subset of
|
||||
:paramref:`user_administrator_rights`. If not specified, no additional restrictions are
|
||||
applied.
|
||||
bot_is_member (:obj:`bool`, optional): Pass :obj:`True` to request a chat with the bot
|
||||
as a member. Otherwise, no additional restrictions are applied.
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
chat_is_channel (:obj:`bool`): Pass :obj:`True` to request a channel chat, pass
|
||||
:obj:`False` to request a group or a supergroup chat.
|
||||
chat_is_forum (:obj:`bool`): Optional. Pass :obj:`True` to request a forum supergroup, pass
|
||||
:obj:`False` to request a non-forum chat. If not specified, no additional
|
||||
restrictions are applied.
|
||||
chat_has_username (:obj:`bool`, optional): Pass :obj:`True` to request a supergroup or a
|
||||
channel with a username, pass :obj:`False` to request a chat without a username. If
|
||||
not specified, no additional restrictions are applied.
|
||||
chat_is_created (:obj:`bool`) Optional. Pass :obj:`True` to request a chat owned by the
|
||||
user. Otherwise, no additional restrictions are applied.
|
||||
user_administrator_rights (:class:`ChatAdministratorRights`) Optional. Specifies the
|
||||
required administrator rights of the user in the chat. If not specified, no additional
|
||||
restrictions are applied.
|
||||
bot_administrator_rights (:class:`ChatAdministratorRights`) Optional. Specifies the
|
||||
required administrator rights of the bot in the chat. The rights must be a subset of
|
||||
:attr:`user_administrator_rights`. If not specified, no additional restrictions are
|
||||
applied.
|
||||
bot_is_member (:obj:`bool`) Optional. Pass :obj:`True` to request a chat with the bot
|
||||
as a member. Otherwise, no additional restrictions are applied.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"request_id",
|
||||
"chat_is_channel",
|
||||
"chat_is_forum",
|
||||
"chat_has_username",
|
||||
"chat_is_created",
|
||||
"user_administrator_rights",
|
||||
"bot_administrator_rights",
|
||||
"bot_is_member",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
chat_is_channel: bool,
|
||||
chat_is_forum: bool = None,
|
||||
chat_has_username: bool = None,
|
||||
chat_is_created: bool = None,
|
||||
user_administrator_rights: ChatAdministratorRights = None,
|
||||
bot_administrator_rights: ChatAdministratorRights = None,
|
||||
bot_is_member: bool = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None, # skipcq: PYL-W0622
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# required
|
||||
self.request_id: int = request_id
|
||||
self.chat_is_channel: bool = chat_is_channel
|
||||
|
||||
# optional
|
||||
self.chat_is_forum: Optional[bool] = chat_is_forum
|
||||
self.chat_has_username: Optional[bool] = chat_has_username
|
||||
self.chat_is_created: Optional[bool] = chat_is_created
|
||||
self.user_administrator_rights: Optional[
|
||||
ChatAdministratorRights
|
||||
] = user_administrator_rights
|
||||
self.bot_administrator_rights: Optional[ChatAdministratorRights] = bot_administrator_rights
|
||||
self.bot_is_member: Optional[bool] = bot_is_member
|
||||
|
||||
self._id_attrs = (self.request_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: "Bot"
|
||||
) -> Optional["KeyboardButtonRequestChat"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["user_administrator_rights"] = ChatAdministratorRights.de_json(
|
||||
data.get("user_administrator_rights"), bot
|
||||
)
|
||||
data["bot_administrator_rights"] = ChatAdministratorRights.de_json(
|
||||
data.get("bot_administrator_rights"), bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
|
@ -53,6 +53,7 @@ from telegram._payment.invoice import Invoice
|
|||
from telegram._payment.successfulpayment import SuccessfulPayment
|
||||
from telegram._poll import Poll
|
||||
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
||||
from telegram._shared import ChatShared, UserShared
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
|
@ -316,6 +317,14 @@ class Message(TelegramObject):
|
|||
by a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
user_shared (:class:`telegram.UserShared`, optional): Service message: a user was shared
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
chat_shared (:class:`telegram.ChatShared`, optional):Service message: a chat was shared
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
|
@ -543,6 +552,14 @@ class Message(TelegramObject):
|
|||
by a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
user_shared (:class:`telegram.UserShared`): Optional. Service message: a user was shared
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
chat_shared (:class:`telegram.ChatShared`): Optional. Service message: a chat was shared
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
.. |custom_emoji_formatting_note| replace:: Custom emoji entities will currently be ignored
|
||||
by this function. Instead, the supplied replacement for the emoji will be used.
|
||||
|
@ -620,6 +637,8 @@ class Message(TelegramObject):
|
|||
"general_forum_topic_unhidden",
|
||||
"write_access_allowed",
|
||||
"has_media_spoiler",
|
||||
"user_shared",
|
||||
"chat_shared",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -693,6 +712,8 @@ class Message(TelegramObject):
|
|||
general_forum_topic_unhidden: GeneralForumTopicUnhidden = None,
|
||||
write_access_allowed: WriteAccessAllowed = None,
|
||||
has_media_spoiler: bool = None,
|
||||
user_shared: UserShared = None,
|
||||
chat_shared: ChatShared = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -779,6 +800,8 @@ class Message(TelegramObject):
|
|||
] = general_forum_topic_unhidden
|
||||
self.write_access_allowed: Optional[WriteAccessAllowed] = write_access_allowed
|
||||
self.has_media_spoiler: Optional[bool] = has_media_spoiler
|
||||
self.user_shared: Optional[UserShared] = user_shared
|
||||
self.chat_shared: Optional[ChatShared] = chat_shared
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
||||
|
@ -888,6 +911,8 @@ class Message(TelegramObject):
|
|||
data["write_access_allowed"] = WriteAccessAllowed.de_json(
|
||||
data.get("write_access_allowed"), bot
|
||||
)
|
||||
data["user_shared"] = UserShared.de_json(data.get("user_shared"), bot)
|
||||
data["chat_shared"] = ChatShared.de_json(data.get("chat_shared"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
|
107
telegram/_shared.py
Normal file
107
telegram/_shared.py
Normal file
|
@ -0,0 +1,107 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 two objects used for request chats/users service messages."""
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class UserShared(TelegramObject):
|
||||
"""
|
||||
This object contains information about the user whose identifier was shared with the bot
|
||||
using a :class:`telegram.KeyboardButtonRequestUser` button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`request_id` and :attr:`user_id` are equal.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
user_id (:obj:`int`): Identifier of the shared user. This number may be greater than 32
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
user_id (:obj:`int`): Identifier of the shared user. This number may be greater than 32
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
"""
|
||||
|
||||
__slots__ = ("request_id", "user_id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
user_id: int,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.request_id: int = request_id
|
||||
self.user_id: int = user_id
|
||||
|
||||
self._id_attrs = (self.request_id, self.user_id)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ChatShared(TelegramObject):
|
||||
"""
|
||||
This object contains information about the chat whose identifier was shared with the bot
|
||||
using a :class:`telegram.KeyboardButtonRequestChat` button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`request_id` and :attr:`chat_id` are equal.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
chat_id (:obj:`int`): Identifier of the shared user. This number may be greater than 32
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
chat_id (:obj:`int`): Identifier of the shared user. This number may be greater than 32
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
"""
|
||||
|
||||
__slots__ = ("request_id", "chat_id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
chat_id: int,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.request_id: int = request_id
|
||||
self.chat_id: int = chat_id
|
||||
|
||||
self._id_attrs = (self.request_id, self.chat_id)
|
||||
|
||||
self._freeze()
|
|
@ -109,6 +109,9 @@ class User(TelegramObject):
|
|||
the bot to the attachment menu.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
.. |user_chat_id_note| replace:: This shortcuts build on the assumption that :attr:`User.id`
|
||||
coincides with the :attr:`Chat.id` of the private chat with the user. This has been the
|
||||
case so far, but Telegram does not guarantee that this stays this way.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
|
@ -293,6 +296,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.pin_chat_message`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
|
@ -324,6 +330,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.unpin_chat_message`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
|
@ -354,6 +363,9 @@ class User(TelegramObject):
|
|||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.unpin_all_chat_messages`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
|
@ -392,6 +404,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_message`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -442,6 +457,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_photo`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -493,6 +511,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
Tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message`
|
||||
instances that were sent is returned.
|
||||
|
@ -546,6 +567,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_audio`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -591,6 +615,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_chat_action`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:obj:`True`: On success.
|
||||
|
||||
|
@ -635,6 +662,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_contact`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -681,6 +711,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_dice`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -729,6 +762,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_document`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -777,6 +813,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_game`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -845,6 +884,9 @@ class User(TelegramObject):
|
|||
order of the arguments had to be changed. Use keyword arguments to make sure that the
|
||||
arguments are passed correctly.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionchanged:: 13.5
|
||||
As of Bot API 5.2, the parameter
|
||||
:paramref:`start_parameter <telegram.Bot.send_invoice.start_parameter>` is optional.
|
||||
|
@ -917,6 +959,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_location`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -974,6 +1019,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_animation`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1025,6 +1073,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_sticker`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1077,6 +1128,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_video`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1137,6 +1191,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_venue`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1191,6 +1248,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_video_note`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1242,6 +1302,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_voice`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1300,6 +1363,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_poll`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1357,6 +1423,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.copy_message`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1407,6 +1476,9 @@ class User(TelegramObject):
|
|||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.copy_message`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
|
@ -1448,6 +1520,9 @@ class User(TelegramObject):
|
|||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.approve_chat_join_request`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionadded:: 13.8
|
||||
|
||||
Returns:
|
||||
|
@ -1481,6 +1556,9 @@ class User(TelegramObject):
|
|||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.decline_chat_join_request`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionadded:: 13.8
|
||||
|
||||
Returns:
|
||||
|
@ -1516,6 +1594,9 @@ class User(TelegramObject):
|
|||
|
||||
.. seealso:: :meth:`get_menu_button`
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
Returns:
|
||||
|
@ -1549,6 +1630,9 @@ class User(TelegramObject):
|
|||
|
||||
.. seealso:: :meth:`set_menu_button`
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
Returns:
|
||||
|
|
|
@ -111,7 +111,7 @@ class _BotAPIVersion(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO = _BotAPIVersion(major=6, minor=4)
|
||||
BOT_API_VERSION_INFO = _BotAPIVersion(major=6, minor=5)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
|
|
|
@ -2088,6 +2088,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
user_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
until_date: Union[int, datetime] = None,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -2101,6 +2102,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
user_id=user_id,
|
||||
permissions=permissions,
|
||||
until_date=until_date,
|
||||
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -3008,6 +3010,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
self,
|
||||
chat_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
use_independent_chat_permissions: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -3019,6 +3022,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
return await super().set_chat_permissions(
|
||||
chat_id=chat_id,
|
||||
permissions=permissions,
|
||||
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
|
|
@ -1760,6 +1760,8 @@ class StatusUpdate:
|
|||
or StatusUpdate.GENERAL_FORUM_TOPIC_HIDDEN.check_update(update)
|
||||
or StatusUpdate.GENERAL_FORUM_TOPIC_UNHIDDEN.check_update(update)
|
||||
or StatusUpdate.WRITE_ACCESS_ALLOWED.check_update(update)
|
||||
or StatusUpdate.USER_SHARED.check_update(update)
|
||||
or StatusUpdate.CHAT_SHARED.check_update(update)
|
||||
)
|
||||
|
||||
ALL = _All(name="filters.StatusUpdate.ALL")
|
||||
|
@ -1780,6 +1782,18 @@ class StatusUpdate:
|
|||
:attr:`telegram.Message.supergroup_chat_created` or
|
||||
:attr:`telegram.Message.channel_chat_created`."""
|
||||
|
||||
class _ChatShared(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.chat_shared)
|
||||
|
||||
CHAT_SHARED = _ChatShared(name="filters.StatusUpdate.CHAT_SHARED")
|
||||
"""Messages that contain :attr:`telegram.Message.chat_shared`.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
"""
|
||||
|
||||
class _ConnectedWebsite(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
|
@ -1954,6 +1968,18 @@ class StatusUpdate:
|
|||
)
|
||||
"""Messages that contain :attr:`telegram.Message.proximity_alert_triggered`."""
|
||||
|
||||
class _UserShared(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.user_shared)
|
||||
|
||||
USER_SHARED = _UserShared(name="filters.StatusUpdate.USER_SHARED")
|
||||
"""Messages that contain :attr:`telegram.Message.user_shared`.
|
||||
|
||||
.. versionadded:: 20.1
|
||||
"""
|
||||
|
||||
class _VideoChatEnded(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
|
|
|
@ -1584,11 +1584,12 @@ class TestBot:
|
|||
data = request_data.json_parameters
|
||||
chat_id = data["chat_id"] == "2"
|
||||
permissions = data["permissions"] == chat_permissions.to_json()
|
||||
return chat_id and permissions
|
||||
use_independent_chat_permissions = data["use_independent_chat_permissions"]
|
||||
return chat_id and permissions and use_independent_chat_permissions
|
||||
|
||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
|
||||
assert await bot.set_chat_permissions(2, chat_permissions)
|
||||
assert await bot.set_chat_permissions(2, chat_permissions, True)
|
||||
|
||||
async def test_set_chat_administrator_custom_title(self, monkeypatch, bot):
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
|
@ -2183,14 +2184,26 @@ class TestBot:
|
|||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
assert await bot.answer_pre_checkout_query(1, False, error_message="Not enough fish")
|
||||
|
||||
@pytest.mark.flaky(3, 1)
|
||||
async def test_restrict_chat_member(self, bot, channel_id, chat_permissions):
|
||||
# TODO: Add bot to supergroup so this can be tested properly
|
||||
with pytest.raises(BadRequest, match="Method is available only for supergroups"):
|
||||
assert await bot.restrict_chat_member(
|
||||
channel_id, 95205500, chat_permissions, until_date=dtm.datetime.utcnow()
|
||||
async def test_restrict_chat_member(self, bot, chat_permissions, monkeypatch):
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
data = request_data.json_parameters
|
||||
chat_id = data["chat_id"] == "@chat"
|
||||
user_id = data["user_id"] == "2"
|
||||
permissions = data["permissions"] == chat_permissions.to_json()
|
||||
until_date = data["until_date"] == "200"
|
||||
use_independent_chat_permissions = data["use_independent_chat_permissions"]
|
||||
return (
|
||||
chat_id
|
||||
and user_id
|
||||
and permissions
|
||||
and until_date
|
||||
and use_independent_chat_permissions
|
||||
)
|
||||
|
||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
|
||||
assert await bot.restrict_chat_member("@chat", 2, chat_permissions, 200, True)
|
||||
|
||||
async def test_restrict_chat_member_default_tz(
|
||||
self, monkeypatch, tz_bot, channel_id, chat_permissions
|
||||
):
|
||||
|
|
|
@ -42,6 +42,7 @@ def chat_join_request(bot, time):
|
|||
date=time,
|
||||
bio=TestChatJoinRequest.bio,
|
||||
invite_link=TestChatJoinRequest.invite_link,
|
||||
user_chat_id=TestChatJoinRequest.from_user.id,
|
||||
)
|
||||
cjr.set_bot(bot)
|
||||
return cjr
|
||||
|
@ -71,6 +72,7 @@ class TestChatJoinRequest:
|
|||
"chat": self.chat.to_dict(),
|
||||
"from": self.from_user.to_dict(),
|
||||
"date": to_timestamp(time),
|
||||
"user_chat_id": self.from_user.id,
|
||||
}
|
||||
chat_join_request = ChatJoinRequest.de_json(json_dict, bot)
|
||||
assert chat_join_request.api_kwargs == {}
|
||||
|
@ -79,6 +81,7 @@ class TestChatJoinRequest:
|
|||
assert chat_join_request.from_user == self.from_user
|
||||
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
||||
assert to_timestamp(chat_join_request.date) == to_timestamp(time)
|
||||
assert chat_join_request.user_chat_id == self.from_user.id
|
||||
|
||||
json_dict.update({"bio": self.bio, "invite_link": self.invite_link.to_dict()})
|
||||
chat_join_request = ChatJoinRequest.de_json(json_dict, bot)
|
||||
|
@ -88,6 +91,7 @@ class TestChatJoinRequest:
|
|||
assert chat_join_request.from_user == self.from_user
|
||||
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
||||
assert to_timestamp(chat_join_request.date) == to_timestamp(time)
|
||||
assert chat_join_request.user_chat_id == self.from_user.id
|
||||
assert chat_join_request.bio == self.bio
|
||||
assert chat_join_request.invite_link == self.invite_link
|
||||
|
||||
|
@ -100,13 +104,16 @@ class TestChatJoinRequest:
|
|||
assert chat_join_request_dict["date"] == to_timestamp(chat_join_request.date)
|
||||
assert chat_join_request_dict["bio"] == chat_join_request.bio
|
||||
assert chat_join_request_dict["invite_link"] == chat_join_request.invite_link.to_dict()
|
||||
assert chat_join_request_dict["user_chat_id"] == self.from_user.id
|
||||
|
||||
def test_equality(self, chat_join_request, time):
|
||||
a = chat_join_request
|
||||
b = ChatJoinRequest(self.chat, self.from_user, time)
|
||||
c = ChatJoinRequest(self.chat, self.from_user, time, bio="bio")
|
||||
d = ChatJoinRequest(self.chat, self.from_user, time + datetime.timedelta(1))
|
||||
e = ChatJoinRequest(self.chat, User(-1, "last_name", True), time)
|
||||
b = ChatJoinRequest(self.chat, self.from_user, time, self.from_user.id)
|
||||
c = ChatJoinRequest(self.chat, self.from_user, time, self.from_user.id, bio="bio")
|
||||
d = ChatJoinRequest(
|
||||
self.chat, self.from_user, time + datetime.timedelta(1), self.from_user.id
|
||||
)
|
||||
e = ChatJoinRequest(self.chat, User(-1, "last_name", True), time, -1)
|
||||
f = User(456, "", False)
|
||||
|
||||
assert a == b
|
||||
|
|
|
@ -89,6 +89,7 @@ def chat_join_request(time, bot):
|
|||
is_revoked=False,
|
||||
is_primary=False,
|
||||
),
|
||||
user_chat_id=2,
|
||||
)
|
||||
cjr.set_bot(bot)
|
||||
return cjr
|
||||
|
|
|
@ -61,6 +61,12 @@ class CMDefaults:
|
|||
can_manage_chat: bool = True
|
||||
can_manage_video_chats: bool = True
|
||||
can_manage_topics: bool = True
|
||||
can_send_audios: bool = True
|
||||
can_send_documents: bool = True
|
||||
can_send_photos: bool = True
|
||||
can_send_videos: bool = True
|
||||
can_send_video_notes: bool = True
|
||||
can_send_voice_notes: bool = True
|
||||
|
||||
|
||||
def chat_member_owner():
|
||||
|
@ -105,6 +111,12 @@ def chat_member_restricted():
|
|||
CMDefaults.can_add_web_page_previews,
|
||||
CMDefaults.can_manage_topics,
|
||||
CMDefaults.until_date,
|
||||
CMDefaults.can_send_audios,
|
||||
CMDefaults.can_send_documents,
|
||||
CMDefaults.can_send_photos,
|
||||
CMDefaults.can_send_videos,
|
||||
CMDefaults.can_send_video_notes,
|
||||
CMDefaults.can_send_voice_notes,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,12 @@ def chat_permissions():
|
|||
can_invite_users=True,
|
||||
can_pin_messages=True,
|
||||
can_manage_topics=True,
|
||||
can_send_audios=True,
|
||||
can_send_documents=True,
|
||||
can_send_photos=True,
|
||||
can_send_videos=True,
|
||||
can_send_video_notes=True,
|
||||
can_send_voice_notes=True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -47,6 +53,12 @@ class TestChatPermissions:
|
|||
can_invite_users = None
|
||||
can_pin_messages = None
|
||||
can_manage_topics = None
|
||||
can_send_audios = True
|
||||
can_send_documents = False
|
||||
can_send_photos = None
|
||||
can_send_videos = True
|
||||
can_send_video_notes = False
|
||||
can_send_voice_notes = None
|
||||
|
||||
def test_slot_behaviour(self, chat_permissions, mro_slots):
|
||||
inst = chat_permissions
|
||||
|
@ -64,7 +76,12 @@ class TestChatPermissions:
|
|||
"can_change_info": self.can_change_info,
|
||||
"can_invite_users": self.can_invite_users,
|
||||
"can_pin_messages": self.can_pin_messages,
|
||||
"can_manage_topics": self.can_manage_topics,
|
||||
"can_send_audios": self.can_send_audios,
|
||||
"can_send_documents": self.can_send_documents,
|
||||
"can_send_photos": self.can_send_photos,
|
||||
"can_send_videos": self.can_send_videos,
|
||||
"can_send_video_notes": self.can_send_video_notes,
|
||||
"can_send_voice_notes": self.can_send_voice_notes,
|
||||
}
|
||||
permissions = ChatPermissions.de_json(json_dict, bot)
|
||||
assert permissions.api_kwargs == {}
|
||||
|
@ -78,6 +95,12 @@ class TestChatPermissions:
|
|||
assert permissions.can_invite_users == self.can_invite_users
|
||||
assert permissions.can_pin_messages == self.can_pin_messages
|
||||
assert permissions.can_manage_topics == self.can_manage_topics
|
||||
assert permissions.can_send_audios == self.can_send_audios
|
||||
assert permissions.can_send_documents == self.can_send_documents
|
||||
assert permissions.can_send_photos == self.can_send_photos
|
||||
assert permissions.can_send_videos == self.can_send_videos
|
||||
assert permissions.can_send_video_notes == self.can_send_video_notes
|
||||
assert permissions.can_send_voice_notes == self.can_send_voice_notes
|
||||
|
||||
def test_to_dict(self, chat_permissions):
|
||||
permissions_dict = chat_permissions.to_dict()
|
||||
|
@ -99,6 +122,12 @@ class TestChatPermissions:
|
|||
assert permissions_dict["can_invite_users"] == chat_permissions.can_invite_users
|
||||
assert permissions_dict["can_pin_messages"] == chat_permissions.can_pin_messages
|
||||
assert permissions_dict["can_manage_topics"] == chat_permissions.can_manage_topics
|
||||
assert permissions_dict["can_send_audios"] == chat_permissions.can_send_audios
|
||||
assert permissions_dict["can_send_documents"] == chat_permissions.can_send_documents
|
||||
assert permissions_dict["can_send_photos"] == chat_permissions.can_send_photos
|
||||
assert permissions_dict["can_send_videos"] == chat_permissions.can_send_videos
|
||||
assert permissions_dict["can_send_video_notes"] == chat_permissions.can_send_video_notes
|
||||
assert permissions_dict["can_send_voice_notes"] == chat_permissions.can_send_voice_notes
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatPermissions(
|
||||
|
@ -120,6 +149,18 @@ class TestChatPermissions:
|
|||
can_send_other_messages=False,
|
||||
)
|
||||
d = User(123, "", False)
|
||||
e = ChatPermissions(
|
||||
can_send_messages=True,
|
||||
can_send_media_messages=True,
|
||||
can_send_polls=True,
|
||||
can_send_other_messages=False,
|
||||
can_send_audios=True,
|
||||
can_send_documents=True,
|
||||
can_send_photos=True,
|
||||
can_send_videos=True,
|
||||
can_send_video_notes=True,
|
||||
can_send_voice_notes=True,
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
@ -131,6 +172,10 @@ class TestChatPermissions:
|
|||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
# we expect this to be true since we don't compare these in V20
|
||||
assert a == e
|
||||
assert hash(a) == hash(e)
|
||||
|
||||
def test_all_permissions(self):
|
||||
f = ChatPermissions()
|
||||
t = ChatPermissions.all_permissions()
|
||||
|
@ -149,8 +194,18 @@ class TestChatPermissions:
|
|||
# if the dirs are the same, the attributes will all be there
|
||||
assert dir(f) == dir(t)
|
||||
# now we just need to check that all attributes are True. _id_attrs returns all values,
|
||||
# if a new one is added without defaulting to True, this will fail
|
||||
# if a new one is added without defaulting to False, this will fail
|
||||
for key in t.__slots__:
|
||||
assert t[key] is False
|
||||
# and as a finisher, make sure the default is different.
|
||||
assert f != t
|
||||
|
||||
def test_equality_warning(self, recwarn, chat_permissions):
|
||||
|
||||
recwarn.clear()
|
||||
assert chat_permissions == chat_permissions
|
||||
|
||||
assert str(recwarn[0].message) == (
|
||||
"In v21, granular media settings will be considered as well when comparing"
|
||||
" ChatPermissions instances."
|
||||
)
|
||||
|
|
|
@ -1046,6 +1046,16 @@ class TestFilters:
|
|||
assert filters.StatusUpdate.WRITE_ACCESS_ALLOWED.check_update(update)
|
||||
update.message.write_access_allowed = None
|
||||
|
||||
update.message.user_shared = "user_shared"
|
||||
assert filters.StatusUpdate.ALL.check_update(update)
|
||||
assert filters.StatusUpdate.USER_SHARED.check_update(update)
|
||||
update.message.user_shared = None
|
||||
|
||||
update.message.chat_shared = "user_shared"
|
||||
assert filters.StatusUpdate.ALL.check_update(update)
|
||||
assert filters.StatusUpdate.CHAT_SHARED.check_update(update)
|
||||
update.message.chat_shared = None
|
||||
|
||||
def test_filters_forwarded(self, update):
|
||||
assert not filters.FORWARDED.check_update(update)
|
||||
update.message.forward_date = datetime.datetime.utcnow()
|
||||
|
|
|
@ -18,7 +18,14 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import pytest
|
||||
|
||||
from telegram import InlineKeyboardButton, KeyboardButton, KeyboardButtonPollType, WebAppInfo
|
||||
from telegram import (
|
||||
InlineKeyboardButton,
|
||||
KeyboardButton,
|
||||
KeyboardButtonPollType,
|
||||
KeyboardButtonRequestChat,
|
||||
KeyboardButtonRequestUser,
|
||||
WebAppInfo,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
|
@ -29,6 +36,8 @@ def keyboard_button():
|
|||
request_contact=TestKeyboardButton.request_contact,
|
||||
request_poll=TestKeyboardButton.request_poll,
|
||||
web_app=TestKeyboardButton.web_app,
|
||||
request_chat=TestKeyboardButton.request_chat,
|
||||
request_user=TestKeyboardButton.request_user,
|
||||
)
|
||||
|
||||
|
||||
|
@ -38,6 +47,8 @@ class TestKeyboardButton:
|
|||
request_contact = True
|
||||
request_poll = KeyboardButtonPollType("quiz")
|
||||
web_app = WebAppInfo(url="https://example.com")
|
||||
request_chat = KeyboardButtonRequestChat(1, True)
|
||||
request_user = KeyboardButtonRequestUser(2)
|
||||
|
||||
def test_slot_behaviour(self, keyboard_button, mro_slots):
|
||||
inst = keyboard_button
|
||||
|
@ -51,6 +62,8 @@ class TestKeyboardButton:
|
|||
assert keyboard_button.request_contact == self.request_contact
|
||||
assert keyboard_button.request_poll == self.request_poll
|
||||
assert keyboard_button.web_app == self.web_app
|
||||
assert keyboard_button.request_chat == self.request_chat
|
||||
assert keyboard_button.request_user == self.request_user
|
||||
|
||||
def test_to_dict(self, keyboard_button):
|
||||
keyboard_button_dict = keyboard_button.to_dict()
|
||||
|
@ -61,6 +74,8 @@ class TestKeyboardButton:
|
|||
assert keyboard_button_dict["request_contact"] == keyboard_button.request_contact
|
||||
assert keyboard_button_dict["request_poll"] == keyboard_button.request_poll.to_dict()
|
||||
assert keyboard_button_dict["web_app"] == keyboard_button.web_app.to_dict()
|
||||
assert keyboard_button_dict["request_chat"] == keyboard_button.request_chat.to_dict()
|
||||
assert keyboard_button_dict["request_user"] == keyboard_button.request_user.to_dict()
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
|
@ -69,6 +84,8 @@ class TestKeyboardButton:
|
|||
"request_contact": self.request_contact,
|
||||
"request_poll": self.request_poll.to_dict(),
|
||||
"web_app": self.web_app.to_dict(),
|
||||
"request_chat": self.request_chat.to_dict(),
|
||||
"request_user": self.request_user.to_dict(),
|
||||
}
|
||||
|
||||
inline_keyboard_button = KeyboardButton.de_json(json_dict, None)
|
||||
|
@ -78,6 +95,8 @@ class TestKeyboardButton:
|
|||
assert inline_keyboard_button.request_contact == self.request_contact
|
||||
assert inline_keyboard_button.request_poll == self.request_poll
|
||||
assert inline_keyboard_button.web_app == self.web_app
|
||||
assert inline_keyboard_button.request_chat == self.request_chat
|
||||
assert inline_keyboard_button.request_user == self.request_user
|
||||
|
||||
none = KeyboardButton.de_json({}, None)
|
||||
assert none is None
|
||||
|
@ -88,6 +107,12 @@ class TestKeyboardButton:
|
|||
c = KeyboardButton("Test", request_location=True)
|
||||
d = KeyboardButton("Test", web_app=WebAppInfo(url="https://ptb.org"))
|
||||
e = InlineKeyboardButton("test", callback_data="test")
|
||||
f = KeyboardButton(
|
||||
"test",
|
||||
request_contact=True,
|
||||
request_chat=KeyboardButtonRequestChat(1, False),
|
||||
request_user=KeyboardButtonRequestUser(2),
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
@ -100,3 +125,17 @@ class TestKeyboardButton:
|
|||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
# we expect this to be true since we don't compare these in V20
|
||||
assert a == f
|
||||
assert hash(a) == hash(f)
|
||||
|
||||
def test_equality_warning(self, recwarn, keyboard_button):
|
||||
|
||||
recwarn.clear()
|
||||
assert keyboard_button == keyboard_button
|
||||
|
||||
assert str(recwarn[0].message) == (
|
||||
"In v21, granular media settings will be considered as well when comparing"
|
||||
" ChatPermissions instances."
|
||||
)
|
||||
|
|
163
tests/test_keyboardbuttonrequest.py
Normal file
163
tests/test_keyboardbuttonrequest.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 ChatAdministratorRights, KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def request_user():
|
||||
return KeyboardButtonRequestUser(
|
||||
TestKeyboardButtonRequestUser.request_id,
|
||||
TestKeyboardButtonRequestUser.user_is_bot,
|
||||
TestKeyboardButtonRequestUser.user_is_premium,
|
||||
)
|
||||
|
||||
|
||||
class TestKeyboardButtonRequestUser:
|
||||
request_id = 123
|
||||
user_is_bot = True
|
||||
user_is_premium = False
|
||||
|
||||
def test_slot_behaviour(self, request_user, mro_slots):
|
||||
for attr in request_user.__slots__:
|
||||
assert getattr(request_user, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(request_user)) == len(set(mro_slots(request_user))), "duplicate slot"
|
||||
|
||||
def test_to_dict(self, request_user):
|
||||
request_user_dict = request_user.to_dict()
|
||||
|
||||
assert isinstance(request_user_dict, dict)
|
||||
assert request_user_dict["request_id"] == self.request_id
|
||||
assert request_user_dict["user_is_bot"] == self.user_is_bot
|
||||
assert request_user_dict["user_is_premium"] == self.user_is_premium
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"request_id": self.request_id,
|
||||
"user_is_bot": self.user_is_bot,
|
||||
"user_is_premium": self.user_is_premium,
|
||||
}
|
||||
request_user = KeyboardButtonRequestUser.de_json(json_dict, bot)
|
||||
assert request_user.api_kwargs == {}
|
||||
|
||||
assert request_user.request_id == self.request_id
|
||||
assert request_user.user_is_bot == self.user_is_bot
|
||||
assert request_user.user_is_premium == self.user_is_premium
|
||||
|
||||
def test_equality(self):
|
||||
a = KeyboardButtonRequestUser(self.request_id)
|
||||
b = KeyboardButtonRequestUser(self.request_id)
|
||||
c = KeyboardButtonRequestUser(1)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def request_chat():
|
||||
return KeyboardButtonRequestChat(
|
||||
TestKeyboardButtonRequestChat.request_id,
|
||||
TestKeyboardButtonRequestChat.chat_is_channel,
|
||||
TestKeyboardButtonRequestChat.chat_is_forum,
|
||||
TestKeyboardButtonRequestChat.chat_has_username,
|
||||
TestKeyboardButtonRequestChat.chat_is_created,
|
||||
TestKeyboardButtonRequestChat.user_administrator_rights,
|
||||
TestKeyboardButtonRequestChat.bot_administrator_rights,
|
||||
TestKeyboardButtonRequestChat.bot_is_member,
|
||||
)
|
||||
|
||||
|
||||
class TestKeyboardButtonRequestChat:
|
||||
request_id = 456
|
||||
chat_is_channel = True
|
||||
chat_is_forum = False
|
||||
chat_has_username = True
|
||||
chat_is_created = False
|
||||
user_administrator_rights = ChatAdministratorRights(
|
||||
True, False, True, False, True, False, True, False
|
||||
)
|
||||
bot_administrator_rights = ChatAdministratorRights(
|
||||
True, False, True, False, True, False, True, False
|
||||
)
|
||||
bot_is_member = True
|
||||
|
||||
def test_slot_behaviour(self, request_chat, mro_slots):
|
||||
for attr in request_chat.__slots__:
|
||||
assert getattr(request_chat, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(request_chat)) == len(set(mro_slots(request_chat))), "duplicate slot"
|
||||
|
||||
def test_to_dict(self, request_chat):
|
||||
request_chat_dict = request_chat.to_dict()
|
||||
|
||||
assert isinstance(request_chat_dict, dict)
|
||||
assert request_chat_dict["request_id"] == self.request_id
|
||||
assert request_chat_dict["chat_is_channel"] == self.chat_is_channel
|
||||
assert request_chat_dict["chat_is_forum"] == self.chat_is_forum
|
||||
assert request_chat_dict["chat_has_username"] == self.chat_has_username
|
||||
assert (
|
||||
request_chat_dict["user_administrator_rights"]
|
||||
== self.user_administrator_rights.to_dict()
|
||||
)
|
||||
assert (
|
||||
request_chat_dict["bot_administrator_rights"]
|
||||
== self.bot_administrator_rights.to_dict()
|
||||
)
|
||||
assert request_chat_dict["bot_is_member"] == self.bot_is_member
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"request_id": self.request_id,
|
||||
"chat_is_channel": self.chat_is_channel,
|
||||
"chat_is_forum": self.chat_is_forum,
|
||||
"chat_has_username": self.chat_has_username,
|
||||
"user_administrator_rights": self.user_administrator_rights.to_dict(),
|
||||
"bot_administrator_rights": self.bot_administrator_rights.to_dict(),
|
||||
"bot_is_member": self.bot_is_member,
|
||||
}
|
||||
request_chat = KeyboardButtonRequestChat.de_json(json_dict, bot)
|
||||
assert request_chat.api_kwargs == {}
|
||||
|
||||
assert request_chat.request_id == self.request_id
|
||||
assert request_chat.chat_is_channel == self.chat_is_channel
|
||||
assert request_chat.chat_is_forum == self.chat_is_forum
|
||||
assert request_chat.chat_has_username == self.chat_has_username
|
||||
assert request_chat.user_administrator_rights == self.user_administrator_rights
|
||||
assert request_chat.bot_administrator_rights == self.bot_administrator_rights
|
||||
assert request_chat.bot_is_member == self.bot_is_member
|
||||
|
||||
empty_chat = KeyboardButtonRequestChat.de_json({}, bot)
|
||||
assert empty_chat is None
|
||||
|
||||
def test_equality(self):
|
||||
a = KeyboardButtonRequestChat(self.request_id, True)
|
||||
b = KeyboardButtonRequestChat(self.request_id, True)
|
||||
c = KeyboardButtonRequestChat(1, True)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
|
@ -26,6 +26,7 @@ from telegram import (
|
|||
Audio,
|
||||
Bot,
|
||||
Chat,
|
||||
ChatShared,
|
||||
Contact,
|
||||
Dice,
|
||||
Document,
|
||||
|
@ -44,6 +45,7 @@ from telegram import (
|
|||
SuccessfulPayment,
|
||||
Update,
|
||||
User,
|
||||
UserShared,
|
||||
Venue,
|
||||
Video,
|
||||
VideoChatEnded,
|
||||
|
@ -207,6 +209,8 @@ def message(bot):
|
|||
},
|
||||
{"web_app_data": WebAppData("some_data", "some_button_text")},
|
||||
{"message_thread_id": 123},
|
||||
{"user_shared": UserShared(1, 2)},
|
||||
{"chat_shared": ChatShared(3, 4)},
|
||||
],
|
||||
ids=[
|
||||
"forwarded_user",
|
||||
|
@ -261,6 +265,8 @@ def message(bot):
|
|||
"entities",
|
||||
"web_app_data",
|
||||
"message_thread_id",
|
||||
"user_shared",
|
||||
"chat_shared",
|
||||
],
|
||||
)
|
||||
def message_params(bot, request):
|
||||
|
|
|
@ -194,6 +194,8 @@ def check_object(h4):
|
|||
ignored |= {"caption", "caption_entities", "media", "media_type", "parse_mode"}
|
||||
elif name.startswith("InputMedia"):
|
||||
ignored |= {"filename"} # Convenience parameter
|
||||
elif name in ("ChatMemberRestricted", "ChatPermissions"):
|
||||
ignored |= {"can_send_media_messages"} # Depreciated param we keep
|
||||
|
||||
assert (sig.parameters.keys() ^ checked) - ignored == set()
|
||||
|
||||
|
|
126
tests/test_shared.py
Normal file
126
tests/test_shared.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2023
|
||||
# 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 ChatShared, UserShared
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def user_shared():
|
||||
return UserShared(
|
||||
TestUserShared.request_id,
|
||||
TestUserShared.user_id,
|
||||
)
|
||||
|
||||
|
||||
class TestUserShared:
|
||||
request_id = 789
|
||||
user_id = 101112
|
||||
|
||||
def test_slot_behaviour(self, user_shared, mro_slots):
|
||||
for attr in user_shared.__slots__:
|
||||
assert getattr(user_shared, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(user_shared)) == len(set(mro_slots(user_shared))), "duplicate slot"
|
||||
|
||||
def test_to_dict(self, user_shared):
|
||||
user_shared_dict = user_shared.to_dict()
|
||||
|
||||
assert isinstance(user_shared_dict, dict)
|
||||
assert user_shared_dict["request_id"] == self.request_id
|
||||
assert user_shared_dict["user_id"] == self.user_id
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"request_id": self.request_id,
|
||||
"user_id": self.user_id,
|
||||
}
|
||||
user_shared = UserShared.de_json(json_dict, bot)
|
||||
assert user_shared.api_kwargs == {}
|
||||
|
||||
assert user_shared.request_id == self.request_id
|
||||
assert user_shared.user_id == self.user_id
|
||||
|
||||
def test_equality(self):
|
||||
a = UserShared(self.request_id, self.user_id)
|
||||
b = UserShared(self.request_id, self.user_id)
|
||||
c = UserShared(1, self.user_id)
|
||||
d = UserShared(self.request_id, 1)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def chat_shared():
|
||||
return ChatShared(
|
||||
TestChatShared.request_id,
|
||||
TestChatShared.chat_id,
|
||||
)
|
||||
|
||||
|
||||
class TestChatShared:
|
||||
request_id = 131415
|
||||
chat_id = 161718
|
||||
|
||||
def test_slot_behaviour(self, chat_shared, mro_slots):
|
||||
for attr in chat_shared.__slots__:
|
||||
assert getattr(chat_shared, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(chat_shared)) == len(set(mro_slots(chat_shared))), "duplicate slot"
|
||||
|
||||
def test_to_dict(self, chat_shared):
|
||||
chat_shared_dict = chat_shared.to_dict()
|
||||
|
||||
assert isinstance(chat_shared_dict, dict)
|
||||
assert chat_shared_dict["request_id"] == self.request_id
|
||||
assert chat_shared_dict["chat_id"] == self.chat_id
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
"request_id": self.request_id,
|
||||
"chat_id": self.chat_id,
|
||||
}
|
||||
chat_shared = ChatShared.de_json(json_dict, bot)
|
||||
assert chat_shared.api_kwargs == {}
|
||||
|
||||
assert chat_shared.request_id == self.request_id
|
||||
assert chat_shared.chat_id == self.chat_id
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatShared(self.request_id, self.chat_id)
|
||||
b = ChatShared(self.request_id, self.chat_id)
|
||||
c = ChatShared(1, self.chat_id)
|
||||
d = ChatShared(self.request_id, 1)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
|
@ -54,6 +54,7 @@ chat_join_request = ChatJoinRequest(
|
|||
chat=Chat(1, Chat.SUPERGROUP),
|
||||
from_user=User(1, "first_name", False),
|
||||
date=from_timestamp(int(time.time())),
|
||||
user_chat_id=1,
|
||||
bio="bio",
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue