README.md edited

This commit is contained in:
2024-12-06 10:45:08 +09:00
parent 09e4edee6b
commit 1aa387aa59
13921 changed files with 2057290 additions and 10 deletions

View File

@@ -0,0 +1,538 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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/].
"""A library that provides a Python interface to the Telegram Bot API"""
__author__ = "devs@python-telegram-bot.org"
__all__ = (
"Animation",
"Audio",
"BackgroundFill",
"BackgroundFillFreeformGradient",
"BackgroundFillGradient",
"BackgroundFillSolid",
"BackgroundType",
"BackgroundTypeChatTheme",
"BackgroundTypeFill",
"BackgroundTypePattern",
"BackgroundTypeWallpaper",
"Birthdate",
"Bot",
"BotCommand",
"BotCommandScope",
"BotCommandScopeAllChatAdministrators",
"BotCommandScopeAllGroupChats",
"BotCommandScopeAllPrivateChats",
"BotCommandScopeChat",
"BotCommandScopeChatAdministrators",
"BotCommandScopeChatMember",
"BotCommandScopeDefault",
"BotDescription",
"BotName",
"BotShortDescription",
"BusinessConnection",
"BusinessIntro",
"BusinessLocation",
"BusinessMessagesDeleted",
"BusinessOpeningHours",
"BusinessOpeningHoursInterval",
"CallbackGame",
"CallbackQuery",
"Chat",
"ChatAdministratorRights",
"ChatBackground",
"ChatBoost",
"ChatBoostAdded",
"ChatBoostRemoved",
"ChatBoostSource",
"ChatBoostSourceGiftCode",
"ChatBoostSourceGiveaway",
"ChatBoostSourcePremium",
"ChatBoostUpdated",
"ChatFullInfo",
"ChatInviteLink",
"ChatJoinRequest",
"ChatLocation",
"ChatMember",
"ChatMemberAdministrator",
"ChatMemberBanned",
"ChatMemberLeft",
"ChatMemberMember",
"ChatMemberOwner",
"ChatMemberRestricted",
"ChatMemberUpdated",
"ChatPermissions",
"ChatPhoto",
"ChatShared",
"ChosenInlineResult",
"Contact",
"CopyTextButton",
"Credentials",
"DataCredentials",
"Dice",
"Document",
"EncryptedCredentials",
"EncryptedPassportElement",
"ExternalReplyInfo",
"File",
"FileCredentials",
"ForceReply",
"ForumTopic",
"ForumTopicClosed",
"ForumTopicCreated",
"ForumTopicEdited",
"ForumTopicReopened",
"Game",
"GameHighScore",
"GeneralForumTopicHidden",
"GeneralForumTopicUnhidden",
"Gift",
"Gifts",
"Giveaway",
"GiveawayCompleted",
"GiveawayCreated",
"GiveawayWinners",
"IdDocumentData",
"InaccessibleMessage",
"InlineKeyboardButton",
"InlineKeyboardMarkup",
"InlineQuery",
"InlineQueryResult",
"InlineQueryResultArticle",
"InlineQueryResultAudio",
"InlineQueryResultCachedAudio",
"InlineQueryResultCachedDocument",
"InlineQueryResultCachedGif",
"InlineQueryResultCachedMpeg4Gif",
"InlineQueryResultCachedPhoto",
"InlineQueryResultCachedSticker",
"InlineQueryResultCachedVideo",
"InlineQueryResultCachedVoice",
"InlineQueryResultContact",
"InlineQueryResultDocument",
"InlineQueryResultGame",
"InlineQueryResultGif",
"InlineQueryResultLocation",
"InlineQueryResultMpeg4Gif",
"InlineQueryResultPhoto",
"InlineQueryResultVenue",
"InlineQueryResultVideo",
"InlineQueryResultVoice",
"InlineQueryResultsButton",
"InputContactMessageContent",
"InputFile",
"InputInvoiceMessageContent",
"InputLocationMessageContent",
"InputMedia",
"InputMediaAnimation",
"InputMediaAudio",
"InputMediaDocument",
"InputMediaPhoto",
"InputMediaVideo",
"InputMessageContent",
"InputPaidMedia",
"InputPaidMediaPhoto",
"InputPaidMediaVideo",
"InputPollOption",
"InputSticker",
"InputTextMessageContent",
"InputVenueMessageContent",
"Invoice",
"KeyboardButton",
"KeyboardButtonPollType",
"KeyboardButtonRequestChat",
"KeyboardButtonRequestUsers",
"LabeledPrice",
"LinkPreviewOptions",
"Location",
"LoginUrl",
"MaskPosition",
"MaybeInaccessibleMessage",
"MenuButton",
"MenuButtonCommands",
"MenuButtonDefault",
"MenuButtonWebApp",
"Message",
"MessageAutoDeleteTimerChanged",
"MessageEntity",
"MessageId",
"MessageOrigin",
"MessageOriginChannel",
"MessageOriginChat",
"MessageOriginHiddenUser",
"MessageOriginUser",
"MessageReactionCountUpdated",
"MessageReactionUpdated",
"OrderInfo",
"PaidMedia",
"PaidMediaInfo",
"PaidMediaPhoto",
"PaidMediaPreview",
"PaidMediaPurchased",
"PaidMediaVideo",
"PassportData",
"PassportElementError",
"PassportElementErrorDataField",
"PassportElementErrorFile",
"PassportElementErrorFiles",
"PassportElementErrorFrontSide",
"PassportElementErrorReverseSide",
"PassportElementErrorSelfie",
"PassportElementErrorTranslationFile",
"PassportElementErrorTranslationFiles",
"PassportElementErrorUnspecified",
"PassportFile",
"PersonalDetails",
"PhotoSize",
"Poll",
"PollAnswer",
"PollOption",
"PreCheckoutQuery",
"PreparedInlineMessage",
"ProximityAlertTriggered",
"ReactionCount",
"ReactionType",
"ReactionTypeCustomEmoji",
"ReactionTypeEmoji",
"ReactionTypePaid",
"RefundedPayment",
"ReplyKeyboardMarkup",
"ReplyKeyboardRemove",
"ReplyParameters",
"ResidentialAddress",
"RevenueWithdrawalState",
"RevenueWithdrawalStateFailed",
"RevenueWithdrawalStatePending",
"RevenueWithdrawalStateSucceeded",
"SecureData",
"SecureValue",
"SentWebAppMessage",
"SharedUser",
"ShippingAddress",
"ShippingOption",
"ShippingQuery",
"StarTransaction",
"StarTransactions",
"Sticker",
"StickerSet",
"Story",
"SuccessfulPayment",
"SwitchInlineQueryChosenChat",
"TelegramObject",
"TextQuote",
"TransactionPartner",
"TransactionPartnerFragment",
"TransactionPartnerOther",
"TransactionPartnerTelegramAds",
"TransactionPartnerTelegramApi",
"TransactionPartnerUser",
"Update",
"User",
"UserChatBoosts",
"UserProfilePhotos",
"UsersShared",
"Venue",
"Video",
"VideoChatEnded",
"VideoChatParticipantsInvited",
"VideoChatScheduled",
"VideoChatStarted",
"VideoNote",
"Voice",
"WebAppData",
"WebAppInfo",
"WebhookInfo",
"WriteAccessAllowed",
"__bot_api_version__",
"__bot_api_version_info__",
"__version__",
"__version_info__",
"constants",
"error",
"helpers",
"request",
"warnings",
)
from . import _version, constants, error, helpers, request, warnings
from ._birthdate import Birthdate
from ._bot import Bot
from ._botcommand import BotCommand
from ._botcommandscope import (
BotCommandScope,
BotCommandScopeAllChatAdministrators,
BotCommandScopeAllGroupChats,
BotCommandScopeAllPrivateChats,
BotCommandScopeChat,
BotCommandScopeChatAdministrators,
BotCommandScopeChatMember,
BotCommandScopeDefault,
)
from ._botdescription import BotDescription, BotShortDescription
from ._botname import BotName
from ._business import (
BusinessConnection,
BusinessIntro,
BusinessLocation,
BusinessMessagesDeleted,
BusinessOpeningHours,
BusinessOpeningHoursInterval,
)
from ._callbackquery import CallbackQuery
from ._chat import Chat
from ._chatadministratorrights import ChatAdministratorRights
from ._chatbackground import (
BackgroundFill,
BackgroundFillFreeformGradient,
BackgroundFillGradient,
BackgroundFillSolid,
BackgroundType,
BackgroundTypeChatTheme,
BackgroundTypeFill,
BackgroundTypePattern,
BackgroundTypeWallpaper,
ChatBackground,
)
from ._chatboost import (
ChatBoost,
ChatBoostAdded,
ChatBoostRemoved,
ChatBoostSource,
ChatBoostSourceGiftCode,
ChatBoostSourceGiveaway,
ChatBoostSourcePremium,
ChatBoostUpdated,
UserChatBoosts,
)
from ._chatfullinfo import ChatFullInfo
from ._chatinvitelink import ChatInviteLink
from ._chatjoinrequest import ChatJoinRequest
from ._chatlocation import ChatLocation
from ._chatmember import (
ChatMember,
ChatMemberAdministrator,
ChatMemberBanned,
ChatMemberLeft,
ChatMemberMember,
ChatMemberOwner,
ChatMemberRestricted,
)
from ._chatmemberupdated import ChatMemberUpdated
from ._chatpermissions import ChatPermissions
from ._choseninlineresult import ChosenInlineResult
from ._copytextbutton import CopyTextButton
from ._dice import Dice
from ._files.animation import Animation
from ._files.audio import Audio
from ._files.chatphoto import ChatPhoto
from ._files.contact import Contact
from ._files.document import Document
from ._files.file import File
from ._files.inputfile import InputFile
from ._files.inputmedia import (
InputMedia,
InputMediaAnimation,
InputMediaAudio,
InputMediaDocument,
InputMediaPhoto,
InputMediaVideo,
InputPaidMedia,
InputPaidMediaPhoto,
InputPaidMediaVideo,
)
from ._files.inputsticker import InputSticker
from ._files.location import Location
from ._files.photosize import PhotoSize
from ._files.sticker import MaskPosition, Sticker, StickerSet
from ._files.venue import Venue
from ._files.video import Video
from ._files.videonote import VideoNote
from ._files.voice import Voice
from ._forcereply import ForceReply
from ._forumtopic import (
ForumTopic,
ForumTopicClosed,
ForumTopicCreated,
ForumTopicEdited,
ForumTopicReopened,
GeneralForumTopicHidden,
GeneralForumTopicUnhidden,
)
from ._games.callbackgame import CallbackGame
from ._games.game import Game
from ._games.gamehighscore import GameHighScore
from ._gifts import Gift, Gifts
from ._giveaway import Giveaway, GiveawayCompleted, GiveawayCreated, GiveawayWinners
from ._inline.inlinekeyboardbutton import InlineKeyboardButton
from ._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from ._inline.inlinequery import InlineQuery
from ._inline.inlinequeryresult import InlineQueryResult
from ._inline.inlinequeryresultarticle import InlineQueryResultArticle
from ._inline.inlinequeryresultaudio import InlineQueryResultAudio
from ._inline.inlinequeryresultcachedaudio import InlineQueryResultCachedAudio
from ._inline.inlinequeryresultcacheddocument import InlineQueryResultCachedDocument
from ._inline.inlinequeryresultcachedgif import InlineQueryResultCachedGif
from ._inline.inlinequeryresultcachedmpeg4gif import InlineQueryResultCachedMpeg4Gif
from ._inline.inlinequeryresultcachedphoto import InlineQueryResultCachedPhoto
from ._inline.inlinequeryresultcachedsticker import InlineQueryResultCachedSticker
from ._inline.inlinequeryresultcachedvideo import InlineQueryResultCachedVideo
from ._inline.inlinequeryresultcachedvoice import InlineQueryResultCachedVoice
from ._inline.inlinequeryresultcontact import InlineQueryResultContact
from ._inline.inlinequeryresultdocument import InlineQueryResultDocument
from ._inline.inlinequeryresultgame import InlineQueryResultGame
from ._inline.inlinequeryresultgif import InlineQueryResultGif
from ._inline.inlinequeryresultlocation import InlineQueryResultLocation
from ._inline.inlinequeryresultmpeg4gif import InlineQueryResultMpeg4Gif
from ._inline.inlinequeryresultphoto import InlineQueryResultPhoto
from ._inline.inlinequeryresultsbutton import InlineQueryResultsButton
from ._inline.inlinequeryresultvenue import InlineQueryResultVenue
from ._inline.inlinequeryresultvideo import InlineQueryResultVideo
from ._inline.inlinequeryresultvoice import InlineQueryResultVoice
from ._inline.inputcontactmessagecontent import InputContactMessageContent
from ._inline.inputinvoicemessagecontent import InputInvoiceMessageContent
from ._inline.inputlocationmessagecontent import InputLocationMessageContent
from ._inline.inputmessagecontent import InputMessageContent
from ._inline.inputtextmessagecontent import InputTextMessageContent
from ._inline.inputvenuemessagecontent import InputVenueMessageContent
from ._inline.preparedinlinemessage import PreparedInlineMessage
from ._keyboardbutton import KeyboardButton
from ._keyboardbuttonpolltype import KeyboardButtonPollType
from ._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUsers
from ._linkpreviewoptions import LinkPreviewOptions
from ._loginurl import LoginUrl
from ._menubutton import MenuButton, MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
from ._message import InaccessibleMessage, MaybeInaccessibleMessage, Message
from ._messageautodeletetimerchanged import MessageAutoDeleteTimerChanged
from ._messageentity import MessageEntity
from ._messageid import MessageId
from ._messageorigin import (
MessageOrigin,
MessageOriginChannel,
MessageOriginChat,
MessageOriginHiddenUser,
MessageOriginUser,
)
from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
from ._paidmedia import (
PaidMedia,
PaidMediaInfo,
PaidMediaPhoto,
PaidMediaPreview,
PaidMediaPurchased,
PaidMediaVideo,
)
from ._passport.credentials import (
Credentials,
DataCredentials,
EncryptedCredentials,
FileCredentials,
SecureData,
SecureValue,
)
from ._passport.data import IdDocumentData, PersonalDetails, ResidentialAddress
from ._passport.encryptedpassportelement import EncryptedPassportElement
from ._passport.passportdata import PassportData
from ._passport.passportelementerrors import (
PassportElementError,
PassportElementErrorDataField,
PassportElementErrorFile,
PassportElementErrorFiles,
PassportElementErrorFrontSide,
PassportElementErrorReverseSide,
PassportElementErrorSelfie,
PassportElementErrorTranslationFile,
PassportElementErrorTranslationFiles,
PassportElementErrorUnspecified,
)
from ._passport.passportfile import PassportFile
from ._payment.invoice import Invoice
from ._payment.labeledprice import LabeledPrice
from ._payment.orderinfo import OrderInfo
from ._payment.precheckoutquery import PreCheckoutQuery
from ._payment.refundedpayment import RefundedPayment
from ._payment.shippingaddress import ShippingAddress
from ._payment.shippingoption import ShippingOption
from ._payment.shippingquery import ShippingQuery
from ._payment.stars import (
RevenueWithdrawalState,
RevenueWithdrawalStateFailed,
RevenueWithdrawalStatePending,
RevenueWithdrawalStateSucceeded,
StarTransaction,
StarTransactions,
TransactionPartner,
TransactionPartnerFragment,
TransactionPartnerOther,
TransactionPartnerTelegramAds,
TransactionPartnerTelegramApi,
TransactionPartnerUser,
)
from ._payment.successfulpayment import SuccessfulPayment
from ._poll import InputPollOption, Poll, PollAnswer, PollOption
from ._proximityalerttriggered import ProximityAlertTriggered
from ._reaction import (
ReactionCount,
ReactionType,
ReactionTypeCustomEmoji,
ReactionTypeEmoji,
ReactionTypePaid,
)
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
from ._replykeyboardmarkup import ReplyKeyboardMarkup
from ._replykeyboardremove import ReplyKeyboardRemove
from ._sentwebappmessage import SentWebAppMessage
from ._shared import ChatShared, SharedUser, UsersShared
from ._story import Story
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
from ._telegramobject import TelegramObject
from ._update import Update
from ._user import User
from ._userprofilephotos import UserProfilePhotos
from ._videochat import (
VideoChatEnded,
VideoChatParticipantsInvited,
VideoChatScheduled,
VideoChatStarted,
)
from ._webappdata import WebAppData
from ._webappinfo import WebAppInfo
from ._webhookinfo import WebhookInfo
from ._writeaccessallowed import WriteAccessAllowed
#: :obj:`str`: The version of the `python-telegram-bot` library as string.
#: To get detailed information about the version number, please use :data:`__version_info__`
#: instead.
__version__: str = _version.__version__
#: :class:`typing.NamedTuple`: A tuple containing the five components of the version number:
#: `major`, `minor`, `micro`, `releaselevel`, and `serial`.
#: All values except `releaselevel` are integers.
#: The release level is ``'alpha'``, ``'beta'``, ``'candidate'``, or ``'final'``.
#: The components can also be accessed by name, so ``__version_info__[0]`` is equivalent to
#: ``__version_info__.major`` and so on.
#:
#: .. versionadded:: 20.0
__version_info__: _version.Version = _version.__version_info__
#: :obj:`str`: Shortcut for :const:`telegram.constants.BOT_API_VERSION`.
#:
#: .. versionchanged:: 20.0
#: This constant was previously named ``bot_api_version``.
__bot_api_version__: str = constants.BOT_API_VERSION
#: :class:`typing.NamedTuple`: Shortcut for :const:`telegram.constants.BOT_API_VERSION_INFO`.
#:
#: .. versionadded:: 20.0
__bot_api_version_info__: constants._BotAPIVersion = constants.BOT_API_VERSION_INFO

View File

@@ -0,0 +1,54 @@
# !/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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/].
# pylint: disable=missing-module-docstring
# ruff: noqa: T201, D100, S603, S607
import subprocess
import sys
from typing import Optional
from . import __version__ as telegram_ver
from .constants import BOT_API_VERSION
def _git_revision() -> Optional[str]:
try:
output = subprocess.check_output(
["git", "describe", "--long", "--tags"], stderr=subprocess.STDOUT
)
except (subprocess.SubprocessError, OSError):
return None
return output.decode().strip()
def print_ver_info() -> None:
"""Prints version information for python-telegram-bot, the Bot API and Python."""
git_revision = _git_revision()
print(f"python-telegram-bot {telegram_ver}" + (f" ({git_revision})" if git_revision else ""))
print(f"Bot API {BOT_API_VERSION}")
sys_version = sys.version.replace("\n", " ")
print(f"Python {sys_version}")
def main() -> None:
"""Prints version information for python-telegram-bot, the Bot API and Python."""
print_ver_info()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,92 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram Birthday."""
from datetime import date
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class Birthdate(TelegramObject):
"""
This object describes the birthdate of a user.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`day`, and :attr:`month` are equal.
.. versionadded:: 21.1
Args:
day (:obj:`int`): Day of the user's birth; 1-31.
month (:obj:`int`): Month of the user's birth; 1-12.
year (:obj:`int`, optional): Year of the user's birth.
Attributes:
day (:obj:`int`): Day of the user's birth; 1-31.
month (:obj:`int`): Month of the user's birth; 1-12.
year (:obj:`int`): Optional. Year of the user's birth.
"""
__slots__ = ("day", "month", "year")
def __init__(
self,
day: int,
month: int,
year: Optional[int] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.day: int = day
self.month: int = month
# Optional
self.year: Optional[int] = year
self._id_attrs = (
self.day,
self.month,
)
self._freeze()
def to_date(self, year: Optional[int] = None) -> date:
"""Return the birthdate as a date object.
.. versionchanged:: 21.2
Now returns a :obj:`datetime.date` object instead of a :obj:`datetime.datetime` object,
as was originally intended.
Args:
year (:obj:`int`, optional): The year to use. Required, if the :attr:`year` was not
present.
Returns:
:obj:`datetime.date`: The birthdate as a date object.
"""
if self.year is None and year is None:
raise ValueError(
"The `year` argument is required if the `year` attribute was not present."
)
return date(year or self.year, self.month, self.day) # type: ignore[arg-type]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram Bot Command."""
from typing import Final, Optional
from telegram import constants
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class BotCommand(TelegramObject):
"""
This object represents a bot command.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`command` and :attr:`description` are equal.
Args:
command (:obj:`str`): Text of the command; :tg-const:`telegram.BotCommand.MIN_COMMAND`-
:tg-const:`telegram.BotCommand.MAX_COMMAND` characters. Can contain only lowercase
English letters, digits and underscores.
description (:obj:`str`): Description of the command;
:tg-const:`telegram.BotCommand.MIN_DESCRIPTION`-
:tg-const:`telegram.BotCommand.MAX_DESCRIPTION` characters.
Attributes:
command (:obj:`str`): Text of the command; :tg-const:`telegram.BotCommand.MIN_COMMAND`-
:tg-const:`telegram.BotCommand.MAX_COMMAND` characters. Can contain only lowercase
English letters, digits and underscores.
description (:obj:`str`): Description of the command;
:tg-const:`telegram.BotCommand.MIN_DESCRIPTION`-
:tg-const:`telegram.BotCommand.MAX_DESCRIPTION` characters.
"""
__slots__ = ("command", "description")
def __init__(self, command: str, description: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.command: str = command
self.description: str = description
self._id_attrs = (self.command, self.description)
self._freeze()
MIN_COMMAND: Final[int] = constants.BotCommandLimit.MIN_COMMAND
""":const:`telegram.constants.BotCommandLimit.MIN_COMMAND`
.. versionadded:: 20.0
"""
MAX_COMMAND: Final[int] = constants.BotCommandLimit.MAX_COMMAND
""":const:`telegram.constants.BotCommandLimit.MAX_COMMAND`
.. versionadded:: 20.0
"""
MIN_DESCRIPTION: Final[int] = constants.BotCommandLimit.MIN_DESCRIPTION
""":const:`telegram.constants.BotCommandLimit.MIN_DESCRIPTION`
.. versionadded:: 20.0
"""
MAX_DESCRIPTION: Final[int] = constants.BotCommandLimit.MAX_DESCRIPTION
""":const:`telegram.constants.BotCommandLimit.MAX_DESCRIPTION`
.. versionadded:: 20.0
"""

View File

@@ -0,0 +1,273 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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/].
# pylint: disable=redefined-builtin
"""This module contains objects representing Telegram bot command scopes."""
from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants
from telegram._telegramobject import TelegramObject
from telegram._utils import enum
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class BotCommandScope(TelegramObject):
"""Base class for objects that represent the scope to which bot commands are applied.
Currently, the following 7 scopes are supported:
* :class:`telegram.BotCommandScopeDefault`
* :class:`telegram.BotCommandScopeAllPrivateChats`
* :class:`telegram.BotCommandScopeAllGroupChats`
* :class:`telegram.BotCommandScopeAllChatAdministrators`
* :class:`telegram.BotCommandScopeChat`
* :class:`telegram.BotCommandScopeChatAdministrators`
* :class:`telegram.BotCommandScopeChatMember`
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal. For subclasses with additional attributes,
the notion of equality is overridden.
Note:
Please see the `official docs`_ on how Telegram determines which commands to display.
.. _`official docs`: https://core.telegram.org/bots/api#determining-list-of-commands
.. versionadded:: 13.7
Args:
type (:obj:`str`): Scope type.
Attributes:
type (:obj:`str`): Scope type.
"""
__slots__ = ("type",)
DEFAULT: Final[str] = constants.BotCommandScopeType.DEFAULT
""":const:`telegram.constants.BotCommandScopeType.DEFAULT`"""
ALL_PRIVATE_CHATS: Final[str] = constants.BotCommandScopeType.ALL_PRIVATE_CHATS
""":const:`telegram.constants.BotCommandScopeType.ALL_PRIVATE_CHATS`"""
ALL_GROUP_CHATS: Final[str] = constants.BotCommandScopeType.ALL_GROUP_CHATS
""":const:`telegram.constants.BotCommandScopeType.ALL_GROUP_CHATS`"""
ALL_CHAT_ADMINISTRATORS: Final[str] = constants.BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
""":const:`telegram.constants.BotCommandScopeType.ALL_CHAT_ADMINISTRATORS`"""
CHAT: Final[str] = constants.BotCommandScopeType.CHAT
""":const:`telegram.constants.BotCommandScopeType.CHAT`"""
CHAT_ADMINISTRATORS: Final[str] = constants.BotCommandScopeType.CHAT_ADMINISTRATORS
""":const:`telegram.constants.BotCommandScopeType.CHAT_ADMINISTRATORS`"""
CHAT_MEMBER: Final[str] = constants.BotCommandScopeType.CHAT_MEMBER
""":const:`telegram.constants.BotCommandScopeType.CHAT_MEMBER`"""
def __init__(self, type: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.type: str = enum.get_member(constants.BotCommandScopeType, type, type)
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BotCommandScope"]:
"""Converts JSON data to the appropriate :class:`BotCommandScope` object, i.e. takes
care of selecting the correct subclass.
Args:
data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
:obj:`None`, in which case shortcut methods will not be available.
.. versionchanged:: 21.4
:paramref:`bot` is now optional and defaults to :obj:`None`
Returns:
The Telegram object.
"""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: dict[str, type[BotCommandScope]] = {
cls.DEFAULT: BotCommandScopeDefault,
cls.ALL_PRIVATE_CHATS: BotCommandScopeAllPrivateChats,
cls.ALL_GROUP_CHATS: BotCommandScopeAllGroupChats,
cls.ALL_CHAT_ADMINISTRATORS: BotCommandScopeAllChatAdministrators,
cls.CHAT: BotCommandScopeChat,
cls.CHAT_ADMINISTRATORS: BotCommandScopeChatAdministrators,
cls.CHAT_MEMBER: BotCommandScopeChatMember,
}
if cls is BotCommandScope and data.get("type") in _class_mapping:
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
return super().de_json(data=data, bot=bot)
class BotCommandScopeDefault(BotCommandScope):
"""Represents the default scope of bot commands. Default commands are used if no commands with
a `narrower scope`_ are specified for the user.
.. _`narrower scope`: https://core.telegram.org/bots/api#determining-list-of-commands
.. versionadded:: 13.7
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.DEFAULT`.
"""
__slots__ = ()
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.DEFAULT, api_kwargs=api_kwargs)
self._freeze()
class BotCommandScopeAllPrivateChats(BotCommandScope):
"""Represents the scope of bot commands, covering all private chats.
.. versionadded:: 13.7
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.ALL_PRIVATE_CHATS`.
"""
__slots__ = ()
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.ALL_PRIVATE_CHATS, api_kwargs=api_kwargs)
self._freeze()
class BotCommandScopeAllGroupChats(BotCommandScope):
"""Represents the scope of bot commands, covering all group and supergroup chats.
.. versionadded:: 13.7
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.ALL_GROUP_CHATS`.
"""
__slots__ = ()
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.ALL_GROUP_CHATS, api_kwargs=api_kwargs)
self._freeze()
class BotCommandScopeAllChatAdministrators(BotCommandScope):
"""Represents the scope of bot commands, covering all group and supergroup chat administrators.
.. versionadded:: 13.7
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.ALL_CHAT_ADMINISTRATORS`.
"""
__slots__ = ()
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.ALL_CHAT_ADMINISTRATORS, api_kwargs=api_kwargs)
self._freeze()
class BotCommandScopeChat(BotCommandScope):
"""Represents the scope of bot commands, covering a specific chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` and :attr:`chat_id` are equal.
.. versionadded:: 13.7
Args:
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.CHAT`.
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
"""
__slots__ = ("chat_id",)
def __init__(self, chat_id: Union[str, int], *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.CHAT, api_kwargs=api_kwargs)
with self._unfrozen():
self.chat_id: Union[str, int] = (
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
)
self._id_attrs = (self.type, self.chat_id)
class BotCommandScopeChatAdministrators(BotCommandScope):
"""Represents the scope of bot commands, covering all administrators of a specific group or
supergroup chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` and :attr:`chat_id` are equal.
.. versionadded:: 13.7
Args:
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.CHAT_ADMINISTRATORS`.
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
"""
__slots__ = ("chat_id",)
def __init__(self, chat_id: Union[str, int], *, api_kwargs: Optional[JSONDict] = None):
super().__init__(type=BotCommandScope.CHAT_ADMINISTRATORS, api_kwargs=api_kwargs)
with self._unfrozen():
self.chat_id: Union[str, int] = (
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
)
self._id_attrs = (self.type, self.chat_id)
class BotCommandScopeChatMember(BotCommandScope):
"""Represents the scope of bot commands, covering a specific member of a group or supergroup
chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type`, :attr:`chat_id` and :attr:`user_id` are equal.
.. versionadded:: 13.7
Args:
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
user_id (:obj:`int`): Unique identifier of the target user.
Attributes:
type (:obj:`str`): Scope type :tg-const:`telegram.BotCommandScope.CHAT_MEMBER`.
chat_id (:obj:`str` | :obj:`int`): |chat_id_group|
user_id (:obj:`int`): Unique identifier of the target user.
"""
__slots__ = ("chat_id", "user_id")
def __init__(
self, chat_id: Union[str, int], user_id: int, *, api_kwargs: Optional[JSONDict] = None
):
super().__init__(type=BotCommandScope.CHAT_MEMBER, api_kwargs=api_kwargs)
with self._unfrozen():
self.chat_id: Union[str, int] = (
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
)
self.user_id: int = user_id
self._id_attrs = (self.type, self.chat_id, self.user_id)

View File

@@ -0,0 +1,77 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 that represent a Telegram bots (short) description."""
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class BotDescription(TelegramObject):
"""This object represents the bot's description.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`description` is equal.
.. versionadded:: 20.2
Args:
description (:obj:`str`): The bot's description.
Attributes:
description (:obj:`str`): The bot's description.
"""
__slots__ = ("description",)
def __init__(self, description: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.description: str = description
self._id_attrs = (self.description,)
self._freeze()
class BotShortDescription(TelegramObject):
"""This object represents the bot's short description.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`short_description` is equal.
.. versionadded:: 20.2
Args:
short_description (:obj:`str`): The bot's short description.
Attributes:
short_description (:obj:`str`): The bot's short description.
"""
__slots__ = ("short_description",)
def __init__(self, short_description: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.short_description: str = short_description
self._id_attrs = (self.short_description,)
self._freeze()

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represent a Telegram bots name."""
from typing import Final, Optional
from telegram import constants
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class BotName(TelegramObject):
"""This object represents the bot's name.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`name` is equal.
.. versionadded:: 20.3
Args:
name (:obj:`str`): The bot's name.
Attributes:
name (:obj:`str`): The bot's name.
"""
__slots__ = ("name",)
def __init__(self, name: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.name: str = name
self._id_attrs = (self.name,)
self._freeze()
MAX_LENGTH: Final[int] = constants.BotNameLimit.MAX_NAME_LENGTH
""":const:`telegram.constants.BotNameLimit.MAX_NAME_LENGTH`"""

View File

@@ -0,0 +1,456 @@
#!/usr/bin/env python
# pylint: disable=redefined-builtin
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 the Telegram Business related classes."""
from collections.abc import Sequence
from datetime import datetime
from typing import TYPE_CHECKING, Optional
from telegram._chat import Chat
from telegram._files.location import Location
from telegram._files.sticker import Sticker
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class BusinessConnection(TelegramObject):
"""
Describes the connection of the bot with a business account.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal if their :attr:`id`, :attr:`user`, :attr:`user_chat_id`, :attr:`date`,
:attr:`can_reply`, and :attr:`is_enabled` are equal.
.. versionadded:: 21.1
Args:
id (:obj:`str`): Unique identifier of the business connection.
user (:class:`telegram.User`): Business account user that created the business connection.
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
business connection.
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
chats that were active in the last 24 hours.
is_enabled (:obj:`bool`): True, if the connection is active.
Attributes:
id (:obj:`str`): Unique identifier of the business connection.
user (:class:`telegram.User`): Business account user that created the business connection.
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
business connection.
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
chats that were active in the last 24 hours.
is_enabled (:obj:`bool`): True, if the connection is active.
"""
__slots__ = (
"can_reply",
"date",
"id",
"is_enabled",
"user",
"user_chat_id",
)
def __init__(
self,
id: str,
user: "User",
user_chat_id: int,
date: datetime,
can_reply: bool,
is_enabled: bool,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.id: str = id
self.user: User = user
self.user_chat_id: int = user_chat_id
self.date: datetime = date
self.can_reply: bool = can_reply
self.is_enabled: bool = is_enabled
self._id_attrs = (
self.id,
self.user,
self.user_chat_id,
self.date,
self.can_reply,
self.is_enabled,
)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BusinessConnection"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["date"] = from_timestamp(data.get("date"), tzinfo=loc_tzinfo)
data["user"] = User.de_json(data.get("user"), bot)
return super().de_json(data=data, bot=bot)
class BusinessMessagesDeleted(TelegramObject):
"""
This object is received when messages are deleted from a connected business account.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal if their :attr:`business_connection_id`, :attr:`message_ids`, and
:attr:`chat` are equal.
.. versionadded:: 21.1
Args:
business_connection_id (:obj:`str`): Unique identifier of the business connection.
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
may not have access to the chat or the corresponding user.
message_ids (Sequence[:obj:`int`]): A list of identifiers of the deleted messages in the
chat of the business account.
Attributes:
business_connection_id (:obj:`str`): Unique identifier of the business connection.
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
may not have access to the chat or the corresponding user.
message_ids (tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
chat of the business account.
"""
__slots__ = (
"business_connection_id",
"chat",
"message_ids",
)
def __init__(
self,
business_connection_id: str,
chat: Chat,
message_ids: Sequence[int],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.business_connection_id: str = business_connection_id
self.chat: Chat = chat
self.message_ids: tuple[int, ...] = parse_sequence_arg(message_ids)
self._id_attrs = (
self.business_connection_id,
self.chat,
self.message_ids,
)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BusinessMessagesDeleted"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["chat"] = Chat.de_json(data.get("chat"), bot)
return super().de_json(data=data, bot=bot)
class BusinessIntro(TelegramObject):
"""
This object contains information about the start page settings of a Telegram Business account.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`title`, :attr:`message` and :attr:`sticker` are equal.
.. versionadded:: 21.1
Args:
title (:obj:`str`, optional): Title text of the business intro.
message (:obj:`str`, optional): Message text of the business intro.
sticker (:class:`telegram.Sticker`, optional): Sticker of the business intro.
Attributes:
title (:obj:`str`): Optional. Title text of the business intro.
message (:obj:`str`): Optional. Message text of the business intro.
sticker (:class:`telegram.Sticker`): Optional. Sticker of the business intro.
"""
__slots__ = (
"message",
"sticker",
"title",
)
def __init__(
self,
title: Optional[str] = None,
message: Optional[str] = None,
sticker: Optional[Sticker] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.title: Optional[str] = title
self.message: Optional[str] = message
self.sticker: Optional[Sticker] = sticker
self._id_attrs = (self.title, self.message, self.sticker)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BusinessIntro"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
return super().de_json(data=data, bot=bot)
class BusinessLocation(TelegramObject):
"""
This object contains information about the location of a Telegram Business account.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`address` is equal.
.. versionadded:: 21.1
Args:
address (:obj:`str`): Address of the business.
location (:class:`telegram.Location`, optional): Location of the business.
Attributes:
address (:obj:`str`): Address of the business.
location (:class:`telegram.Location`): Optional. Location of the business.
"""
__slots__ = (
"address",
"location",
)
def __init__(
self,
address: str,
location: Optional[Location] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.address: str = address
self.location: Optional[Location] = location
self._id_attrs = (self.address,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BusinessLocation"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["location"] = Location.de_json(data.get("location"), bot)
return super().de_json(data=data, bot=bot)
class BusinessOpeningHoursInterval(TelegramObject):
"""
This object describes an interval of time during which a business is open.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`opening_minute` and :attr:`closing_minute` are equal.
.. versionadded:: 21.1
Examples:
A day has (24 * 60 =) 1440 minutes, a week has (7 * 1440 =) 10080 minutes.
Starting the the minute's sequence from Monday, example values of
:attr:`opening_minute`, :attr:`closing_minute` will map to the following day times:
* Monday - 8am to 8:30pm:
- ``opening_minute = 480`` :guilabel:`8 * 60`
- ``closing_minute = 1230`` :guilabel:`20 * 60 + 30`
* Tuesday - 24 hours:
- ``opening_minute = 1440`` :guilabel:`24 * 60`
- ``closing_minute = 2879`` :guilabel:`2 * 24 * 60 - 1`
* Sunday - 12am - 11:58pm:
- ``opening_minute = 8640`` :guilabel:`6 * 24 * 60`
- ``closing_minute = 10078`` :guilabel:`7 * 24 * 60 - 2`
Args:
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
marking the start of the time interval during which the business is open;
0 - 7 * 24 * 60.
closing_minute (:obj:`int`): The minute's
sequence number in a week, starting on Monday, marking the end of the time interval
during which the business is open; 0 - 8 * 24 * 60
Attributes:
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
marking the start of the time interval during which the business is open;
0 - 7 * 24 * 60.
closing_minute (:obj:`int`): The minute's
sequence number in a week, starting on Monday, marking the end of the time interval
during which the business is open; 0 - 8 * 24 * 60
"""
__slots__ = ("_closing_time", "_opening_time", "closing_minute", "opening_minute")
def __init__(
self,
opening_minute: int,
closing_minute: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.opening_minute: int = opening_minute
self.closing_minute: int = closing_minute
self._opening_time: Optional[tuple[int, int, int]] = None
self._closing_time: Optional[tuple[int, int, int]] = None
self._id_attrs = (self.opening_minute, self.closing_minute)
self._freeze()
def _parse_minute(self, minute: int) -> tuple[int, int, int]:
return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60)
@property
def opening_time(self) -> tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns:
tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
"""
if self._opening_time is None:
self._opening_time = self._parse_minute(self.opening_minute)
return self._opening_time
@property
def closing_time(self) -> tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns:
tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
"""
if self._closing_time is None:
self._closing_time = self._parse_minute(self.closing_minute)
return self._closing_time
class BusinessOpeningHours(TelegramObject):
"""
This object describes the opening hours of a business.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`time_zone_name` and :attr:`opening_hours` are equal.
.. versionadded:: 21.1
Args:
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
hours are defined.
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
time intervals describing business opening hours.
Attributes:
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
hours are defined.
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
time intervals describing business opening hours.
"""
__slots__ = ("opening_hours", "time_zone_name")
def __init__(
self,
time_zone_name: str,
opening_hours: Sequence[BusinessOpeningHoursInterval],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.time_zone_name: str = time_zone_name
self.opening_hours: Sequence[BusinessOpeningHoursInterval] = parse_sequence_arg(
opening_hours
)
self._id_attrs = (self.time_zone_name, self.opening_hours)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BusinessOpeningHours"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["opening_hours"] = BusinessOpeningHoursInterval.de_list(
data.get("opening_hours"), bot
)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,895 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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/].
# pylint: disable=redefined-builtin
"""This module contains an object that represents a Telegram CallbackQuery"""
from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants
from telegram._files.location import Location
from telegram._message import MaybeInaccessibleMessage, Message
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram._utils.types import JSONDict, ODVInput, ReplyMarkup
if TYPE_CHECKING:
from telegram import (
Bot,
GameHighScore,
InlineKeyboardMarkup,
InputMedia,
LinkPreviewOptions,
MessageEntity,
MessageId,
ReplyParameters,
)
class CallbackQuery(TelegramObject):
"""
This object represents an incoming callback query from a callback button in an inline keyboard.
If the button that originated the query was attached to a message sent by the bot, the field
:attr:`message` will be present. If the button was attached to a message sent via the bot (in
inline mode), the field :attr:`inline_message_id` will be present.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`id` is equal.
Note:
* In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead.
* Exactly one of the fields :attr:`data` or :attr:`game_short_name` will be present.
* After the user presses an inline button, Telegram clients will display a progress bar
until you call :attr:`answer`. It is, therefore, necessary to react
by calling :attr:`telegram.Bot.answer_callback_query` even if no notification to the user
is needed (e.g., without specifying any of the optional parameters).
* If you're using :attr:`telegram.ext.ExtBot.callback_data_cache`, :attr:`data` may be
an instance
of :class:`telegram.ext.InvalidCallbackData`. This will be the case, if the data
associated with the button triggering the :class:`telegram.CallbackQuery` was already
deleted or if :attr:`data` was manipulated by a malicious client.
.. versionadded:: 13.6
Args:
id (:obj:`str`): Unique identifier for this query.
from_user (:class:`telegram.User`): Sender.
chat_instance (:obj:`str`): Global identifier, uniquely corresponding to the chat to which
the message with the callback button was sent. Useful for high scores in games.
message (:class:`telegram.MaybeInaccessibleMessage`, optional): Message sent by the bot
with the callback button that originated the query.
.. versionchanged:: 20.8
Accept objects of type :class:`telegram.MaybeInaccessibleMessage` since Bot API 7.0.
data (:obj:`str`, optional): Data associated with the callback button. Be aware that the
message, which originated the query, can contain no callback buttons with this data.
inline_message_id (:obj:`str`, optional): Identifier of the message sent via the bot in
inline mode, that originated the query.
game_short_name (:obj:`str`, optional): Short name of a Game to be returned, serves as
the unique identifier for the game.
Attributes:
id (:obj:`str`): Unique identifier for this query.
from_user (:class:`telegram.User`): Sender.
chat_instance (:obj:`str`): Global identifier, uniquely corresponding to the chat to which
the message with the callback button was sent. Useful for high scores in games.
message (:class:`telegram.MaybeInaccessibleMessage`): Optional. Message sent by the bot
with the callback button that originated the query.
.. versionchanged:: 20.8
Objects may be of type :class:`telegram.MaybeInaccessibleMessage` since Bot API
7.0.
data (:obj:`str` | :obj:`object`): Optional. Data associated with the callback button.
Be aware that the message, which originated the query, can contain no callback buttons
with this data.
Tip:
The value here is the same as the value passed in
:paramref:`telegram.InlineKeyboardButton.callback_data`.
inline_message_id (:obj:`str`): Optional. Identifier of the message sent via the bot in
inline mode, that originated the query.
game_short_name (:obj:`str`): Optional. Short name of a Game to be returned, serves as
the unique identifier for the game.
"""
__slots__ = (
"chat_instance",
"data",
"from_user",
"game_short_name",
"id",
"inline_message_id",
"message",
)
def __init__(
self,
id: str,
from_user: User,
chat_instance: str,
message: Optional[MaybeInaccessibleMessage] = None,
data: Optional[str] = None,
inline_message_id: Optional[str] = None,
game_short_name: Optional[str] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.id: str = id
self.from_user: User = from_user
self.chat_instance: str = chat_instance
# Optionals
self.message: Optional[MaybeInaccessibleMessage] = message
self.data: Optional[str] = data
self.inline_message_id: Optional[str] = inline_message_id
self.game_short_name: Optional[str] = game_short_name
self._id_attrs = (self.id,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["CallbackQuery"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["from_user"] = User.de_json(data.pop("from", None), bot)
data["message"] = Message.de_json(data.get("message"), bot)
return super().de_json(data=data, bot=bot)
async def answer(
self,
text: Optional[str] = None,
show_alert: Optional[bool] = None,
url: Optional[str] = None,
cache_time: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await bot.answer_callback_query(update.callback_query.id, *args, **kwargs)
For the documentation of the arguments, please see
:meth:`telegram.Bot.answer_callback_query`.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().answer_callback_query(
callback_query_id=self.id,
text=text,
show_alert=show_alert,
url=url,
cache_time=cache_time,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
def _get_message(self, action: str = "edit") -> Message:
"""Helper method to get the message for the shortcut methods. Must be called only
if :attr:`inline_message_id` is *not* set.
"""
if not isinstance(self.message, Message):
raise TypeError(f"Cannot {action} an inaccessible message")
return self.message
async def edit_message_text(
self,
text: str,
parse_mode: ODVInput[str] = DEFAULT_NONE,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
entities: Optional[Sequence["MessageEntity"]] = None,
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
*,
disable_web_page_preview: Optional[bool] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.edit_text(*args, **kwargs)
or::
await bot.edit_message_text(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs,
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.edit_message_text` and :meth:`telegram.Message.edit_text`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().edit_message_text(
inline_message_id=self.inline_message_id,
text=text,
parse_mode=parse_mode,
disable_web_page_preview=disable_web_page_preview,
link_preview_options=link_preview_options,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
entities=entities,
chat_id=None,
message_id=None,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().edit_text(
text=text,
parse_mode=parse_mode,
disable_web_page_preview=disable_web_page_preview,
link_preview_options=link_preview_options,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
entities=entities,
)
async def edit_message_caption(
self,
caption: Optional[str] = None,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None,
show_caption_above_media: Optional[bool] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.edit_caption(*args, **kwargs)
or::
await bot.edit_message_caption(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs,
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.edit_message_caption` and :meth:`telegram.Message.edit_caption`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().edit_message_caption(
caption=caption,
inline_message_id=self.inline_message_id,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
parse_mode=parse_mode,
api_kwargs=api_kwargs,
caption_entities=caption_entities,
chat_id=None,
message_id=None,
show_caption_above_media=show_caption_above_media,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().edit_caption(
caption=caption,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
parse_mode=parse_mode,
api_kwargs=api_kwargs,
caption_entities=caption_entities,
show_caption_above_media=show_caption_above_media,
)
async def edit_message_reply_markup(
self,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.edit_reply_markup(*args, **kwargs)
or::
await bot.edit_message_reply_markup(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.edit_message_reply_markup` and
:meth:`telegram.Message.edit_reply_markup`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().edit_message_reply_markup(
reply_markup=reply_markup,
inline_message_id=self.inline_message_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
chat_id=None,
message_id=None,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().edit_reply_markup(
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def edit_message_media(
self,
media: "InputMedia",
reply_markup: Optional["InlineKeyboardMarkup"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.edit_media(*args, **kwargs)
or::
await bot.edit_message_media(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.edit_message_media` and :meth:`telegram.Message.edit_media`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is not an inline message, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().edit_message_media(
inline_message_id=self.inline_message_id,
media=media,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
chat_id=None,
message_id=None,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().edit_media(
media=media,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def edit_message_live_location(
self,
latitude: Optional[float] = None,
longitude: Optional[float] = None,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
horizontal_accuracy: Optional[float] = None,
heading: Optional[int] = None,
proximity_alert_radius: Optional[int] = None,
live_period: Optional[int] = None,
*,
location: Optional[Location] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.edit_live_location(*args, **kwargs)
or::
await bot.edit_message_live_location(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.edit_message_live_location` and
:meth:`telegram.Message.edit_live_location`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().edit_message_live_location(
inline_message_id=self.inline_message_id,
latitude=latitude,
longitude=longitude,
location=location,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
horizontal_accuracy=horizontal_accuracy,
heading=heading,
proximity_alert_radius=proximity_alert_radius,
live_period=live_period,
chat_id=None,
message_id=None,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().edit_live_location(
latitude=latitude,
longitude=longitude,
location=location,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
horizontal_accuracy=horizontal_accuracy,
heading=heading,
proximity_alert_radius=proximity_alert_radius,
live_period=live_period,
)
async def stop_message_live_location(
self,
reply_markup: Optional["InlineKeyboardMarkup"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.stop_live_location(*args, **kwargs)
or::
await bot.stop_message_live_location(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.stop_message_live_location` and
:meth:`telegram.Message.stop_live_location`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().stop_message_live_location(
inline_message_id=self.inline_message_id,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
chat_id=None,
message_id=None,
# inline messages can not be sent on behalf of a bcid
business_connection_id=None,
)
return await self._get_message().stop_live_location(
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def set_game_score(
self,
user_id: int,
score: int,
force: Optional[bool] = None,
disable_edit_message: Optional[bool] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> Union[Message, bool]:
"""Shortcut for either::
await update.callback_query.message.set_game_score(*args, **kwargs)
or::
await bot.set_game_score(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.set_game_score` and :meth:`telegram.Message.set_game_score`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
edited Message is returned, otherwise :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().set_game_score(
inline_message_id=self.inline_message_id,
user_id=user_id,
score=score,
force=force,
disable_edit_message=disable_edit_message,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
chat_id=None,
message_id=None,
)
return await self._get_message().set_game_score(
user_id=user_id,
score=score,
force=force,
disable_edit_message=disable_edit_message,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def get_game_high_scores(
self,
user_id: int,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> tuple["GameHighScore", ...]:
"""Shortcut for either::
await update.callback_query.message.get_game_high_score(*args, **kwargs)
or::
await bot.get_game_high_scores(
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.get_game_high_scores` and
:meth:`telegram.Message.get_game_high_scores`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
tuple[:class:`telegram.GameHighScore`]
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
if self.inline_message_id:
return await self.get_bot().get_game_high_scores(
inline_message_id=self.inline_message_id,
user_id=user_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
chat_id=None,
message_id=None,
)
return await self._get_message().get_game_high_scores(
user_id=user_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def delete_message(
self,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await update.callback_query.message.delete(*args, **kwargs)
For the documentation of the arguments, please see :meth:`telegram.Message.delete`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
return await self._get_message(action="delete").delete(
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def pin_message(
self,
disable_notification: ODVInput[bool] = DEFAULT_NONE,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await update.callback_query.message.pin(*args, **kwargs)
For the documentation of the arguments, please see :meth:`telegram.Message.pin`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
return await self._get_message(action="pin").pin(
disable_notification=disable_notification,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def unpin_message(
self,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await update.callback_query.message.unpin(*args, **kwargs)
For the documentation of the arguments, please see :meth:`telegram.Message.unpin`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
return await self._get_message(action="unpin").unpin(
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def copy_message(
self,
chat_id: Union[int, str],
caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None,
disable_notification: ODVInput[bool] = DEFAULT_NONE,
reply_markup: Optional[ReplyMarkup] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
reply_parameters: Optional["ReplyParameters"] = None,
show_caption_above_media: Optional[bool] = None,
allow_paid_broadcast: Optional[bool] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> "MessageId":
"""Shortcut for::
await update.callback_query.message.copy(
from_chat_id=update.message.chat_id,
message_id=update.message.message_id,
*args,
**kwargs
)
For the documentation of the arguments, please see :meth:`telegram.Message.copy`.
.. versionchanged:: 20.8
Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns:
:class:`telegram.MessageId`: On success, returns the MessageId of the sent message.
Raises:
:exc:`TypeError` if :attr:`message` is not accessible.
"""
return await self._get_message(action="copy").copy(
chat_id=chat_id,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=reply_markup,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
protect_content=protect_content,
message_thread_id=message_thread_id,
reply_parameters=reply_parameters,
show_caption_above_media=show_caption_above_media,
allow_paid_broadcast=allow_paid_broadcast,
)
MAX_ANSWER_TEXT_LENGTH: Final[int] = (
constants.CallbackQueryLimit.ANSWER_CALLBACK_QUERY_TEXT_LENGTH
)
"""
:const:`telegram.constants.CallbackQueryLimit.ANSWER_CALLBACK_QUERY_TEXT_LENGTH`
.. versionadded:: 13.2
"""

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 the class which represents a Telegram ChatAdministratorRights."""
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class ChatAdministratorRights(TelegramObject):
"""Represents the rights of an administrator in a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`is_anonymous`, :attr:`can_manage_chat`,
:attr:`can_delete_messages`, :attr:`can_manage_video_chats`, :attr:`can_restrict_members`,
:attr:`can_promote_members`, :attr:`can_change_info`, :attr:`can_invite_users`,
:attr:`can_post_messages`, :attr:`can_edit_messages`, :attr:`can_pin_messages`,
:attr:`can_manage_topics`, :attr:`can_post_stories`, :attr:`can_delete_stories`, and
:attr:`can_edit_stories` are equal.
.. versionadded:: 20.0
.. versionchanged:: 20.0
:attr:`can_manage_topics` is considered as well when comparing objects of
this type in terms of equality.
.. versionchanged:: 20.6
:attr:`can_post_stories`, :attr:`can_edit_stories`, and :attr:`can_delete_stories` are
considered as well when comparing objects of this type in terms of equality.
.. versionchanged:: 21.1
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
changed.
Args:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
chats.
can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or
unban chat members, or access supergroup statistics.
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
administrators with a subset of their own privileges or demote administrators
that they have promoted, directly or indirectly (promoted by administrators that
were appointed by the user).
can_change_info (:obj:`bool`): :obj:`True`, if the user is allowed to change the chat title
, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
the chat.
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can post
messages in the channel, or access channel statistics; for channels only.
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
messages of other users and can pin messages; for channels only.
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
Attributes:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
chats.
can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or
unban chat members, or access supergroup statistics.
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
administrators with a subset of their own privileges or demote administrators that he
has promoted, directly or indirectly (promoted by administrators that were appointed by
the user.)
can_change_info (:obj:`bool`): :obj:`True`, if the user is allowed to change the chat title
,photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
the chat.
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
messages in the channel, or access channel statistics; for channels only.
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
messages of other users and can pin messages; for channels only.
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
"""
__slots__ = (
"can_change_info",
"can_delete_messages",
"can_delete_stories",
"can_edit_messages",
"can_edit_stories",
"can_invite_users",
"can_manage_chat",
"can_manage_topics",
"can_manage_video_chats",
"can_pin_messages",
"can_post_messages",
"can_post_stories",
"can_promote_members",
"can_restrict_members",
"is_anonymous",
)
def __init__(
self,
is_anonymous: bool,
can_manage_chat: bool,
can_delete_messages: bool,
can_manage_video_chats: bool,
can_restrict_members: bool,
can_promote_members: bool,
can_change_info: bool,
can_invite_users: bool,
can_post_stories: bool,
can_edit_stories: bool,
can_delete_stories: bool,
can_post_messages: Optional[bool] = None,
can_edit_messages: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
) -> None:
super().__init__(api_kwargs=api_kwargs)
# Required
self.is_anonymous: bool = is_anonymous
self.can_manage_chat: bool = can_manage_chat
self.can_delete_messages: bool = can_delete_messages
self.can_manage_video_chats: bool = can_manage_video_chats
self.can_restrict_members: bool = can_restrict_members
self.can_promote_members: bool = can_promote_members
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_post_stories: bool = can_post_stories
self.can_edit_stories: bool = can_edit_stories
self.can_delete_stories: bool = can_delete_stories
# Optionals
self.can_post_messages: Optional[bool] = can_post_messages
self.can_edit_messages: Optional[bool] = can_edit_messages
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self._id_attrs = (
self.is_anonymous,
self.can_manage_chat,
self.can_delete_messages,
self.can_manage_video_chats,
self.can_restrict_members,
self.can_promote_members,
self.can_change_info,
self.can_invite_users,
self.can_post_messages,
self.can_edit_messages,
self.can_pin_messages,
self.can_manage_topics,
self.can_post_stories,
self.can_edit_stories,
self.can_delete_stories,
)
self._freeze()
@classmethod
def all_rights(cls) -> "ChatAdministratorRights":
"""
This method returns the :class:`ChatAdministratorRights` object with all attributes set to
:obj:`True`. This is e.g. useful when changing the bot's default administrator rights with
:meth:`telegram.Bot.set_my_default_administrator_rights`.
.. versionadded:: 20.0
"""
return cls(*(True,) * len(cls.__slots__))
@classmethod
def no_rights(cls) -> "ChatAdministratorRights":
"""
This method returns the :class:`ChatAdministratorRights` object with all attributes set to
:obj:`False`.
.. versionadded:: 20.0
"""
return cls(*(False,) * len(cls.__slots__))

View File

@@ -0,0 +1,547 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects related to chat backgrounds."""
from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants
from telegram._files.document import Document
from telegram._telegramobject import TelegramObject
from telegram._utils import enum
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class BackgroundFill(TelegramObject):
"""Base class for Telegram BackgroundFill Objects. It can be one of:
* :class:`telegram.BackgroundFillSolid`
* :class:`telegram.BackgroundFillGradient`
* :class:`telegram.BackgroundFillFreeformGradient`
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:obj:`str`): Type of the background fill. Can be one of:
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
Attributes:
type (:obj:`str`): Type of the background fill. Can be one of:
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
"""
__slots__ = ("type",)
SOLID: Final[constants.BackgroundFillType] = constants.BackgroundFillType.SOLID
""":const:`telegram.constants.BackgroundFillType.SOLID`"""
GRADIENT: Final[constants.BackgroundFillType] = constants.BackgroundFillType.GRADIENT
""":const:`telegram.constants.BackgroundFillType.GRADIENT`"""
FREEFORM_GRADIENT: Final[constants.BackgroundFillType] = (
constants.BackgroundFillType.FREEFORM_GRADIENT
)
""":const:`telegram.constants.BackgroundFillType.FREEFORM_GRADIENT`"""
def __init__(
self,
type: str, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses
self.type: str = enum.get_member(constants.BackgroundFillType, type, type)
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BackgroundFill"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: dict[str, type[BackgroundFill]] = {
cls.SOLID: BackgroundFillSolid,
cls.GRADIENT: BackgroundFillGradient,
cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient,
}
if cls is BackgroundFill and data.get("type") in _class_mapping:
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
return super().de_json(data=data, bot=bot)
class BackgroundFillSolid(BackgroundFill):
"""
The background is filled using the selected color.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`color` is equal.
.. versionadded:: 21.2
Args:
color (:obj:`int`): The color of the background fill in the `RGB24` format.
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.SOLID`.
color (:obj:`int`): The color of the background fill in the `RGB24` format.
"""
__slots__ = ("color",)
def __init__(
self,
color: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.SOLID, api_kwargs=api_kwargs)
with self._unfrozen():
self.color: int = color
self._id_attrs = (self.color,)
class BackgroundFillGradient(BackgroundFill):
"""
The background is a gradient fill.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`top_color`, :attr:`bottom_color`
and :attr:`rotation_angle` are equal.
.. versionadded:: 21.2
Args:
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
fill in degrees;
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.GRADIENT`.
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
fill in degrees;
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
"""
__slots__ = ("bottom_color", "rotation_angle", "top_color")
def __init__(
self,
top_color: int,
bottom_color: int,
rotation_angle: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.GRADIENT, api_kwargs=api_kwargs)
with self._unfrozen():
self.top_color: int = top_color
self.bottom_color: int = bottom_color
self.rotation_angle: int = rotation_angle
self._id_attrs = (self.top_color, self.bottom_color, self.rotation_angle)
class BackgroundFillFreeformGradient(BackgroundFill):
"""
The background is a freeform gradient that rotates after every message in the chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`colors` is equal.
.. versionadded:: 21.2
Args:
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
generate the freeform gradient in the `RGB24` format
Attributes:
type (:obj:`str`): Type of the background fill. Always
:attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
generate the freeform gradient in the `RGB24` format
"""
__slots__ = ("colors",)
def __init__(
self,
colors: Sequence[int],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs)
with self._unfrozen():
self.colors: tuple[int, ...] = parse_sequence_arg(colors)
self._id_attrs = (self.colors,)
class BackgroundType(TelegramObject):
"""Base class for Telegram BackgroundType Objects. It can be one of:
* :class:`telegram.BackgroundTypeFill`
* :class:`telegram.BackgroundTypeWallpaper`
* :class:`telegram.BackgroundTypePattern`
* :class:`telegram.BackgroundTypeChatTheme`.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:obj:`str`): Type of the background. Can be one of:
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
:attr:`~telegram.BackgroundType.PATTERN` or
:attr:`~telegram.BackgroundType.CHAT_THEME`.
Attributes:
type (:obj:`str`): Type of the background. Can be one of:
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
:attr:`~telegram.BackgroundType.PATTERN` or
:attr:`~telegram.BackgroundType.CHAT_THEME`.
"""
__slots__ = ("type",)
FILL: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.FILL
""":const:`telegram.constants.BackgroundTypeType.FILL`"""
WALLPAPER: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.WALLPAPER
""":const:`telegram.constants.BackgroundTypeType.WALLPAPER`"""
PATTERN: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.PATTERN
""":const:`telegram.constants.BackgroundTypeType.PATTERN`"""
CHAT_THEME: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.CHAT_THEME
""":const:`telegram.constants.BackgroundTypeType.CHAT_THEME`"""
def __init__(
self,
type: str, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses
self.type: str = enum.get_member(constants.BackgroundTypeType, type, type)
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["BackgroundType"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: dict[str, type[BackgroundType]] = {
cls.FILL: BackgroundTypeFill,
cls.WALLPAPER: BackgroundTypeWallpaper,
cls.PATTERN: BackgroundTypePattern,
cls.CHAT_THEME: BackgroundTypeChatTheme,
}
if cls is BackgroundType and data.get("type") in _class_mapping:
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
if "fill" in data:
data["fill"] = BackgroundFill.de_json(data.get("fill"), bot)
if "document" in data:
data["document"] = Document.de_json(data.get("document"), bot)
return super().de_json(data=data, bot=bot)
class BackgroundTypeFill(BackgroundType):
"""
The background is automatically filled based on the selected colors.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`fill` and :attr:`dark_theme_dimming` are equal.
.. versionadded:: 21.2
Args:
fill (:class:`telegram.BackgroundFill`): The background fill.
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.FILL`.
fill (:class:`telegram.BackgroundFill`): The background fill.
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
"""
__slots__ = ("dark_theme_dimming", "fill")
def __init__(
self,
fill: BackgroundFill,
dark_theme_dimming: int,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.FILL, api_kwargs=api_kwargs)
with self._unfrozen():
self.fill: BackgroundFill = fill
self.dark_theme_dimming: int = dark_theme_dimming
self._id_attrs = (self.fill, self.dark_theme_dimming)
class BackgroundTypeWallpaper(BackgroundType):
"""
The background is a wallpaper in the `JPEG` format.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`document` and :attr:`dark_theme_dimming` are equal.
.. versionadded:: 21.2
Args:
document (:class:`telegram.Document`): Document with the wallpaper
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
is_blurred (:obj:`bool`, optional): :obj:`True`, if the wallpaper is downscaled to fit
in a 450x450 square and then box-blurred with radius 12
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
when the device is tilted
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.WALLPAPER`.
document (:class:`telegram.Document`): Document with the wallpaper
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
percentage;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
is_blurred (:obj:`bool`): Optional. :obj:`True`, if the wallpaper is downscaled to fit
in a 450x450 square and then box-blurred with radius 12
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
when the device is tilted
"""
__slots__ = ("dark_theme_dimming", "document", "is_blurred", "is_moving")
def __init__(
self,
document: Document,
dark_theme_dimming: int,
is_blurred: Optional[bool] = None,
is_moving: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.WALLPAPER, api_kwargs=api_kwargs)
with self._unfrozen():
# Required
self.document: Document = document
self.dark_theme_dimming: int = dark_theme_dimming
# Optionals
self.is_blurred: Optional[bool] = is_blurred
self.is_moving: Optional[bool] = is_moving
self._id_attrs = (self.document, self.dark_theme_dimming)
class BackgroundTypePattern(BackgroundType):
"""
The background is a `PNG` or `TGV` (gzipped subset of `SVG` with `MIME` type
`"application/x-tgwallpattern"`) pattern to be combined with the background fill
chosen by the user.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`document` and :attr:`fill` and :attr:`intensity` are equal.
.. versionadded:: 21.2
Args:
document (:class:`telegram.Document`): Document with the pattern.
fill (:class:`telegram.BackgroundFill`): The background fill that is combined with
the pattern.
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
background;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
is_inverted (:obj:`int`, optional): :obj:`True`, if the background fill must be applied
only to the pattern itself. All other pixels are black in this case. For dark
themes only.
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
when the device is tilted.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.PATTERN`.
document (:class:`telegram.Document`): Document with the pattern.
fill (:class:`telegram.BackgroundFill`): The background fill that is combined with
the pattern.
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
background;
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
is_inverted (:obj:`int`): Optional. :obj:`True`, if the background fill must be applied
only to the pattern itself. All other pixels are black in this case. For dark
themes only.
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
when the device is tilted.
"""
__slots__ = (
"document",
"fill",
"intensity",
"is_inverted",
"is_moving",
)
def __init__(
self,
document: Document,
fill: BackgroundFill,
intensity: int,
is_inverted: Optional[bool] = None,
is_moving: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.PATTERN, api_kwargs=api_kwargs)
with self._unfrozen():
# Required
self.document: Document = document
self.fill: BackgroundFill = fill
self.intensity: int = intensity
# Optionals
self.is_inverted: Optional[bool] = is_inverted
self.is_moving: Optional[bool] = is_moving
self._id_attrs = (self.document, self.fill, self.intensity)
class BackgroundTypeChatTheme(BackgroundType):
"""
The background is taken directly from a built-in chat theme.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`theme_name` is equal.
.. versionadded:: 21.2
Args:
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
Attributes:
type (:obj:`str`): Type of the background. Always
:attr:`~telegram.BackgroundType.CHAT_THEME`.
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
"""
__slots__ = ("theme_name",)
def __init__(
self,
theme_name: str,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(type=self.CHAT_THEME, api_kwargs=api_kwargs)
with self._unfrozen():
self.theme_name: str = theme_name
self._id_attrs = (self.theme_name,)
class ChatBackground(TelegramObject):
"""
This object represents a chat background.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`type` is equal.
.. versionadded:: 21.2
Args:
type (:class:`telegram.BackgroundType`): Type of the background.
Attributes:
type (:class:`telegram.BackgroundType`): Type of the background.
"""
__slots__ = ("type",)
def __init__(
self,
type: BackgroundType, # pylint: disable=redefined-builtin
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.type: BackgroundType = type
self._id_attrs = (self.type,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatBackground"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["type"] = BackgroundType.de_json(data.get("type"), bot)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,465 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 the classes that represent Telegram ChatBoosts."""
from collections.abc import Sequence
from datetime import datetime
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants
from telegram._chat import Chat
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils import enum
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatBoostAdded(TelegramObject):
"""
This object represents a service message about a user boosting a chat.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if their
:attr:`boost_count` are equal.
.. versionadded:: 21.0
Args:
boost_count (:obj:`int`): Number of boosts added by the user.
Attributes:
boost_count (:obj:`int`): Number of boosts added by the user.
"""
__slots__ = ("boost_count",)
def __init__(
self,
boost_count: int,
*,
api_kwargs: Optional[JSONDict] = None,
) -> None:
super().__init__(api_kwargs=api_kwargs)
self.boost_count: int = boost_count
self._id_attrs = (self.boost_count,)
self._freeze()
class ChatBoostSource(TelegramObject):
"""
Base class for Telegram ChatBoostSource objects. It can be one of:
* :class:`telegram.ChatBoostSourcePremium`
* :class:`telegram.ChatBoostSourceGiftCode`
* :class:`telegram.ChatBoostSourceGiveaway`
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`source` is equal.
.. versionadded:: 20.8
Args:
source (:obj:`str`): The source of the chat boost. Can be one of:
:attr:`~telegram.ChatBoostSource.PREMIUM`, :attr:`~telegram.ChatBoostSource.GIFT_CODE`,
or :attr:`~telegram.ChatBoostSource.GIVEAWAY`.
Attributes:
source (:obj:`str`): The source of the chat boost. Can be one of:
:attr:`~telegram.ChatBoostSource.PREMIUM`, :attr:`~telegram.ChatBoostSource.GIFT_CODE`,
or :attr:`~telegram.ChatBoostSource.GIVEAWAY`.
"""
__slots__ = ("source",)
PREMIUM: Final[str] = constants.ChatBoostSources.PREMIUM
""":const:`telegram.constants.ChatBoostSources.PREMIUM`"""
GIFT_CODE: Final[str] = constants.ChatBoostSources.GIFT_CODE
""":const:`telegram.constants.ChatBoostSources.GIFT_CODE`"""
GIVEAWAY: Final[str] = constants.ChatBoostSources.GIVEAWAY
""":const:`telegram.constants.ChatBoostSources.GIVEAWAY`"""
def __init__(self, source: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses:
self.source: str = enum.get_member(constants.ChatBoostSources, source, source)
self._id_attrs = (self.source,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatBoostSource"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: dict[str, type[ChatBoostSource]] = {
cls.PREMIUM: ChatBoostSourcePremium,
cls.GIFT_CODE: ChatBoostSourceGiftCode,
cls.GIVEAWAY: ChatBoostSourceGiveaway,
}
if cls is ChatBoostSource and data.get("source") in _class_mapping:
return _class_mapping[data.pop("source")].de_json(data=data, bot=bot)
if "user" in data:
data["user"] = User.de_json(data.get("user"), bot)
return super().de_json(data=data, bot=bot)
class ChatBoostSourcePremium(ChatBoostSource):
"""
The boost was obtained by subscribing to Telegram Premium or by gifting a Telegram Premium
subscription to another user.
.. versionadded:: 20.8
Args:
user (:class:`telegram.User`): User that boosted the chat.
Attributes:
source (:obj:`str`): The source of the chat boost. Always
:attr:`~telegram.ChatBoostSource.PREMIUM`.
user (:class:`telegram.User`): User that boosted the chat.
"""
__slots__ = ("user",)
def __init__(self, user: User, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(source=self.PREMIUM, api_kwargs=api_kwargs)
with self._unfrozen():
self.user: User = user
class ChatBoostSourceGiftCode(ChatBoostSource):
"""
The boost was obtained by the creation of Telegram Premium gift codes to boost a chat. Each
such code boosts the chat 4 times for the duration of the corresponding Telegram Premium
subscription.
.. versionadded:: 20.8
Args:
user (:class:`telegram.User`): User for which the gift code was created.
Attributes:
source (:obj:`str`): The source of the chat boost. Always
:attr:`~telegram.ChatBoostSource.GIFT_CODE`.
user (:class:`telegram.User`): User for which the gift code was created.
"""
__slots__ = ("user",)
def __init__(self, user: User, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(source=self.GIFT_CODE, api_kwargs=api_kwargs)
with self._unfrozen():
self.user: User = user
class ChatBoostSourceGiveaway(ChatBoostSource):
"""
The boost was obtained by the creation of a Telegram Premium giveaway or a Telegram Star.
This boosts the chat 4 times for the duration of the corresponding Telegram Premium
subscription for Telegram Premium giveaways and :attr:`prize_star_count` / 500 times for
one year for Telegram Star giveaways.
.. versionadded:: 20.8
Args:
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
the message could have been deleted already. May be 0 if the message isn't sent yet.
user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any;
for Telegram Premium giveaways only.
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
giveaway winners; for Telegram Star giveaways only.
.. versionadded:: 21.6
is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but
there was no user to win the prize.
Attributes:
source (:obj:`str`): Source of the boost. Always
:attr:`~telegram.ChatBoostSource.GIVEAWAY`.
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
the message could have been deleted already. May be 0 if the message isn't sent yet.
user (:class:`telegram.User`): Optional. User that won the prize in the giveaway if any.
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
giveaway winners; for Telegram Star giveaways only.
.. versionadded:: 21.6
is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but
there was no user to win the prize.
"""
__slots__ = ("giveaway_message_id", "is_unclaimed", "prize_star_count", "user")
def __init__(
self,
giveaway_message_id: int,
user: Optional[User] = None,
is_unclaimed: Optional[bool] = None,
prize_star_count: Optional[int] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(source=self.GIVEAWAY, api_kwargs=api_kwargs)
with self._unfrozen():
self.giveaway_message_id: int = giveaway_message_id
self.user: Optional[User] = user
self.prize_star_count: Optional[int] = prize_star_count
self.is_unclaimed: Optional[bool] = is_unclaimed
class ChatBoost(TelegramObject):
"""
This object contains information about a chat boost.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`boost_id`, :attr:`add_date`, :attr:`expiration_date`,
and :attr:`source` are equal.
.. versionadded:: 20.8
Args:
boost_id (:obj:`str`): Unique identifier of the boost.
add_date (:obj:`datetime.datetime`): Point in time when the chat was boosted.
expiration_date (:obj:`datetime.datetime`): Point in time when the boost
will automatically expire, unless the booster's Telegram Premium subscription is
prolonged.
source (:class:`telegram.ChatBoostSource`): Source of the added boost.
Attributes:
boost_id (:obj:`str`): Unique identifier of the boost.
add_date (:obj:`datetime.datetime`): Point in time when the chat was boosted.
|datetime_localization|
expiration_date (:obj:`datetime.datetime`): Point in time when the boost
will automatically expire, unless the booster's Telegram Premium subscription is
prolonged. |datetime_localization|
source (:class:`telegram.ChatBoostSource`): Source of the added boost.
"""
__slots__ = ("add_date", "boost_id", "expiration_date", "source")
def __init__(
self,
boost_id: str,
add_date: datetime,
expiration_date: datetime,
source: ChatBoostSource,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.boost_id: str = boost_id
self.add_date: datetime = add_date
self.expiration_date: datetime = expiration_date
self.source: ChatBoostSource = source
self._id_attrs = (self.boost_id, self.add_date, self.expiration_date, self.source)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatBoost"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["source"] = ChatBoostSource.de_json(data.get("source"), bot)
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["add_date"] = from_timestamp(data["add_date"], tzinfo=loc_tzinfo)
data["expiration_date"] = from_timestamp(data["expiration_date"], tzinfo=loc_tzinfo)
return super().de_json(data=data, bot=bot)
class ChatBoostUpdated(TelegramObject):
"""This object represents a boost added to a chat or changed.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`chat`, and :attr:`boost` are equal.
.. versionadded:: 20.8
Args:
chat (:class:`telegram.Chat`): Chat which was boosted.
boost (:class:`telegram.ChatBoost`): Information about the chat boost.
Attributes:
chat (:class:`telegram.Chat`): Chat which was boosted.
boost (:class:`telegram.ChatBoost`): Information about the chat boost.
"""
__slots__ = ("boost", "chat")
def __init__(
self,
chat: Chat,
boost: ChatBoost,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.chat: Chat = chat
self.boost: ChatBoost = boost
self._id_attrs = (self.chat.id, self.boost)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatBoostUpdated"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["chat"] = Chat.de_json(data.get("chat"), bot)
data["boost"] = ChatBoost.de_json(data.get("boost"), bot)
return super().de_json(data=data, bot=bot)
class ChatBoostRemoved(TelegramObject):
"""
This object represents a boost removed from a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`chat`, :attr:`boost_id`, :attr:`remove_date`, and
:attr:`source` are equal.
Args:
chat (:class:`telegram.Chat`): Chat which was boosted.
boost_id (:obj:`str`): Unique identifier of the boost.
remove_date (:obj:`datetime.datetime`): Point in time when the boost was removed.
source (:class:`telegram.ChatBoostSource`): Source of the removed boost.
Attributes:
chat (:class:`telegram.Chat`): Chat which was boosted.
boost_id (:obj:`str`): Unique identifier of the boost.
remove_date (:obj:`datetime.datetime`): Point in time when the boost was removed.
|datetime_localization|
source (:class:`telegram.ChatBoostSource`): Source of the removed boost.
"""
__slots__ = ("boost_id", "chat", "remove_date", "source")
def __init__(
self,
chat: Chat,
boost_id: str,
remove_date: datetime,
source: ChatBoostSource,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.chat: Chat = chat
self.boost_id: str = boost_id
self.remove_date: datetime = remove_date
self.source: ChatBoostSource = source
self._id_attrs = (self.chat, self.boost_id, self.remove_date, self.source)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatBoostRemoved"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["chat"] = Chat.de_json(data.get("chat"), bot)
data["source"] = ChatBoostSource.de_json(data.get("source"), bot)
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["remove_date"] = from_timestamp(data["remove_date"], tzinfo=loc_tzinfo)
return super().de_json(data=data, bot=bot)
class UserChatBoosts(TelegramObject):
"""This object represents a list of boosts added to a chat by a user.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`boosts` are equal.
.. versionadded:: 20.8
Args:
boosts (Sequence[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the
user.
Attributes:
boosts (tuple[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the user.
"""
__slots__ = ("boosts",)
def __init__(
self,
boosts: Sequence[ChatBoost],
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.boosts: tuple[ChatBoost, ...] = parse_sequence_arg(boosts)
self._id_attrs = (self.boosts,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["UserChatBoosts"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["boosts"] = ChatBoost.de_list(data.get("boosts"), bot)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,550 @@
#!/usr/bin/env python
# pylint: disable=redefined-builtin
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChatFullInfo."""
from collections.abc import Sequence
from datetime import datetime
from typing import TYPE_CHECKING, Optional
from telegram._birthdate import Birthdate
from telegram._chat import Chat, _ChatBase
from telegram._chatlocation import ChatLocation
from telegram._chatpermissions import ChatPermissions
from telegram._files.chatphoto import ChatPhoto
from telegram._reaction import ReactionType
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot, BusinessIntro, BusinessLocation, BusinessOpeningHours, Message
class ChatFullInfo(_ChatBase):
"""
This object contains full information about a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`~telegram.Chat.id` is equal.
.. versionadded:: 21.2
.. versionchanged:: 21.3
Explicit support for all shortcut methods known from :class:`telegram.Chat` on this
object. Previously those were only available because this class inherited from
:class:`telegram.Chat`.
Args:
id (:obj:`int`): Unique identifier for this chat.
type (:obj:`str`): Type of chat, can be either :attr:`PRIVATE`, :attr:`GROUP`,
:attr:`SUPERGROUP` or :attr:`CHANNEL`.
accent_color_id (:obj:`int`, optional): Identifier of the
:class:`accent color <telegram.constants.AccentColor>` for the chat name and
backgrounds of the chat photo, reply header, and link preview. See `accent colors`_
for more details.
.. versionadded:: 20.8
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
message in the chat.
.. versionadded:: 21.2
title (:obj:`str`, optional): Title, for supergroups, channels and group chats.
username (:obj:`str`, optional): Username, for private chats, supergroups and channels if
available.
first_name (:obj:`str`, optional): First name of the other party in a private chat.
last_name (:obj:`str`, optional): Last name of the other party in a private chat.
is_forum (:obj:`bool`, optional): :obj:`True`, if the supergroup chat is a forum
(has topics_ enabled).
.. versionadded:: 20.0
photo (:class:`telegram.ChatPhoto`, optional): Chat photo.
active_usernames (Sequence[:obj:`str`], optional): If set, the list of all `active chat
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
#collectible-usernames>`_; for private chats, supergroups and channels.
.. versionadded:: 20.0
birthdate (:class:`telegram.Birthdate`, optional): For private chats,
the date of birth of the user.
.. versionadded:: 21.1
business_intro (:class:`telegram.BusinessIntro`, optional): For private chats with
business accounts, the intro of the business.
.. versionadded:: 21.1
business_location (:class:`telegram.BusinessLocation`, optional): For private chats with
business accounts, the location of the business.
.. versionadded:: 21.1
business_opening_hours (:class:`telegram.BusinessOpeningHours`, optional): For private
chats with business accounts, the opening hours of the business.
.. versionadded:: 21.1
personal_chat (:class:`telegram.Chat`, optional): For private chats, the personal channel
of the user.
.. versionadded:: 21.1
available_reactions (Sequence[:class:`telegram.ReactionType`], optional): List of available
reactions allowed in the chat. If omitted, then all of
:const:`telegram.constants.ReactionEmoji` are allowed.
.. versionadded:: 20.8
background_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of emoji chosen
by the chat for the reply header and link preview background.
.. versionadded:: 20.8
profile_accent_color_id (:obj:`int`, optional): Identifier of the
:class:`accent color <telegram.constants.ProfileAccentColor>` for the chat's profile
background. See profile `accent colors`_ for more details.
.. versionadded:: 20.8
profile_background_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of
the emoji chosen by the chat for its profile background.
.. versionadded:: 20.8
emoji_status_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of emoji
status of the chat or the other party in a private chat.
.. versionadded:: 20.0
emoji_status_expiration_date (:class:`datetime.datetime`, optional): Expiration date of
emoji status of the chat or the other party in a private chat, as a datetime object,
if any.
|datetime_localization|
.. versionadded:: 20.5
bio (:obj:`str`, optional): Bio of the other party in a private chat.
has_private_forwards (:obj:`bool`, optional): :obj:`True`, if privacy settings of the other
party in the private chat allows to use ``tg://user?id=<user_id>`` links only in chats
with the user.
.. versionadded:: 13.9
has_restricted_voice_and_video_messages (:obj:`bool`, optional): :obj:`True`, if the
privacy settings of the other party restrict sending voice and video note messages
in the private chat.
.. versionadded:: 20.0
join_to_send_messages (:obj:`bool`, optional): :obj:`True`, if users need to join the
supergroup before they can send messages.
.. versionadded:: 20.0
join_by_request (:obj:`bool`, optional): :obj:`True`, if all users directly joining the
supergroup without using an invite link need to be approved by supergroup
administrators.
.. versionadded:: 20.0
description (:obj:`str`, optional): Description, for groups, supergroups and channel chats.
invite_link (:obj:`str`, optional): Primary invite link, for groups, supergroups and
channel.
pinned_message (:class:`telegram.Message`, optional): The most recent pinned message
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
unrestrict_boost_count (:obj:`int`, optional): For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.
.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`, optional): The time after which all messages sent to
the chat will be automatically deleted; in seconds.
.. versionadded:: 13.4
has_aggressive_anti_spam_enabled (:obj:`bool`, optional): :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
.. versionadded:: 20.0
has_hidden_members (:obj:`bool`, optional): :obj:`True`, if non-administrators can only
get the list of bots and administrators in the chat.
.. versionadded:: 20.0
has_protected_content (:obj:`bool`, optional): :obj:`True`, if messages from the chat can't
be forwarded to other chats.
.. versionadded:: 13.9
has_visible_history (:obj:`bool`, optional): :obj:`True`, if new chat members will have
access to old messages; available only to chat administrators.
.. versionadded:: 20.8
sticker_set_name (:obj:`str`, optional): For supergroups, name of group sticker set.
can_set_sticker_set (:obj:`bool`, optional): :obj:`True`, if the bot can change group the
sticker set.
custom_emoji_sticker_set_name (:obj:`str`, optional): For supergroups, the name of the
group's custom emoji sticker set. Custom emoji from this set can be used by all users
and bots in the group.
.. versionadded:: 21.0
linked_chat_id (:obj:`int`, optional): Unique identifier for the linked chat, i.e. the
discussion group identifier for a channel and vice versa; for supergroups and channel
chats.
location (:class:`telegram.ChatLocation`, optional): For supergroups, the location to which
the supergroup is connected.
can_send_paid_media (:obj:`bool`, optional): :obj:`True`, if paid media messages can be
sent or forwarded to the channel chat. The field is available only for channel chats.
.. versionadded:: 21.4
Attributes:
id (:obj:`int`): Unique identifier for this chat.
type (:obj:`str`): Type of chat, can be either :attr:`PRIVATE`, :attr:`GROUP`,
:attr:`SUPERGROUP` or :attr:`CHANNEL`.
accent_color_id (:obj:`int`): Optional. Identifier of the
:class:`accent color <telegram.constants.AccentColor>` for the chat name and
backgrounds of the chat photo, reply header, and link preview. See `accent colors`_
for more details.
.. versionadded:: 20.8
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
message in the chat.
.. versionadded:: 21.2
title (:obj:`str`, optional): Title, for supergroups, channels and group chats.
username (:obj:`str`, optional): Username, for private chats, supergroups and channels if
available.
first_name (:obj:`str`, optional): First name of the other party in a private chat.
last_name (:obj:`str`, optional): Last name of the other party in a private chat.
is_forum (:obj:`bool`, optional): :obj:`True`, if the supergroup chat is a forum
(has topics_ enabled).
.. versionadded:: 20.0
photo (:class:`telegram.ChatPhoto`): Optional. Chat photo.
active_usernames (tuple[:obj:`str`]): Optional. If set, the list of all `active chat
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
#collectible-usernames>`_; for private chats, supergroups and channels.
This list is empty if the chat has no active usernames or this chat instance was not
obtained via :meth:`~telegram.Bot.get_chat`.
.. versionadded:: 20.0
birthdate (:class:`telegram.Birthdate`): Optional. For private chats,
the date of birth of the user.
.. versionadded:: 21.1
business_intro (:class:`telegram.BusinessIntro`): Optional. For private chats with
business accounts, the intro of the business.
.. versionadded:: 21.1
business_location (:class:`telegram.BusinessLocation`): Optional. For private chats with
business accounts, the location of the business.
.. versionadded:: 21.1
business_opening_hours (:class:`telegram.BusinessOpeningHours`): Optional. For private
chats with business accounts, the opening hours of the business.
.. versionadded:: 21.1
personal_chat (:class:`telegram.Chat`): Optional. For private chats, the personal channel
of the user.
.. versionadded:: 21.1
available_reactions (tuple[:class:`telegram.ReactionType`]): Optional. List of available
reactions allowed in the chat. If omitted, then all of
:const:`telegram.constants.ReactionEmoji` are allowed.
.. versionadded:: 20.8
background_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji chosen
by the chat for the reply header and link preview background.
.. versionadded:: 20.8
profile_accent_color_id (:obj:`int`): Optional. Identifier of the
:class:`accent color <telegram.constants.ProfileAccentColor>` for the chat's profile
background. See profile `accent colors`_ for more details.
.. versionadded:: 20.8
profile_background_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of
the emoji chosen by the chat for its profile background.
.. versionadded:: 20.8
emoji_status_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji
status of the chat or the other party in a private chat.
.. versionadded:: 20.0
emoji_status_expiration_date (:class:`datetime.datetime`): Optional. Expiration date of
emoji status of the chat or the other party in a private chat, as a datetime object,
if any.
|datetime_localization|
.. versionadded:: 20.5
bio (:obj:`str`): Optional. Bio of the other party in a private chat.
has_private_forwards (:obj:`bool`): Optional. :obj:`True`, if privacy settings of the other
party in the private chat allows to use ``tg://user?id=<user_id>`` links only in chats
with the user.
.. versionadded:: 13.9
has_restricted_voice_and_video_messages (:obj:`bool`): Optional. :obj:`True`, if the
privacy settings of the other party restrict sending voice and video note messages
in the private chat.
.. versionadded:: 20.0
join_to_send_messages (:obj:`bool`): Optional. :obj:`True`, if users need to join
the supergroup before they can send messages.
.. versionadded:: 20.0
join_by_request (:obj:`bool`): Optional. :obj:`True`, if all users directly joining the
supergroup without using an invite link need to be approved by supergroup
administrators.
.. versionadded:: 20.0
description (:obj:`str`): Optional. Description, for groups, supergroups and channel chats.
invite_link (:obj:`str`): Optional. Primary invite link, for groups, supergroups and
channel.
pinned_message (:class:`telegram.Message`): Optional. The most recent pinned message
(by sending date).
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
for groups and supergroups.
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
consecutive messages sent by each unprivileged user.
unrestrict_boost_count (:obj:`int`): Optional. For supergroups, the minimum number of
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
permissions.
.. versionadded:: 21.0
message_auto_delete_time (:obj:`int`): Optional. The time after which all messages sent to
the chat will be automatically deleted; in seconds.
.. versionadded:: 13.4
has_aggressive_anti_spam_enabled (:obj:`bool`): Optional. :obj:`True`, if aggressive
anti-spam checks are enabled in the supergroup. The field is only available to chat
administrators.
.. versionadded:: 20.0
has_hidden_members (:obj:`bool`): Optional. :obj:`True`, if non-administrators can only
get the list of bots and administrators in the chat.
.. versionadded:: 20.0
has_protected_content (:obj:`bool`): Optional. :obj:`True`, if messages from the chat can't
be forwarded to other chats.
.. versionadded:: 13.9
has_visible_history (:obj:`bool`): Optional. :obj:`True`, if new chat members will have
access to old messages; available only to chat administrators.
.. versionadded:: 20.8
sticker_set_name (:obj:`str`): Optional. For supergroups, name of Group sticker set.
can_set_sticker_set (:obj:`bool`): Optional. :obj:`True`, if the bot can change group the
sticker set.
custom_emoji_sticker_set_name (:obj:`str`): Optional. For supergroups, the name of the
group's custom emoji sticker set. Custom emoji from this set can be used by all users
and bots in the group.
.. versionadded:: 21.0
linked_chat_id (:obj:`int`): Optional. Unique identifier for the linked chat, i.e. the
discussion group identifier for a channel and vice versa; for supergroups and channel
chats.
location (:class:`telegram.ChatLocation`): Optional. For supergroups, the location to which
the supergroup is connected.
can_send_paid_media (:obj:`bool`): Optional. :obj:`True`, if paid media messages can be
sent or forwarded to the channel chat. The field is available only for channel chats.
.. versionadded:: 21.4
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
"""
__slots__ = (
"accent_color_id",
"active_usernames",
"available_reactions",
"background_custom_emoji_id",
"bio",
"birthdate",
"business_intro",
"business_location",
"business_opening_hours",
"can_send_paid_media",
"can_set_sticker_set",
"custom_emoji_sticker_set_name",
"description",
"emoji_status_custom_emoji_id",
"emoji_status_expiration_date",
"has_aggressive_anti_spam_enabled",
"has_hidden_members",
"has_private_forwards",
"has_protected_content",
"has_restricted_voice_and_video_messages",
"has_visible_history",
"invite_link",
"join_by_request",
"join_to_send_messages",
"linked_chat_id",
"location",
"max_reaction_count",
"message_auto_delete_time",
"permissions",
"personal_chat",
"photo",
"pinned_message",
"profile_accent_color_id",
"profile_background_custom_emoji_id",
"slow_mode_delay",
"sticker_set_name",
"unrestrict_boost_count",
)
def __init__(
self,
id: int,
type: str,
accent_color_id: int,
max_reaction_count: int,
title: Optional[str] = None,
username: Optional[str] = None,
first_name: Optional[str] = None,
last_name: Optional[str] = None,
is_forum: Optional[bool] = None,
photo: Optional[ChatPhoto] = None,
active_usernames: Optional[Sequence[str]] = None,
birthdate: Optional[Birthdate] = None,
business_intro: Optional["BusinessIntro"] = None,
business_location: Optional["BusinessLocation"] = None,
business_opening_hours: Optional["BusinessOpeningHours"] = None,
personal_chat: Optional["Chat"] = None,
available_reactions: Optional[Sequence[ReactionType]] = None,
background_custom_emoji_id: Optional[str] = None,
profile_accent_color_id: Optional[int] = None,
profile_background_custom_emoji_id: Optional[str] = None,
emoji_status_custom_emoji_id: Optional[str] = None,
emoji_status_expiration_date: Optional[datetime] = None,
bio: Optional[str] = None,
has_private_forwards: Optional[bool] = None,
has_restricted_voice_and_video_messages: Optional[bool] = None,
join_to_send_messages: Optional[bool] = None,
join_by_request: Optional[bool] = None,
description: Optional[str] = None,
invite_link: Optional[str] = None,
pinned_message: Optional["Message"] = None,
permissions: Optional[ChatPermissions] = None,
slow_mode_delay: Optional[int] = None,
unrestrict_boost_count: Optional[int] = None,
message_auto_delete_time: Optional[int] = None,
has_aggressive_anti_spam_enabled: Optional[bool] = None,
has_hidden_members: Optional[bool] = None,
has_protected_content: Optional[bool] = None,
has_visible_history: Optional[bool] = None,
sticker_set_name: Optional[str] = None,
can_set_sticker_set: Optional[bool] = None,
custom_emoji_sticker_set_name: Optional[str] = None,
linked_chat_id: Optional[int] = None,
location: Optional[ChatLocation] = None,
can_send_paid_media: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(
id=id,
type=type,
title=title,
username=username,
first_name=first_name,
last_name=last_name,
is_forum=is_forum,
api_kwargs=api_kwargs,
)
# Required and unique to this class-
with self._unfrozen():
self.max_reaction_count: int = max_reaction_count
self.photo: Optional[ChatPhoto] = photo
self.bio: Optional[str] = bio
self.has_private_forwards: Optional[bool] = has_private_forwards
self.description: Optional[str] = description
self.invite_link: Optional[str] = invite_link
self.pinned_message: Optional[Message] = pinned_message
self.permissions: Optional[ChatPermissions] = permissions
self.slow_mode_delay: Optional[int] = slow_mode_delay
self.message_auto_delete_time: Optional[int] = (
int(message_auto_delete_time) if message_auto_delete_time is not None else None
)
self.has_protected_content: Optional[bool] = has_protected_content
self.has_visible_history: Optional[bool] = has_visible_history
self.sticker_set_name: Optional[str] = sticker_set_name
self.can_set_sticker_set: Optional[bool] = can_set_sticker_set
self.linked_chat_id: Optional[int] = linked_chat_id
self.location: Optional[ChatLocation] = location
self.join_to_send_messages: Optional[bool] = join_to_send_messages
self.join_by_request: Optional[bool] = join_by_request
self.has_restricted_voice_and_video_messages: Optional[bool] = (
has_restricted_voice_and_video_messages
)
self.active_usernames: tuple[str, ...] = parse_sequence_arg(active_usernames)
self.emoji_status_custom_emoji_id: Optional[str] = emoji_status_custom_emoji_id
self.emoji_status_expiration_date: Optional[datetime] = emoji_status_expiration_date
self.has_aggressive_anti_spam_enabled: Optional[bool] = (
has_aggressive_anti_spam_enabled
)
self.has_hidden_members: Optional[bool] = has_hidden_members
self.available_reactions: Optional[tuple[ReactionType, ...]] = parse_sequence_arg(
available_reactions
)
self.accent_color_id: Optional[int] = accent_color_id
self.background_custom_emoji_id: Optional[str] = background_custom_emoji_id
self.profile_accent_color_id: Optional[int] = profile_accent_color_id
self.profile_background_custom_emoji_id: Optional[str] = (
profile_background_custom_emoji_id
)
self.unrestrict_boost_count: Optional[int] = unrestrict_boost_count
self.custom_emoji_sticker_set_name: Optional[str] = custom_emoji_sticker_set_name
self.birthdate: Optional[Birthdate] = birthdate
self.personal_chat: Optional[Chat] = personal_chat
self.business_intro: Optional[BusinessIntro] = business_intro
self.business_location: Optional[BusinessLocation] = business_location
self.business_opening_hours: Optional[BusinessOpeningHours] = business_opening_hours
self.can_send_paid_media: Optional[bool] = can_send_paid_media
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatFullInfo"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["emoji_status_expiration_date"] = from_timestamp(
data.get("emoji_status_expiration_date"), tzinfo=loc_tzinfo
)
data["photo"] = ChatPhoto.de_json(data.get("photo"), bot)
from telegram import ( # pylint: disable=import-outside-toplevel
BusinessIntro,
BusinessLocation,
BusinessOpeningHours,
Message,
)
data["pinned_message"] = Message.de_json(data.get("pinned_message"), bot)
data["permissions"] = ChatPermissions.de_json(data.get("permissions"), bot)
data["location"] = ChatLocation.de_json(data.get("location"), bot)
data["available_reactions"] = ReactionType.de_list(data.get("available_reactions"), bot)
data["birthdate"] = Birthdate.de_json(data.get("birthdate"), bot)
data["personal_chat"] = Chat.de_json(data.get("personal_chat"), bot)
data["business_intro"] = BusinessIntro.de_json(data.get("business_intro"), bot)
data["business_location"] = BusinessLocation.de_json(data.get("business_location"), bot)
data["business_opening_hours"] = BusinessOpeningHours.de_json(
data.get("business_opening_hours"), bot
)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,195 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents an invite link for a chat."""
import datetime
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatInviteLink(TelegramObject):
"""This object represents an invite link for a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`invite_link`, :attr:`creator`, :attr:`creates_join_request`,
:attr:`is_primary` and :attr:`is_revoked` are equal.
.. versionadded:: 13.4
.. versionchanged:: 20.0
* The argument & attribute :attr:`creates_join_request` is now required to comply with the
Bot API.
* Comparing objects of this class now also takes :attr:`creates_join_request` into account.
Args:
invite_link (:obj:`str`): The invite link.
creator (:class:`telegram.User`): Creator of the link.
creates_join_request (:obj:`bool`): :obj:`True`, if users joining the chat via
the link need to be approved by chat administrators.
.. versionadded:: 13.8
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
expire_date (:class:`datetime.datetime`, optional): Date when the link will expire or
has been expired.
.. versionchanged:: 20.3
|datetime_localization|
member_limit (:obj:`int`, optional): Maximum number of users that can be members of the
chat simultaneously after joining the chat via this invite link;
:tg-const:`telegram.constants.ChatInviteLinkLimit.MIN_MEMBER_LIMIT`-
:tg-const:`telegram.constants.ChatInviteLinkLimit.MAX_MEMBER_LIMIT`.
name (:obj:`str`, optional): Invite link name.
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
.. versionadded:: 13.8
pending_join_request_count (:obj:`int`, optional): Number of pending join requests
created using this link.
.. versionadded:: 13.8
subscription_period (:obj:`int`, optional): The number of seconds the subscription will be
active for before the next payment.
.. versionadded:: 21.5
subscription_price (:obj:`int`, optional): The amount of Telegram Stars a user must pay
initially and after each subsequent subscription period to be a member of the chat
using the link.
.. versionadded:: 21.5
Attributes:
invite_link (:obj:`str`): The invite link. If the link was created by another chat
administrator, then the second part of the link will be replaced with ``''``.
creator (:class:`telegram.User`): Creator of the link.
creates_join_request (:obj:`bool`): :obj:`True`, if users joining the chat via
the link need to be approved by chat administrators.
.. versionadded:: 13.8
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
expire_date (:class:`datetime.datetime`): Optional. Date when the link will expire or
has been expired.
.. versionchanged:: 20.3
|datetime_localization|
member_limit (:obj:`int`): Optional. Maximum number of users that can be members
of the chat simultaneously after joining the chat via this invite link;
:tg-const:`telegram.constants.ChatInviteLinkLimit.MIN_MEMBER_LIMIT`-
:tg-const:`telegram.constants.ChatInviteLinkLimit.MAX_MEMBER_LIMIT`.
name (:obj:`str`): Optional. Invite link name.
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
.. versionadded:: 13.8
pending_join_request_count (:obj:`int`): Optional. Number of pending join requests
created using this link.
.. versionadded:: 13.8
subscription_period (:obj:`int`): Optional. The number of seconds the subscription will be
active for before the next payment.
.. versionadded:: 21.5
subscription_price (:obj:`int`): Optional. The amount of Telegram Stars a user must pay
initially and after each subsequent subscription period to be a member of the chat
using the link.
.. versionadded:: 21.5
"""
__slots__ = (
"creates_join_request",
"creator",
"expire_date",
"invite_link",
"is_primary",
"is_revoked",
"member_limit",
"name",
"pending_join_request_count",
"subscription_period",
"subscription_price",
)
def __init__(
self,
invite_link: str,
creator: User,
creates_join_request: bool,
is_primary: bool,
is_revoked: bool,
expire_date: Optional[datetime.datetime] = None,
member_limit: Optional[int] = None,
name: Optional[str] = None,
pending_join_request_count: Optional[int] = None,
subscription_period: Optional[int] = None,
subscription_price: Optional[int] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.invite_link: str = invite_link
self.creator: User = creator
self.creates_join_request: bool = creates_join_request
self.is_primary: bool = is_primary
self.is_revoked: bool = is_revoked
# Optionals
self.expire_date: Optional[datetime.datetime] = expire_date
self.member_limit: Optional[int] = member_limit
self.name: Optional[str] = name
self.pending_join_request_count: Optional[int] = (
int(pending_join_request_count) if pending_join_request_count is not None else None
)
self.subscription_period: Optional[int] = subscription_period
self.subscription_price: Optional[int] = subscription_price
self._id_attrs = (
self.invite_link,
self.creates_join_request,
self.creator,
self.is_primary,
self.is_revoked,
)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatInviteLink"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["creator"] = User.de_json(data.get("creator"), bot)
data["expire_date"] = from_timestamp(data.get("expire_date", None), tzinfo=loc_tzinfo)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,213 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChatJoinRequest."""
import datetime
from typing import TYPE_CHECKING, Optional
from telegram._chat import Chat
from telegram._chatinvitelink import ChatInviteLink
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram._utils.types import JSONDict, ODVInput
if TYPE_CHECKING:
from telegram import Bot
class ChatJoinRequest(TelegramObject):
"""This object represents a join request sent to a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`chat`, :attr:`from_user` and :attr:`date` are equal.
Note:
* Since Bot API 5.5, bots are allowed to contact users who sent a join request to a chat
where the bot is an administrator with the
:attr:`~telegram.ChatMemberAdministrator.can_invite_users` administrator right - even
if the user never interacted with the bot before.
* Telegram does not guarantee that :attr:`from_user.id <from_user>` coincides with the
``chat_id`` of the user. Please use :attr:`user_chat_id` to contact the user in
response to their join request.
.. versionadded:: 13.8
.. versionchanged:: 20.1
In Bot API 6.5 the argument :paramref:`user_chat_id` was added, which changes the position
of the optional arguments :paramref:`bio` and :paramref:`invite_link`.
Args:
chat (:class:`telegram.Chat`): Chat to which the request was sent.
from_user (:class:`telegram.User`): User that sent the join request.
date (:class:`datetime.datetime`): Date the request was sent.
.. versionchanged:: 20.3
|datetime_localization|
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 5 minutes to send messages
until the join request is processed, assuming no other administrator contacted the
user.
.. versionadded:: 20.1
bio (:obj:`str`, optional): Bio of the user.
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link that was used
by the user to send the join request.
Attributes:
chat (:class:`telegram.Chat`): Chat to which the request was sent.
from_user (:class:`telegram.User`): User that sent the join request.
date (:class:`datetime.datetime`): Date the request was sent.
.. versionchanged:: 20.3
|datetime_localization|
user_chat_id (:obj:`int`): Identifier of a private chat with the user who sent the join
request. This number may have more than 32 significant bits and some programming
languages may have difficulty/silent defects in interpreting it. But it has at most 52
significant bits, so a 64-bit integer or double-precision float type are safe for
storing this identifier. The bot can use this identifier for 24 hours to send messages
until the join request is processed, assuming no other administrator contacted the
user.
.. versionadded:: 20.1
bio (:obj:`str`): Optional. Bio of the user.
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link that was used
by the user to send the join request.
Note:
When a user joins a *public* group via an invite link, this attribute may not
be present. However, this behavior is undocument and may be subject to change.
See `this GitHub thread <https://github.com/tdlib/telegram-bot-api/issues/428>`_
for some discussion.
"""
__slots__ = ("bio", "chat", "date", "from_user", "invite_link", "user_chat_id")
def __init__(
self,
chat: Chat,
from_user: User,
date: datetime.datetime,
user_chat_id: int,
bio: Optional[str] = None,
invite_link: Optional[ChatInviteLink] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.chat: Chat = chat
self.from_user: User = from_user
self.date: datetime.datetime = date
self.user_chat_id: int = user_chat_id
# Optionals
self.bio: Optional[str] = bio
self.invite_link: Optional[ChatInviteLink] = invite_link
self._id_attrs = (self.chat, self.from_user, self.date)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatJoinRequest"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["chat"] = Chat.de_json(data.get("chat"), bot)
data["from_user"] = User.de_json(data.pop("from", None), bot)
data["date"] = from_timestamp(data.get("date", None), tzinfo=loc_tzinfo)
data["invite_link"] = ChatInviteLink.de_json(data.get("invite_link"), bot)
return super().de_json(data=data, bot=bot)
async def approve(
self,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await bot.approve_chat_join_request(
chat_id=update.effective_chat.id, user_id=update.effective_user.id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.approve_chat_join_request`.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().approve_chat_join_request(
chat_id=self.chat.id,
user_id=self.from_user.id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def decline(
self,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::
await bot.decline_chat_join_request(
chat_id=update.effective_chat.id, user_id=update.effective_user.id, *args, **kwargs
)
For the documentation of the arguments, please see
:meth:`telegram.Bot.decline_chat_join_request`.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().decline_chat_join_request(
chat_id=self.chat.id,
user_id=self.from_user.id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a location to which a chat is connected."""
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants
from telegram._files.location import Location
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatLocation(TelegramObject):
"""This object represents a location to which a chat is connected.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`location` is equal.
Args:
location (:class:`telegram.Location`): The location to which the supergroup is connected.
Can't be a live location.
address (:obj:`str`): Location address;
:tg-const:`telegram.ChatLocation.MIN_ADDRESS`-
:tg-const:`telegram.ChatLocation.MAX_ADDRESS` characters, as defined by the chat owner.
Attributes:
location (:class:`telegram.Location`): The location to which the supergroup is connected.
Can't be a live location.
address (:obj:`str`): Location address;
:tg-const:`telegram.ChatLocation.MIN_ADDRESS`-
:tg-const:`telegram.ChatLocation.MAX_ADDRESS` characters, as defined by the chat owner.
"""
__slots__ = ("address", "location")
def __init__(
self,
location: Location,
address: str,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
self.location: Location = location
self.address: str = address
self._id_attrs = (self.location,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatLocation"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
data["location"] = Location.de_json(data.get("location"), bot)
return super().de_json(data=data, bot=bot)
MIN_ADDRESS: Final[int] = constants.LocationLimit.MIN_CHAT_LOCATION_ADDRESS
""":const:`telegram.constants.LocationLimit.MIN_CHAT_LOCATION_ADDRESS`
.. versionadded:: 20.0
"""
MAX_ADDRESS: Final[int] = constants.LocationLimit.MAX_CHAT_LOCATION_ADDRESS
""":const:`telegram.constants.LocationLimit.MAX_CHAT_LOCATION_ADDRESS`
.. versionadded:: 20.0
"""

View File

@@ -0,0 +1,665 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChatMember."""
import datetime
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatMember(TelegramObject):
"""Base class for Telegram ChatMember Objects.
Currently, the following 6 types of chat members are supported:
* :class:`telegram.ChatMemberOwner`
* :class:`telegram.ChatMemberAdministrator`
* :class:`telegram.ChatMemberMember`
* :class:`telegram.ChatMemberRestricted`
* :class:`telegram.ChatMemberLeft`
* :class:`telegram.ChatMemberBanned`
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`user` and :attr:`status` are equal.
Examples:
:any:`Chat Member Bot <examples.chatmemberbot>`
.. versionchanged:: 20.0
* As of Bot API 5.3, :class:`ChatMember` is nothing but the base class for the subclasses
listed above and is no longer returned directly by :meth:`~telegram.Bot.get_chat`.
Therefore, most of the arguments and attributes were removed and you should no longer
use :class:`ChatMember` directly.
* The constant ``ChatMember.CREATOR`` was replaced by :attr:`~telegram.ChatMember.OWNER`
* The constant ``ChatMember.KICKED`` was replaced by :attr:`~telegram.ChatMember.BANNED`
Args:
user (:class:`telegram.User`): Information about the user.
status (:obj:`str`): The member's status in the chat. Can be
:attr:`~telegram.ChatMember.ADMINISTRATOR`, :attr:`~telegram.ChatMember.OWNER`,
:attr:`~telegram.ChatMember.BANNED`, :attr:`~telegram.ChatMember.LEFT`,
:attr:`~telegram.ChatMember.MEMBER` or :attr:`~telegram.ChatMember.RESTRICTED`.
Attributes:
user (:class:`telegram.User`): Information about the user.
status (:obj:`str`): The member's status in the chat. Can be
:attr:`~telegram.ChatMember.ADMINISTRATOR`, :attr:`~telegram.ChatMember.OWNER`,
:attr:`~telegram.ChatMember.BANNED`, :attr:`~telegram.ChatMember.LEFT`,
:attr:`~telegram.ChatMember.MEMBER` or :attr:`~telegram.ChatMember.RESTRICTED`.
"""
__slots__ = ("status", "user")
ADMINISTRATOR: Final[str] = constants.ChatMemberStatus.ADMINISTRATOR
""":const:`telegram.constants.ChatMemberStatus.ADMINISTRATOR`"""
OWNER: Final[str] = constants.ChatMemberStatus.OWNER
""":const:`telegram.constants.ChatMemberStatus.OWNER`"""
BANNED: Final[str] = constants.ChatMemberStatus.BANNED
""":const:`telegram.constants.ChatMemberStatus.BANNED`"""
LEFT: Final[str] = constants.ChatMemberStatus.LEFT
""":const:`telegram.constants.ChatMemberStatus.LEFT`"""
MEMBER: Final[str] = constants.ChatMemberStatus.MEMBER
""":const:`telegram.constants.ChatMemberStatus.MEMBER`"""
RESTRICTED: Final[str] = constants.ChatMemberStatus.RESTRICTED
""":const:`telegram.constants.ChatMemberStatus.RESTRICTED`"""
def __init__(
self,
user: User,
status: str,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required by all subclasses
self.user: User = user
self.status: str = status
self._id_attrs = (self.user, self.status)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatMember"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
_class_mapping: dict[str, type[ChatMember]] = {
cls.OWNER: ChatMemberOwner,
cls.ADMINISTRATOR: ChatMemberAdministrator,
cls.MEMBER: ChatMemberMember,
cls.RESTRICTED: ChatMemberRestricted,
cls.LEFT: ChatMemberLeft,
cls.BANNED: ChatMemberBanned,
}
if cls is ChatMember and data.get("status") in _class_mapping:
return _class_mapping[data.pop("status")].de_json(data=data, bot=bot)
data["user"] = User.de_json(data.get("user"), bot)
if "until_date" in data:
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["until_date"] = from_timestamp(data["until_date"], tzinfo=loc_tzinfo)
# This is a deprecated field that TG still returns for backwards compatibility
# Let's filter it out to speed up the de-json process
if cls is ChatMemberRestricted and data.get("can_send_media_messages") is not None:
api_kwargs = {"can_send_media_messages": data.pop("can_send_media_messages")}
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
return super().de_json(data=data, bot=bot)
class ChatMemberOwner(ChatMember):
"""
Represents a chat member that owns the chat
and has all administrator privileges.
.. versionadded:: 13.7
Args:
user (:class:`telegram.User`): Information about the user.
is_anonymous (:obj:`bool`): :obj:`True`, if the
user's presence in the chat is hidden.
custom_title (:obj:`str`, optional): Custom title for this user.
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.OWNER`.
user (:class:`telegram.User`): Information about the user.
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
presence in the chat is hidden.
custom_title (:obj:`str`): Optional. Custom title for
this user.
"""
__slots__ = ("custom_title", "is_anonymous")
def __init__(
self,
user: User,
is_anonymous: bool,
custom_title: Optional[str] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.OWNER, user=user, api_kwargs=api_kwargs)
with self._unfrozen():
self.is_anonymous: bool = is_anonymous
self.custom_title: Optional[str] = custom_title
class ChatMemberAdministrator(ChatMember):
"""
Represents a chat member that has some additional privileges.
.. versionadded:: 13.7
.. versionchanged:: 20.0
* Argument and attribute ``can_manage_voice_chats`` were renamed to
:paramref:`can_manage_video_chats` and :attr:`can_manage_video_chats` in accordance to
Bot API 6.0.
* The argument :paramref:`can_manage_topics` was added, which changes the position of the
optional argument :paramref:`custom_title`.
.. versionchanged:: 21.1
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
changed.
Args:
user (:class:`telegram.User`): Information about the user.
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
is allowed to edit administrator privileges of that user.
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the
administrator can delete messages of other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the
administrator can manage video chats.
.. versionadded:: 20.0
can_restrict_members (:obj:`bool`): :obj:`True`, if the
administrator can restrict, ban or unban chat members.
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator
can add new administrators with a subset of his own privileges or demote
administrators that he has promoted, directly or indirectly (promoted by
administrators that were appointed by the user).
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
the chat title, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
new users to the chat.
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the
administrator can post messages in the channel, or access channel statistics;
for channels only.
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the
administrator can edit messages of other users and can pin
messages; for channels only.
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to pin messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
custom_title (:obj:`str`, optional): Custom title for this user.
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.ADMINISTRATOR`.
user (:class:`telegram.User`): Information about the user.
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
is allowed to edit administrator privileges of that user.
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
log, get boost list, see hidden supergroup and channel members, report spam messages
and ignore slow mode. Implied by any other administrator privilege.
can_delete_messages (:obj:`bool`): :obj:`True`, if the
administrator can delete messages of other users.
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the
administrator can manage video chats.
.. versionadded:: 20.0
can_restrict_members (:obj:`bool`): :obj:`True`, if the
administrator can restrict, ban or unban chat members, or access supergroup statistics.
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
administrators with a subset of their own privileges or demote administrators
that they have promoted, directly or indirectly (promoted by administrators that
were appointed by the user).
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
the chat title, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
new users to the chat.
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the
administrator can post messages in the channel or access channel statistics;
for channels only.
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the
administrator can edit messages of other users and can pin
messages; for channels only.
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to pin messages; for groups and supergroups only.
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
stories to the chat.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
by other users, post stories to the chat page, pin chat stories, and access the chat's
story archive
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
stories posted by other users.
.. versionadded:: 20.6
.. versionchanged:: 21.0
|non_optional_story_argument|
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to create, rename, close, and reopen forum topics; for supergroups only
.. versionadded:: 20.0
custom_title (:obj:`str`): Optional. Custom title for this user.
"""
__slots__ = (
"can_be_edited",
"can_change_info",
"can_delete_messages",
"can_delete_stories",
"can_edit_messages",
"can_edit_stories",
"can_invite_users",
"can_manage_chat",
"can_manage_topics",
"can_manage_video_chats",
"can_pin_messages",
"can_post_messages",
"can_post_stories",
"can_promote_members",
"can_restrict_members",
"custom_title",
"is_anonymous",
)
def __init__(
self,
user: User,
can_be_edited: bool,
is_anonymous: bool,
can_manage_chat: bool,
can_delete_messages: bool,
can_manage_video_chats: bool,
can_restrict_members: bool,
can_promote_members: bool,
can_change_info: bool,
can_invite_users: bool,
can_post_stories: bool,
can_edit_stories: bool,
can_delete_stories: bool,
can_post_messages: Optional[bool] = None,
can_edit_messages: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
custom_title: Optional[str] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.ADMINISTRATOR, user=user, api_kwargs=api_kwargs)
with self._unfrozen():
self.can_be_edited: bool = can_be_edited
self.is_anonymous: bool = is_anonymous
self.can_manage_chat: bool = can_manage_chat
self.can_delete_messages: bool = can_delete_messages
self.can_manage_video_chats: bool = can_manage_video_chats
self.can_restrict_members: bool = can_restrict_members
self.can_promote_members: bool = can_promote_members
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_post_stories: bool = can_post_stories
self.can_edit_stories: bool = can_edit_stories
self.can_delete_stories: bool = can_delete_stories
# Optionals
self.can_post_messages: Optional[bool] = can_post_messages
self.can_edit_messages: Optional[bool] = can_edit_messages
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self.custom_title: Optional[str] = custom_title
class ChatMemberMember(ChatMember):
"""
Represents a chat member that has no additional
privileges or restrictions.
.. versionadded:: 13.7
Args:
user (:class:`telegram.User`): Information about the user.
until_date (:class:`datetime.datetime`, optional): Date when the user's subscription will
expire.
.. versionadded:: 21.5
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.MEMBER`.
user (:class:`telegram.User`): Information about the user.
until_date (:class:`datetime.datetime`): Optional. Date when the user's subscription will
expire.
.. versionadded:: 21.5
"""
__slots__ = ("until_date",)
def __init__(
self,
user: User,
until_date: Optional[datetime.datetime] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.MEMBER, user=user, api_kwargs=api_kwargs)
with self._unfrozen():
self.until_date: Optional[datetime.datetime] = until_date
class ChatMemberRestricted(ChatMember):
"""
Represents a chat member that is under certain restrictions
in the chat. Supergroups only.
.. versionadded:: 13.7
.. versionchanged:: 20.0
All arguments were made positional and their order was changed.
The argument can_manage_topics was added.
.. versionchanged:: 20.5
Removed deprecated argument and attribute ``can_send_media_messages``.
Args:
user (:class:`telegram.User`): Information about the user.
is_member (:obj:`bool`): :obj:`True`, if the user is a
member of the chat at the moment of the request.
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
the chat title, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
new users to the chat.
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to pin messages; groups and supergroups only.
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to send text messages, contacts, invoices, locations and venues.
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
to send polls.
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to send animations, games, stickers and use inline bots.
can_add_web_page_previews (:obj:`bool`): :obj:`True`, if the user is
allowed to add web page previews to their messages.
can_manage_topics (:obj:`bool`): :obj:`True`, if the user is allowed to create
forum topics.
.. versionadded:: 20.0
until_date (:class:`datetime.datetime`): Date when restrictions
will be lifted for this user.
.. versionchanged:: 20.3
|datetime_localization|
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
.. versionadded:: 20.1
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
.. versionadded:: 20.1
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
.. versionadded:: 20.1
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
.. versionadded:: 20.1
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
notes.
.. versionadded:: 20.1
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
notes.
.. versionadded:: 20.1
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.RESTRICTED`.
user (:class:`telegram.User`): Information about the user.
is_member (:obj:`bool`): :obj:`True`, if the user is a
member of the chat at the moment of the request.
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
the chat title, photo and other settings.
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
new users to the chat.
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to pin messages; groups and supergroups only.
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to send text messages, contacts, locations and venues.
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
to send polls.
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
to send animations, games, stickers and use inline bots.
can_add_web_page_previews (:obj:`bool`): :obj:`True`, if the user is
allowed to add web page previews to their messages.
can_manage_topics (:obj:`bool`): :obj:`True`, if the user is allowed to create
forum topics.
.. versionadded:: 20.0
until_date (:class:`datetime.datetime`): Date when restrictions
will be lifted for this user.
.. versionchanged:: 20.3
|datetime_localization|
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
"""
__slots__ = (
"can_add_web_page_previews",
"can_change_info",
"can_invite_users",
"can_manage_topics",
"can_pin_messages",
"can_send_audios",
"can_send_documents",
"can_send_messages",
"can_send_other_messages",
"can_send_photos",
"can_send_polls",
"can_send_video_notes",
"can_send_videos",
"can_send_voice_notes",
"is_member",
"until_date",
)
def __init__(
self,
user: User,
is_member: bool,
can_change_info: bool,
can_invite_users: bool,
can_pin_messages: bool,
can_send_messages: bool,
can_send_polls: bool,
can_send_other_messages: bool,
can_add_web_page_previews: bool,
can_manage_topics: bool,
until_date: datetime.datetime,
can_send_audios: bool,
can_send_documents: bool,
can_send_photos: bool,
can_send_videos: bool,
can_send_video_notes: bool,
can_send_voice_notes: bool,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.RESTRICTED, user=user, api_kwargs=api_kwargs)
with self._unfrozen():
self.is_member: bool = is_member
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_pin_messages: bool = can_pin_messages
self.can_send_messages: bool = can_send_messages
self.can_send_polls: bool = can_send_polls
self.can_send_other_messages: bool = can_send_other_messages
self.can_add_web_page_previews: bool = can_add_web_page_previews
self.can_manage_topics: bool = can_manage_topics
self.until_date: datetime.datetime = until_date
self.can_send_audios: bool = can_send_audios
self.can_send_documents: bool = can_send_documents
self.can_send_photos: bool = can_send_photos
self.can_send_videos: bool = can_send_videos
self.can_send_video_notes: bool = can_send_video_notes
self.can_send_voice_notes: bool = can_send_voice_notes
class ChatMemberLeft(ChatMember):
"""
Represents a chat member that isn't currently a member of the chat,
but may join it themselves.
.. versionadded:: 13.7
Args:
user (:class:`telegram.User`): Information about the user.
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.LEFT`.
user (:class:`telegram.User`): Information about the user.
"""
__slots__ = ()
def __init__(
self,
user: User,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.LEFT, user=user, api_kwargs=api_kwargs)
self._freeze()
class ChatMemberBanned(ChatMember):
"""
Represents a chat member that was banned in the chat and
can't return to the chat or view chat messages.
.. versionadded:: 13.7
Args:
user (:class:`telegram.User`): Information about the user.
until_date (:class:`datetime.datetime`): Date when restrictions
will be lifted for this user.
.. versionchanged:: 20.3
|datetime_localization|
Attributes:
status (:obj:`str`): The member's status in the chat,
always :tg-const:`telegram.ChatMember.BANNED`.
user (:class:`telegram.User`): Information about the user.
until_date (:class:`datetime.datetime`): Date when restrictions
will be lifted for this user.
.. versionchanged:: 20.3
|datetime_localization|
"""
__slots__ = ("until_date",)
def __init__(
self,
user: User,
until_date: datetime.datetime,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(status=ChatMember.BANNED, user=user, api_kwargs=api_kwargs)
with self._unfrozen():
self.until_date: datetime.datetime = until_date

View File

@@ -0,0 +1,219 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChatMemberUpdated."""
import datetime
from typing import TYPE_CHECKING, Optional, Union
from telegram._chat import Chat
from telegram._chatinvitelink import ChatInviteLink
from telegram._chatmember import ChatMember
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatMemberUpdated(TelegramObject):
"""This object represents changes in the status of a chat member.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`chat`, :attr:`from_user`, :attr:`date`,
:attr:`old_chat_member` and :attr:`new_chat_member` are equal.
.. versionadded:: 13.4
Note:
In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead.
Examples:
:any:`Chat Member Bot <examples.chatmemberbot>`
Args:
chat (:class:`telegram.Chat`): Chat the user belongs to.
from_user (:class:`telegram.User`): Performer of the action, which resulted in the change.
date (:class:`datetime.datetime`): Date the change was done in Unix time. Converted to
:class:`datetime.datetime`.
.. versionchanged:: 20.3
|datetime_localization|
old_chat_member (:class:`telegram.ChatMember`): Previous information about the chat member.
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link, which was used
by the user to join the chat. For joining by invite link events only.
via_chat_folder_invite_link (:obj:`bool`, optional): :obj:`True`, if the user joined the
chat via a chat folder invite link
.. versionadded:: 20.3
via_join_request (:obj:`bool`, optional): :obj:`True`, if the user joined the chat after
sending a direct join request without using an invite link and being approved by
an administrator
.. versionadded:: 21.2
Attributes:
chat (:class:`telegram.Chat`): Chat the user belongs to.
from_user (:class:`telegram.User`): Performer of the action, which resulted in the change.
date (:class:`datetime.datetime`): Date the change was done in Unix time. Converted to
:class:`datetime.datetime`.
.. versionchanged:: 20.3
|datetime_localization|
old_chat_member (:class:`telegram.ChatMember`): Previous information about the chat member.
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link, which was used
by the user to join the chat. For joining by invite link events only.
via_chat_folder_invite_link (:obj:`bool`): Optional. :obj:`True`, if the user joined the
chat via a chat folder invite link
.. versionadded:: 20.3
via_join_request (:obj:`bool`): Optional. :obj:`True`, if the user joined the chat after
sending a direct join request without using an invite link and being approved
by an administrator
.. versionadded:: 21.2
"""
__slots__ = (
"chat",
"date",
"from_user",
"invite_link",
"new_chat_member",
"old_chat_member",
"via_chat_folder_invite_link",
"via_join_request",
)
def __init__(
self,
chat: Chat,
from_user: User,
date: datetime.datetime,
old_chat_member: ChatMember,
new_chat_member: ChatMember,
invite_link: Optional[ChatInviteLink] = None,
via_chat_folder_invite_link: Optional[bool] = None,
via_join_request: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.chat: Chat = chat
self.from_user: User = from_user
self.date: datetime.datetime = date
self.old_chat_member: ChatMember = old_chat_member
self.new_chat_member: ChatMember = new_chat_member
self.via_chat_folder_invite_link: Optional[bool] = via_chat_folder_invite_link
# Optionals
self.invite_link: Optional[ChatInviteLink] = invite_link
self.via_join_request: Optional[bool] = via_join_request
self._id_attrs = (
self.chat,
self.from_user,
self.date,
self.old_chat_member,
self.new_chat_member,
)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatMemberUpdated"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["chat"] = Chat.de_json(data.get("chat"), bot)
data["from_user"] = User.de_json(data.pop("from", None), bot)
data["date"] = from_timestamp(data.get("date"), tzinfo=loc_tzinfo)
data["old_chat_member"] = ChatMember.de_json(data.get("old_chat_member"), bot)
data["new_chat_member"] = ChatMember.de_json(data.get("new_chat_member"), bot)
data["invite_link"] = ChatInviteLink.de_json(data.get("invite_link"), bot)
return super().de_json(data=data, bot=bot)
def _get_attribute_difference(self, attribute: str) -> tuple[object, object]:
try:
old = self.old_chat_member[attribute]
except KeyError:
old = None
try:
new = self.new_chat_member[attribute]
except KeyError:
new = None
return old, new
def difference(
self,
) -> dict[
str,
tuple[
Union[str, bool, datetime.datetime, User], Union[str, bool, datetime.datetime, User]
],
]:
"""Computes the difference between :attr:`old_chat_member` and :attr:`new_chat_member`.
Example:
.. code:: pycon
>>> chat_member_updated.difference()
{'custom_title': ('old title', 'new title')}
Note:
To determine, if the :attr:`telegram.ChatMember.user` attribute has changed, *every*
attribute of the user will be checked.
.. versionadded:: 13.5
Returns:
dict[:obj:`str`, tuple[:class:`object`, :class:`object`]]: A dictionary mapping
attribute names to tuples of the form ``(old_value, new_value)``
"""
# we first get the names of the attributes that have changed
# user.to_dict() is unhashable, so that needs some special casing further down
old_dict = self.old_chat_member.to_dict()
old_user_dict = old_dict.pop("user")
new_dict = self.new_chat_member.to_dict()
new_user_dict = new_dict.pop("user")
# Generator for speed: we only need to iterate over it once
# we can't directly use the values from old_dict ^ new_dict b/c that set is unordered
attributes = (entry[0] for entry in set(old_dict.items()) ^ set(new_dict.items()))
result = {attribute: self._get_attribute_difference(attribute) for attribute in attributes}
if old_user_dict != new_user_dict:
result["user"] = (self.old_chat_member.user, self.new_chat_member.user)
return result # type: ignore[return-value]

View File

@@ -0,0 +1,249 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChatPermission."""
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChatPermissions(TelegramObject):
"""Describes actions that a non-administrator user is allowed to take in a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`can_send_messages`,
:attr:`can_send_polls`, :attr:`can_send_other_messages`, :attr:`can_add_web_page_previews`,
:attr:`can_change_info`, :attr:`can_invite_users`, :attr:`can_pin_messages`,
:attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
:attr:`can_send_videos`, :attr:`can_send_video_notes`, :attr:`can_send_voice_notes`, and
:attr:`can_manage_topics` are equal.
.. versionchanged:: 20.0
:attr:`can_manage_topics` is considered as well when comparing objects of
this type in terms of equality.
.. versionchanged:: 20.5
* :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`
are considered as well when comparing objects of this type in terms of equality.
* Removed deprecated argument and attribute ``can_send_media_messages``.
Note:
Though not stated explicitly in the official docs, Telegram changes not only the
permissions that are set, but also sets all the others to :obj:`False`. However, since not
documented, this behavior may change unbeknown to PTB.
Args:
can_send_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send text
messages, contacts, locations and venues.
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls.
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
send animations, games, stickers and use inline bots.
can_add_web_page_previews (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
add web page previews to their messages.
can_change_info (:obj:`bool`, optional): :obj:`True`, if the user is allowed to change the
chat title, photo and other settings. Ignored in public supergroups.
can_invite_users (:obj:`bool`, optional): :obj:`True`, if the user is allowed to invite new
users to the chat.
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
messages. Ignored in public supergroups.
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
to create forum topics. If omitted defaults to the value of
:attr:`can_pin_messages`.
.. versionadded:: 20.0
can_send_audios (:obj:`bool`): :obj:`True`, if the user is allowed to send audios.
.. versionadded:: 20.1
can_send_documents (:obj:`bool`): :obj:`True`, if the user is allowed to send documents.
.. versionadded:: 20.1
can_send_photos (:obj:`bool`): :obj:`True`, if the user is allowed to send photos.
.. versionadded:: 20.1
can_send_videos (:obj:`bool`): :obj:`True`, if the user is allowed to send videos.
.. versionadded:: 20.1
can_send_video_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send video
notes.
.. versionadded:: 20.1
can_send_voice_notes (:obj:`bool`): :obj:`True`, if the user is allowed to send voice
notes.
.. versionadded:: 20.1
Attributes:
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
messages, contacts, locations and venues.
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send polls,
implies :attr:`can_send_messages`.
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
send animations, games, stickers and use inline bots.
can_add_web_page_previews (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
add web page previews to their messages.
can_change_info (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to change the
chat title, photo and other settings. Ignored in public supergroups.
can_invite_users (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to invite
new users to the chat.
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
messages. Ignored in public supergroups.
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
to create forum topics. If omitted defaults to the value of
:attr:`can_pin_messages`.
.. versionadded:: 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
"""
__slots__ = (
"can_add_web_page_previews",
"can_change_info",
"can_invite_users",
"can_manage_topics",
"can_pin_messages",
"can_send_audios",
"can_send_documents",
"can_send_messages",
"can_send_other_messages",
"can_send_photos",
"can_send_polls",
"can_send_video_notes",
"can_send_videos",
"can_send_voice_notes",
)
def __init__(
self,
can_send_messages: Optional[bool] = None,
can_send_polls: Optional[bool] = None,
can_send_other_messages: Optional[bool] = None,
can_add_web_page_previews: Optional[bool] = None,
can_change_info: Optional[bool] = None,
can_invite_users: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
can_send_audios: Optional[bool] = None,
can_send_documents: Optional[bool] = None,
can_send_photos: Optional[bool] = None,
can_send_videos: Optional[bool] = None,
can_send_video_notes: Optional[bool] = None,
can_send_voice_notes: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.can_send_messages: Optional[bool] = can_send_messages
self.can_send_polls: Optional[bool] = can_send_polls
self.can_send_other_messages: Optional[bool] = can_send_other_messages
self.can_add_web_page_previews: Optional[bool] = can_add_web_page_previews
self.can_change_info: Optional[bool] = can_change_info
self.can_invite_users: Optional[bool] = can_invite_users
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self.can_send_audios: Optional[bool] = can_send_audios
self.can_send_documents: Optional[bool] = can_send_documents
self.can_send_photos: Optional[bool] = can_send_photos
self.can_send_videos: Optional[bool] = can_send_videos
self.can_send_video_notes: Optional[bool] = can_send_video_notes
self.can_send_voice_notes: Optional[bool] = can_send_voice_notes
self._id_attrs = (
self.can_send_messages,
self.can_send_polls,
self.can_send_other_messages,
self.can_add_web_page_previews,
self.can_change_info,
self.can_invite_users,
self.can_pin_messages,
self.can_manage_topics,
self.can_send_audios,
self.can_send_documents,
self.can_send_photos,
self.can_send_videos,
self.can_send_video_notes,
self.can_send_voice_notes,
)
self._freeze()
@classmethod
def all_permissions(cls) -> "ChatPermissions":
"""
This method returns an :class:`ChatPermissions` instance with all attributes
set to :obj:`True`. This is e.g. useful when unrestricting a chat member with
:meth:`telegram.Bot.restrict_chat_member`.
.. versionadded:: 20.0
"""
return cls(*(14 * (True,)))
@classmethod
def no_permissions(cls) -> "ChatPermissions":
"""
This method returns an :class:`ChatPermissions` instance
with all attributes set to :obj:`False`.
.. versionadded:: 20.0
"""
return cls(*(14 * (False,)))
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChatPermissions"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
api_kwargs = {}
# This is a deprecated field that TG still returns for backwards compatibility
# Let's filter it out to speed up the de-json process
if data.get("can_send_media_messages") is not None:
api_kwargs["can_send_media_messages"] = data.pop("can_send_media_messages")
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python
# pylint: disable=too-many-arguments
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram ChosenInlineResult."""
from typing import TYPE_CHECKING, Optional
from telegram._files.location import Location
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram import Bot
class ChosenInlineResult(TelegramObject):
"""
Represents a result of an inline query that was chosen by the user and sent to their chat
partner.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`result_id` is equal.
Note:
* In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead.
* It is necessary to enable inline feedback via `@Botfather <https://t.me/BotFather>`_ in
order to receive these objects in updates.
Args:
result_id (:obj:`str`): The unique identifier for the result that was chosen.
from_user (:class:`telegram.User`): The user that chose the result.
location (:class:`telegram.Location`, optional): Sender location, only for bots that
require user location.
inline_message_id (:obj:`str`, optional): Identifier of the sent inline message. Available
only if there is an inline keyboard attached to the message. Will be also received in
callback queries and can be used to edit the message.
query (:obj:`str`): The query that was used to obtain the result.
Attributes:
result_id (:obj:`str`): The unique identifier for the result that was chosen.
from_user (:class:`telegram.User`): The user that chose the result.
location (:class:`telegram.Location`): Optional. Sender location, only for bots that
require user location.
inline_message_id (:obj:`str`): Optional. Identifier of the sent inline message. Available
only if there is an inline keyboard attached to the message. Will be also received in
callback queries and can be used to edit the message.
query (:obj:`str`): The query that was used to obtain the result.
"""
__slots__ = ("from_user", "inline_message_id", "location", "query", "result_id")
def __init__(
self,
result_id: str,
from_user: User,
query: str,
location: Optional[Location] = None,
inline_message_id: Optional[str] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.result_id: str = result_id
self.from_user: User = from_user
self.query: str = query
# Optionals
self.location: Optional[Location] = location
self.inline_message_id: Optional[str] = inline_message_id
self._id_attrs = (self.result_id,)
self._freeze()
@classmethod
def de_json(
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional["ChosenInlineResult"]:
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
if not data:
return None
# Required
data["from_user"] = User.de_json(data.pop("from", None), bot)
# Optionals
data["location"] = Location.de_json(data.get("location"), bot)
return super().de_json(data=data, bot=bot)

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram CopyTextButton."""
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class CopyTextButton(TelegramObject):
"""
This object represents an inline keyboard button that copies specified text to the clipboard.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`text` is equal.
.. versionadded:: 21.7
Args:
text (:obj:`str`): The text to be copied to the clipboard;
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MIN_COPY_TEXT`-
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MAX_COPY_TEXT` characters
Attributes:
text (:obj:`str`): The text to be copied to the clipboard;
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MIN_COPY_TEXT`-
:tg-const:`telegram.constants.InlineKeyboardButtonLimit.MAX_COPY_TEXT` characters
"""
__slots__ = ("text",)
def __init__(self, text: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.text: str = text
self._id_attrs = (self.text,)
self._freeze()

View File

@@ -0,0 +1,160 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 an object that represents a Telegram Dice."""
from typing import Final, Optional
from telegram import constants
from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict
class Dice(TelegramObject):
"""
This object represents an animated emoji with a random value for currently supported base
emoji. (The singular form of "dice" is "die". However, PTB mimics the Telegram API, which uses
the term "dice".)
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`value` and :attr:`emoji` are equal.
Note:
If :attr:`emoji` is :tg-const:`telegram.Dice.DARTS`, a value of 6 currently
represents a bullseye, while a value of 1 indicates that the dartboard was missed.
However, this behaviour is undocumented and might be changed by Telegram.
If :attr:`emoji` is :tg-const:`telegram.Dice.BASKETBALL`, a value of 4 or 5
currently score a basket, while a value of 1 to 3 indicates that the basket was missed.
However, this behaviour is undocumented and might be changed by Telegram.
If :attr:`emoji` is :tg-const:`telegram.Dice.FOOTBALL`, a value of 4 to 5
currently scores a goal, while a value of 1 to 3 indicates that the goal was missed.
However, this behaviour is undocumented and might be changed by Telegram.
If :attr:`emoji` is :tg-const:`telegram.Dice.BOWLING`, a value of 6 knocks
all the pins, while a value of 1 means all the pins were missed.
However, this behaviour is undocumented and might be changed by Telegram.
If :attr:`emoji` is :tg-const:`telegram.Dice.SLOT_MACHINE`, each value
corresponds to a unique combination of symbols, which
can be found in our
:wiki:`wiki <Code-snippets#map-a-slot-machine-dice-value-to-the-corresponding-symbols>`.
However, this behaviour is undocumented and might be changed by Telegram.
..
In args, some links for limits of `value` intentionally point to constants for only
one emoji of a group to avoid duplication. For example, maximum value for Dice, Darts and
Bowling is linked to a constant for Bowling.
Args:
value (:obj:`int`): Value of the dice.
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_BOWLING`
for :tg-const:`telegram.Dice.DICE`, :tg-const:`telegram.Dice.DARTS` and
:tg-const:`telegram.Dice.BOWLING` base emoji,
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_BASKETBALL`
for :tg-const:`telegram.Dice.BASKETBALL` and :tg-const:`telegram.Dice.FOOTBALL`
base emoji,
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_SLOT_MACHINE`
for :tg-const:`telegram.Dice.SLOT_MACHINE` base emoji.
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
Attributes:
value (:obj:`int`): Value of the dice.
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_BOWLING`
for :tg-const:`telegram.Dice.DICE`, :tg-const:`telegram.Dice.DARTS` and
:tg-const:`telegram.Dice.BOWLING` base emoji,
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_BASKETBALL`
for :tg-const:`telegram.Dice.BASKETBALL` and :tg-const:`telegram.Dice.FOOTBALL`
base emoji,
:tg-const:`telegram.Dice.MIN_VALUE`-:tg-const:`telegram.Dice.MAX_VALUE_SLOT_MACHINE`
for :tg-const:`telegram.Dice.SLOT_MACHINE` base emoji.
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
"""
__slots__ = ("emoji", "value")
def __init__(self, value: int, emoji: str, *, api_kwargs: Optional[JSONDict] = None):
super().__init__(api_kwargs=api_kwargs)
self.value: int = value
self.emoji: str = emoji
self._id_attrs = (self.value, self.emoji)
self._freeze()
DICE: Final[str] = constants.DiceEmoji.DICE
""":const:`telegram.constants.DiceEmoji.DICE`"""
DARTS: Final[str] = constants.DiceEmoji.DARTS
""":const:`telegram.constants.DiceEmoji.DARTS`"""
BASKETBALL: Final[str] = constants.DiceEmoji.BASKETBALL
""":const:`telegram.constants.DiceEmoji.BASKETBALL`"""
FOOTBALL: Final[str] = constants.DiceEmoji.FOOTBALL
""":const:`telegram.constants.DiceEmoji.FOOTBALL`"""
SLOT_MACHINE: Final[str] = constants.DiceEmoji.SLOT_MACHINE
""":const:`telegram.constants.DiceEmoji.SLOT_MACHINE`"""
BOWLING: Final[str] = constants.DiceEmoji.BOWLING
"""
:const:`telegram.constants.DiceEmoji.BOWLING`
.. versionadded:: 13.4
"""
ALL_EMOJI: Final[list[str]] = list(constants.DiceEmoji)
"""list[:obj:`str`]: A list of all available dice emoji."""
MIN_VALUE: Final[int] = constants.DiceLimit.MIN_VALUE
""":const:`telegram.constants.DiceLimit.MIN_VALUE`
.. versionadded:: 20.0
"""
MAX_VALUE_BOWLING: Final[int] = constants.DiceLimit.MAX_VALUE_BOWLING
""":const:`telegram.constants.DiceLimit.MAX_VALUE_BOWLING`
.. versionadded:: 20.0
"""
MAX_VALUE_DARTS: Final[int] = constants.DiceLimit.MAX_VALUE_DARTS
""":const:`telegram.constants.DiceLimit.MAX_VALUE_DARTS`
.. versionadded:: 20.0
"""
MAX_VALUE_DICE: Final[int] = constants.DiceLimit.MAX_VALUE_DICE
""":const:`telegram.constants.DiceLimit.MAX_VALUE_DICE`
.. versionadded:: 20.0
"""
MAX_VALUE_BASKETBALL: Final[int] = constants.DiceLimit.MAX_VALUE_BASKETBALL
""":const:`telegram.constants.DiceLimit.MAX_VALUE_BASKETBALL`
.. versionadded:: 20.0
"""
MAX_VALUE_FOOTBALL: Final[int] = constants.DiceLimit.MAX_VALUE_FOOTBALL
""":const:`telegram.constants.DiceLimit.MAX_VALUE_FOOTBALL`
.. versionadded:: 20.0
"""
MAX_VALUE_SLOT_MACHINE: Final[int] = constants.DiceLimit.MAX_VALUE_SLOT_MACHINE
""":const:`telegram.constants.DiceLimit.MAX_VALUE_SLOT_MACHINE`
.. versionadded:: 20.0
"""

Some files were not shown because too many files have changed in this diff Show More