diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9fdb0abc6..cff02cde1 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -14,7 +14,7 @@ permissions: jobs: test: runs-on: ubuntu-24.04 - timeout-minutes: 60 + timeout-minutes: 30 steps: - uses: actions/checkout@v6 - uses: docker/setup-buildx-action@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 556b2d854..89b12c6dc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,7 @@ permissions: jobs: lint: runs-on: ubuntu-24.04 - timeout-minutes: 60 + timeout-minutes: 30 steps: - uses: actions/checkout@v6 - id: python diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccf20236..df42b89bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,6 @@ find_package(CURL 7.58.0 REQUIRED) find_package(nlohmann_json 3.7.3 REQUIRED) find_package(Threads REQUIRED) -file(GLOB TYPE_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/types/*.cpp") - add_library(TgBot src/Api.cpp src/ApiCodec.cpp @@ -26,7 +24,8 @@ add_library(TgBot src/TgLongPoll.cpp src/TgWebhookLocalServer.cpp src/TgWebhookTcpServer.cpp - ${TYPE_SOURCES} + src/InputFile.cpp + src/Types.cpp ) add_library(TgBot::TgBot ALIAS TgBot) diff --git a/Dockerfile_test b/Dockerfile_test index a2e13a547..0f21be083 100644 --- a/Dockerfile_test +++ b/Dockerfile_test @@ -47,12 +47,12 @@ RUN make test && \ RUN make example EXAMPLE=echobot RUN make example EXAMPLE=echobot-proxy RUN make example EXAMPLE=echobot-setmycommands -RUN make example EXAMPLE=echobot-submodule RUN make example EXAMPLE=echobot-webhook-server RUN make example EXAMPLE=inline-keyboard RUN make example EXAMPLE=photo RUN make example EXAMPLE=receive-file RUN make example EXAMPLE=received-text-processing RUN make example EXAMPLE=reply-keyboard +RUN make example EXAMPLE=echobot-submodule CMD ["make", "test-only"] diff --git a/api_codegen/generate.py b/api_codegen/generate.py index 3ea36bbc9..3abecdbc8 100644 --- a/api_codegen/generate.py +++ b/api_codegen/generate.py @@ -22,7 +22,6 @@ trim_blocks=True, lstrip_blocks=True, ) -GENERATED_MARKER = "// Generated by `make api-generate`. Do not edit." CONFIG = yaml.safe_load(DEFAULT_CONFIG.read_text(encoding="utf-8")) TYPE_CONFIG = CONFIG.get("types", {}) API_CONFIG = CONFIG.get("api", {}) @@ -111,41 +110,18 @@ def generate_openapi(schema_path: Path, root: Path) -> GeneratedCount: } objects = _build_objects(components) methods = _build_methods(document["paths"]) - api_objects = _api_objects(methods, objects) outputs = { - root / "include" / "tgbot" / "types" / "types_fwd.h": _render_template( - "types_fwd.h.j2", objects=objects - ), - root / "include" / "tgbot" / "types" / "types.h": _render_template( + root / "include" / "tgbot" / "Types.h": _render_template( "types.h.j2", objects=objects ), + root / "src" / "Types.cpp": _render_template("types.cpp.j2", objects=objects), root / "include" / "tgbot" / "ApiMethods.inc.h": _render_template( "api_methods.inc.h.j2", methods=methods ), root / "src" / "ApiMethods.cpp": _render_template( - "api_methods.cpp.j2", methods=methods, objects=api_objects + "api_methods.cpp.j2", methods=methods ), } - type_headers = { - root / "include" / "tgbot" / "types" / f"{object.name}.h": _render_template( - "type.h.j2", - object=object, - ) - for object in objects - } - outputs.update(type_headers) - type_sources = { - root / "src" / "types" / f"{object.name}.cpp": _render_template( - "type.cpp.j2", - object=object, - ) - for object in objects - } - outputs.update(type_sources) - expected_type_headers = set(type_headers) - expected_type_headers.add(root / "include" / "tgbot" / "types" / "types_fwd.h") - _sync_generated_type_headers(root, expected_type_headers) - _sync_generated_type_sources(root, set(type_sources)) for path, content in outputs.items(): _write(path, content) @@ -220,24 +196,6 @@ def _object_constants(fields: tuple[FieldModel, ...]) -> tuple[ConstantModel, .. return tuple(field.constant for field in fields if field.constant) -def _api_objects( - methods: tuple[MethodModel, ...], objects: tuple[ObjectModel, ...] -) -> tuple[ObjectModel, ...]: - object_names = {object.name for object in objects} - cpp_types = [method.return_type for method in methods] - cpp_types.extend( - parameter.cpp_type for method in methods for parameter in method.parameters - ) - used_names = { - token - for cpp_type in cpp_types - for token in re.findall(r"\b[A-Z][A-Za-z0-9]*\b", cpp_type) - if token in object_names - } - - return tuple(object for object in objects if object.name in used_names) - - def _object_dependencies( name: str, fields: tuple[FieldModel, ...], @@ -426,34 +384,6 @@ def _write(path: Path, content: str) -> None: path.write_text(content, encoding="utf-8") -def _sync_generated_type_headers(root: Path, expected_paths: set[Path]) -> None: - types_dir = root / "include" / "tgbot" / "types" - if not types_dir.exists(): - return - stale_paths = [ - path - for path in types_dir.glob("*.h") - if path not in expected_paths - and path.read_text(encoding="utf-8").startswith(GENERATED_MARKER) - ] - for path in stale_paths: - path.unlink() - - -def _sync_generated_type_sources(root: Path, expected_paths: set[Path]) -> None: - types_dir = root / "src" / "types" - if not types_dir.exists(): - return - stale_paths = [ - path - for path in types_dir.glob("*.cpp") - if path not in expected_paths - and path.read_text(encoding="utf-8").startswith(GENERATED_MARKER) - ] - for path in stale_paths: - path.unlink() - - def _format_cpp(path: Path, content: str) -> str: if path.name.endswith(".inc.h"): return _format_cpp_class_fragment(path, content) diff --git a/api_codegen/templates/api_methods.cpp.j2 b/api_codegen/templates/api_methods.cpp.j2 index 1090e1107..963666e12 100644 --- a/api_codegen/templates/api_methods.cpp.j2 +++ b/api_codegen/templates/api_methods.cpp.j2 @@ -2,9 +2,7 @@ #include "tgbot/Api.h" #include "tgbot/ApiCodec.h" -{% for object in objects %} -#include "tgbot/types/{{ object.name }}.h" -{% endfor %} +#include "tgbot/Types.h" namespace TgBot { diff --git a/api_codegen/templates/type.h.j2 b/api_codegen/templates/type.h.j2 deleted file mode 100644 index 35ff4e5b7..000000000 --- a/api_codegen/templates/type.h.j2 +++ /dev/null @@ -1,75 +0,0 @@ -// Generated by `make api-generate`. Do not edit. - -#pragma once - -#include "tgbot/export.h" - -#include -{% for header in object.standard_headers %} -#include <{{ header }}> -{% endfor %} - -namespace TgBot { - -{% for dependency in object.dependencies %} -struct {{ dependency }}; -{% endfor %} -{% if object.dependencies %} - -{% endif %} - -/** - * @brief{{ " " + object.description[0] if object.description else "" }} -{% for line in object.description[1:] %} - * {{ line }} -{% endfor %} - */ -struct {{ object.name }} { - using Ptr = std::shared_ptr<{{ object.name }}>; - -{% for constant in object.constants %} - static TGBOT_API const std::string {{ constant.name }}; -{% endfor %} -{% if object.constants %} - -{% endif %} -{% for enum in object.enums %} - enum class {{ enum.name }} { -{% for value in enum.values %} - {{ value.name }}{{ "," if not loop.last else "" }} -{% endfor %} - }; - -{% endfor %} -{% if object.union_members %} - std::variant< -{% for member in object.union_members %} - std::shared_ptr<{{ member }}>{{ "," if not loop.last else "" }} -{% endfor %} - > - value; -{% else %} -{% for field in object.fields %} - /** - * @brief{{ " " + field.description[0] if field.description else "" }} -{% for line in field.description[1:] %} - * {{ line }} -{% endfor %} - */ - {{ field.cpp_type }} {{ field.cpp_name }} { {{ field.constant.name if field.constant else "" }} }; - -{% endfor %} -{% endif %} -}; - -{% for enum in object.enums %} -TGBOT_API void from_json(const nlohmann::json& json, {{ object.name }}::{{ enum.name }}& value); -TGBOT_API void to_json(nlohmann::json& json, const {{ object.name }}::{{ enum.name }}& value); -{% endfor %} -{% if object.enums %} - -{% endif %} -TGBOT_API void from_json(const nlohmann::json& json, {{ object.name }}& value); -TGBOT_API void to_json(nlohmann::json& json, const {{ object.name }}& value); - -} // namespace TgBot diff --git a/api_codegen/templates/type.cpp.j2 b/api_codegen/templates/types.cpp.j2 similarity index 92% rename from api_codegen/templates/type.cpp.j2 rename to api_codegen/templates/types.cpp.j2 index 60a94cd2b..b9a7a9624 100644 --- a/api_codegen/templates/type.cpp.j2 +++ b/api_codegen/templates/types.cpp.j2 @@ -1,17 +1,13 @@ // Generated by `make api-generate`. Do not edit. -#include "tgbot/types/{{ object.name }}.h" #include "tgbot/Json.h" -{% for dependency in object.dependencies %} -#include "tgbot/types/{{ dependency }}.h" -{% endfor %} -{% if object.enums %} +#include "tgbot/Types.h" #include -{% endif %} namespace TgBot { +{% for object in objects %} {% for constant in object.constants %} const std::string {{ object.name }}::{{ constant.name }} = "{{ constant.value }}"; {% endfor %} @@ -63,4 +59,5 @@ void to_json(nlohmann::json& json, const {{ object.name }}& value) { {% endif %} } +{% endfor %} } // namespace TgBot diff --git a/api_codegen/templates/types.h.j2 b/api_codegen/templates/types.h.j2 index c92c77205..f6860f051 100644 --- a/api_codegen/templates/types.h.j2 +++ b/api_codegen/templates/types.h.j2 @@ -2,7 +2,77 @@ #pragma once -#include "tgbot/types/InputFile.h" +#include "tgbot/export.h" + +#include + +#include +#include +#include +#include +#include +#include + +namespace TgBot { + {% for object in objects %} -#include "tgbot/types/{{ object.name }}.h" +struct {{ object.name }}; +{% endfor %} + +{% for object in objects %} +/** + * @brief{{ " " + object.description[0] if object.description else "" }} +{% for line in object.description[1:] %} + * {{ line }} +{% endfor %} + */ +struct {{ object.name }} { + using Ptr = std::shared_ptr<{{ object.name }}>; + +{% for constant in object.constants %} + static TGBOT_API const std::string {{ constant.name }}; +{% endfor %} +{% if object.constants %} + +{% endif %} +{% for enum in object.enums %} + enum class {{ enum.name }} { +{% for value in enum.values %} + {{ value.name }}{{ "," if not loop.last else "" }} +{% endfor %} + }; + +{% endfor %} +{% if object.union_members %} + std::variant< +{% for member in object.union_members %} + std::shared_ptr<{{ member }}>{{ "," if not loop.last else "" }} +{% endfor %} + > + value; +{% else %} +{% for field in object.fields %} + /** + * @brief{{ " " + field.description[0] if field.description else "" }} +{% for line in field.description[1:] %} + * {{ line }} +{% endfor %} + */ + {{ field.cpp_type }} {{ field.cpp_name }} { {{ field.constant.name if field.constant else "" }} }; + +{% endfor %} +{% endif %} +}; + +{% for enum in object.enums %} +TGBOT_API void from_json(const nlohmann::json& json, {{ object.name }}::{{ enum.name }}& value); +TGBOT_API void to_json(nlohmann::json& json, const {{ object.name }}::{{ enum.name }}& value); +{% endfor %} +{% if object.enums %} + +{% endif %} +TGBOT_API void from_json(const nlohmann::json& json, {{ object.name }}& value); +TGBOT_API void to_json(nlohmann::json& json, const {{ object.name }}& value); + {% endfor %} +} // namespace TgBot diff --git a/api_codegen/templates/types_fwd.h.j2 b/api_codegen/templates/types_fwd.h.j2 deleted file mode 100644 index 17804336d..000000000 --- a/api_codegen/templates/types_fwd.h.j2 +++ /dev/null @@ -1,11 +0,0 @@ -// Generated by `make api-generate`. Do not edit. - -#pragma once - -namespace TgBot { - -{% for object in objects %} -struct {{ object.name }}; -{% endfor %} - -} // namespace TgBot diff --git a/api_codegen/tests/test_generate.py b/api_codegen/tests/test_generate.py index 4e31676d3..017222f4f 100644 --- a/api_codegen/tests/test_generate.py +++ b/api_codegen/tests/test_generate.py @@ -184,42 +184,36 @@ def test_generate_openapi_renders_types_methods_and_documentation( generated = generate_openapi(schema_path, tmp_path) - types = tmp_path.joinpath("include/tgbot/types/types.h").read_text() - user = tmp_path.joinpath("include/tgbot/types/User.h").read_text() - cached_audio = tmp_path.joinpath( - "include/tgbot/types/InlineQueryResultCachedAudio.h" - ).read_text() - user_source = tmp_path.joinpath("src/types/User.cpp").read_text() - cached_audio_source = tmp_path.joinpath( - "src/types/InlineQueryResultCachedAudio.cpp" - ).read_text() + types = tmp_path.joinpath("include/tgbot/Types.h").read_text() + types_source = tmp_path.joinpath("src/Types.cpp").read_text() api_source = tmp_path.joinpath("src/ApiMethods.cpp").read_text() methods = tmp_path.joinpath("include/tgbot/ApiMethods.inc.h").read_text() assert generated.objects == 2 assert generated.methods == 2 - assert user.startswith( + assert types.startswith( "// Generated by `make api-generate`. Do not edit.\n\n#pragma once" ) - assert '#include "tgbot/types/User.h"' in types - assert "struct User" not in types - assert "struct User" in user - assert "This object represents a Telegram user." in user - assert "Unique identifier for this user." in user - assert "@brief This object represents a Telegram user." in user - assert "@brief Unique identifier for this user." in user - assert "static TGBOT_API const std::string TYPE;" in cached_audio - assert "TGBOT_API void from_json" in cached_audio - assert "TGBOT_API void to_json" in cached_audio - assert "std::string type { TYPE };" in cached_audio - assert "std::string id { };\n\n /**" in cached_audio + assert "struct User;" in types + assert "struct InlineQueryResultCachedAudio;" in types + assert "struct User {" in types + assert "This object represents a Telegram user." in types + assert "Unique identifier for this user." in types + assert "@brief This object represents a Telegram user." in types + assert "@brief Unique identifier for this user." in types + assert "static TGBOT_API const std::string TYPE;" in types + assert "TGBOT_API void from_json" in types + assert "TGBOT_API void to_json" in types + assert "std::string type { TYPE };" in types + assert "std::string id { };\n\n /**" in types assert ( 'const std::string InlineQueryResultCachedAudio::TYPE = "audio";' - in cached_audio_source + in types_source ) - assert '#include "tgbot/Json.h"' in user_source - assert '#include "tgbot/types/User.h"' in cached_audio_source - assert 'Json::readRequiredField(json, "id", value.id);' in user_source - assert not tmp_path.joinpath("src/Types.cpp").exists() + assert '#include "tgbot/Json.h"' in types_source + assert '#include "tgbot/Types.h"' in types_source + assert 'Json::readRequiredField(json, "id", value.id);' in types_source + assert not tmp_path.joinpath("include/tgbot/types").exists() + assert not tmp_path.joinpath("src/types").exists() assert "\n /**\n * @brief Returns information about the bot.\n" in methods assert "\n std::shared_ptr getMe() const" in methods assert "Returns information about the bot." in methods @@ -236,40 +230,11 @@ def test_generate_openapi_renders_types_methods_and_documentation( generated_again = generate_openapi(schema_path, tmp_path) assert generated_again == generated - assert tmp_path.joinpath("include/tgbot/types/User.h").read_text() == user + assert tmp_path.joinpath("include/tgbot/Types.h").read_text() == types + assert tmp_path.joinpath("src/Types.cpp").read_text() == types_source assert tmp_path.joinpath("src/ApiMethods.cpp").read_text() == api_source -def test_generate_openapi_removes_only_stale_generated_type_files( - tmp_path: Path, -) -> None: - schema_path = tmp_path / "schema.yaml" - schema_path.write_text(yaml.safe_dump(_schema()), encoding="utf-8") - types_dir = tmp_path / "include" / "tgbot" / "types" - types_dir.mkdir(parents=True) - stale = types_dir / "OldType.h" - stale.write_text( - "// Generated by `make api-generate`. Do not edit.\n", encoding="utf-8" - ) - manual = types_dir / "InputFile.h" - manual.write_text("// Hand-written.\n", encoding="utf-8") - type_sources_dir = tmp_path / "src" / "types" - type_sources_dir.mkdir(parents=True) - stale_source = type_sources_dir / "OldType.cpp" - stale_source.write_text( - "// Generated by `make api-generate`. Do not edit.\n", encoding="utf-8" - ) - manual_source = type_sources_dir / "InputFile.cpp" - manual_source.write_text("// Hand-written.\n", encoding="utf-8") - - generate_openapi(schema_path, tmp_path) - - assert not stale.exists() - assert manual.read_text(encoding="utf-8") == "// Hand-written.\n" - assert not stale_source.exists() - assert manual_source.read_text(encoding="utf-8") == "// Hand-written.\n" - - def test_generate_openapi_rejects_method_without_result_schema(tmp_path: Path) -> None: schema = _schema() response_parts = schema["paths"]["/getMe"]["post"]["responses"]["200"]["content"][ diff --git a/include/tgbot/Api.h b/include/tgbot/Api.h index 2c91d2f95..382a3f53f 100644 --- a/include/tgbot/Api.h +++ b/include/tgbot/Api.h @@ -1,10 +1,9 @@ #pragma once #include "tgbot/HttpFormField.h" +#include "tgbot/InputFile.h" +#include "tgbot/Types.h" #include "tgbot/export.h" -#include "tgbot/types/InputFile.h" -#include "tgbot/types/Sticker.h" -#include "tgbot/types/types_fwd.h" #include diff --git a/include/tgbot/ApiCodec.h b/include/tgbot/ApiCodec.h index 13e1340e6..b724575c9 100644 --- a/include/tgbot/ApiCodec.h +++ b/include/tgbot/ApiCodec.h @@ -1,8 +1,8 @@ #pragma once #include "tgbot/HttpFormField.h" +#include "tgbot/InputFile.h" #include "tgbot/Json.h" -#include "tgbot/types/InputFile.h" #include diff --git a/include/tgbot/EventBroadcaster.h b/include/tgbot/EventBroadcaster.h index 8a7b7bf93..39fd2bf5c 100644 --- a/include/tgbot/EventBroadcaster.h +++ b/include/tgbot/EventBroadcaster.h @@ -1,19 +1,7 @@ #pragma once +#include "tgbot/Types.h" #include "tgbot/export.h" -#include "tgbot/types/CallbackQuery.h" -#include "tgbot/types/ChatJoinRequest.h" -#include "tgbot/types/ChatMemberUpdated.h" -#include "tgbot/types/ChosenInlineResult.h" -#include "tgbot/types/InlineQuery.h" -#include "tgbot/types/Message.h" -#include "tgbot/types/MessageReactionCountUpdated.h" -#include "tgbot/types/MessageReactionUpdated.h" -#include "tgbot/types/Poll.h" -#include "tgbot/types/PollAnswer.h" -#include "tgbot/types/PreCheckoutQuery.h" -#include "tgbot/types/ShippingQuery.h" -#include "tgbot/types/SuccessfulPayment.h" #include #include diff --git a/include/tgbot/EventHandler.h b/include/tgbot/EventHandler.h index fce8b8ad6..50469125f 100644 --- a/include/tgbot/EventHandler.h +++ b/include/tgbot/EventHandler.h @@ -1,9 +1,8 @@ #pragma once #include "tgbot/EventBroadcaster.h" +#include "tgbot/Types.h" #include "tgbot/export.h" -#include "tgbot/types/Message.h" -#include "tgbot/types/Update.h" namespace TgBot { diff --git a/include/tgbot/types/InputFile.h b/include/tgbot/InputFile.h similarity index 100% rename from include/tgbot/types/InputFile.h rename to include/tgbot/InputFile.h diff --git a/include/tgbot/TgLongPoll.h b/include/tgbot/TgLongPoll.h index 8c3684a86..9a0643928 100644 --- a/include/tgbot/TgLongPoll.h +++ b/include/tgbot/TgLongPoll.h @@ -1,7 +1,7 @@ #pragma once +#include "tgbot/Types.h" #include "tgbot/export.h" -#include "tgbot/types/Update.h" #include #include diff --git a/include/tgbot/Types.h b/include/tgbot/Types.h new file mode 100644 index 000000000..9eea2f884 --- /dev/null +++ b/include/tgbot/Types.h @@ -0,0 +1,15060 @@ +// Generated by `make api-generate`. Do not edit. + +#pragma once + +#include "tgbot/export.h" + +#include + +#include +#include +#include +#include +#include +#include + +namespace TgBot { + +struct AcceptedGiftTypes; +struct AffiliateInfo; +struct Animation; +struct Audio; +struct BackgroundFill; +struct BackgroundFillFreeformGradient; +struct BackgroundFillGradient; +struct BackgroundFillSolid; +struct BackgroundType; +struct BackgroundTypeChatTheme; +struct BackgroundTypeFill; +struct BackgroundTypePattern; +struct BackgroundTypeWallpaper; +struct Birthdate; +struct BotAccessSettings; +struct BotCommand; +struct BotCommandScope; +struct BotCommandScopeAllChatAdministrators; +struct BotCommandScopeAllGroupChats; +struct BotCommandScopeAllPrivateChats; +struct BotCommandScopeChat; +struct BotCommandScopeChatAdministrators; +struct BotCommandScopeChatMember; +struct BotCommandScopeDefault; +struct BotDescription; +struct BotName; +struct BotShortDescription; +struct BotSubscriptionUpdated; +struct BusinessBotRights; +struct BusinessConnection; +struct BusinessIntro; +struct BusinessLocation; +struct BusinessMessagesDeleted; +struct BusinessOpeningHours; +struct BusinessOpeningHoursInterval; +struct CallbackGame; +struct CallbackQuery; +struct Chat; +struct ChatAdministratorRights; +struct ChatBackground; +struct ChatBoost; +struct ChatBoostAdded; +struct ChatBoostRemoved; +struct ChatBoostSource; +struct ChatBoostSourceGiftCode; +struct ChatBoostSourceGiveaway; +struct ChatBoostSourcePremium; +struct ChatBoostUpdated; +struct ChatFullInfo; +struct ChatInviteLink; +struct ChatJoinRequest; +struct ChatLocation; +struct ChatMember; +struct ChatMemberAdministrator; +struct ChatMemberBanned; +struct ChatMemberLeft; +struct ChatMemberMember; +struct ChatMemberOwner; +struct ChatMemberRestricted; +struct ChatMemberUpdated; +struct ChatOwnerChanged; +struct ChatOwnerLeft; +struct ChatPermissions; +struct ChatPhoto; +struct ChatShared; +struct Checklist; +struct ChecklistTask; +struct ChecklistTasksAdded; +struct ChecklistTasksDone; +struct ChosenInlineResult; +struct Community; +struct CommunityChatAdded; +struct CommunityChatRemoved; +struct Contact; +struct CopyTextButton; +struct Dice; +struct DirectMessagePriceChanged; +struct DirectMessagesTopic; +struct Document; +struct EncryptedCredentials; +struct EncryptedPassportElement; +struct ExternalReplyInfo; +struct File; +struct ForceReply; +struct ForumTopic; +struct ForumTopicClosed; +struct ForumTopicCreated; +struct ForumTopicEdited; +struct ForumTopicReopened; +struct Game; +struct GameHighScore; +struct GeneralForumTopicHidden; +struct GeneralForumTopicUnhidden; +struct Gift; +struct GiftBackground; +struct GiftInfo; +struct Gifts; +struct Giveaway; +struct GiveawayCompleted; +struct GiveawayCreated; +struct GiveawayWinners; +struct InaccessibleMessage; +struct InlineKeyboardButton; +struct InlineKeyboardMarkup; +struct InlineQuery; +struct InlineQueryResult; +struct InlineQueryResultArticle; +struct InlineQueryResultAudio; +struct InlineQueryResultCachedAudio; +struct InlineQueryResultCachedDocument; +struct InlineQueryResultCachedGif; +struct InlineQueryResultCachedMpeg4Gif; +struct InlineQueryResultCachedPhoto; +struct InlineQueryResultCachedSticker; +struct InlineQueryResultCachedVideo; +struct InlineQueryResultCachedVoice; +struct InlineQueryResultContact; +struct InlineQueryResultDocument; +struct InlineQueryResultGame; +struct InlineQueryResultGif; +struct InlineQueryResultLocation; +struct InlineQueryResultMpeg4Gif; +struct InlineQueryResultPhoto; +struct InlineQueryResultVenue; +struct InlineQueryResultVideo; +struct InlineQueryResultVoice; +struct InlineQueryResultsButton; +struct InputChecklist; +struct InputChecklistTask; +struct InputContactMessageContent; +struct InputInvoiceMessageContent; +struct InputLocationMessageContent; +struct InputMedia; +struct InputMediaAnimation; +struct InputMediaAudio; +struct InputMediaDocument; +struct InputMediaLink; +struct InputMediaLivePhoto; +struct InputMediaLocation; +struct InputMediaPhoto; +struct InputMediaSticker; +struct InputMediaVenue; +struct InputMediaVideo; +struct InputMediaVoiceNote; +struct InputMessageContent; +struct InputPaidMedia; +struct InputPaidMediaLivePhoto; +struct InputPaidMediaPhoto; +struct InputPaidMediaVideo; +struct InputPollMedia; +struct InputPollOption; +struct InputPollOptionMedia; +struct InputProfilePhoto; +struct InputProfilePhotoAnimated; +struct InputProfilePhotoStatic; +struct InputRichBlock; +struct InputRichBlockAnchor; +struct InputRichBlockAnimation; +struct InputRichBlockAudio; +struct InputRichBlockBlockQuotation; +struct InputRichBlockCollage; +struct InputRichBlockDetails; +struct InputRichBlockDivider; +struct InputRichBlockFooter; +struct InputRichBlockList; +struct InputRichBlockListItem; +struct InputRichBlockMap; +struct InputRichBlockMathematicalExpression; +struct InputRichBlockParagraph; +struct InputRichBlockPhoto; +struct InputRichBlockPreformatted; +struct InputRichBlockPullQuotation; +struct InputRichBlockSectionHeading; +struct InputRichBlockSlideshow; +struct InputRichBlockTable; +struct InputRichBlockThinking; +struct InputRichBlockVideo; +struct InputRichBlockVoiceNote; +struct InputRichMessage; +struct InputRichMessageContent; +struct InputRichMessageMedia; +struct InputSticker; +struct InputStoryContent; +struct InputStoryContentPhoto; +struct InputStoryContentVideo; +struct InputTextMessageContent; +struct InputVenueMessageContent; +struct Invoice; +struct KeyboardButton; +struct KeyboardButtonPollType; +struct KeyboardButtonRequestChat; +struct KeyboardButtonRequestManagedBot; +struct KeyboardButtonRequestUsers; +struct LabeledPrice; +struct Link; +struct LinkPreviewOptions; +struct LivePhoto; +struct Location; +struct LocationAddress; +struct LoginUrl; +struct ManagedBotCreated; +struct ManagedBotUpdated; +struct MaskPosition; +struct MaybeInaccessibleMessage; +struct MenuButton; +struct MenuButtonCommands; +struct MenuButtonDefault; +struct MenuButtonWebApp; +struct Message; +struct MessageAutoDeleteTimerChanged; +struct MessageEntity; +struct MessageId; +struct MessageOrigin; +struct MessageOriginChannel; +struct MessageOriginChat; +struct MessageOriginHiddenUser; +struct MessageOriginUser; +struct MessageReactionCountUpdated; +struct MessageReactionUpdated; +struct OrderInfo; +struct OwnedGift; +struct OwnedGiftRegular; +struct OwnedGiftUnique; +struct OwnedGifts; +struct PaidMedia; +struct PaidMediaInfo; +struct PaidMediaLivePhoto; +struct PaidMediaPhoto; +struct PaidMediaPreview; +struct PaidMediaPurchased; +struct PaidMediaVideo; +struct PaidMessagePriceChanged; +struct PassportData; +struct PassportElementError; +struct PassportElementErrorDataField; +struct PassportElementErrorFile; +struct PassportElementErrorFiles; +struct PassportElementErrorFrontSide; +struct PassportElementErrorReverseSide; +struct PassportElementErrorSelfie; +struct PassportElementErrorTranslationFile; +struct PassportElementErrorTranslationFiles; +struct PassportElementErrorUnspecified; +struct PassportFile; +struct PhotoSize; +struct Poll; +struct PollAnswer; +struct PollMedia; +struct PollOption; +struct PollOptionAdded; +struct PollOptionDeleted; +struct PreCheckoutQuery; +struct PreparedInlineMessage; +struct PreparedKeyboardButton; +struct ProximityAlertTriggered; +struct ReactionCount; +struct ReactionType; +struct ReactionTypeCustomEmoji; +struct ReactionTypeEmoji; +struct ReactionTypePaid; +struct RefundedPayment; +struct ReplyKeyboardMarkup; +struct ReplyKeyboardRemove; +struct ReplyParameters; +struct ResponseParameters; +struct RevenueWithdrawalState; +struct RevenueWithdrawalStateFailed; +struct RevenueWithdrawalStatePending; +struct RevenueWithdrawalStateSucceeded; +struct RichBlock; +struct RichBlockAnchor; +struct RichBlockAnimation; +struct RichBlockAudio; +struct RichBlockBlockQuotation; +struct RichBlockCaption; +struct RichBlockCollage; +struct RichBlockDetails; +struct RichBlockDivider; +struct RichBlockFooter; +struct RichBlockList; +struct RichBlockListItem; +struct RichBlockMap; +struct RichBlockMathematicalExpression; +struct RichBlockParagraph; +struct RichBlockPhoto; +struct RichBlockPreformatted; +struct RichBlockPullQuotation; +struct RichBlockSectionHeading; +struct RichBlockSlideshow; +struct RichBlockTable; +struct RichBlockTableCell; +struct RichBlockThinking; +struct RichBlockVideo; +struct RichBlockVoiceNote; +struct RichMessage; +struct RichText; +struct RichTextAnchor; +struct RichTextAnchorLink; +struct RichTextBankCardNumber; +struct RichTextBold; +struct RichTextBotCommand; +struct RichTextCashtag; +struct RichTextCode; +struct RichTextCustomEmoji; +struct RichTextDateTime; +struct RichTextEmailAddress; +struct RichTextHashtag; +struct RichTextItalic; +struct RichTextMarked; +struct RichTextMathematicalExpression; +struct RichTextMention; +struct RichTextPhoneNumber; +struct RichTextReference; +struct RichTextReferenceLink; +struct RichTextSpoiler; +struct RichTextStrikethrough; +struct RichTextSubscript; +struct RichTextSuperscript; +struct RichTextTextMention; +struct RichTextUnderline; +struct RichTextUrl; +struct SentGuestMessage; +struct SentWebAppMessage; +struct SharedUser; +struct ShippingAddress; +struct ShippingOption; +struct ShippingQuery; +struct StarAmount; +struct StarTransaction; +struct StarTransactions; +struct Sticker; +struct StickerSet; +struct Story; +struct StoryArea; +struct StoryAreaPosition; +struct StoryAreaType; +struct StoryAreaTypeLink; +struct StoryAreaTypeLocation; +struct StoryAreaTypeSuggestedReaction; +struct StoryAreaTypeUniqueGift; +struct StoryAreaTypeWeather; +struct SuccessfulPayment; +struct SuggestedPostApprovalFailed; +struct SuggestedPostApproved; +struct SuggestedPostDeclined; +struct SuggestedPostInfo; +struct SuggestedPostPaid; +struct SuggestedPostParameters; +struct SuggestedPostPrice; +struct SuggestedPostRefunded; +struct SwitchInlineQueryChosenChat; +struct TextQuote; +struct TransactionPartner; +struct TransactionPartnerAffiliateProgram; +struct TransactionPartnerChat; +struct TransactionPartnerFragment; +struct TransactionPartnerOther; +struct TransactionPartnerTelegramAds; +struct TransactionPartnerTelegramApi; +struct TransactionPartnerUser; +struct UniqueGift; +struct UniqueGiftBackdrop; +struct UniqueGiftBackdropColors; +struct UniqueGiftColors; +struct UniqueGiftInfo; +struct UniqueGiftModel; +struct UniqueGiftSymbol; +struct Update; +struct User; +struct UserChatBoosts; +struct UserProfileAudios; +struct UserProfilePhotos; +struct UserRating; +struct UsersShared; +struct Venue; +struct Video; +struct VideoChatEnded; +struct VideoChatParticipantsInvited; +struct VideoChatScheduled; +struct VideoChatStarted; +struct VideoNote; +struct VideoQuality; +struct Voice; +struct WebAppData; +struct WebAppInfo; +struct WebhookInfo; +struct WriteAccessAllowed; + +/** + * @brief This object describes the types of gifts that can be gifted to a user or a chat. + */ +struct AcceptedGiftTypes { + using Ptr = std::shared_ptr; + + /** + * @brief True, if unlimited regular gifts are accepted + */ + bool unlimitedGifts { }; + + /** + * @brief True, if limited regular gifts are accepted + */ + bool limitedGifts { }; + + /** + * @brief True, if unique gifts or gifts that can be upgraded to unique for free are accepted + */ + bool uniqueGifts { }; + + /** + * @brief True, if a Telegram Premium subscription is accepted + */ + bool premiumSubscription { }; + + /** + * @brief True, if transfers of unique gifts from channels are accepted + */ + bool giftsFromChannels { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, AcceptedGiftTypes& value); +TGBOT_API void to_json(nlohmann::json& json, const AcceptedGiftTypes& value); + +/** + * @brief Contains information about the affiliate that received a commission via this transaction. + */ +struct AffiliateInfo { + using Ptr = std::shared_ptr; + + /** + * @brief Optional. The bot or the user that received an affiliate commission if it was received + * by a bot or a user + */ + std::shared_ptr affiliateUser { }; + + /** + * @brief Optional. The chat that received an affiliate commission if it was received by a chat + */ + std::shared_ptr affiliateChat { }; + + /** + * @brief The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars + * received by the bot from referred users + */ + std::int32_t commissionPerMille { }; + + /** + * @brief Integer amount of Telegram Stars received by the affiliate from the transaction, rounded + * to 0; can be negative for refunds + */ + std::int32_t amount { }; + + /** + * @brief Optional. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; + * from -999999999 to 999999999; can be negative for refunds + */ + std::optional nanostarAmount { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, AffiliateInfo& value); +TGBOT_API void to_json(nlohmann::json& json, const AffiliateInfo& value); + +/** + * @brief This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound). + */ +struct Animation { + using Ptr = std::shared_ptr; + + /** + * @brief Identifier for this file, which can be used to download or reuse the file + */ + std::string fileId { }; + + /** + * @brief Unique identifier for this file, which is supposed to be the same over time and for + * different bots. Can't be used to download or reuse the file. + */ + std::string fileUniqueId { }; + + /** + * @brief Video width as defined by the sender + */ + std::int32_t width { }; + + /** + * @brief Video height as defined by the sender + */ + std::int32_t height { }; + + /** + * @brief Duration of the video in seconds as defined by the sender + */ + std::int32_t duration { }; + + /** + * @brief Optional. Animation thumbnail as defined by the sender + */ + std::shared_ptr thumbnail { }; + + /** + * @brief Optional. Original animation filename as defined by the sender + */ + std::optional fileName { }; + + /** + * @brief Optional. MIME type of the file as defined by the sender + */ + std::optional mimeType { }; + + /** + * @brief Optional. File size in bytes. It can be bigger than 2^31 and some programming languages + * may have difficulty/silent defects in interpreting it. But it has at most 52 significant + * bits, so a signed 64-bit integer or double-precision float type are safe for storing + * this value. + */ + std::optional fileSize { }; +}; + +TGBOT_API void from_json(const nlohmann::json& json, Animation& value); +TGBOT_API void to_json(nlohmann::json& json, const Animation& value); + +/** + * @brief This object represents an audio file to be treated as music by the Telegram clients. + */ +struct Audio { + using Ptr = std::shared_ptr