diff --git a/include/tgbotxx/Api.hpp b/include/tgbotxx/Api.hpp index a3ea40c94..3fc832c59 100644 --- a/include/tgbotxx/Api.hpp +++ b/include/tgbotxx/Api.hpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -81,7 +83,6 @@ #include #include #include -#include namespace nl = nlohmann; namespace tgbotxx { @@ -311,6 +312,56 @@ namespace tgbotxx { bool allowSendingWithoutReply = false, const Ptr& replyMarkup = nullptr) const; + + /// @brief Use this method to send video files, Telegram clients support MPEG4 videos (other formats may be sent as Document using Api::sendDocument()). + /// Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @param video Video to send. + /// Pass a fileId as String to send a video that exists on the Telegram servers (recommended), + /// Pass an HTTP URL as a String for Telegram to get a video from the Internet, or upload a new video using multipart/form-data. + /// More information on Sending Files » https://core.telegram.org/bots/api#sending-files + /// @param messageThreadId Optional. Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// @param duration Optional. Duration of sent video in seconds + /// @param width Optional. Video width + /// @param height Optional. Video height + /// @param thumbnail Optional. Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. + /// The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. + /// Ignored if the file is not uploaded using multipart/form-data. + /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under . + /// More information on Sending Files » https://core.telegram.org/bots/api#sending-files + /// @param caption Optional. Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing + /// @param parseMode Optional. Mode for parsing entities in the video caption. See formatting options for more details. https://core.telegram.org/bots/api#formatting-options + /// @param captionEntities Optional. A JSON-serialized list of special entities that appear in the new caption, which can be specified instead of parseMode + /// @param hasSpoiler Optional. Pass True if the video needs to be covered with a spoiler animation + /// @param supportsStreaming Optional. Pass True if the uploaded video is suitable for streaming + /// @param disableNotification Optional. Sends the message silently. Users will receive a notification with no sound. + /// @param protectContent Optional. Protects the contents of the sent message from forwarding and saving + /// @param replyToMessageId Optional. If the message is a reply, ID of the original message + /// @param allowSendingWithoutReply Optional. Pass True if the message should be sent even if the specified replied-to message is not found + /// @param replyMarkup Optional. Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + /// One of InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardRemove or ForceReply. + /// @returns the sent Message on success. + /// @note Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. + /// @ref https://core.telegram.org/bots/api#sendvideo + Ptr sendVideo(std::int64_t chatId, + std::variant video, + std::int32_t messageThreadId = 0, + std::int32_t duration = 0, + std::int32_t width = 0, + std::int32_t height = 0, + std::optional> thumbnail = std::nullopt, + const std::string& caption = "", + const std::string& parseMode = "", + const std::vector>& captionEntities = std::vector>(), + bool hasSpoiler = false, + bool supportsStreaming = false, + bool disableNotification = false, + bool protectContent = false, + std::int32_t replyToMessageId = 0, + bool allowSendingWithoutReply = false, + const Ptr& replyMarkup = nullptr) const; + + /// @brief Use this method to get basic information about a file and prepare it for downloading. /// For the moment, bots can download files of up to 20MB in size. /// The file can then be downloaded using Api::downloadFile or via the link https://api.telegram.org/file/bot/, where is taken from the response. diff --git a/src/Api.cpp b/src/Api.cpp index 95a6e5d55..7fefb6262 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -434,3 +434,77 @@ std::string Api::downloadFile(const std::string& filePath, const std::function Api::sendVideo(std::int64_t chatId, + std::variant video, + std::int32_t messageThreadId, + std::int32_t duration, + std::int32_t width, + std::int32_t height, + std::optional> thumbnail, + const std::string& caption, + const std::string& parseMode, + const std::vector>& captionEntities, + bool hasSpoiler, + bool supportsStreaming, + bool disableNotification, + bool protectContent, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + const Ptr& replyMarkup) const { + cpr::Multipart data{}; + data.parts.reserve(12); + data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + if (video.index() == 0) /* cpr::File */ { + const cpr::File& file = std::get(video); + data.parts.emplace_back("video", cpr::Files{file}); + } else /* std::string (fileId or Url) */ { + const std::string& fileIdOrUrl = std::get(video); + data.parts.emplace_back("video", fileIdOrUrl); + } + if (messageThreadId) + data.parts.emplace_back("message_thread_id", messageThreadId); + if (duration) + data.parts.emplace_back("duration", duration); + if (width) + data.parts.emplace_back("width", width); + if (height) + data.parts.emplace_back("height", height); + if (thumbnail.has_value()) { + if (thumbnail->index() == 0) /* cpr::File */ { + const cpr::File& file = std::get(*thumbnail); + data.parts.emplace_back("thumbnail", cpr::Files{file}); + } else /* std::string (fileId or Url) */ { + const std::string& fileIdOrUrl = std::get(*thumbnail); + data.parts.emplace_back("thumbnail", fileIdOrUrl); + } + } + if (not caption.empty()) + data.parts.emplace_back("caption", caption); + if (not parseMode.empty()) + data.parts.emplace_back("parse_mode", parseMode); + if (not captionEntities.empty()) { + nl::json entitiesArray = nl::json::array(); + for (const Ptr& entity: captionEntities) + entitiesArray.push_back(entity->toJson()); + data.parts.emplace_back("caption_entities", entitiesArray.dump()); + } + if (hasSpoiler) + data.parts.emplace_back("has_spoiler", hasSpoiler); + if (supportsStreaming) + data.parts.emplace_back("supports_streaming", supportsStreaming); + if (disableNotification) + data.parts.emplace_back("disable_notification", disableNotification); + if (protectContent) + data.parts.emplace_back("protect_content", protectContent); + if (replyToMessageId) + data.parts.emplace_back("reply_to_message_id", replyToMessageId); + if (allowSendingWithoutReply) + data.parts.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + if (replyMarkup) + data.parts.emplace_back("reply_markup", replyMarkup->toJson().dump()); + + nl::json sentMessageObj = sendRequest("sendVideo", data); + Ptr message(new Message(sentMessageObj)); + return message; +}