Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changes/unreleased/5234.FgQx53cjQCCm2d7tEiMR.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
features = "Added the class :class:`telegram.SentGuestMessage` and the method :meth:`telegram.Bot.answer_guest_query` as well as the filter :attr:`telegram.ext.filters.UpdateType.GUEST_MESSAGE` for Bot API 10.0 Guest Mode support."
[[pull_requests]]
uid = "5234"
author_uids = ["Phil9l"]
closes_threads = ["5228"]
1 change: 1 addition & 0 deletions docs/source/telegram.at-tree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ Available Types
telegram.replykeyboardmarkup
telegram.replykeyboardremove
telegram.replyparameters
telegram.sentguestmessage
telegram.sentwebappmessage
telegram.shareduser
telegram.story
Expand Down
6 changes: 6 additions & 0 deletions docs/source/telegram.sentguestmessage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SentGuestMessage
================

.. autoclass:: telegram.SentGuestMessage
:members:
:show-inheritance:
2 changes: 2 additions & 0 deletions src/telegram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
"RevenueWithdrawalStateSucceeded",
"SecureData",
"SecureValue",
"SentGuestMessage",
"SentWebAppMessage",
"SharedUser",
"ShippingAddress",
Expand Down Expand Up @@ -595,6 +596,7 @@
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
from ._replykeyboardmarkup import ReplyKeyboardMarkup
from ._replykeyboardremove import ReplyKeyboardRemove
from ._sentguestmessage import SentGuestMessage
from ._sentwebappmessage import SentWebAppMessage
from ._shared import ChatShared, SharedUser, UsersShared
from ._story import Story
Expand Down
48 changes: 48 additions & 0 deletions src/telegram/_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
from telegram._preparedkeyboardbutton import PreparedKeyboardButton
from telegram._reaction import ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
from telegram._reply import ReplyParameters
from telegram._sentguestmessage import SentGuestMessage
from telegram._sentwebappmessage import SentWebAppMessage
from telegram._story import Story
from telegram._telegramobject import TelegramObject
Expand Down Expand Up @@ -5848,6 +5849,51 @@ async def answer_web_app_query(

return SentWebAppMessage.de_json(api_result, self)

async def answer_guest_query(
self,
guest_query_id: str,
result: "InlineQueryResult",
*,
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: JSONDict | None = None,
) -> SentGuestMessage:
"""Use this method to reply to a received guest message.

.. versionadded:: NEXT.VERSION

Args:
guest_query_id (:obj:`str`): Unique identifier for the query to be answered.
result (:class:`telegram.InlineQueryResult`): An object describing the message to be
sent.

Returns:
:class:`telegram.SentGuestMessage`: On success, a sent
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:class:`telegram.SentGuestMessage`: On success, a sent
:class:`telegram.SentGuestMessage`: On success, a

:class:`telegram.SentGuestMessage` is returned.

Raises:
:class:`telegram.error.TelegramError`

"""
data: JSONDict = {
"guest_query_id": guest_query_id,
"result": self._insert_defaults_for_ilq_results(result),
}

api_result = await self._post(
"answerGuestQuery",
data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

return SentGuestMessage.de_json(api_result, self)

async def restrict_chat_member(
self,
chat_id: str | int,
Expand Down Expand Up @@ -12399,6 +12445,8 @@ def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
"""Alias for :meth:`answer_pre_checkout_query`"""
answerWebAppQuery = answer_web_app_query
"""Alias for :meth:`answer_web_app_query`"""
answerGuestQuery = answer_guest_query
"""Alias for :meth:`answer_guest_query`"""
restrictChatMember = restrict_chat_member
"""Alias for :meth:`restrict_chat_member`"""
promoteChatMember = promote_chat_member
Expand Down
45 changes: 45 additions & 0 deletions src/telegram/_message.py
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a shortcut for answer_guest_query here would be ideal

Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,21 @@ class Message(MaybeInaccessibleMessage):
managed_bot_created (:class:`telegram.ManagedBotCreated`, optional): Service message: user
created a bot that will be managed by the current bot.

.. versionadded:: NEXT.VERSION
guest_bot_caller_user (:class:`telegram.User`, optional): For a message sent by a guest
bot, this is the user whose original message triggered the bot's response.

.. versionadded:: NEXT.VERSION
guest_bot_caller_chat (:class:`telegram.Chat`, optional): For a message sent by a guest
bot, this is the user whose original message triggered the bot's response.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bot, this is the user whose original message triggered the bot's response.
bot, this is the chat whose original message triggered the bot's response.


.. versionadded:: NEXT.VERSION
guest_query_id (:obj:`str`, optional): The unique identifier for the guest query. Use this
identifier with the method :meth:`telegram.Bot.answer_guest_query` to send a response
message. If non-empty, the message belongs to a chat of the corresponding business
account that is independent from any potential bot chat which might share the same
identifier.
Comment on lines +721 to +723
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
message. If non-empty, the message belongs to a chat of the corresponding business
account that is independent from any potential bot chat which might share the same
identifier.
message. If non-empty, the message belongs to the chat where the guest
bot was summoned, which may not coincide with other existing bot chats
sharing the same identifier.


.. versionadded:: NEXT.VERSION

Attributes:
Expand Down Expand Up @@ -1139,6 +1154,21 @@ class Message(MaybeInaccessibleMessage):
managed_bot_created (:class:`telegram.ManagedBotCreated`): Optional. Service message: user
created a bot that will be managed by the current bot.

.. versionadded:: NEXT.VERSION
guest_bot_caller_user (:class:`telegram.User`): Optional. For a message sent by a guest
bot, this is the user whose original message triggered the bot's response.

.. versionadded:: NEXT.VERSION
guest_bot_caller_chat (:class:`telegram.Chat`): Optional. For a message sent by a guest
bot, this is the user whose original message triggered the bot's response.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bot, this is the user whose original message triggered the bot's response.
bot, this is the chat whose original message triggered the bot's response.


.. versionadded:: NEXT.VERSION
guest_query_id (:obj:`str`): Optional. The unique identifier for the guest query. Use this
identifier with the method :meth:`telegram.Bot.answer_guest_query` to send a response
message. If non-empty, the message belongs to a chat of the corresponding business
account that is independent from any potential bot chat which might share the same
identifier.
Comment on lines +1168 to +1170
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
message. If non-empty, the message belongs to a chat of the corresponding business
account that is independent from any potential bot chat which might share the same
identifier.
message. If non-empty, the message belongs to the chat where the guest
bot was summoned, which may not coincide with other existing bot chats
sharing the same identifier.


.. versionadded:: NEXT.VERSION

.. |custom_emoji_no_md1_support| replace:: Since custom emoji entities are not supported by
Expand Down Expand Up @@ -1201,6 +1231,9 @@ class Message(MaybeInaccessibleMessage):
"giveaway_created",
"giveaway_winners",
"group_chat_created",
"guest_bot_caller_chat",
"guest_bot_caller_user",
"guest_query_id",
"has_media_spoiler",
"has_protected_content",
"invoice",
Expand Down Expand Up @@ -1380,6 +1413,9 @@ def __init__(
poll_option_deleted: PollOptionDeleted | None = None,
reply_to_poll_option_id: str | None = None,
managed_bot_created: ManagedBotCreated | None = None,
guest_bot_caller_user: User | None = None,
guest_bot_caller_chat: Chat | None = None,
guest_query_id: str | None = None,
*,
api_kwargs: JSONDict | None = None,
):
Expand Down Expand Up @@ -1514,6 +1550,9 @@ def __init__(
self.poll_option_deleted: PollOptionDeleted | None = poll_option_deleted
self.reply_to_poll_option_id: str | None = reply_to_poll_option_id
self.managed_bot_created: ManagedBotCreated | None = managed_bot_created
self.guest_bot_caller_user: User | None = guest_bot_caller_user
self.guest_bot_caller_chat: Chat | None = guest_bot_caller_chat
self.guest_query_id: str | None = guest_query_id

self._effective_attachment = DEFAULT_NONE

Expand Down Expand Up @@ -1743,6 +1782,12 @@ def de_json(cls, data: JSONDict, bot: "Bot | None" = None) -> "Message":
data["managed_bot_created"] = de_json_optional(
data.get("managed_bot_created"), ManagedBotCreated, bot
)
data["guest_bot_caller_user"] = de_json_optional(
data.get("guest_bot_caller_user"), User, bot
)
data["guest_bot_caller_chat"] = de_json_optional(
data.get("guest_bot_caller_chat"), Chat, bot
)

api_kwargs = {}
# This is a deprecated field that TG still returns for backwards compatibility
Expand Down
54 changes: 54 additions & 0 deletions src/telegram/_sentguestmessage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2026
# 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 Sent Guest Message."""

from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict


class SentGuestMessage(TelegramObject):
"""Describes an inline message sent by a guest bot.

Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`inline_message_id` are equal.

.. versionadded:: NEXT.VERSION

Args:
inline_message_id (:obj:`str`): Identifier of the sent inline message.

Attributes:
inline_message_id (:obj:`str`): Identifier of the sent inline message.
"""

__slots__ = ("inline_message_id",)

def __init__(
self,
inline_message_id: str,
*,
api_kwargs: JSONDict | None = None,
):
super().__init__(api_kwargs=api_kwargs)
# Required
self.inline_message_id: str = inline_message_id

self._id_attrs = (self.inline_message_id,)

self._freeze()
Loading
Loading