diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..3e5834d5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,9 @@ +# Repository workflow + +- Use the repository's `make` targets for formatting, linting, generation, builds, and tests whenever a matching target exists. +- Run `make api-generate` after changing the API schema, code generator, or generator configuration. +- Run `make format` and `make lint`; do not invoke `clang-format` directly on generated files. `ApiMethods.cpp` and `ApiMethods.inc.h` require the dedicated formatting commands encoded in the `Makefile`. +- Run the complete build and test suite with `make test`. It installs the required dependencies, builds the C++ library and tests, runs the C++ tests, and runs the API codegen tests. +- Do not split a normal full verification into `make build-with-test`, `make test-only`, and `make test-api-codegen`; those targets are implementation details or for deliberately narrow reruns after `make test` has already built their prerequisites. +- Do not override `BUILD_DIR` for normal builds or tests. The Conan layout writes its toolchain to the repository's standard build directory, so a custom `BUILD_DIR` can make CMake look for a toolchain that Conan did not place there. +- Preserve public source compatibility when updating the Telegram Bot API. Do not reorder, remove, or change the types or defaults of existing positional `Api` method parameters, and do not remove existing fields from `*Args` structs. Append new optional parameters or expose them through `*Args`; when Telegram replaces parameters, keep the legacy API and translate it to the new wire representation. Add regression tests for the preserved signatures and translation. diff --git a/README.md b/README.md index 747bfe88..79dd7ef5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Documentation is located [here](http://reo7sp.github.io/tgbot-cpp). ## State -- [x] Telegram Bot API 10.2. +- [x] Telegram Bot API 10.3. ## Example diff --git a/api/codegen.yaml b/api/codegen.yaml index affc1c06..270c9c39 100644 --- a/api/codegen.yaml +++ b/api/codegen.yaml @@ -88,6 +88,10 @@ api: args_order: [scope, language_code] editChatInviteLink: args_order: [chat_id, invite_link, expire_date, member_limit, name, creates_join_request] + editEphemeralMessageMedia: + supports_attach_references: true + editEphemeralMessageText: + args_order: [chat_id, ephemeral_message_id, receiver_user_id, text, entities, link_preview_options, parse_mode, reply_markup, rich_message] editForumTopic: args_order: [chat_id, message_thread_id, name, icon_custom_emoji_id] editMessageCaption: @@ -133,17 +137,21 @@ api: restrictChatMember: args_order: [chat_id, user_id, permissions, until_date, use_independent_chat_permissions] sendAnimation: - args_order: [chat_id, animation, duration, width, height, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id] + args_order: [chat_id, animation, duration, width, height, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, show_caption_above_media, suggested_post_parameters] + legacy_ephemeral_parameters: true sendAudio: - args_order: [chat_id, audio, caption, duration, performer, title, thumbnail, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, audio, caption, duration, performer, title, thumbnail, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendChatAction: args_order: [chat_id, action, message_thread_id, business_connection_id] sendContact: - args_order: [chat_id, phone_number, first_name, last_name, vcard, disable_notification, reply_parameters, reply_markup, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, phone_number, first_name, last_name, vcard, disable_notification, reply_parameters, reply_markup, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendDice: args_order: [chat_id, disable_notification, reply_parameters, reply_markup, emoji, message_thread_id, protect_content, business_connection_id] sendDocument: - args_order: [chat_id, document, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, disable_content_type_detection, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, document, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, disable_content_type_detection, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendGame: args_order: [chat_id, game_short_name, reply_parameters, reply_markup, disable_notification, message_thread_id, protect_content, business_connection_id] sendInvoice: @@ -151,7 +159,11 @@ api: args: provider_token: {declaration_required: true} sendLocation: - args_order: [chat_id, latitude, longitude, live_period, reply_parameters, reply_markup, disable_notification, horizontal_accuracy, heading, proximity_alert_radius, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, latitude, longitude, live_period, reply_parameters, reply_markup, disable_notification, horizontal_accuracy, heading, proximity_alert_radius, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true + sendLivePhoto: + args_order: [chat_id, live_photo, photo, allow_paid_broadcast, business_connection_id, callback_query_id, caption, caption_entities, direct_messages_topic_id, disable_notification, has_spoiler, message_effect_id, message_thread_id, parse_mode, protect_content, receiver_user_id, reply_markup, reply_parameters, show_caption_above_media, suggested_post_parameters] + legacy_ephemeral_parameters: true sendMediaGroup: args_order: [chat_id, media, disable_notification, reply_parameters, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, direct_messages_topic_id, message_effect_id] supports_attach_references: true @@ -159,24 +171,36 @@ api: supports_attach_references: true sendRichMessage: supports_attach_references: true + direct_exclude: [ephemeral_message_parameters] + sendRichMessageDraft: + args_order: [chat_id, draft_id, rich_message, message_thread_id, can_stop, keep_on_stop] sendMessage: - args_order: [chat_id, text, link_preview_options, reply_parameters, reply_markup, parse_mode, disable_notification, entities, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, text, link_preview_options, reply_parameters, reply_markup, parse_mode, disable_notification, entities, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true + sendMessageDraft: + args_order: [chat_id, draft_id, entities, message_thread_id, parse_mode, text, can_stop, keep_on_stop] sendPhoto: - args_order: [chat_id, photo, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id] + args_order: [chat_id, photo, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, show_caption_above_media, suggested_post_parameters] + legacy_ephemeral_parameters: true sendPoll: args_order: [chat_id, question, options, disable_notification, reply_parameters, reply_markup, is_anonymous, type, allows_multiple_answers, correct_option_id, explanation, explanation_parse_mode, explanation_entities, open_period, close_date, is_closed, message_thread_id, protect_content, business_connection_id] args: is_anonymous: {default: true} sendSticker: - args_order: [chat_id, sticker, reply_parameters, reply_markup, disable_notification, message_thread_id, protect_content, emoji, business_connection_id] + args_order: [chat_id, sticker, reply_parameters, reply_markup, disable_notification, message_thread_id, protect_content, emoji, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendVenue: - args_order: [chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type, disable_notification, reply_parameters, reply_markup, google_place_id, google_place_type, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type, disable_notification, reply_parameters, reply_markup, google_place_id, google_place_type, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendVideo: - args_order: [chat_id, video, supports_streaming, duration, width, height, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id] + args_order: [chat_id, video, supports_streaming, duration, width, height, thumbnail, caption, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, has_spoiler, business_connection_id, allow_paid_broadcast, callback_query_id, cover, direct_messages_topic_id, message_effect_id, receiver_user_id, show_caption_above_media, start_timestamp, suggested_post_parameters] + legacy_ephemeral_parameters: true sendVideoNote: - args_order: [chat_id, video_note, reply_parameters, disable_notification, duration, length, thumbnail, reply_markup, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, video_note, reply_parameters, disable_notification, duration, length, thumbnail, reply_markup, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true sendVoice: - args_order: [chat_id, voice, caption, duration, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, business_connection_id] + args_order: [chat_id, voice, caption, duration, reply_parameters, reply_markup, parse_mode, disable_notification, caption_entities, message_thread_id, protect_content, business_connection_id, allow_paid_broadcast, callback_query_id, direct_messages_topic_id, message_effect_id, receiver_user_id, suggested_post_parameters] + legacy_ephemeral_parameters: true postStory: supports_attach_references: true setBusinessAccountProfilePhoto: diff --git a/api/telegram-bot-api.yaml b/api/telegram-bot-api.yaml index 1113bb33..abf31366 100644 --- a/api/telegram-bot-api.yaml +++ b/api/telegram-bot-api.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 info: title: "Telegram Bot API" - version: "10.2" + version: "10.3" description: |- This OpenAPI specification was generated using the [tgbotspec](https://github.com/metalagman/tgbotspec) tool. servers: @@ -102,7 +102,7 @@ paths: properties: cache_time: type: integer - description: The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. + description: The maximum amount of time in seconds that the result of the callback query may be cached client-side. Defaults to 0. callback_query_id: type: string description: Unique identifier for the query to be answered @@ -2388,6 +2388,9 @@ paths: description: A JSON-serialized object for an inline keyboard allOf: - $ref: '#/components/schemas/InlineKeyboardMarkup' + show_caption_above_media: + type: boolean + description: Pass True if the caption must be shown above the message media. Supported only for animation, photo and video messages. required: - chat_id - ephemeral_message_id @@ -2441,7 +2444,7 @@ paths: type: integer description: Identifier of the ephemeral message to edit media: - description: A JSON-serialized object for the new media content of the message. A new file can't be uploaded; use a previously uploaded file via its file_id or specify a URL. + description: A JSON-serialized object for the new media content of the message allOf: - $ref: '#/components/schemas/InputMedia' receiver_user_id: @@ -2469,7 +2472,7 @@ paths: description: Identifier of the ephemeral message to edit media: type: string - description: A JSON-serialized object for the new media content of the message. A new file can't be uploaded; use a previously uploaded file via its file_id or specify a URL. + description: A JSON-serialized object for the new media content of the message receiver_user_id: type: integer description: Identifier of the user who received the message @@ -2573,7 +2576,7 @@ paths: tags: - Updating messages description: |- - Use this method to edit an ephemeral text message. Note that it is not guaranteed that the user will receive the message edit event, especially if they are offline. On success, True is returned. + Use this method to edit an ephemeral text or rich message. Note that it is not guaranteed that the user will receive the message edit event, especially if they are offline. On success, True is returned. requestBody: required: true content: @@ -2607,14 +2610,17 @@ paths: description: A JSON-serialized object for an inline keyboard allOf: - $ref: '#/components/schemas/InlineKeyboardMarkup' + rich_message: + description: New rich content of the message; required if text isn't specified + allOf: + - $ref: '#/components/schemas/InputRichMessage' text: type: string - description: New text of the message, 1-4096 characters after entity parsing + description: New text of the message, 1-4096 characters after entity parsing; required if rich_message isn't specified required: - chat_id - ephemeral_message_id - receiver_user_id - - text responses: '200': description: OK @@ -3163,7 +3169,7 @@ paths: allOf: - $ref: '#/components/schemas/InlineKeyboardMarkup' rich_message: - description: New rich content of the message; required if text isn't specified. Direct upload of new files isn't supported when an inline message is edited. + description: New rich content of the message; required if text isn't specified. Direct upload of new files and explicit upload of files by a URL isn't supported when an inline message is edited. allOf: - $ref: '#/components/schemas/InputRichMessage' text: @@ -5431,6 +5437,9 @@ paths: can_restrict_members: type: boolean description: Pass True if the administrator can restrict, ban or unban chat members, or access supergroup statistics. For backward compatibility, defaults to True for promotions of channel administrators. + can_send_welcome_messages: + type: boolean + description: Pass True if the administrator can manage chat welcome messages or directly send them in the case of bots chat_id: type: integer format: int64 @@ -6286,9 +6295,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Animation caption (may also be used when resending animation by file_id), 0-1024 characters after entities parsing @@ -6310,6 +6316,10 @@ paths: duration: type: integer description: Duration of sent animation in seconds + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' has_spoiler: type: boolean description: Pass True if the animation needs to be covered with a spoiler animation @@ -6328,9 +6338,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -6372,9 +6379,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Animation caption (may also be used when resending animation by file_id), 0-1024 characters after entities parsing @@ -6394,6 +6398,9 @@ paths: duration: type: integer description: Duration of sent animation in seconds + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send has_spoiler: type: boolean description: Pass True if the animation needs to be covered with a spoiler animation @@ -6412,9 +6419,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -6492,9 +6496,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Audio caption, 0-1024 characters after entities parsing @@ -6516,6 +6517,10 @@ paths: duration: type: integer description: Duration of the audio in seconds + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -6531,9 +6536,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -6572,9 +6574,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Audio caption, 0-1024 characters after entities parsing @@ -6594,6 +6593,9 @@ paths: duration: type: integer description: Duration of the audio in seconds + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -6609,9 +6611,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -6862,9 +6861,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -6875,6 +6871,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' first_name: type: string description: Contact's first name @@ -6893,9 +6893,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7049,9 +7046,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing @@ -7076,6 +7070,10 @@ paths: document: type: string description: File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. More information on Sending Files » + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -7088,9 +7086,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7122,9 +7117,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing @@ -7148,6 +7140,9 @@ paths: type: string format: binary description: File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. More information on Sending Files » + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -7160,9 +7155,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7521,9 +7513,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing @@ -7542,6 +7531,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' has_spoiler: type: boolean description: Pass True if the video needs to be covered with a spoiler animation @@ -7563,9 +7556,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7598,9 +7588,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing @@ -7617,6 +7604,9 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send has_spoiler: type: boolean description: Pass True if the video needs to be covered with a spoiler animation @@ -7640,9 +7630,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7710,9 +7697,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -7723,6 +7707,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' heading: type: integer description: For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. @@ -7750,9 +7738,6 @@ paths: proximity_alert_radius: type: integer description: For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified. - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -7941,9 +7926,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -7959,6 +7941,10 @@ paths: description: A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse_mode items: $ref: '#/components/schemas/MessageEntity' + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' link_preview_options: description: Link preview generation options for the message allOf: @@ -7975,9 +7961,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8039,18 +8022,24 @@ paths: schema: type: object properties: + can_stop: + type: boolean + description: Pass True to show the user a button to stop further drafts. The bot will receive an Update “stopped_message_generation” if the user presses the button. chat_id: type: integer format: int64 description: Unique identifier for the target private chat draft_id: type: integer - description: Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated. + description: Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated. Otherwise, the draft is replaced without animation. entities: type: array description: A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse_mode items: $ref: '#/components/schemas/MessageEntity' + keep_on_stop: + type: boolean + description: Pass True to keep the draft in the chat when the button is pressed. The draft will still disappear after a short time or if the bot sends a message. To fully preserve the partial draft, the bot should send it as a new message. message_thread_id: type: integer description: Unique identifier for the target message thread @@ -8216,9 +8205,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Photo caption (may also be used when resending photos by file_id), 0-1024 characters after entities parsing @@ -8237,6 +8223,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' has_spoiler: type: boolean description: Pass True if the photo needs to be covered with a spoiler animation @@ -8255,9 +8245,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8289,9 +8276,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Photo caption (may also be used when resending photos by file_id), 0-1024 characters after entities parsing @@ -8308,6 +8292,9 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send has_spoiler: type: boolean description: Pass True if the photo needs to be covered with a spoiler animation @@ -8327,9 +8314,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8572,6 +8556,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -8643,18 +8631,24 @@ paths: schema: type: object properties: + can_stop: + type: boolean + description: Pass True to show the user a button to stop further drafts. The bot will receive an Update “stopped_message_generation” if the user presses the button. chat_id: type: integer format: int64 description: Unique identifier for the target private chat draft_id: type: integer - description: Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated. + description: Unique identifier of the message draft; must be non-zero. Changes to drafts with the same identifier are animated. Otherwise, the draft is replaced without animation. + keep_on_stop: + type: boolean + description: Pass True to keep the draft in the chat when the button is pressed. The draft will still disappear after a short time or if the bot sends a message. To fully preserve the partial draft, the bot should send it as a new message. message_thread_id: type: integer description: Unique identifier for the target message thread rich_message: - description: The partial message to be streamed. Direct upload of new files isn't supported. + description: The partial message to be streamed. Direct upload of new files and explicit upload of files by a URL isn't supported. allOf: - $ref: '#/components/schemas/InputRichMessage' required: @@ -8708,9 +8702,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -8724,6 +8715,10 @@ paths: emoji: type: string description: Emoji associated with the sticker; only for just uploaded stickers + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -8733,9 +8728,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8767,9 +8759,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -8783,6 +8772,9 @@ paths: emoji: type: string description: Emoji associated with the sticker; only for just uploaded stickers + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -8792,9 +8784,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8865,9 +8854,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -8878,6 +8864,10 @@ paths: disable_notification: type: boolean description: Sends the message silently. Users will receive a notification with no sound. + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' foursquare_id: type: string description: Foursquare identifier of the venue @@ -8905,9 +8895,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -8978,9 +8965,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing @@ -9005,6 +8989,10 @@ paths: duration: type: integer description: Duration of sent video in seconds + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' has_spoiler: type: boolean description: Pass True if the video needs to be covered with a spoiler animation @@ -9023,9 +9011,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -9072,9 +9057,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing @@ -9098,6 +9080,9 @@ paths: duration: type: integer description: Duration of sent video in seconds + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send has_spoiler: type: boolean description: Pass True if the video needs to be covered with a spoiler animation @@ -9116,9 +9101,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -9188,7 +9170,7 @@ paths: tags: - Available methods description: |- - As of v.4.0, Telegram clients support rounded square MPEG4 videos of up to 1 minute long. Use this method to send video messages. On success, the sent Message is returned. + Use this method to send a rounded square MPEG4 video of up to 1 minute long. On success, the sent Message is returned. requestBody: required: true content: @@ -9202,9 +9184,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -9218,6 +9197,10 @@ paths: duration: type: integer description: Duration of sent video in seconds + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' length: type: integer description: Video width and height, i.e. diameter of the video message @@ -9230,9 +9213,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -9267,9 +9247,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any chat_id: type: integer format: int64 @@ -9283,6 +9260,9 @@ paths: duration: type: integer description: Duration of sent video in seconds + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send length: type: integer description: Video width and height, i.e. diameter of the video message @@ -9295,9 +9275,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -9369,9 +9346,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Voice message caption, 0-1024 characters after entities parsing @@ -9393,6 +9367,10 @@ paths: duration: type: integer description: Duration of the voice message in seconds + ephemeral_message_parameters: + description: A JSON-serialized object containing the parameters of the ephemeral message to send + allOf: + - $ref: '#/components/schemas/EphemeralMessageParameters' message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -9405,9 +9383,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -9439,9 +9414,6 @@ paths: business_connection_id: type: string description: Unique identifier of the business connection on behalf of which the message will be sent - callback_query_id: - type: string - description: For outgoing ephemeral messages, identifier of the callback query which triggered the message if any caption: type: string description: Voice message caption, 0-1024 characters after entities parsing @@ -9461,6 +9433,9 @@ paths: duration: type: integer description: Duration of the voice message in seconds + ephemeral_message_parameters: + type: string + description: A JSON-serialized object containing the parameters of the ephemeral message to send message_effect_id: type: string description: Unique identifier of the message effect to be added to the message; for private chats only @@ -9473,9 +9448,6 @@ paths: protect_content: type: boolean description: Protects the contents of the sent message from forwarding and saving - receiver_user_id: - type: integer - description: For outgoing ephemeral messages, unique identifier of the user who will receive the message; for group and supergroup chats only. It is not guaranteed that the user will receive the message, especially if they are offline. See ephemeral message sending for more details. reply_markup: description: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user. oneOf: @@ -12929,7 +12901,10 @@ components: description: Optional. True, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only can_manage_tags: type: boolean - description: Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted, defaults to the value of can_pin_messages. + description: Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only + can_send_welcome_messages: + type: boolean + description: True, if the administrator can manage chat welcome messages or directly send them in the case of bots required: - is_anonymous - can_manage_chat @@ -12942,6 +12917,7 @@ components: - can_post_stories - can_edit_stories - can_delete_stories + - can_send_welcome_messages ChatBackground: type: object description: |- @@ -13492,7 +13468,10 @@ components: description: Optional. True, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only can_manage_tags: type: boolean - description: Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted, defaults to the value of can_pin_messages. + description: Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only + can_send_welcome_messages: + type: boolean + description: True, if the administrator can manage chat welcome messages or directly send them in the case of bots custom_title: type: string description: Optional. Custom title for this user @@ -13511,6 +13490,7 @@ components: - can_post_stories - can_edit_stories - can_delete_stories + - can_send_welcome_messages ChatMemberBanned: type: object description: |- @@ -14011,12 +13991,25 @@ components: CommunityChatAdded: type: object description: |- - Describes a service message about a chat being added to a community. + Describes a service message about a chat or a bot being added to a community. x-tags: - Available types properties: community: - description: The new community to which the chat belongs + description: The new community to which the chat or the bot belongs + allOf: + - $ref: '#/components/schemas/Community' + required: + - community + CommunityChatJoined: + type: object + description: |- + Describes a service message about a chat being joined by a user from a community. + x-tags: + - Available types + properties: + community: + description: The community from which the chat was joined allOf: - $ref: '#/components/schemas/Community' required: @@ -14024,7 +14017,7 @@ components: CommunityChatRemoved: type: object description: |- - Describes a service message about a chat being removed from a community. Currently holds no information. + Describes a service message about a chat or a bot being removed from a community. Currently holds no information. x-tags: - Available types Contact: @@ -14113,6 +14106,12 @@ components: - $ref: '#/components/schemas/User' required: - topic_id + DisabledButton: + type: object + description: |- + This object represents a disabled button which does nothing. Currently holds no information. + x-tags: + - Available types Document: type: object description: |- @@ -14210,6 +14209,23 @@ components: required: - type - hash + EphemeralMessageParameters: + type: object + description: |- + x-tags: + - Available types + properties: + receiver_user_id: + type: integer + description: Identifier of the user who will receive the message. It is not guaranteed that the user will receive the message, especially if they are offline. See here for more details. + callback_query_id: + type: string + description: Optional. Identifier of the callback query which triggered the message, if any + replace_callback_query_message: + type: boolean + description: Optional. Pass True if the ephemeral message must be shown in place of the original message. Must be False for callback queries from ephemeral messages, which must be edited using regular editEphemeralMessage… methods. + required: + - receiver_user_id ExternalReplyInfo: type: object description: |- @@ -14355,7 +14371,7 @@ components: properties: force_reply: type: boolean - description: Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply' + description: Shows reply interface to the user, as if they had manually selected the bot's message and tapped 'Reply' default: true input_field_placeholder: type: string @@ -14820,7 +14836,7 @@ components: allOf: - $ref: '#/components/schemas/WebAppInfo' login_url: - description: Optional. An HTTPS URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget. + description: Optional. An HTTPS URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget. Not supported for ephemeral messages. allOf: - $ref: '#/components/schemas/LoginUrl' switch_inline_query: @@ -14844,6 +14860,10 @@ components: pay: type: boolean description: 'Optional. Specify True, to send a Pay button. Substrings “” and “XTR” in the buttons''s text will be replaced with a Telegram Star icon.NOTE: This type of button must always be the first button in the first row and can only be used in invoice messages.' + disabled: + description: Optional. If set, then the button is disabled and does nothing + allOf: + - $ref: '#/components/schemas/DisabledButton' required: - text InlineKeyboardMarkup: @@ -14860,6 +14880,9 @@ components: type: array items: $ref: '#/components/schemas/InlineKeyboardButton' + force_reply: + type: boolean + description: Optional. Pass True if the reply interface must be shown to the user, as if they had manually selected the bot's message and tapped 'Reply'. The value of the field can't be changed when the inline keyboard is edited. required: - inline_keyboard InlineQuery: @@ -16682,14 +16705,17 @@ components: InputRichBlockAnchor InputRichBlockList InputRichBlockBlockQuotation + InputRichBlockExpandableBlockQuotation InputRichBlockPullQuotation InputRichBlockCollage InputRichBlockSlideshow InputRichBlockTable InputRichBlockDetails InputRichBlockMap + InputRichBlockButtons InputRichBlockAnimation InputRichBlockAudio + InputRichBlockDocument InputRichBlockPhoto InputRichBlockVideo InputRichBlockVoiceNote @@ -16776,6 +16802,27 @@ components: required: - type - blocks + InputRichBlockButtons: + type: object + description: |- + A block containing a list of buttons that are shown in one row, corresponding to the custom HTML tag . + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “buttons” + buttons: + type: array + description: List of 1-8 buttons to send + items: + $ref: '#/components/schemas/RichMessageButton' + align: + type: string + description: Optional. Horizontal alignment of the buttons. Currently, must be one of “left”, “center”, or “right”. + required: + - type + - buttons InputRichBlockCollage: type: object description: |- @@ -16837,6 +16884,48 @@ components: description: Type of the block, always “divider” required: - type + InputRichBlockDocument: + type: object + description: |- + A block with a general file, corresponding to the custom HTML tag . + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “document” + document: + description: The document. Caption is ignored. + allOf: + - $ref: '#/components/schemas/InputMediaDocument' + caption: + description: Optional. Caption of the block + allOf: + - $ref: '#/components/schemas/RichBlockCaption' + required: + - type + - document + InputRichBlockExpandableBlockQuotation: + type: object + description: |- + A block quotation, corresponding to the HTML tag
with custom attribute "expandable". + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “expandable_blockquote” + text: + description: Content of the block + allOf: + - $ref: '#/components/schemas/RichText' + credit: + description: Optional. Credit of the block + allOf: + - $ref: '#/components/schemas/RichText' + required: + - type + - text InputRichBlockFooter: type: object description: |- @@ -16916,13 +17005,13 @@ components: - $ref: '#/components/schemas/Location' zoom: type: integer - description: Map zoom level; 0-24 + description: Optional. Map zoom level; 0-24 width: type: integer - description: Map width; 0-10000 + description: Optional. Map width; 0-10000 height: type: integer - description: Map height; 0-10000 + description: Optional. Map height; 0-10000 caption: description: Optional. Caption of the block allOf: @@ -16930,9 +17019,6 @@ components: required: - type - location - - zoom - - width - - height InputRichBlockMathematicalExpression: type: object description: |- @@ -17096,6 +17182,10 @@ components: type: boolean description: Optional. Pass True if the table is striped default: true + is_compact: + type: boolean + description: Optional. Pass True if table cells must have smaller indents + default: true caption: description: Optional. Caption of the table allOf: @@ -17182,7 +17272,7 @@ components: description: Optional. Content of the rich message to send described using Markdown formatting. See rich message formatting options for more details. Use media field to specify the media used in the message. media: type: array - description: Optional. List of media that are specified in the markdown or html fields using tg://photo?id=, tg://video?id=, and tg://audio?id= links + description: Optional. List of media that are specified in the markdown or html fields using tg://photo?id=, tg://video?id=, tg://document?id=, and tg://audio?id= links items: $ref: '#/components/schemas/InputRichMessageMedia' is_rtl: @@ -17199,7 +17289,7 @@ components: - Inline mode properties: rich_message: - description: The message to be sent + description: The message to be sent. Only previously uploaded files may be used in the message. allOf: - $ref: '#/components/schemas/InputRichMessage' required: @@ -17213,12 +17303,13 @@ components: properties: id: type: string - description: Unique identifier of the media used in a tg://photo?id=, tg://video?id=, or tg://audio?id= link. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. + description: Unique identifier of the media used in a tg://photo?id=, tg://video?id=, tg://document?id=, or tg://audio?id= link. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. media: description: The media to be sent. Everything except the media itself and its properties is ignored. oneOf: - $ref: '#/components/schemas/InputMediaAnimation' - $ref: '#/components/schemas/InputMediaAudio' + - $ref: '#/components/schemas/InputMediaDocument' - $ref: '#/components/schemas/InputMediaPhoto' - $ref: '#/components/schemas/InputMediaVideo' - $ref: '#/components/schemas/InputMediaVoiceNote' @@ -17682,8 +17773,7 @@ components: LoginUrl: type: object description: |- - This object represents a parameter of the inline keyboard button used to automatically authorize a user. Serves as a great replacement for the Telegram Login Widget when the user is coming from Telegram. All the user needs to do is tap/click a button and confirm that they want to log in: - Telegram apps support these buttons as of version 5.7. + This object represents a parameter of the inline keyboard button used to automatically authorize a user. It serves as a great replacement for the Telegram Login Widget when the user is coming from Telegram. All the user needs to do is tap/click a button and confirm that they want to log in: x-tags: - Available types properties: @@ -17695,7 +17785,7 @@ components: description: Optional. New text of the button in forwarded messages bot_username: type: string - description: Optional. Username of a bot, which will be used for user authorization. See Setting up a bot for more details. If not specified, the current bot's username will be assumed. The url's domain must be the same as the domain linked with the bot. See Linking your domain to the bot for more details. + description: Optional. Username of a bot, which will be used for user authorization; not supported in RichMessageButton. See Setting up a bot for more details. If not specified, the current bot's username will be assumed. The url's domain must be the same as the domain linked with the bot. See Linking your domain to the bot for more details. request_write_access: type: boolean description: Optional. Pass True to request the permission for your bot to send messages to the user @@ -18177,11 +18267,15 @@ components: allOf: - $ref: '#/components/schemas/ChecklistTasksAdded' community_chat_added: - description: 'Optional. Service message: chat added to a Community' + description: 'Optional. Service message: chat or bot added to a Community' allOf: - $ref: '#/components/schemas/CommunityChatAdded' + community_chat_joined: + description: 'Optional. Service message: chat was joined by a user from a Community' + allOf: + - $ref: '#/components/schemas/CommunityChatJoined' community_chat_removed: - description: 'Optional. Service message: chat removed from a Community' + description: 'Optional. Service message: chat or bot removed from a Community' allOf: - $ref: '#/components/schemas/CommunityChatRemoved' direct_message_price_changed: @@ -18343,6 +18437,26 @@ components: - type - offset - length + MessageGenerationStopped: + type: object + description: |- + This object describes an update about a user stopping message generation. + x-tags: + - Available types + properties: + chat: + description: Chat in which the message is generated + allOf: + - $ref: '#/components/schemas/Chat' + message_thread_id: + type: integer + description: Optional. Unique identifier of the message thread in which the message is generated + draft_id: + type: integer + description: Unique identifier of the message draft which was stopped + required: + - chat + - draft_id MessageId: type: object description: |- @@ -19598,6 +19712,9 @@ components: selective: type: boolean description: 'Optional. Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot''s message is a reply to a message in the same chat and forum topic, sender of the original message.Example: A user requests to change the bot''s language, bot replies to the request with a keyboard to select the new language. Other users in the group don''t see the keyboard.' + force_reply: + type: boolean + description: Optional. Pass True if the reply interface must be shown to the user, as if they had manually selected the bot's message and tapped 'Reply' required: - keyboard ReplyKeyboardRemove: @@ -19736,14 +19853,17 @@ components: RichBlockAnchor RichBlockList RichBlockBlockQuotation + RichBlockExpandableBlockQuotation RichBlockPullQuotation RichBlockCollage RichBlockSlideshow RichBlockTable RichBlockDetails RichBlockMap + RichBlockButtons RichBlockAnimation RichBlockAudio + RichBlockDocument RichBlockPhoto RichBlockVideo RichBlockVoiceNote @@ -19834,6 +19954,27 @@ components: required: - type - blocks + RichBlockButtons: + type: object + description: |- + A block containing a list of buttons that are shown in one row, corresponding to the custom HTML tag . + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “buttons” + buttons: + type: array + description: The buttons + items: + $ref: '#/components/schemas/RichMessageButton' + align: + type: string + description: Optional. Horizontal alignment of the buttons. Currently, must be one of “left”, “center”, or “right”. + required: + - type + - buttons RichBlockCaption: type: object description: |- @@ -19912,6 +20053,48 @@ components: description: Type of the block, always “divider” required: - type + RichBlockDocument: + type: object + description: |- + A block with a general file, corresponding to the custom HTML tag . + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “document” + document: + description: The document + allOf: + - $ref: '#/components/schemas/Document' + caption: + description: Optional. Caption of the block + allOf: + - $ref: '#/components/schemas/RichBlockCaption' + required: + - type + - document + RichBlockExpandableBlockQuotation: + type: object + description: |- + A block quotation, corresponding to the HTML tag
with custom attribute "expandable". + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the block, always “expandable_blockquote” + text: + description: Content of the block + allOf: + - $ref: '#/components/schemas/RichText' + credit: + description: Optional. Credit of the block + allOf: + - $ref: '#/components/schemas/RichText' + required: + - type + - text RichBlockFooter: type: object description: |- @@ -19995,7 +20178,7 @@ components: - $ref: '#/components/schemas/Location' zoom: type: integer - description: Map zoom level; 13-20 + description: Map zoom level width: type: integer description: Expected width of the map @@ -20180,6 +20363,10 @@ components: type: boolean description: Optional. True, if the table is striped default: true + is_compact: + type: boolean + description: Optional. True, if table cells have smaller indents + default: true caption: description: Optional. Caption of the table allOf: @@ -20297,6 +20484,54 @@ components: description: Optional. True, if the rich message must be shown right-to-left required: - blocks + RichMessageButton: + type: object + description: |- + This object represents a button in a RichMessage. Exactly one of the fields other than text and style must be used to specify the type of the button. + x-tags: + - Rich messages + properties: + text: + description: Text of the button. May contain only plain text, RichTextCustomEmoji and RichTextDateTime entities. + allOf: + - $ref: '#/components/schemas/RichText' + style: + type: string + description: Optional. Style of the button. Must be one of “danger”, “success”, “primary”, or “link” (the button is shown as a regular link without borders). Apps may use theme-specific colors for the button background and text based on the style. The style “link” is allowed only for callback buttons. + url: + type: string + description: Optional. HTTP or tg:// URL to be opened when the button is pressed. Links tg://user?id= can be used to mention a user by their identifier without using a username, if this is allowed by their privacy settings. + callback_data: + type: string + description: Optional. Data to be sent in a callback query to the bot when the button is pressed, 1-64 bytes + web_app: + description: Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to send an arbitrary message on behalf of the user using the method answerWebAppQuery. Available only in private chats between a user and the bot. Not supported for messages sent on behalf of a business account. + allOf: + - $ref: '#/components/schemas/WebAppInfo' + login_url: + description: Optional. An HTTPS URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget. Not supported for ephemeral messages. + allOf: + - $ref: '#/components/schemas/LoginUrl' + switch_inline_query: + type: string + description: Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot's username and the specified inline query in the input field. May be empty, in which case just the bot's username will be inserted. Not supported for messages sent in channel direct messages chats and on behalf of a business account. + switch_inline_query_current_chat: + type: string + description: Optional. If set, pressing the button will insert the bot's username and the specified inline query in the current chat's input field. May be empty, in which case only the bot's username will be inserted. Not supported in channels and for messages sent in channel direct messages chats and on behalf of a business account. + switch_inline_query_chosen_chat: + description: Optional. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field. Not supported for messages sent in channel direct messages chats and on behalf of a business account. + allOf: + - $ref: '#/components/schemas/SwitchInlineQueryChosenChat' + copy_text: + description: Optional. A button that copies the specified text to the clipboard + allOf: + - $ref: '#/components/schemas/CopyTextButton' + disabled: + description: Optional. If set, then the button is disabled and does nothing + allOf: + - $ref: '#/components/schemas/DisabledButton' + required: + - text RichText: type: object description: |- @@ -20322,6 +20557,7 @@ components: RichTextHashtag RichTextCashtag RichTextBotCommand + RichTextButton RichTextAnchor RichTextAnchorLink RichTextReference @@ -20424,6 +20660,23 @@ components: - type - text - bot_command + RichTextButton: + type: object + description: |- + A button. + x-tags: + - Rich messages + properties: + type: + type: string + description: Type of the rich text, always “button” + button: + description: The button + allOf: + - $ref: '#/components/schemas/RichMessageButton' + required: + - type + - button RichTextCashtag: type: object description: |- @@ -21817,6 +22070,18 @@ components: origin: type: string description: Origin of the gift. Currently, either “upgrade” for gifts upgraded from regular gifts, “transfer” for gifts transferred from other users or channels, “resale” for gifts bought from other users, “gifted_upgrade” for upgrades purchased after the gift was sent, or “offer” for gifts bought or sold through gift purchase offers. + text: + type: string + description: Optional. Text of the message that was added to the gift + entities: + type: array + description: Optional. Special entities that appear in the text + items: + $ref: '#/components/schemas/MessageEntity' + is_private: + type: boolean + description: Optional. True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them + default: true last_resale_currency: type: string description: Optional. For gifts bought from other users, the currency in which the payment for the gift was done. Currently, one of “XTR” for Telegram Stars or “TON” for TON grams. @@ -21994,6 +22259,10 @@ components: description: Optional. User payment subscription has changed allOf: - $ref: '#/components/schemas/BotSubscriptionUpdated' + stopped_message_generation: + description: Optional. A user asked the bot to stop the generation of a message + allOf: + - $ref: '#/components/schemas/MessageGenerationStopped' required: - update_id User: @@ -22292,7 +22561,7 @@ components: VideoNote: type: object description: |- - This object represents a video message (available in Telegram apps as of v.4.0). + This object represents a video message. x-tags: - Available types properties: diff --git a/api_codegen/generate.py b/api_codegen/generate.py index 4e037139..b29e1517 100644 --- a/api_codegen/generate.py +++ b/api_codegen/generate.py @@ -103,7 +103,10 @@ class _MethodModel: return_description: str description: tuple[str, ...] args: tuple[_ArgModel, ...] + direct_args: tuple[_ArgModel, ...] + struct_args: tuple[_ArgModel, ...] compatibility_args: tuple[_ArgModel, ...] + legacy_ephemeral_parameters: bool args_name: str | None @@ -388,6 +391,40 @@ def _build_method(self, operation: Schema) -> _MethodModel: ) for arg_name in arg_names ) + legacy_ephemeral_parameters = bool(method_config.get("legacy_ephemeral_parameters")) + direct_properties = { + arg_name: schema + for arg_name, schema in properties.items() + if arg_name not in method_config.get("direct_exclude", ()) + } + if legacy_ephemeral_parameters: + direct_properties.pop("ephemeral_message_parameters", None) + direct_properties.update( + { + "callback_query_id": { + "type": "string", + "description": "Identifier of the callback query which triggered the ephemeral message", + }, + "receiver_user_id": { + "type": "integer", + "format": "int64", + "description": "Identifier of the user who will receive the ephemeral message", + }, + } + ) + direct_arg_names = self._ordered_arg_names(name, direct_properties, required & direct_properties.keys()) + direct_args = tuple( + self._build_arg( + name, + arg_name, + direct_properties[arg_name], + arg_name in required, + arg_name in binary, + ) + for arg_name in direct_arg_names + ) + direct_arg_wire_names = {arg.wire_name for arg in direct_args} + struct_args = direct_args + tuple(arg for arg in args if arg.wire_name not in direct_arg_wire_names) compatibility_without = set(method_config.get("compatibility_overload_without", ())) return _MethodModel( name=name, @@ -396,7 +433,10 @@ def _build_method(self, operation: Schema) -> _MethodModel: return_description=self._return_description(return_type, response_type), description=self._comment_lines(operation.get("description", ""), 88), args=args, - compatibility_args=tuple(arg for arg in args if arg.wire_name not in compatibility_without), + direct_args=direct_args, + struct_args=struct_args, + compatibility_args=tuple(arg for arg in direct_args if arg.wire_name not in compatibility_without), + legacy_ephemeral_parameters=legacy_ephemeral_parameters, args_name=f"{name[0].upper()}{name[1:]}Args" if args else None, ) diff --git a/api_codegen/templates/api_methods.cpp.j2 b/api_codegen/templates/api_methods.cpp.j2 index 2caeaafe..93d2b1cc 100644 --- a/api_codegen/templates/api_methods.cpp.j2 +++ b/api_codegen/templates/api_methods.cpp.j2 @@ -8,14 +8,14 @@ {{ "decodeObjectOrTrue" if method.return_type != method.response_type else "decode<" + method.return_type + ">" }} {%- endmacro %} -{% macro request_field(arg) -%} +{% macro request_field(arg, value=none) -%} {% set factory = "required" if arg.required or arg.always_send else "optional" -%} {% set wire_default = ", " + arg.wire_default_value if arg.wire_default_value is not none else "" -%} -ApiRequest::{{ factory }}("{{ arg.wire_name }}", {{ arg.cpp_name }}{{ wire_default }}) +ApiRequest::{{ factory }}("{{ arg.wire_name }}", {{ arg.cpp_name if value is none else value }}{{ wire_default }}) {%- endmacro %} {% macro method_definition(method, argument_object=false, args=none) -%} -{% set definition_args = method.args if args is none else args -%} +{% set definition_args = method.direct_args if args is none else args -%} {{ method.return_type }} Api::{{ method.name }}( {% if argument_object %} const {{ method.args_name }}& args @@ -32,6 +32,13 @@ namespace TgBot { {% for method in methods %} {{ method_definition(method) }} { +{% if method.direct_args != method.args %} + {{ method.args_name }} args; +{% for arg in method.direct_args %} + args.{{ arg.cpp_name }} = {{ arg.cpp_name }}; +{% endfor %} + return {{ method.name }}(args); +{% else %} return ApiResponse::{{ decoder(method) }}( sendRequest( "{{ method.name }}", @@ -46,12 +53,13 @@ namespace TgBot { {% endif %} ) ); +{% endif %} } -{% if method.compatibility_args != method.args %} +{% if method.compatibility_args != method.direct_args %} {{ method_definition(method, args=method.compatibility_args) }} { return {{ method.name }}( -{% for arg in method.args %} +{% for arg in method.direct_args %} {{ arg.cpp_name if arg in method.compatibility_args else "{ }" }}{{ "," if not loop.last else "" }} {% endfor %} ); @@ -60,11 +68,34 @@ namespace TgBot { {% endif %} {% if method.args_name %} {{ method_definition(method, argument_object=true) }} { +{% if method.direct_args != method.args %} +{% if method.legacy_ephemeral_parameters %} + auto ephemeralMessageParameters = args.ephemeralMessageParameters; + if (!ephemeralMessageParameters && (args.receiverUserId != 0 || !args.callbackQueryId.empty())) { + ephemeralMessageParameters = std::make_shared(); + ephemeralMessageParameters->receiverUserId = args.receiverUserId; + if (!args.callbackQueryId.empty()) { + ephemeralMessageParameters->callbackQueryId = args.callbackQueryId; + } + } +{% endif %} + return ApiResponse::{{ decoder(method) }}( + sendRequest( + "{{ method.name }}", + ApiRequest::makeFields( +{% for arg in method.args %} + {{ request_field(arg, "ephemeralMessageParameters" if arg.wire_name == "ephemeral_message_parameters" and method.legacy_ephemeral_parameters else "args." + arg.cpp_name) }}{{ "," if not loop.last else "" }} +{% endfor %} + ) + ) + ); +{% else %} return {{ method.name }}( {% for arg in method.args %} args.{{ arg.cpp_name }}{{ "," if not loop.last else "" }} {% endfor %} ); +{% endif %} } {% endif %} diff --git a/api_codegen/templates/api_methods.inc.h.j2 b/api_codegen/templates/api_methods.inc.h.j2 index 797cebdc..ca2e5314 100644 --- a/api_codegen/templates/api_methods.inc.h.j2 +++ b/api_codegen/templates/api_methods.inc.h.j2 @@ -6,7 +6,7 @@ {%- endmacro %} {% macro documentation(method, argument_object=false, args=none) -%} -{% set documented_args = method.args if args is none else args -%} +{% set documented_args = method.direct_args if args is none else args -%} /** * @brief{{ " " + method.description[0] if method.description else "" }} {% for line in method.description[1:] %} @@ -29,7 +29,7 @@ {%- endmacro %} {% macro method_declaration(method, argument_object=false, args=none) -%} -{% set declared_args = method.args if args is none else args -%} +{% set declared_args = method.direct_args if args is none else args -%} {{ method.return_type }} {{ method.name }}( {% if argument_object %} const {{ method.args_name }}& args @@ -46,7 +46,7 @@ {{ documentation(method) }} {{ method_declaration(method) }} -{% if method.compatibility_args != method.args %} +{% if method.compatibility_args != method.direct_args %} {{ documentation(method, args=method.compatibility_args) }} {{ method_declaration(method, args=method.compatibility_args) }} diff --git a/api_codegen/templates/types.h.j2 b/api_codegen/templates/types.h.j2 index 192a2293..5b292b7b 100644 --- a/api_codegen/templates/types.h.j2 +++ b/api_codegen/templates/types.h.j2 @@ -81,7 +81,7 @@ TGBOT_API void to_json(nlohmann::json& json, const {{ type.name }}& value); * @ingroup api */ struct {{ method.args_name }} { -{% for arg in method.args %} +{% for arg in method.struct_args %} /** * @brief{{ " " + arg.description[0] if arg.description else "" }} {% for line in arg.description[1:] %} diff --git a/api_codegen/tests/test_generate.py b/api_codegen/tests/test_generate.py index fb419fc5..1f1e7866 100644 --- a/api_codegen/tests/test_generate.py +++ b/api_codegen/tests/test_generate.py @@ -50,6 +50,7 @@ def test_compatibility_config_is_grouped_by_telegram_entity() -> None: assert {name for name, config in API_CONFIG.items() if config.get("supports_attach_references")} == { "addStickerToSet", "createNewStickerSet", + "editEphemeralMessageMedia", "editMessageMedia", "editMessageText", "editStory", @@ -168,6 +169,82 @@ def test_high_risk_methods_keep_legacy_args_order() -> None: ] +def test_bot_api_10_3_keeps_legacy_ephemeral_arguments() -> None: + schema_path = Path(__file__).parents[2] / "api" / "telegram-bot-api.yaml" + document = yaml.safe_load(schema_path.read_text(encoding="utf-8")) + methods = {method.name: method for method in _MethodModelBuilder(document["paths"]).build()} + legacy_methods = { + "sendAnimation", + "sendAudio", + "sendContact", + "sendDocument", + "sendLivePhoto", + "sendLocation", + "sendMessage", + "sendPhoto", + "sendSticker", + "sendVenue", + "sendVideo", + "sendVideoNote", + "sendVoice", + } + + assert {name for name, config in API_CONFIG.items() if config.get("legacy_ephemeral_parameters")} == legacy_methods + for name in legacy_methods: + method = methods[name] + direct_names = [arg.wire_name for arg in method.direct_args] + struct_names = [arg.wire_name for arg in method.struct_args] + wire_names = [arg.wire_name for arg in method.args] + assert direct_names == API_CONFIG[name]["args_order"] + assert struct_names == [*direct_names, "ephemeral_message_parameters"] + assert "callback_query_id" in direct_names + assert "receiver_user_id" in direct_names + assert "ephemeral_message_parameters" not in direct_names + assert "callback_query_id" not in wire_names + assert "receiver_user_id" not in wire_names + assert "ephemeral_message_parameters" in wire_names + + +def test_bot_api_10_3_appends_new_direct_arguments() -> None: + schema_path = Path(__file__).parents[2] / "api" / "telegram-bot-api.yaml" + document = yaml.safe_load(schema_path.read_text(encoding="utf-8")) + methods = {method.name: method for method in _MethodModelBuilder(document["paths"]).build()} + legacy_prefixes = { + "editEphemeralMessageText": [ + "chat_id", + "ephemeral_message_id", + "receiver_user_id", + "text", + "entities", + "link_preview_options", + "parse_mode", + "reply_markup", + ], + "sendMessageDraft": ["chat_id", "draft_id", "entities", "message_thread_id", "parse_mode", "text"], + "sendRichMessageDraft": ["chat_id", "draft_id", "rich_message", "message_thread_id"], + } + + for name, legacy_prefix in legacy_prefixes.items(): + direct_names = [arg.wire_name for arg in methods[name].direct_args] + assert direct_names[: len(legacy_prefix)] == legacy_prefix + + assert [arg.wire_name for arg in methods["sendRichMessage"].direct_args] == [ + "chat_id", + "rich_message", + "allow_paid_broadcast", + "business_connection_id", + "direct_messages_topic_id", + "disable_notification", + "message_effect_id", + "message_thread_id", + "protect_content", + "reply_markup", + "reply_parameters", + "suggested_post_parameters", + "attachments", + ] + + def test_field_constant_recognizes_only_fixed_discriminators() -> None: constant = _TypeModelBuilder._field_constant( "status", @@ -299,7 +376,7 @@ def test_generator_renders_optional_attach_reference_argument(method_name: str) assert attachment.cpp_type == "std::vector" assert attachment.default_value == "{ }" assert method.args[-1] == attachment - assert method.compatibility_args == method.args + assert method.compatibility_args == method.direct_args def test_generator_rejects_method_without_result_schema(tmp_path: Path) -> None: @@ -349,12 +426,6 @@ def test_every_method_with_args_generates_ordered_argument_object_delegation(tmp classic_start = definitions.index(f"Api::{method.name}(") classic_end = definitions.index("\n}", classic_start) classic_body = definitions[classic_start:classic_end] - normalized_classic_body = " ".join(classic_body.split()) - assert f'sendRequest( "{method.name}", ApiRequest::makeFields(' in normalized_classic_body - for arg in method.args: - field_factory = "required" if arg.required or arg.always_send else "optional" - assert f'ApiRequest::{field_factory}("{arg.wire_name}", {arg.cpp_name}' in classic_body - args_signature = re.search( rf"Api::{method.name}\(\s*const {expected_args_name}& args\s*\) const \{{", definitions, @@ -363,9 +434,22 @@ def test_every_method_with_args_generates_ordered_argument_object_delegation(tmp args_start = args_signature.start() args_end = definitions.index("\n}", args_start) args_body = definitions[args_start:args_end] - assert f"return {method.name}(" in args_body - positions = [args_body.index(f"args.{arg.cpp_name}") for arg in method.args] - assert positions == sorted(positions) + if method.direct_args == method.args: + request_body = classic_body + assert f"return {method.name}(" in args_body + positions = [args_body.index(f"args.{arg.cpp_name}") for arg in method.args] + assert positions == sorted(positions) + else: + request_body = args_body + assert f"return {method.name}(args);" in classic_body + positions = [classic_body.index(f"args.{arg.cpp_name}") for arg in method.direct_args] + assert positions == sorted(positions) + + normalized_request_body = " ".join(request_body.split()) + assert f'sendRequest( "{method.name}", ApiRequest::makeFields(' in normalized_request_body + for arg in method.args: + field_factory = "required" if arg.required or arg.always_send else "optional" + assert f'ApiRequest::{field_factory}("{arg.wire_name}",' in request_body def _schema() -> dict: diff --git a/include/tgbot/ApiMethods.inc.h b/include/tgbot/ApiMethods.inc.h index c5a6a636..ab13cf11 100644 --- a/include/tgbot/ApiMethods.inc.h +++ b/include/tgbot/ApiMethods.inc.h @@ -48,8 +48,7 @@ * callback_game button.Otherwise, you may use links like * t.me/your_bot?start=XXXX that open your bot with a parameter. * @param cacheTime The maximum amount of time in seconds that the result of the callback - * query may be cached client-side. Telegram apps will support caching - * starting in version 3.14. Defaults to 0. + * query may be cached client-side. Defaults to 0. * * @return True on success. */ @@ -1311,6 +1310,8 @@ * @param parseMode Mode for parsing entities in the message caption. See formatting options * for more details. * @param replyMarkup A JSON-serialized object for an inline keyboard + * @param showCaptionAboveMedia Pass True if the caption must be shown above the message media. + * Supported only for animation, photo and video messages. * * @return True on success. */ @@ -1320,7 +1321,8 @@ std::string_view caption = "", const std::vector>& captionEntities = { }, std::string_view parseMode = "", - std::shared_ptr replyMarkup = nullptr) const; + std::shared_ptr replyMarkup = nullptr, + bool showCaptionAboveMedia = false) const; /** * @brief Use this method to edit the caption of an ephemeral message. Note that it is not @@ -1341,11 +1343,12 @@ * @param chatId Unique identifier for the target chat or username of the target * supergroup in the format @username * @param ephemeralMessageId Identifier of the ephemeral message to edit - * @param media A JSON-serialized object for the new media content of the message. A new - * file can't be uploaded; use a previously uploaded file via its file_id - * or specify a URL. + * @param media A JSON-serialized object for the new media content of the message * @param receiverUserId Identifier of the user who received the message * @param replyMarkup A JSON-serialized object for an inline keyboard + * @param attachments Files uploaded as named multipart parts. Reference each file from a + * composite Telegram API argument as attach:// and use the same name + * in InputFileAttachment. * * @return True on success. */ @@ -1353,7 +1356,8 @@ std::int32_t ephemeralMessageId, std::shared_ptr media, std::int64_t receiverUserId, - std::shared_ptr replyMarkup = nullptr) const; + std::shared_ptr replyMarkup = nullptr, + const std::vector& attachments = { }) const; /** * @brief Use this method to edit the media of an ephemeral message. Note that it is not @@ -1396,37 +1400,40 @@ bool editEphemeralMessageReplyMarkup(const EditEphemeralMessageReplyMarkupArgs& args) const; /** - * @brief Use this method to edit an ephemeral text message. Note that it is not guaranteed that - * the user will receive the message edit event, especially if they are offline. On - * success, True is returned. + * @brief Use this method to edit an ephemeral text or rich message. Note that it is not + * guaranteed that the user will receive the message edit event, especially if they are + * offline. On success, True is returned. * * @param chatId Unique identifier for the target chat or username of the target * supergroup in the format @username * @param ephemeralMessageId Identifier of the ephemeral message to edit * @param receiverUserId Identifier of the user who received the message - * @param text New text of the message, 1-4096 characters after entity parsing + * @param text New text of the message, 1-4096 characters after entity parsing; + * required if rich_message isn't specified * @param entities A JSON-serialized list of special entities that appear in message text, * which can be specified instead of parse_mode * @param linkPreviewOptions Link preview generation options for the message * @param parseMode Mode for parsing entities in the message text. See formatting options * for more details. * @param replyMarkup A JSON-serialized object for an inline keyboard + * @param richMessage New rich content of the message; required if text isn't specified * * @return True on success. */ bool editEphemeralMessageText(std::variant chatId, std::int32_t ephemeralMessageId, std::int64_t receiverUserId, - std::string_view text, + std::string_view text = "", const std::vector>& entities = { }, std::shared_ptr linkPreviewOptions = nullptr, std::string_view parseMode = "", - std::shared_ptr replyMarkup = nullptr) const; + std::shared_ptr replyMarkup = nullptr, + std::shared_ptr richMessage = nullptr) const; /** - * @brief Use this method to edit an ephemeral text message. Note that it is not guaranteed that - * the user will receive the message edit event, especially if they are offline. On - * success, True is returned. + * @brief Use this method to edit an ephemeral text or rich message. Note that it is not + * guaranteed that the user will receive the message edit event, especially if they are + * offline. On success, True is returned. * * @param args Method arguments. * @@ -1743,8 +1750,8 @@ * @param businessConnectionId Unique identifier of the business connection on behalf of which the * message to be edited was sent * @param richMessage New rich content of the message; required if text isn't specified. - * Direct upload of new files isn't supported when an inline message is - * edited. + * Direct upload of new files and explicit upload of files by a URL isn't + * supported when an inline message is edited. * @param attachments Files uploaded as named multipart parts. Reference each file from a * composite Telegram API argument as attach:// and use the same name * in InputFileAttachment. @@ -2928,6 +2935,8 @@ * channel and decline suggested posts; for channels only * @param canManageTags Pass True if the administrator can edit the tags of regular members; for * groups and supergroups only + * @param canSendWelcomeMessages Pass True if the administrator can manage chat welcome messages or + * directly send them in the case of bots * * @return True on success. */ @@ -2949,7 +2958,8 @@ bool canEditStories = false, bool canDeleteStories = false, bool canManageDirectMessages = false, - bool canManageTags = false) const; + bool canManageTags = false, + bool canSendWelcomeMessages = false) const; /** * @brief Use this method to promote or demote a user in a supergroup or a channel. The bot must @@ -3386,16 +3396,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param showCaptionAboveMedia Pass True if the caption must be shown above the message media * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a @@ -3487,16 +3493,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -3671,16 +3673,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -3823,16 +3821,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -4105,8 +4099,7 @@ * will be withdrawn from the bot's balance. * @param businessConnectionId Unique identifier of the business connection on behalf of which the * message will be sent - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param caption Video caption (may also be used when resending videos by file_id), * 0-1024 characters after entities parsing * @param captionEntities A JSON-serialized list of special entities that appear in the caption, @@ -4124,10 +4117,7 @@ * @param parseMode Mode for parsing entities in the video caption. See formatting options * for more details. * @param protectContent Protects the contents of the sent message from forwarding and saving - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param replyMarkup Additional interface options. A JSON-serialized object for an inline * keyboard, custom reply keyboard, instructions to remove a reply keyboard * or to force a reply from the user. @@ -4206,16 +4196,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -4341,16 +4327,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -4397,7 +4379,8 @@ * * @param chatId Unique identifier for the target private chat * @param draftId Unique identifier of the message draft; must be non-zero. Changes to - * drafts with the same identifier are animated. + * drafts with the same identifier are animated. Otherwise, the draft is + * replaced without animation. * @param entities A JSON-serialized list of special entities that appear in message text, * which can be specified instead of parse_mode * @param messageThreadId Unique identifier for the target message thread @@ -4405,6 +4388,13 @@ * for more details. * @param text Text of the message to be sent, 0-4096 characters after entities * parsing. Pass an empty text to show a “Thinking…” placeholder. + * @param canStop Pass True to show the user a button to stop further drafts. The bot will + * receive an Update “stopped_message_generation” if the user presses the + * button. + * @param keepOnStop Pass True to keep the draft in the chat when the button is pressed. The + * draft will still disappear after a short time or if the bot sends a + * message. To fully preserve the partial draft, the bot should send it as + * a new message. * * @return True on success. */ @@ -4413,7 +4403,9 @@ const std::vector>& entities = { }, std::int32_t messageThreadId = 0, std::string_view parseMode = "", - std::string_view text = "") const; + std::string_view text = "", + bool canStop = false, + bool keepOnStop = false) const; /** * @brief Use this method to stream a partial message to a user while the message is being @@ -4537,16 +4529,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param showCaptionAboveMedia Pass True if the caption must be shown above the message media * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a @@ -4783,17 +4771,27 @@ * * @param chatId Unique identifier for the target private chat * @param draftId Unique identifier of the message draft; must be non-zero. Changes to - * drafts with the same identifier are animated. - * @param richMessage The partial message to be streamed. Direct upload of new files isn't - * supported. + * drafts with the same identifier are animated. Otherwise, the draft is + * replaced without animation. + * @param richMessage The partial message to be streamed. Direct upload of new files and + * explicit upload of files by a URL isn't supported. * @param messageThreadId Unique identifier for the target message thread + * @param canStop Pass True to show the user a button to stop further drafts. The bot will + * receive an Update “stopped_message_generation” if the user presses the + * button. + * @param keepOnStop Pass True to keep the draft in the chat when the button is pressed. The + * draft will still disappear after a short time or if the bot sends a + * message. To fully preserve the partial draft, the bot should send it as + * a new message. * * @return True on success. */ bool sendRichMessageDraft(std::variant chatId, std::int32_t draftId, std::shared_ptr richMessage, - std::int32_t messageThreadId = 0) const; + std::int32_t messageThreadId = 0, + bool canStop = false, + bool keepOnStop = false) const; /** * @brief Use this method to stream a partial rich message to a user while the message is being @@ -4835,16 +4833,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -4913,16 +4907,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -5012,8 +5002,7 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param cover Cover for the video in the message. Pass a file_id to send a file that * exists on the Telegram servers (recommended), pass an HTTP URL for * Telegram to get a file from the Internet, or pass @@ -5023,10 +5012,7 @@ * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param showCaptionAboveMedia Pass True if the caption must be shown above the message media * @param startTimestamp Start timestamp for the video in the message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post @@ -5080,8 +5066,8 @@ std::shared_ptr sendVideo(const SendVideoArgs& args) const; /** - * @brief As of v.4.0, Telegram clients support rounded square MPEG4 videos of up to 1 minute - * long. Use this method to send video messages. On success, the sent Message is returned. + * @brief Use this method to send a rounded square MPEG4 video of up to 1 minute long. On success, + * the sent Message is returned. * * @param chatId Unique identifier for the target chat or username of the target bot, * supergroup or channel in the format @username @@ -5114,16 +5100,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is @@ -5154,8 +5136,8 @@ = nullptr) const; /** - * @brief As of v.4.0, Telegram clients support rounded square MPEG4 videos of up to 1 minute - * long. Use this method to send video messages. On success, the sent Message is returned. + * @brief Use this method to send a rounded square MPEG4 video of up to 1 minute long. On success, + * the sent Message is returned. * * @param args Method arguments. * @@ -5197,16 +5179,12 @@ * @param allowPaidBroadcast Pass True to allow up to 1000 messages per second, ignoring broadcasting * limits for a fee of 0.1 Telegram Stars per message. The relevant Stars * will be withdrawn from the bot's balance. - * @param callbackQueryId For outgoing ephemeral messages, identifier of the callback query which - * triggered the message if any + * @param callbackQueryId Identifier of the callback query which triggered the ephemeral message * @param directMessagesTopicId Identifier of the direct messages topic to which the message will be * sent; required if the message is sent to a direct messages chat * @param messageEffectId Unique identifier of the message effect to be added to the message; for * private chats only - * @param receiverUserId For outgoing ephemeral messages, unique identifier of the user who will - * receive the message; for group and supergroup chats only. It is not - * guaranteed that the user will receive the message, especially if they - * are offline. See ephemeral message sending for more details. + * @param receiverUserId Identifier of the user who will receive the ephemeral message * @param suggestedPostParameters A JSON-serialized object containing the parameters of the suggested post * to send; for direct messages chats only. If the message is sent as a * reply to another suggested post, then that suggested post is diff --git a/include/tgbot/EventBroadcaster.h b/include/tgbot/EventBroadcaster.h index e3c4026d..9b1629f7 100644 --- a/include/tgbot/EventBroadcaster.h +++ b/include/tgbot/EventBroadcaster.h @@ -35,6 +35,7 @@ class TGBOT_API EventBroadcaster { using ChatJoinRequestListener = std::function)>; using MessageReactionUpdatedListener = std::function)>; using MessageReactionCountUpdatedListener = std::function)>; + using MessageGenerationStoppedListener = std::function)>; using SuccessfulPaymentListener = std::function, std::shared_ptr)>; /** @@ -163,6 +164,12 @@ class TGBOT_API EventBroadcaster { */ void onMessageReactionCount(const MessageReactionCountUpdatedListener& listener); + /** + * @brief Registers listener which receives updates when a user stops message generation. + * @param listener Listener. + */ + void onMessageGenerationStopped(const MessageGenerationStoppedListener& listener); + /** * @brief Registers listener which receives information about successful payments. * This listener is triggered when a successful payment is received by the bot. @@ -201,6 +208,8 @@ class TGBOT_API EventBroadcaster { void broadcastMessageReactionUpdated(const std::shared_ptr& messageReaction) const; void broadcastMessageReactionCountUpdated( const std::shared_ptr& messageReactionCount) const; + void + broadcastMessageGenerationStopped(const std::shared_ptr& messageGenerationStopped) const; void broadcastSuccessfulPayment(const std::shared_ptr& message) const; std::vector _onAnyMessageListeners; @@ -220,6 +229,7 @@ class TGBOT_API EventBroadcaster { std::vector _onChatJoinRequestListeners; std::vector _onMessageReactionUpdatedListener; std::vector _onMessageReactionCountUpdatedListener; + std::vector _onMessageGenerationStoppedListeners; std::vector _onSuccessfulPaymentListeners; }; diff --git a/include/tgbot/Types.h b/include/tgbot/Types.h index c19adbdc..97318c12 100644 --- a/include/tgbot/Types.h +++ b/include/tgbot/Types.h @@ -88,15 +88,18 @@ struct ChecklistTasksDone; struct ChosenInlineResult; struct Community; struct CommunityChatAdded; +struct CommunityChatJoined; struct CommunityChatRemoved; struct Contact; struct CopyTextButton; struct Dice; struct DirectMessagePriceChanged; struct DirectMessagesTopic; +struct DisabledButton; struct Document; struct EncryptedCredentials; struct EncryptedPassportElement; +struct EphemeralMessageParameters; struct ExternalReplyInfo; struct File; struct ForceReply; @@ -176,9 +179,12 @@ struct InputRichBlockAnchor; struct InputRichBlockAnimation; struct InputRichBlockAudio; struct InputRichBlockBlockQuotation; +struct InputRichBlockButtons; struct InputRichBlockCollage; struct InputRichBlockDetails; struct InputRichBlockDivider; +struct InputRichBlockDocument; +struct InputRichBlockExpandableBlockQuotation; struct InputRichBlockFooter; struct InputRichBlockList; struct InputRichBlockListItem; @@ -227,6 +233,7 @@ struct MenuButtonWebApp; struct Message; struct MessageAutoDeleteTimerChanged; struct MessageEntity; +struct MessageGenerationStopped; struct MessageId; struct MessageOrigin; struct MessageOriginChannel; @@ -290,10 +297,13 @@ struct RichBlockAnchor; struct RichBlockAnimation; struct RichBlockAudio; struct RichBlockBlockQuotation; +struct RichBlockButtons; struct RichBlockCaption; struct RichBlockCollage; struct RichBlockDetails; struct RichBlockDivider; +struct RichBlockDocument; +struct RichBlockExpandableBlockQuotation; struct RichBlockFooter; struct RichBlockList; struct RichBlockListItem; @@ -311,12 +321,14 @@ struct RichBlockThinking; struct RichBlockVideo; struct RichBlockVoiceNote; struct RichMessage; +struct RichMessageButton; struct RichText; struct RichTextAnchor; struct RichTextAnchorLink; struct RichTextBankCardNumber; struct RichTextBold; struct RichTextBotCommand; +struct RichTextButton; struct RichTextCashtag; struct RichTextCode; struct RichTextCustomEmoji; @@ -1540,9 +1552,14 @@ struct ChatAdministratorRights { std::optional canManageDirectMessages { }; /** * @brief Optional. True, if the administrator can edit the tags of regular members; for groups - * and supergroups only. If omitted, defaults to the value of can_pin_messages. + * and supergroups only */ std::optional canManageTags { }; + /** + * @brief True, if the administrator can manage chat welcome messages or directly send them in the + * case of bots + */ + bool canSendWelcomeMessages { }; }; TGBOT_API void from_json(const nlohmann::json& json, ChatAdministratorRights& value); @@ -2258,9 +2275,14 @@ struct ChatMemberAdministrator { std::optional canManageDirectMessages { }; /** * @brief Optional. True, if the administrator can edit the tags of regular members; for groups - * and supergroups only. If omitted, defaults to the value of can_pin_messages. + * and supergroups only */ std::optional canManageTags { }; + /** + * @brief True, if the administrator can manage chat welcome messages or directly send them in the + * case of bots + */ + bool canSendWelcomeMessages { }; /** * @brief Optional. Custom title for this user */ @@ -2889,14 +2911,14 @@ TGBOT_API void from_json(const nlohmann::json& json, Community& value); TGBOT_API void to_json(nlohmann::json& json, const Community& value); /** - * @brief Describes a service message about a chat being added to a community. + * @brief Describes a service message about a chat or a bot being added to a community. * @ingroup api */ struct CommunityChatAdded { using Ptr = std::shared_ptr; /** - * @brief The new community to which the chat belongs + * @brief The new community to which the chat or the bot belongs */ std::shared_ptr community { }; }; @@ -2905,8 +2927,24 @@ TGBOT_API void from_json(const nlohmann::json& json, CommunityChatAdded& value); TGBOT_API void to_json(nlohmann::json& json, const CommunityChatAdded& value); /** - * @brief Describes a service message about a chat being removed from a community. Currently holds no - * information. + * @brief Describes a service message about a chat being joined by a user from a community. + * @ingroup api + */ +struct CommunityChatJoined { + using Ptr = std::shared_ptr; + + /** + * @brief The community from which the chat was joined + */ + std::shared_ptr community { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, CommunityChatJoined& value); +TGBOT_API void to_json(nlohmann::json& json, const CommunityChatJoined& value); + +/** + * @brief Describes a service message about a chat or a bot being removed from a community. Currently + * holds no information. * @ingroup api */ struct CommunityChatRemoved { @@ -3036,6 +3074,17 @@ struct DirectMessagesTopic { TGBOT_API void from_json(const nlohmann::json& json, DirectMessagesTopic& value); TGBOT_API void to_json(nlohmann::json& json, const DirectMessagesTopic& value); +/** + * @brief This object represents a disabled button which does nothing. Currently holds no information. + * @ingroup api + */ +struct DisabledButton { + using Ptr = std::shared_ptr; +}; + +TGBOT_API void from_json(const nlohmann::json& json, DisabledButton& value); +TGBOT_API void to_json(nlohmann::json& json, const DisabledButton& value); + /** * @brief This object represents a general file (as opposed to photos, voice messages and audio * files). @@ -3177,6 +3226,33 @@ struct EncryptedPassportElement { TGBOT_API void from_json(const nlohmann::json& json, EncryptedPassportElement& value); TGBOT_API void to_json(nlohmann::json& json, const EncryptedPassportElement& value); +/** + * @brief + * @ingroup api + */ +struct EphemeralMessageParameters { + using Ptr = std::shared_ptr; + + /** + * @brief Identifier of the user who will receive the message. It is not guaranteed that the user + * will receive the message, especially if they are offline. See here for more details. + */ + std::int64_t receiverUserId { }; + /** + * @brief Optional. Identifier of the callback query which triggered the message, if any + */ + std::optional callbackQueryId { }; + /** + * @brief Optional. Pass True if the ephemeral message must be shown in place of the original + * message. Must be False for callback queries from ephemeral messages, which must be + * edited using regular editEphemeralMessage… methods. + */ + std::optional replaceCallbackQueryMessage { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, EphemeralMessageParameters& value); +TGBOT_API void to_json(nlohmann::json& json, const EphemeralMessageParameters& value); + /** * @brief This object contains information about a message that is being replied to, which may come * from another chat or forum topic. @@ -3346,8 +3422,8 @@ struct ForceReply { using Ptr = std::shared_ptr; /** - * @brief Shows reply interface to the user, as if they manually selected the bot's message and - * tapped 'Reply' + * @brief Shows reply interface to the user, as if they had manually selected the bot's message + * and tapped 'Reply' */ bool forceReply { }; /** @@ -3963,7 +4039,7 @@ struct InlineKeyboardButton { std::shared_ptr webApp { }; /** * @brief Optional. An HTTPS URL used to automatically authorize the user. Can be used as a - * replacement for the Telegram Login Widget. + * replacement for the Telegram Login Widget. Not supported for ephemeral messages. */ std::shared_ptr loginUrl { }; /** @@ -4005,6 +4081,10 @@ struct InlineKeyboardButton { * the first button in the first row and can only be used in invoice messages. */ std::optional pay { }; + /** + * @brief Optional. If set, then the button is disabled and does nothing + */ + std::shared_ptr disabled { }; }; TGBOT_API void from_json(const nlohmann::json& json, InlineKeyboardButton& value); @@ -4022,6 +4102,12 @@ struct InlineKeyboardMarkup { * @brief Array of button rows, each represented by an Array of InlineKeyboardButton objects */ std::vector>> inlineKeyboard { }; + /** + * @brief Optional. Pass True if the reply interface must be shown to the user, as if they had + * manually selected the bot's message and tapped 'Reply'. The value of the field can't be + * changed when the inline keyboard is edited. + */ + std::optional forceReply { }; }; TGBOT_API void from_json(const nlohmann::json& json, InlineKeyboardMarkup& value); @@ -6493,10 +6579,11 @@ TGBOT_API void to_json(nlohmann::json& json, const InputProfilePhotoStatic& valu * any of the following types: InputRichBlockParagraph InputRichBlockSectionHeading * InputRichBlockPreformatted InputRichBlockFooter InputRichBlockDivider * InputRichBlockMathematicalExpression InputRichBlockAnchor InputRichBlockList - * InputRichBlockBlockQuotation InputRichBlockPullQuotation InputRichBlockCollage - * InputRichBlockSlideshow InputRichBlockTable InputRichBlockDetails InputRichBlockMap - * InputRichBlockAnimation InputRichBlockAudio InputRichBlockPhoto InputRichBlockVideo - * InputRichBlockVoiceNote InputRichBlockThinking + * InputRichBlockBlockQuotation InputRichBlockExpandableBlockQuotation + * InputRichBlockPullQuotation InputRichBlockCollage InputRichBlockSlideshow + * InputRichBlockTable InputRichBlockDetails InputRichBlockMap InputRichBlockButtons + * InputRichBlockAnimation InputRichBlockAudio InputRichBlockDocument InputRichBlockPhoto + * InputRichBlockVideo InputRichBlockVoiceNote InputRichBlockThinking * @ingroup api */ struct InputRichBlock { @@ -6506,13 +6593,14 @@ struct InputRichBlock { std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr, std::shared_ptr, - std::shared_ptr> + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr> value; }; @@ -6619,6 +6707,34 @@ struct InputRichBlockBlockQuotation { TGBOT_API void from_json(const nlohmann::json& json, InputRichBlockBlockQuotation& value); TGBOT_API void to_json(nlohmann::json& json, const InputRichBlockBlockQuotation& value); +/** + * @brief A block containing a list of buttons that are shown in one row, corresponding to the custom + * HTML tag . + * @ingroup api + */ +struct InputRichBlockButtons { + using Ptr = std::shared_ptr; + + static TGBOT_API const std::string TYPE; + + /** + * @brief Type of the block, always “buttons” + */ + std::string type { TYPE }; + /** + * @brief List of 1-8 buttons to send + */ + std::vector> buttons { }; + /** + * @brief Optional. Horizontal alignment of the buttons. Currently, must be one of “left”, + * “center”, or “right”. + */ + std::optional align { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, InputRichBlockButtons& value); +TGBOT_API void to_json(nlohmann::json& json, const InputRichBlockButtons& value); + /** * @brief A collage, corresponding to the custom HTML tag . * @ingroup api @@ -6693,6 +6809,59 @@ struct InputRichBlockDivider { TGBOT_API void from_json(const nlohmann::json& json, InputRichBlockDivider& value); TGBOT_API void to_json(nlohmann::json& json, const InputRichBlockDivider& value); +/** + * @brief A block with a general file, corresponding to the custom HTML tag . + * @ingroup api + */ +struct InputRichBlockDocument { + using Ptr = std::shared_ptr; + + static TGBOT_API const std::string TYPE; + + /** + * @brief Type of the block, always “document” + */ + std::string type { TYPE }; + /** + * @brief The document. Caption is ignored. + */ + std::shared_ptr document { }; + /** + * @brief Optional. Caption of the block + */ + std::shared_ptr caption { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, InputRichBlockDocument& value); +TGBOT_API void to_json(nlohmann::json& json, const InputRichBlockDocument& value); + +/** + * @brief A block quotation, corresponding to the HTML tag
with custom attribute + * "expandable". + * @ingroup api + */ +struct InputRichBlockExpandableBlockQuotation { + using Ptr = std::shared_ptr; + + static TGBOT_API const std::string TYPE; + + /** + * @brief Type of the block, always “expandable_blockquote” + */ + std::string type { TYPE }; + /** + * @brief Content of the block + */ + std::shared_ptr text { }; + /** + * @brief Optional. Credit of the block + */ + std::shared_ptr credit { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, InputRichBlockExpandableBlockQuotation& value); +TGBOT_API void to_json(nlohmann::json& json, const InputRichBlockExpandableBlockQuotation& value); + /** * @brief A footer, corresponding to the HTML tag