mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-01-05 10:24:48 +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/
|
:target: https://pypi.org/project/python-telegram-bot/
|
||||||
:alt: Supported Python versions
|
: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
|
:target: https://core.telegram.org/bots/api-changelog
|
||||||
:alt: Supported Bot API versions
|
:alt: Supported Bot API versions
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||||
Telegram API support
|
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
|
Installing
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||||
:alt: Supported Python versions
|
: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
|
:target: https://core.telegram.org/bots/api-changelog
|
||||||
:alt: Supported Bot API versions
|
:alt: Supported Bot API versions
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||||
Telegram API support
|
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
|
Installing
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -31,6 +31,7 @@ Available Types
|
||||||
telegram.chatmemberupdated
|
telegram.chatmemberupdated
|
||||||
telegram.chatpermissions
|
telegram.chatpermissions
|
||||||
telegram.chatphoto
|
telegram.chatphoto
|
||||||
|
telegram.chatshared
|
||||||
telegram.contact
|
telegram.contact
|
||||||
telegram.dice
|
telegram.dice
|
||||||
telegram.document
|
telegram.document
|
||||||
|
@ -54,6 +55,8 @@ Available Types
|
||||||
telegram.inputmediavideo
|
telegram.inputmediavideo
|
||||||
telegram.keyboardbutton
|
telegram.keyboardbutton
|
||||||
telegram.keyboardbuttonpolltype
|
telegram.keyboardbuttonpolltype
|
||||||
|
telegram.keyboardbuttonrequestchat
|
||||||
|
telegram.keyboardbuttonrequestuser
|
||||||
telegram.location
|
telegram.location
|
||||||
telegram.loginurl
|
telegram.loginurl
|
||||||
telegram.menubutton
|
telegram.menubutton
|
||||||
|
@ -76,6 +79,7 @@ Available Types
|
||||||
telegram.update
|
telegram.update
|
||||||
telegram.user
|
telegram.user
|
||||||
telegram.userprofilephotos
|
telegram.userprofilephotos
|
||||||
|
telegram.usershared
|
||||||
telegram.venue
|
telegram.venue
|
||||||
telegram.video
|
telegram.video
|
||||||
telegram.videochatended
|
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",
|
"ChatMemberUpdated",
|
||||||
"ChatPermissions",
|
"ChatPermissions",
|
||||||
"ChatPhoto",
|
"ChatPhoto",
|
||||||
|
"ChatShared",
|
||||||
"ChosenInlineResult",
|
"ChosenInlineResult",
|
||||||
"constants",
|
"constants",
|
||||||
"Contact",
|
"Contact",
|
||||||
|
@ -118,6 +119,8 @@ __all__ = ( # Keep this alphabetically ordered
|
||||||
"Invoice",
|
"Invoice",
|
||||||
"KeyboardButton",
|
"KeyboardButton",
|
||||||
"KeyboardButtonPollType",
|
"KeyboardButtonPollType",
|
||||||
|
"KeyboardButtonRequestChat",
|
||||||
|
"KeyboardButtonRequestUser",
|
||||||
"LabeledPrice",
|
"LabeledPrice",
|
||||||
"Location",
|
"Location",
|
||||||
"LoginUrl",
|
"LoginUrl",
|
||||||
|
@ -167,6 +170,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||||
"Update",
|
"Update",
|
||||||
"User",
|
"User",
|
||||||
"UserProfilePhotos",
|
"UserProfilePhotos",
|
||||||
|
"UserShared",
|
||||||
"Venue",
|
"Venue",
|
||||||
"Video",
|
"Video",
|
||||||
"VideoChatEnded",
|
"VideoChatEnded",
|
||||||
|
@ -282,6 +286,7 @@ from ._inline.inputtextmessagecontent import InputTextMessageContent
|
||||||
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
|
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
|
||||||
from ._keyboardbutton import KeyboardButton
|
from ._keyboardbutton import KeyboardButton
|
||||||
from ._keyboardbuttonpolltype import KeyboardButtonPollType
|
from ._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||||
|
from ._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||||
from ._loginurl import LoginUrl
|
from ._loginurl import LoginUrl
|
||||||
from ._menubutton import MenuButton, MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
|
from ._menubutton import MenuButton, MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
|
||||||
from ._message import Message
|
from ._message import Message
|
||||||
|
@ -325,6 +330,7 @@ from ._proximityalerttriggered import ProximityAlertTriggered
|
||||||
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||||
from ._sentwebappmessage import SentWebAppMessage
|
from ._sentwebappmessage import SentWebAppMessage
|
||||||
|
from ._shared import ChatShared, UserShared
|
||||||
from ._telegramobject import TelegramObject
|
from ._telegramobject import TelegramObject
|
||||||
from ._update import Update
|
from ._update import Update
|
||||||
from ._user import User
|
from ._user import User
|
||||||
|
|
|
@ -4467,6 +4467,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
user_id: Union[str, int],
|
user_id: Union[str, int],
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
until_date: Union[int, datetime] = None,
|
until_date: Union[int, datetime] = None,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -4493,6 +4494,21 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
used.
|
used.
|
||||||
permissions (:class:`telegram.ChatPermissions`): An object for new user
|
permissions (:class:`telegram.ChatPermissions`): An object for new user
|
||||||
permissions.
|
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:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
@ -4505,6 +4521,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"permissions": permissions,
|
"permissions": permissions,
|
||||||
"until_date": until_date,
|
"until_date": until_date,
|
||||||
|
"use_independent_chat_permissions": use_independent_chat_permissions,
|
||||||
}
|
}
|
||||||
|
|
||||||
result = await self._post(
|
result = await self._post(
|
||||||
|
@ -4633,6 +4650,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
self,
|
self,
|
||||||
chat_id: Union[str, int],
|
chat_id: Union[str, int],
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -4648,6 +4666,21 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
Args:
|
Args:
|
||||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||||
permissions (:class:`telegram.ChatPermissions`): New default chat permissions.
|
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:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
@ -4656,7 +4689,11 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
:class:`telegram.error.TelegramError`
|
: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(
|
result = await self._post(
|
||||||
"setChatPermissions",
|
"setChatPermissions",
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -943,6 +943,7 @@ class Chat(TelegramObject):
|
||||||
user_id: Union[str, int],
|
user_id: Union[str, int],
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
until_date: Union[int, datetime] = None,
|
until_date: Union[int, datetime] = None,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -959,6 +960,9 @@ class Chat(TelegramObject):
|
||||||
|
|
||||||
.. versionadded:: 13.2
|
.. versionadded:: 13.2
|
||||||
|
|
||||||
|
.. versionadded:: 20.1
|
||||||
|
Added :paramref:`~telegram.Bot.restrict_chat_member.use_independent_chat_permissions`.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
|
||||||
|
@ -968,6 +972,7 @@ class Chat(TelegramObject):
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
until_date=until_date,
|
until_date=until_date,
|
||||||
|
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||||
read_timeout=read_timeout,
|
read_timeout=read_timeout,
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_timeout,
|
connect_timeout=connect_timeout,
|
||||||
|
@ -978,6 +983,7 @@ class Chat(TelegramObject):
|
||||||
async def set_permissions(
|
async def set_permissions(
|
||||||
self,
|
self,
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_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
|
For the documentation of the arguments, please see
|
||||||
:meth:`telegram.Bot.set_chat_permissions`.
|
:meth:`telegram.Bot.set_chat_permissions`.
|
||||||
|
|
||||||
|
.. versionadded:: 20.1
|
||||||
|
Added :paramref:`~telegram.Bot.set_chat_permissions.use_independent_chat_permissions`.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
|
||||||
|
@ -999,6 +1008,7 @@ class Chat(TelegramObject):
|
||||||
return await self.get_bot().set_chat_permissions(
|
return await self.get_bot().set_chat_permissions(
|
||||||
chat_id=self.id,
|
chat_id=self.id,
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
|
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||||
read_timeout=read_timeout,
|
read_timeout=read_timeout,
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_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.
|
considered equal, if their :attr:`chat`, :attr:`from_user` and :attr:`date` are equal.
|
||||||
|
|
||||||
Note:
|
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
|
where the bot is an administrator with the
|
||||||
:attr:`~telegram.ChatMemberAdministrator.can_invite_users` administrator right – even if
|
:attr:`~telegram.ChatMemberAdministrator.can_invite_users` administrator right – even
|
||||||
the user never interacted with the bot before.
|
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
|
.. 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:
|
Args:
|
||||||
chat (:class:`telegram.Chat`): Chat to which the request was sent.
|
chat (:class:`telegram.Chat`): Chat to which the request was sent.
|
||||||
from_user (:class:`telegram.User`): User that sent the join request.
|
from_user (:class:`telegram.User`): User that sent the join request.
|
||||||
date (:class:`datetime.datetime`): Date the request was sent.
|
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.
|
bio (:obj:`str`, optional): Bio of the user.
|
||||||
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link that was used
|
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link that was used
|
||||||
by the user to send the join request.
|
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.
|
chat (:class:`telegram.Chat`): Chat to which the request was sent.
|
||||||
from_user (:class:`telegram.User`): User that sent the join request.
|
from_user (:class:`telegram.User`): User that sent the join request.
|
||||||
date (:class:`datetime.datetime`): Date the request was sent.
|
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.
|
bio (:obj:`str`): Optional. Bio of the user.
|
||||||
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link that was used
|
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link that was used
|
||||||
by the user to send the join request.
|
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__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
from_user: User,
|
from_user: User,
|
||||||
date: datetime.datetime,
|
date: datetime.datetime,
|
||||||
|
user_chat_id: int,
|
||||||
bio: str = None,
|
bio: str = None,
|
||||||
invite_link: ChatInviteLink = None,
|
invite_link: ChatInviteLink = None,
|
||||||
*,
|
*,
|
||||||
|
@ -81,6 +106,7 @@ class ChatJoinRequest(TelegramObject):
|
||||||
self.chat: Chat = chat
|
self.chat: Chat = chat
|
||||||
self.from_user: User = from_user
|
self.from_user: User = from_user
|
||||||
self.date: datetime.datetime = date
|
self.date: datetime.datetime = date
|
||||||
|
self.user_chat_id: int = user_chat_id
|
||||||
|
|
||||||
# Optionals
|
# Optionals
|
||||||
self.bio: Optional[str] = bio
|
self.bio: Optional[str] = bio
|
||||||
|
|
|
@ -354,8 +354,8 @@ class ChatMemberRestricted(ChatMember):
|
||||||
|
|
||||||
.. versionadded:: 13.7
|
.. versionadded:: 13.7
|
||||||
.. versionchanged:: 20.0
|
.. versionchanged:: 20.0
|
||||||
The argument :paramref:`can_manage_topics` was added, which changes the position of the
|
All arguments were made positional and their order was changed.
|
||||||
optional argument :paramref:`until_date`.
|
The argument can_manage_topics was added.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user (:class:`telegram.User`): Information about the user.
|
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
|
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
to pin messages; groups and supergroups only.
|
to pin messages; groups and supergroups only.
|
||||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
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
|
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
to send audios, documents, photos, videos, video notes and voice notes.
|
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
|
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
to send polls.
|
to send polls.
|
||||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
|
@ -383,6 +386,26 @@ class ChatMemberRestricted(ChatMember):
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||||
will be lifted for this user.
|
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:
|
Attributes:
|
||||||
status (:obj:`str`): The member's status in the chat,
|
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.
|
to send text messages, contacts, locations and venues.
|
||||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
to send audios, documents, photos, videos, video notes and voice notes.
|
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
|
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
to send polls.
|
to send polls.
|
||||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||||
|
@ -412,6 +438,26 @@ class ChatMemberRestricted(ChatMember):
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||||
will be lifted for this user.
|
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_add_web_page_previews",
|
||||||
"can_manage_topics",
|
"can_manage_topics",
|
||||||
"until_date",
|
"until_date",
|
||||||
|
"can_send_audios",
|
||||||
|
"can_send_documents",
|
||||||
|
"can_send_photos",
|
||||||
|
"can_send_videos",
|
||||||
|
"can_send_video_notes",
|
||||||
|
"can_send_voice_notes",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -443,6 +495,12 @@ class ChatMemberRestricted(ChatMember):
|
||||||
can_add_web_page_previews: bool,
|
can_add_web_page_previews: bool,
|
||||||
can_manage_topics: bool,
|
can_manage_topics: bool,
|
||||||
until_date: datetime.datetime,
|
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,
|
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_add_web_page_previews: bool = can_add_web_page_previews
|
||||||
self.can_manage_topics: bool = can_manage_topics
|
self.can_manage_topics: bool = can_manage_topics
|
||||||
self.until_date: datetime.datetime = until_date
|
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):
|
class ChatMemberLeft(ChatMember):
|
||||||
|
|
|
@ -21,6 +21,8 @@ from typing import Optional
|
||||||
|
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
from telegram._utils.warnings import warn
|
||||||
|
from telegram.warnings import PTBDeprecationWarning
|
||||||
|
|
||||||
|
|
||||||
class ChatPermissions(TelegramObject):
|
class ChatPermissions(TelegramObject):
|
||||||
|
@ -35,6 +37,11 @@ class ChatPermissions(TelegramObject):
|
||||||
.. versionchanged:: 20.0
|
.. versionchanged:: 20.0
|
||||||
:attr:`can_manage_topics` is considered as well when comparing objects of
|
:attr:`can_manage_topics` is considered as well when comparing objects of
|
||||||
this type in terms of equality.
|
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:
|
Note:
|
||||||
Though not stated explicitly in the official docs, Telegram changes not only the
|
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
|
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
|
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||||
:attr:`can_send_messages`.
|
: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,
|
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls,
|
||||||
implies :attr:`can_send_messages`.
|
implies :attr:`can_send_messages`.
|
||||||
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
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`.
|
:attr:`can_pin_messages`.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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:
|
Attributes:
|
||||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
|
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
|
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
|
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||||
:attr:`can_send_messages`.
|
: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,
|
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send polls,
|
||||||
implies :attr:`can_send_messages`.
|
implies :attr:`can_send_messages`.
|
||||||
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
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`.
|
:attr:`can_pin_messages`.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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_pin_messages",
|
||||||
"can_add_web_page_previews",
|
"can_add_web_page_previews",
|
||||||
"can_manage_topics",
|
"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__(
|
def __init__(
|
||||||
|
@ -116,6 +175,12 @@ class ChatPermissions(TelegramObject):
|
||||||
can_invite_users: bool = None,
|
can_invite_users: bool = None,
|
||||||
can_pin_messages: bool = None,
|
can_pin_messages: bool = None,
|
||||||
can_manage_topics: 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,
|
api_kwargs: JSONDict = None,
|
||||||
):
|
):
|
||||||
|
@ -130,6 +195,12 @@ class ChatPermissions(TelegramObject):
|
||||||
self.can_invite_users: Optional[bool] = can_invite_users
|
self.can_invite_users: Optional[bool] = can_invite_users
|
||||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
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._id_attrs = (
|
||||||
self.can_send_messages,
|
self.can_send_messages,
|
||||||
|
@ -145,6 +216,19 @@ class ChatPermissions(TelegramObject):
|
||||||
|
|
||||||
self._freeze()
|
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
|
@classmethod
|
||||||
def all_permissions(cls) -> "ChatPermissions":
|
def all_permissions(cls) -> "ChatPermissions":
|
||||||
"""
|
"""
|
||||||
|
@ -155,7 +239,7 @@ class ChatPermissions(TelegramObject):
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return cls(True, True, True, True, True, True, True, True, True)
|
return cls(*(15 * (True,)))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def no_permissions(cls) -> "ChatPermissions":
|
def no_permissions(cls) -> "ChatPermissions":
|
||||||
|
@ -165,4 +249,4 @@ class ChatPermissions(TelegramObject):
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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 typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from telegram._keyboardbuttonpolltype import KeyboardButtonPollType
|
from telegram._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||||
|
from telegram._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
from telegram._utils.warnings import warn
|
||||||
from telegram._webappinfo import WebAppInfo
|
from telegram._webappinfo import WebAppInfo
|
||||||
|
from telegram.warnings import PTBDeprecationWarning
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from telegram import Bot
|
from telegram import Bot
|
||||||
|
@ -31,12 +34,12 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
class KeyboardButton(TelegramObject):
|
class KeyboardButton(TelegramObject):
|
||||||
"""
|
"""
|
||||||
This object represents one button of the reply keyboard. For simple text buttons String can be
|
This object represents one button of the reply keyboard. For simple text buttons, :obj:`str`
|
||||||
used instead of this object to specify text of the button.
|
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
|
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`,
|
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:
|
Note:
|
||||||
* Optional fields are mutually exclusive.
|
* Optional fields are mutually exclusive.
|
||||||
|
@ -46,10 +49,16 @@ class KeyboardButton(TelegramObject):
|
||||||
January, 2020. Older clients will display unsupported message.
|
January, 2020. Older clients will display unsupported message.
|
||||||
* :attr:`web_app` option will only work in Telegram versions released after 16 April, 2022.
|
* :attr:`web_app` option will only work in Telegram versions released after 16 April, 2022.
|
||||||
Older clients will display unsupported message.
|
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
|
.. versionchanged:: 20.0
|
||||||
:attr:`web_app` is considered as well when comparing objects of this type in terms of
|
:attr:`web_app` is considered as well when comparing objects of this type in terms of
|
||||||
equality.
|
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:
|
Args:
|
||||||
text (:obj:`str`): Text of the button. If none of the optional fields are used, it will be
|
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.
|
Available in private chats only.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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:
|
Attributes:
|
||||||
text (:obj:`str`): Text of the button. If none of the optional fields are used, it will be
|
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.
|
sent to the bot as a message when the button is pressed.
|
||||||
|
@ -83,9 +104,29 @@ class KeyboardButton(TelegramObject):
|
||||||
Available in private chats only.
|
Available in private chats only.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -94,6 +135,8 @@ class KeyboardButton(TelegramObject):
|
||||||
request_location: bool = None,
|
request_location: bool = None,
|
||||||
request_poll: KeyboardButtonPollType = None,
|
request_poll: KeyboardButtonPollType = None,
|
||||||
web_app: WebAppInfo = None,
|
web_app: WebAppInfo = None,
|
||||||
|
request_user: KeyboardButtonRequestUser = None,
|
||||||
|
request_chat: KeyboardButtonRequestChat = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: JSONDict = None,
|
api_kwargs: JSONDict = None,
|
||||||
):
|
):
|
||||||
|
@ -105,6 +148,8 @@ class KeyboardButton(TelegramObject):
|
||||||
self.request_location: Optional[bool] = request_location
|
self.request_location: Optional[bool] = request_location
|
||||||
self.request_poll: Optional[KeyboardButtonPollType] = request_poll
|
self.request_poll: Optional[KeyboardButtonPollType] = request_poll
|
||||||
self.web_app: Optional[WebAppInfo] = web_app
|
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._id_attrs = (
|
||||||
self.text,
|
self.text,
|
||||||
|
@ -116,6 +161,19 @@ class KeyboardButton(TelegramObject):
|
||||||
|
|
||||||
self._freeze()
|
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
|
@classmethod
|
||||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["KeyboardButton"]:
|
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["KeyboardButton"]:
|
||||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||||
|
@ -125,6 +183,8 @@ class KeyboardButton(TelegramObject):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
data["request_poll"] = KeyboardButtonPollType.de_json(data.get("request_poll"), bot)
|
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)
|
data["web_app"] = WebAppInfo.de_json(data.get("web_app"), bot)
|
||||||
|
|
||||||
return super().de_json(data=data, bot=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._payment.successfulpayment import SuccessfulPayment
|
||||||
from telegram._poll import Poll
|
from telegram._poll import Poll
|
||||||
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
||||||
|
from telegram._shared import ChatShared, UserShared
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||||
|
@ -316,6 +317,14 @@ class Message(TelegramObject):
|
||||||
by a spoiler animation.
|
by a spoiler animation.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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:
|
Attributes:
|
||||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||||
|
@ -543,6 +552,14 @@ class Message(TelegramObject):
|
||||||
by a spoiler animation.
|
by a spoiler animation.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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
|
.. |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.
|
by this function. Instead, the supplied replacement for the emoji will be used.
|
||||||
|
@ -620,6 +637,8 @@ class Message(TelegramObject):
|
||||||
"general_forum_topic_unhidden",
|
"general_forum_topic_unhidden",
|
||||||
"write_access_allowed",
|
"write_access_allowed",
|
||||||
"has_media_spoiler",
|
"has_media_spoiler",
|
||||||
|
"user_shared",
|
||||||
|
"chat_shared",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -693,6 +712,8 @@ class Message(TelegramObject):
|
||||||
general_forum_topic_unhidden: GeneralForumTopicUnhidden = None,
|
general_forum_topic_unhidden: GeneralForumTopicUnhidden = None,
|
||||||
write_access_allowed: WriteAccessAllowed = None,
|
write_access_allowed: WriteAccessAllowed = None,
|
||||||
has_media_spoiler: bool = None,
|
has_media_spoiler: bool = None,
|
||||||
|
user_shared: UserShared = None,
|
||||||
|
chat_shared: ChatShared = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: JSONDict = None,
|
api_kwargs: JSONDict = None,
|
||||||
):
|
):
|
||||||
|
@ -779,6 +800,8 @@ class Message(TelegramObject):
|
||||||
] = general_forum_topic_unhidden
|
] = general_forum_topic_unhidden
|
||||||
self.write_access_allowed: Optional[WriteAccessAllowed] = write_access_allowed
|
self.write_access_allowed: Optional[WriteAccessAllowed] = write_access_allowed
|
||||||
self.has_media_spoiler: Optional[bool] = has_media_spoiler
|
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
|
self._effective_attachment = DEFAULT_NONE
|
||||||
|
|
||||||
|
@ -888,6 +911,8 @@ class Message(TelegramObject):
|
||||||
data["write_access_allowed"] = WriteAccessAllowed.de_json(
|
data["write_access_allowed"] = WriteAccessAllowed.de_json(
|
||||||
data.get("write_access_allowed"), bot
|
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)
|
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.
|
the bot to the attachment menu.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. 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__ = (
|
__slots__ = (
|
||||||
|
@ -293,6 +296,9 @@ class User(TelegramObject):
|
||||||
|
|
||||||
For the documentation of the arguments, please see :meth:`telegram.Bot.pin_chat_message`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.pin_chat_message`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.unpin_chat_message`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
|
||||||
|
@ -354,6 +363,9 @@ class User(TelegramObject):
|
||||||
For the documentation of the arguments, please see
|
For the documentation of the arguments, please see
|
||||||
:meth:`telegram.Bot.unpin_all_chat_messages`.
|
:meth:`telegram.Bot.unpin_all_chat_messages`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`bool`: On success, :obj:`True` is returned.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_message`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_photo`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message`
|
Tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message`
|
||||||
instances that were sent is returned.
|
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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_audio`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_chat_action`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`True`: On success.
|
:obj:`True`: On success.
|
||||||
|
|
||||||
|
@ -635,6 +662,9 @@ class User(TelegramObject):
|
||||||
|
|
||||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_contact`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_contact`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_dice`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_document`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_game`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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
|
order of the arguments had to be changed. Use keyword arguments to make sure that the
|
||||||
arguments are passed correctly.
|
arguments are passed correctly.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
.. versionchanged:: 13.5
|
.. versionchanged:: 13.5
|
||||||
As of Bot API 5.2, the parameter
|
As of Bot API 5.2, the parameter
|
||||||
:paramref:`start_parameter <telegram.Bot.send_invoice.start_parameter>` is optional.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_location`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_animation`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_sticker`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_video`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_venue`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_video_note`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_voice`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.send_poll`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.copy_message`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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`.
|
For the documentation of the arguments, please see :meth:`telegram.Bot.copy_message`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
: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
|
For the documentation of the arguments, please see
|
||||||
:meth:`telegram.Bot.approve_chat_join_request`.
|
:meth:`telegram.Bot.approve_chat_join_request`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
.. versionadded:: 13.8
|
.. versionadded:: 13.8
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -1481,6 +1556,9 @@ class User(TelegramObject):
|
||||||
For the documentation of the arguments, please see
|
For the documentation of the arguments, please see
|
||||||
:meth:`telegram.Bot.decline_chat_join_request`.
|
:meth:`telegram.Bot.decline_chat_join_request`.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
.. versionadded:: 13.8
|
.. versionadded:: 13.8
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -1516,6 +1594,9 @@ class User(TelegramObject):
|
||||||
|
|
||||||
.. seealso:: :meth:`get_menu_button`
|
.. seealso:: :meth:`get_menu_button`
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -1549,6 +1630,9 @@ class User(TelegramObject):
|
||||||
|
|
||||||
.. seealso:: :meth:`set_menu_button`
|
.. seealso:: :meth:`set_menu_button`
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|user_chat_id_note|
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
|
@ -111,7 +111,7 @@ class _BotAPIVersion(NamedTuple):
|
||||||
#: :data:`telegram.__bot_api_version_info__`.
|
#: :data:`telegram.__bot_api_version_info__`.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 20.0
|
#: .. 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
|
#: :obj:`str`: Telegram Bot API
|
||||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||||
#: :data:`telegram.__bot_api_version__`.
|
#: :data:`telegram.__bot_api_version__`.
|
||||||
|
|
|
@ -2088,6 +2088,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
user_id: Union[str, int],
|
user_id: Union[str, int],
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
until_date: Union[int, datetime] = None,
|
until_date: Union[int, datetime] = None,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -2101,6 +2102,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
until_date=until_date,
|
until_date=until_date,
|
||||||
|
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||||
read_timeout=read_timeout,
|
read_timeout=read_timeout,
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_timeout,
|
connect_timeout=connect_timeout,
|
||||||
|
@ -3008,6 +3010,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
self,
|
self,
|
||||||
chat_id: Union[str, int],
|
chat_id: Union[str, int],
|
||||||
permissions: ChatPermissions,
|
permissions: ChatPermissions,
|
||||||
|
use_independent_chat_permissions: bool = None,
|
||||||
*,
|
*,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
write_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(
|
return await super().set_chat_permissions(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
|
use_independent_chat_permissions=use_independent_chat_permissions,
|
||||||
read_timeout=read_timeout,
|
read_timeout=read_timeout,
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_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_HIDDEN.check_update(update)
|
||||||
or StatusUpdate.GENERAL_FORUM_TOPIC_UNHIDDEN.check_update(update)
|
or StatusUpdate.GENERAL_FORUM_TOPIC_UNHIDDEN.check_update(update)
|
||||||
or StatusUpdate.WRITE_ACCESS_ALLOWED.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")
|
ALL = _All(name="filters.StatusUpdate.ALL")
|
||||||
|
@ -1780,6 +1782,18 @@ class StatusUpdate:
|
||||||
:attr:`telegram.Message.supergroup_chat_created` or
|
:attr:`telegram.Message.supergroup_chat_created` or
|
||||||
:attr:`telegram.Message.channel_chat_created`."""
|
: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):
|
class _ConnectedWebsite(MessageFilter):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
|
@ -1954,6 +1968,18 @@ class StatusUpdate:
|
||||||
)
|
)
|
||||||
"""Messages that contain :attr:`telegram.Message.proximity_alert_triggered`."""
|
"""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):
|
class _VideoChatEnded(MessageFilter):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
|
|
|
@ -1584,11 +1584,12 @@ class TestBot:
|
||||||
data = request_data.json_parameters
|
data = request_data.json_parameters
|
||||||
chat_id = data["chat_id"] == "2"
|
chat_id = data["chat_id"] == "2"
|
||||||
permissions = data["permissions"] == chat_permissions.to_json()
|
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)
|
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 test_set_chat_administrator_custom_title(self, monkeypatch, bot):
|
||||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||||
|
@ -2183,14 +2184,26 @@ class TestBot:
|
||||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||||
assert await bot.answer_pre_checkout_query(1, False, error_message="Not enough fish")
|
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, chat_permissions, monkeypatch):
|
||||||
async def test_restrict_chat_member(self, bot, channel_id, chat_permissions):
|
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||||
# TODO: Add bot to supergroup so this can be tested properly
|
data = request_data.json_parameters
|
||||||
with pytest.raises(BadRequest, match="Method is available only for supergroups"):
|
chat_id = data["chat_id"] == "@chat"
|
||||||
assert await bot.restrict_chat_member(
|
user_id = data["user_id"] == "2"
|
||||||
channel_id, 95205500, chat_permissions, until_date=dtm.datetime.utcnow()
|
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(
|
async def test_restrict_chat_member_default_tz(
|
||||||
self, monkeypatch, tz_bot, channel_id, chat_permissions
|
self, monkeypatch, tz_bot, channel_id, chat_permissions
|
||||||
):
|
):
|
||||||
|
|
|
@ -42,6 +42,7 @@ def chat_join_request(bot, time):
|
||||||
date=time,
|
date=time,
|
||||||
bio=TestChatJoinRequest.bio,
|
bio=TestChatJoinRequest.bio,
|
||||||
invite_link=TestChatJoinRequest.invite_link,
|
invite_link=TestChatJoinRequest.invite_link,
|
||||||
|
user_chat_id=TestChatJoinRequest.from_user.id,
|
||||||
)
|
)
|
||||||
cjr.set_bot(bot)
|
cjr.set_bot(bot)
|
||||||
return cjr
|
return cjr
|
||||||
|
@ -71,6 +72,7 @@ class TestChatJoinRequest:
|
||||||
"chat": self.chat.to_dict(),
|
"chat": self.chat.to_dict(),
|
||||||
"from": self.from_user.to_dict(),
|
"from": self.from_user.to_dict(),
|
||||||
"date": to_timestamp(time),
|
"date": to_timestamp(time),
|
||||||
|
"user_chat_id": self.from_user.id,
|
||||||
}
|
}
|
||||||
chat_join_request = ChatJoinRequest.de_json(json_dict, bot)
|
chat_join_request = ChatJoinRequest.de_json(json_dict, bot)
|
||||||
assert chat_join_request.api_kwargs == {}
|
assert chat_join_request.api_kwargs == {}
|
||||||
|
@ -79,6 +81,7 @@ class TestChatJoinRequest:
|
||||||
assert chat_join_request.from_user == self.from_user
|
assert chat_join_request.from_user == self.from_user
|
||||||
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
||||||
assert to_timestamp(chat_join_request.date) == to_timestamp(time)
|
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()})
|
json_dict.update({"bio": self.bio, "invite_link": self.invite_link.to_dict()})
|
||||||
chat_join_request = ChatJoinRequest.de_json(json_dict, bot)
|
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 chat_join_request.from_user == self.from_user
|
||||||
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1)
|
||||||
assert to_timestamp(chat_join_request.date) == to_timestamp(time)
|
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.bio == self.bio
|
||||||
assert chat_join_request.invite_link == self.invite_link
|
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["date"] == to_timestamp(chat_join_request.date)
|
||||||
assert chat_join_request_dict["bio"] == chat_join_request.bio
|
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["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):
|
def test_equality(self, chat_join_request, time):
|
||||||
a = chat_join_request
|
a = chat_join_request
|
||||||
b = ChatJoinRequest(self.chat, self.from_user, time)
|
b = ChatJoinRequest(self.chat, self.from_user, time, self.from_user.id)
|
||||||
c = ChatJoinRequest(self.chat, self.from_user, time, bio="bio")
|
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))
|
d = ChatJoinRequest(
|
||||||
e = ChatJoinRequest(self.chat, User(-1, "last_name", True), time)
|
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)
|
f = User(456, "", False)
|
||||||
|
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
|
@ -89,6 +89,7 @@ def chat_join_request(time, bot):
|
||||||
is_revoked=False,
|
is_revoked=False,
|
||||||
is_primary=False,
|
is_primary=False,
|
||||||
),
|
),
|
||||||
|
user_chat_id=2,
|
||||||
)
|
)
|
||||||
cjr.set_bot(bot)
|
cjr.set_bot(bot)
|
||||||
return cjr
|
return cjr
|
||||||
|
|
|
@ -61,6 +61,12 @@ class CMDefaults:
|
||||||
can_manage_chat: bool = True
|
can_manage_chat: bool = True
|
||||||
can_manage_video_chats: bool = True
|
can_manage_video_chats: bool = True
|
||||||
can_manage_topics: 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():
|
def chat_member_owner():
|
||||||
|
@ -105,6 +111,12 @@ def chat_member_restricted():
|
||||||
CMDefaults.can_add_web_page_previews,
|
CMDefaults.can_add_web_page_previews,
|
||||||
CMDefaults.can_manage_topics,
|
CMDefaults.can_manage_topics,
|
||||||
CMDefaults.until_date,
|
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_invite_users=True,
|
||||||
can_pin_messages=True,
|
can_pin_messages=True,
|
||||||
can_manage_topics=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_invite_users = None
|
||||||
can_pin_messages = None
|
can_pin_messages = None
|
||||||
can_manage_topics = 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):
|
def test_slot_behaviour(self, chat_permissions, mro_slots):
|
||||||
inst = chat_permissions
|
inst = chat_permissions
|
||||||
|
@ -64,7 +76,12 @@ class TestChatPermissions:
|
||||||
"can_change_info": self.can_change_info,
|
"can_change_info": self.can_change_info,
|
||||||
"can_invite_users": self.can_invite_users,
|
"can_invite_users": self.can_invite_users,
|
||||||
"can_pin_messages": self.can_pin_messages,
|
"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)
|
permissions = ChatPermissions.de_json(json_dict, bot)
|
||||||
assert permissions.api_kwargs == {}
|
assert permissions.api_kwargs == {}
|
||||||
|
@ -78,6 +95,12 @@ class TestChatPermissions:
|
||||||
assert permissions.can_invite_users == self.can_invite_users
|
assert permissions.can_invite_users == self.can_invite_users
|
||||||
assert permissions.can_pin_messages == self.can_pin_messages
|
assert permissions.can_pin_messages == self.can_pin_messages
|
||||||
assert permissions.can_manage_topics == self.can_manage_topics
|
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):
|
def test_to_dict(self, chat_permissions):
|
||||||
permissions_dict = chat_permissions.to_dict()
|
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_invite_users"] == chat_permissions.can_invite_users
|
||||||
assert permissions_dict["can_pin_messages"] == chat_permissions.can_pin_messages
|
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_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):
|
def test_equality(self):
|
||||||
a = ChatPermissions(
|
a = ChatPermissions(
|
||||||
|
@ -120,6 +149,18 @@ class TestChatPermissions:
|
||||||
can_send_other_messages=False,
|
can_send_other_messages=False,
|
||||||
)
|
)
|
||||||
d = User(123, "", 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 a == b
|
||||||
assert hash(a) == hash(b)
|
assert hash(a) == hash(b)
|
||||||
|
@ -131,6 +172,10 @@ class TestChatPermissions:
|
||||||
assert a != d
|
assert a != d
|
||||||
assert hash(a) != hash(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):
|
def test_all_permissions(self):
|
||||||
f = ChatPermissions()
|
f = ChatPermissions()
|
||||||
t = ChatPermissions.all_permissions()
|
t = ChatPermissions.all_permissions()
|
||||||
|
@ -149,8 +194,18 @@ class TestChatPermissions:
|
||||||
# if the dirs are the same, the attributes will all be there
|
# if the dirs are the same, the attributes will all be there
|
||||||
assert dir(f) == dir(t)
|
assert dir(f) == dir(t)
|
||||||
# now we just need to check that all attributes are True. _id_attrs returns all values,
|
# 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__:
|
for key in t.__slots__:
|
||||||
assert t[key] is False
|
assert t[key] is False
|
||||||
# and as a finisher, make sure the default is different.
|
# and as a finisher, make sure the default is different.
|
||||||
assert f != t
|
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)
|
assert filters.StatusUpdate.WRITE_ACCESS_ALLOWED.check_update(update)
|
||||||
update.message.write_access_allowed = None
|
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):
|
def test_filters_forwarded(self, update):
|
||||||
assert not filters.FORWARDED.check_update(update)
|
assert not filters.FORWARDED.check_update(update)
|
||||||
update.message.forward_date = datetime.datetime.utcnow()
|
update.message.forward_date = datetime.datetime.utcnow()
|
||||||
|
|
|
@ -18,7 +18,14 @@
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from telegram import InlineKeyboardButton, KeyboardButton, KeyboardButtonPollType, WebAppInfo
|
from telegram import (
|
||||||
|
InlineKeyboardButton,
|
||||||
|
KeyboardButton,
|
||||||
|
KeyboardButtonPollType,
|
||||||
|
KeyboardButtonRequestChat,
|
||||||
|
KeyboardButtonRequestUser,
|
||||||
|
WebAppInfo,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="class")
|
@pytest.fixture(scope="class")
|
||||||
|
@ -29,6 +36,8 @@ def keyboard_button():
|
||||||
request_contact=TestKeyboardButton.request_contact,
|
request_contact=TestKeyboardButton.request_contact,
|
||||||
request_poll=TestKeyboardButton.request_poll,
|
request_poll=TestKeyboardButton.request_poll,
|
||||||
web_app=TestKeyboardButton.web_app,
|
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_contact = True
|
||||||
request_poll = KeyboardButtonPollType("quiz")
|
request_poll = KeyboardButtonPollType("quiz")
|
||||||
web_app = WebAppInfo(url="https://example.com")
|
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):
|
def test_slot_behaviour(self, keyboard_button, mro_slots):
|
||||||
inst = keyboard_button
|
inst = keyboard_button
|
||||||
|
@ -51,6 +62,8 @@ class TestKeyboardButton:
|
||||||
assert keyboard_button.request_contact == self.request_contact
|
assert keyboard_button.request_contact == self.request_contact
|
||||||
assert keyboard_button.request_poll == self.request_poll
|
assert keyboard_button.request_poll == self.request_poll
|
||||||
assert keyboard_button.web_app == self.web_app
|
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):
|
def test_to_dict(self, keyboard_button):
|
||||||
keyboard_button_dict = keyboard_button.to_dict()
|
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_contact"] == keyboard_button.request_contact
|
||||||
assert keyboard_button_dict["request_poll"] == keyboard_button.request_poll.to_dict()
|
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["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):
|
def test_de_json(self, bot):
|
||||||
json_dict = {
|
json_dict = {
|
||||||
|
@ -69,6 +84,8 @@ class TestKeyboardButton:
|
||||||
"request_contact": self.request_contact,
|
"request_contact": self.request_contact,
|
||||||
"request_poll": self.request_poll.to_dict(),
|
"request_poll": self.request_poll.to_dict(),
|
||||||
"web_app": self.web_app.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)
|
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_contact == self.request_contact
|
||||||
assert inline_keyboard_button.request_poll == self.request_poll
|
assert inline_keyboard_button.request_poll == self.request_poll
|
||||||
assert inline_keyboard_button.web_app == self.web_app
|
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)
|
none = KeyboardButton.de_json({}, None)
|
||||||
assert none is None
|
assert none is None
|
||||||
|
@ -88,6 +107,12 @@ class TestKeyboardButton:
|
||||||
c = KeyboardButton("Test", request_location=True)
|
c = KeyboardButton("Test", request_location=True)
|
||||||
d = KeyboardButton("Test", web_app=WebAppInfo(url="https://ptb.org"))
|
d = KeyboardButton("Test", web_app=WebAppInfo(url="https://ptb.org"))
|
||||||
e = InlineKeyboardButton("test", callback_data="test")
|
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 a == b
|
||||||
assert hash(a) == hash(b)
|
assert hash(a) == hash(b)
|
||||||
|
@ -100,3 +125,17 @@ class TestKeyboardButton:
|
||||||
|
|
||||||
assert a != e
|
assert a != e
|
||||||
assert hash(a) != hash(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,
|
Audio,
|
||||||
Bot,
|
Bot,
|
||||||
Chat,
|
Chat,
|
||||||
|
ChatShared,
|
||||||
Contact,
|
Contact,
|
||||||
Dice,
|
Dice,
|
||||||
Document,
|
Document,
|
||||||
|
@ -44,6 +45,7 @@ from telegram import (
|
||||||
SuccessfulPayment,
|
SuccessfulPayment,
|
||||||
Update,
|
Update,
|
||||||
User,
|
User,
|
||||||
|
UserShared,
|
||||||
Venue,
|
Venue,
|
||||||
Video,
|
Video,
|
||||||
VideoChatEnded,
|
VideoChatEnded,
|
||||||
|
@ -207,6 +209,8 @@ def message(bot):
|
||||||
},
|
},
|
||||||
{"web_app_data": WebAppData("some_data", "some_button_text")},
|
{"web_app_data": WebAppData("some_data", "some_button_text")},
|
||||||
{"message_thread_id": 123},
|
{"message_thread_id": 123},
|
||||||
|
{"user_shared": UserShared(1, 2)},
|
||||||
|
{"chat_shared": ChatShared(3, 4)},
|
||||||
],
|
],
|
||||||
ids=[
|
ids=[
|
||||||
"forwarded_user",
|
"forwarded_user",
|
||||||
|
@ -261,6 +265,8 @@ def message(bot):
|
||||||
"entities",
|
"entities",
|
||||||
"web_app_data",
|
"web_app_data",
|
||||||
"message_thread_id",
|
"message_thread_id",
|
||||||
|
"user_shared",
|
||||||
|
"chat_shared",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def message_params(bot, request):
|
def message_params(bot, request):
|
||||||
|
|
|
@ -194,6 +194,8 @@ def check_object(h4):
|
||||||
ignored |= {"caption", "caption_entities", "media", "media_type", "parse_mode"}
|
ignored |= {"caption", "caption_entities", "media", "media_type", "parse_mode"}
|
||||||
elif name.startswith("InputMedia"):
|
elif name.startswith("InputMedia"):
|
||||||
ignored |= {"filename"} # Convenience parameter
|
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()
|
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),
|
chat=Chat(1, Chat.SUPERGROUP),
|
||||||
from_user=User(1, "first_name", False),
|
from_user=User(1, "first_name", False),
|
||||||
date=from_timestamp(int(time.time())),
|
date=from_timestamp(int(time.time())),
|
||||||
|
user_chat_id=1,
|
||||||
bio="bio",
|
bio="bio",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue