From c17ab6fb6574bdea6fc9011be0651dc74aa6a53e Mon Sep 17 00:00:00 2001 From: llnulldisk <48621230+llnulldisk@users.noreply.github.com> Date: Sat, 3 Sep 2022 22:41:05 +0200 Subject: Update to API 5.0 --- src/Api.cpp | 660 ++++++++++--- src/TgTypeParser.cpp | 1927 ++++++++++++++++++++++--------------- src/types/InputMedia.cpp | 15 + src/types/InputMessageContent.cpp | 13 + 4 files changed, 1667 insertions(+), 948 deletions(-) create mode 100644 src/types/InputMedia.cpp create mode 100644 src/types/InputMessageContent.cpp (limited to 'src') diff --git a/src/Api.cpp b/src/Api.cpp index 070d72e..86d573b 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -40,15 +40,18 @@ vector Api::getUpdates(std::int32_t offset, std::int32_t limit, std return _tgTypeParser.parseJsonAndGetArray(&TgTypeParser::parseJsonAndGetUpdate, sendRequest("getUpdates", args)); } -void Api::setWebhook(const string& url, const InputFile::Ptr certificate, std::int32_t maxConnection, const StringArrayPtr& allowedUpdates) const { +bool Api::setWebhook(const std::string& url, InputFile::Ptr certificate, const std::string& ipAddress, + std::int32_t maxConnection, const StringArrayPtr& allowedUpdates, bool dropPendingUpdates) const { vector args; - args.reserve(4); - if (!url.empty()) { - args.emplace_back("url", url); - } + args.reserve(6); + + args.emplace_back("url", url); if (certificate != nullptr) { args.emplace_back("certificate", certificate->data, true, certificate->mimeType, certificate->fileName); } + if (!ipAddress.empty()) { + args.emplace_back("ip_address", ipAddress); + } if (maxConnection != 40) { args.emplace_back("max_connections", maxConnection); } @@ -59,11 +62,21 @@ void Api::setWebhook(const string& url, const InputFile::Ptr certificate, std::i }, *allowedUpdates); args.emplace_back("allowed_updates", allowedUpdatesJson); } + if (dropPendingUpdates) { + args.emplace_back("drop_pending_updates", dropPendingUpdates); + } - sendRequest("setWebhook", args); + return sendRequest("setWebhook").get("", false); } -bool Api::deleteWebhook() const { +bool Api::deleteWebhook(bool dropPendingUpdates) const { + vector args; + args.reserve(1); + + if (dropPendingUpdates) { + args.emplace_back("drop_pending_updates", dropPendingUpdates); + } + return sendRequest("deleteWebhook").get("", false); } @@ -84,17 +97,20 @@ User::Ptr Api::getMe() const { return _tgTypeParser.parseJsonAndGetUser(sendRequest("getMe")); } -Message::Ptr Api::sendMessage(boost::variant chatId, const std::string& text, bool disableWebPagePreview, - std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, const std::string& parseMode, - bool disableNotification) const { +Message::Ptr Api::sendMessage(boost::variant chatId, const std::string& text, const std::string& parseMode, + const std::vector& entities, bool disableWebPagePreview, bool disableNotification, + std::int32_t replyToMessageId, bool allowSendingWithoutReply, GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(7); + args.reserve(9); args.emplace_back("chat_id", chatId); args.emplace_back("text", text); if (!parseMode.empty()) { args.emplace_back("parse_mode", parseMode); } + if (!entities.empty()) { + args.emplace_back("entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, entities)); + } if (disableWebPagePreview) { args.emplace_back("disable_web_page_preview", disableWebPagePreview); } @@ -104,6 +120,9 @@ Message::Ptr Api::sendMessage(boost::variant c if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } @@ -123,37 +142,95 @@ Message::Ptr Api::forwardMessage(std::int64_t chatId, std::int64_t fromChatId, s return _tgTypeParser.parseJsonAndGetMessage(sendRequest("forwardMessage", args)); } -Message::Ptr Api::sendPhoto(std::int64_t chatId, boost::variant photo, const string& caption, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +MessageId::Ptr Api::copyMessage(std::int64_t chatId, std::int64_t fromChatId, std::int32_t messageId, + const std::string& caption, const std::string& parseMode, const std::vector& captionEntities, + bool disableNotification, std::int32_t replyToMessageId, bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(7); + args.reserve(10); + args.emplace_back("chat_id", chatId); - if (photo.which() == 0 /* InputFile::Ptr */) { - auto file = boost::get(photo); - args.emplace_back("photo", file->data, true, file->mimeType, file->fileName); - } else /* std::string */ { - args.emplace_back("photo", boost::get(photo)); - } + args.emplace_back("from_chat_id", fromChatId); + args.emplace_back("message_id", messageId); if (!caption.empty()) { args.emplace_back("caption", caption); } + if (!parseMode.empty()) { + args.emplace_back("parse_mode", parseMode); + } + if (!captionEntities.empty()) { + args.emplace_back("caption_entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, captionEntities)); + } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } + + return _tgTypeParser.parseJsonAndGetMessageId(sendRequest("copyMessage", args)); +} + +Message::Ptr Api::sendPhoto(std::int64_t chatId, boost::variant photo, const std::string& caption, + const std::string& parseMode, const std::vector& captionEntities, bool disableNotification, + std::int32_t replyToMessageId, bool allowSendingWithoutReply, GenericReply::Ptr replyMarkup) const { + vector args; + args.reserve(9); + + args.emplace_back("chat_id", chatId); + if (photo.which() == 0 /* InputFile::Ptr */) { + auto file = boost::get(photo); + args.emplace_back("photo", file->data, true, file->mimeType, file->fileName); + } else /* std::string */ { + args.emplace_back("photo", boost::get(photo)); + } + if (!caption.empty()) { + args.emplace_back("caption", caption); + } if (!parseMode.empty()) { args.emplace_back("parse_mode", parseMode); } + if (!captionEntities.empty()) { + args.emplace_back("caption_entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, captionEntities)); + } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); } + if (replyToMessageId) { + args.emplace_back("reply_to_message_id", replyToMessageId); + } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } + if (replyMarkup) { + args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); + } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendPhoto", args)); } -Message::Ptr Api::sendAudio(std::int64_t chatId, boost::variant audio, const string& caption, std::int32_t duration, const string& performer, const string& title, boost::variant thumb, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +Message::Ptr Api::sendAudio(std::int64_t chatId, + boost::variant audio, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + std::int32_t duration, + const std::string& performer, + const std::string& title, + boost::variant thumb, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(11); + args.reserve(13); + args.emplace_back("chat_id", chatId); if (audio.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(audio); @@ -164,6 +241,12 @@ Message::Ptr Api::sendAudio(std::int64_t chatId, boost::variant(&TgTypeParser::parseMessageEntity, captionEntities)); + } if (duration) { args.emplace_back("duration", duration); } @@ -182,24 +265,36 @@ Message::Ptr Api::sendAudio(std::int64_t chatId, boost::variant document, boost::variant thumb, const string& caption, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +Message::Ptr Api::sendDocument(std::int64_t chatId, + boost::variant document, + boost::variant thumb, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + bool disableContentTypeDetection, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(8); + args.reserve(11); + args.emplace_back("chat_id", chatId); if (document.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(document); @@ -219,24 +314,48 @@ Message::Ptr Api::sendDocument(std::int64_t chatId, boost::variant(&TgTypeParser::parseMessageEntity, captionEntities)); + } + if (disableContentTypeDetection) { + args.emplace_back("disable_content_type_detection", disableContentTypeDetection); + } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); } + if (replyToMessageId) { + args.emplace_back("reply_to_message_id", replyToMessageId); + } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } + if (replyMarkup) { + args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); + } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendDocument", args)); } -Message::Ptr Api::sendVideo(std::int64_t chatId, boost::variant video, bool supportsStreaming, std::int32_t duration, std::int32_t width, std::int32_t height, boost::variant thumb, const string& caption, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +Message::Ptr Api::sendVideo(std::int64_t chatId, + boost::variant video, + std::int32_t duration, + std::int32_t width, + std::int32_t height, + boost::variant thumb, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + bool supportsStreaming, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(12); + args.reserve(14); + args.emplace_back("chat_id", chatId); if (video.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(video); @@ -244,9 +363,6 @@ Message::Ptr Api::sendVideo(std::int64_t chatId, boost::variant(video)); } - if (supportsStreaming) { - args.emplace_back("supports_streaming", supportsStreaming); - } if (duration) { args.emplace_back("duration", duration); } @@ -268,24 +384,47 @@ Message::Ptr Api::sendVideo(std::int64_t chatId, boost::variant(&TgTypeParser::parseMessageEntity, captionEntities)); + } + if (supportsStreaming) { + args.emplace_back("supports_streaming", supportsStreaming); + } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); } + if (replyToMessageId) { + args.emplace_back("reply_to_message_id", replyToMessageId); + } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } + if (replyMarkup) { + args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); + } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVideo", args)); } -Message::Ptr Api::sendAnimation(std::int64_t chatId, boost::variant animation, std::int32_t duration, std::int32_t width, std::int32_t height, boost::variant thumb, const string& caption, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +Message::Ptr Api::sendAnimation(std::int64_t chatId, + boost::variant animation, + std::int32_t duration, + std::int32_t width, + std::int32_t height, + boost::variant thumb, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(11); + args.reserve(13); + args.emplace_back("chat_id", chatId); if (animation.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(animation); @@ -314,24 +453,41 @@ Message::Ptr Api::sendAnimation(std::int64_t chatId, boost::variant(&TgTypeParser::parseMessageEntity, captionEntities)); + } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); } + if (replyToMessageId) { + args.emplace_back("reply_to_message_id", replyToMessageId); + } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } + if (replyMarkup) { + args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); + } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendAnimation", args)); } -Message::Ptr Api::sendVoice(std::int64_t chatId, boost::variant voice, const string& caption, int duration, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, const string& parseMode, bool disableNotification) const { +Message::Ptr Api::sendVoice(std::int64_t chatId, + boost::variant voice, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + std::int32_t duration, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(8); + args.reserve(10); + args.emplace_back("chat_id", chatId); if (voice.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(voice); @@ -342,27 +498,43 @@ Message::Ptr Api::sendVoice(std::int64_t chatId, boost::variant(&TgTypeParser::parseMessageEntity, captionEntities)); + } if (duration) { args.emplace_back("duration", duration); } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (!parseMode.empty()) { - args.emplace_back("parse_mode", parseMode); - } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVoice", args)); } -Message::Ptr Api::sendVideoNote(std::int64_t chatId, boost::variant videoNote, std::int64_t replyToMessageId, bool disableNotification, std::int32_t duration, std::int32_t length, boost::variant thumb, const GenericReply::Ptr replyMarkup) const { +Message::Ptr Api::sendVideoNote(std::int64_t chatId, + boost::variant videoNote, + std::int32_t duration, + std::int32_t length, + boost::variant thumb, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(8); + args.reserve(9); + args.emplace_back("chat_id", chatId); if (videoNote.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(videoNote); @@ -370,9 +542,6 @@ Message::Ptr Api::sendVideoNote(std::int64_t chatId, boost::variant(videoNote)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } if (duration) { args.emplace_back("duration", duration); } @@ -388,52 +557,86 @@ Message::Ptr Api::sendVideoNote(std::int64_t chatId, boost::variant Api::sendMediaGroup(std::int64_t chatId, const vector& media, bool disableNotification, std::int32_t replyToMessageId) const { +vector Api::sendMediaGroup(std::int64_t chatId, const std::vector& media, bool disableNotification, + std::int32_t replyToMessageId, bool allowSendingWithoutReply) const { vector args; - args.reserve(4); + args.reserve(5); + args.emplace_back("chat_id", chatId); - string mediaJson = _tgTypeParser.parseArray(&TgTypeParser::parseInputMedia, media); - args.emplace_back("media", mediaJson); - args.emplace_back("disable_notification", disableNotification); - args.emplace_back("reply_to_message_id", replyToMessageId); + args.emplace_back("media", _tgTypeParser.parseArray(&TgTypeParser::parseInputMedia, media)); + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } + if (replyToMessageId != 0) { + args.emplace_back("reply_to_message_id", replyToMessageId); + } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } + return _tgTypeParser.parseJsonAndGetArray(&TgTypeParser::parseJsonAndGetMessage, sendRequest("sendMediaGroup", args)); } -Message::Ptr Api::sendLocation(std::int64_t chatId, float latitude, float longitude, std::uint32_t livePeriod, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, bool disableNotification) const { +Message::Ptr Api::sendLocation(std::int64_t chatId, float latitude, float longitude, + float horizontalAccuracy, std::uint32_t livePeriod, std::uint32_t heading, + std::uint32_t proximityAlertRadius, bool disableNotification, std::int32_t replyToMessageId, + bool allowSendingWithoutReply, GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(7); + args.reserve(11); + args.emplace_back("chat_id", chatId); args.emplace_back("latitude", latitude); args.emplace_back("longitude", longitude); + if (horizontalAccuracy) { + args.emplace_back("horizontal_accuracy", horizontalAccuracy); + } if (livePeriod) { args.emplace_back("live_period", livePeriod); } + if (heading) { + args.emplace_back("heading", heading); + } + if (proximityAlertRadius) { + args.emplace_back("proximity_alert_radius", proximityAlertRadius); + } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendLocation", args)); } -Message::Ptr Api::editMessageLiveLocation(float latitude, float longitude, std::int64_t chatId, std::int32_t messageId, std::int32_t inlineMessageId, const InlineKeyboardMarkup::Ptr replyMarkup) const { +Message::Ptr Api::editMessageLiveLocation(float latitude, float longitude, std::int64_t chatId, + std::int32_t messageId, std::int32_t inlineMessageId, float horizontalAccuracy, + std::int32_t heading, std::int32_t proximityAlertRadius, InlineKeyboardMarkup::Ptr replyMarkup) const { vector args; - args.reserve(6); - args.emplace_back("latitude", latitude); - args.emplace_back("longitude", longitude); + args.reserve(9); + if (chatId) { args.emplace_back("chat_id", chatId); } @@ -443,9 +646,21 @@ Message::Ptr Api::editMessageLiveLocation(float latitude, float longitude, std:: if (inlineMessageId) { args.emplace_back("inline_message_id", inlineMessageId); } + args.emplace_back("latitude", latitude); + args.emplace_back("longitude", longitude); + if (horizontalAccuracy) { + args.emplace_back("horizontal_accuracy", horizontalAccuracy); + } + if (heading) { + args.emplace_back("heading", heading); + } + if (proximityAlertRadius) { + args.emplace_back("proximity_alert_radius", proximityAlertRadius); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseInlineKeyboardMarkup(replyMarkup)); } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("editMessageLiveLocation", args)); } @@ -467,9 +682,22 @@ Message::Ptr Api::stopMessageLiveLocation(std::int64_t chatId, std::int32_t mess return _tgTypeParser.parseJsonAndGetMessage(sendRequest("editMessageLiveLocation", args)); } -Message::Ptr Api::sendVenue(std::int64_t chatId, float latitude, float longitude, const string& title, const string& address, const string& foursquareId, const string& foursquareType, bool disableNotification, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup) const { +Message::Ptr Api::sendVenue(std::int64_t chatId, + float latitude, + float longitude, + const std::string& title, + const std::string& address, + const std::string& foursquareId, + const std::string& foursquareType, + const std::string& googlePlaceId, + const std::string& googlePlaceType, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(10); + args.reserve(13); + args.emplace_back("chat_id", chatId); args.emplace_back("latitude", latitude); args.emplace_back("longitude", longitude); @@ -481,21 +709,40 @@ Message::Ptr Api::sendVenue(std::int64_t chatId, float latitude, float longitude if (!foursquareType.empty()) { args.emplace_back("foursquare_type", foursquareType); } + if (!googlePlaceId.empty()) { + args.emplace_back("google_place_id", googlePlaceId); + } + if (!googlePlaceType.empty()) { + args.emplace_back("google_place_type", googlePlaceType); + } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVenue", args)); } -Message::Ptr Api::sendContact(std::int64_t chatId, const string& phoneNumber, const string& firstName, const string& lastName, const string& vcard, bool disableNotification, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup) const { +Message::Ptr Api::sendContact(std::int64_t chatId, + const std::string& phoneNumber, + const std::string& firstName, + const std::string& lastName, + const std::string& vcard, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(8); + args.reserve(9); + args.emplace_back("chat_id", chatId); args.emplace_back("phone_number", phoneNumber); args.emplace_back("first_name", firstName); @@ -505,25 +752,41 @@ Message::Ptr Api::sendContact(std::int64_t chatId, const string& phoneNumber, co if (!vcard.empty()) { args.emplace_back("vcard", vcard); } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendContact", args)); } -Message::Ptr Api::sendPoll(std::int64_t chatId, const std::string& question, const std::vector& options, - bool isAnonymous, const std::string& type, bool allowsMultipleAnswers, - std::int32_t correctOptionId, const std::string& explanation, const std::string& explanationParseMode, - std::int32_t openPeriod, std::int64_t closeDate, bool isClosed, - bool disableNotification, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup) const { - vector args; - args.reserve(15); +Message::Ptr Api::sendPoll(std::int64_t chatId, + const std::string& question, + const std::vector& options, + bool isAnonymous, + const std::string& type, + bool allowsMultipleAnswers, + std::int32_t correctOptionId, + const std::string& explanation, + const std::string& explanationParseMode, + const std::vector& explanationEntities, + std::int32_t openPeriod, + std::int32_t closeDate, + bool isClosed, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { + vector args; + args.reserve(17); args.emplace_back("chat_id", chatId); args.emplace_back("question", question); @@ -548,6 +811,9 @@ Message::Ptr Api::sendPoll(std::int64_t chatId, const std::string& question, con if (!explanationParseMode.empty()) { args.emplace_back("explanation_parse_mode", explanationParseMode); } + if (!explanationEntities.empty()) { + args.emplace_back("explanation_entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, explanationEntities)); + } if (openPeriod != 0) { args.emplace_back("open_period", openPeriod); } @@ -563,6 +829,9 @@ Message::Ptr Api::sendPoll(std::int64_t chatId, const std::string& question, con if (replyToMessageId != 0) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } @@ -570,21 +839,28 @@ Message::Ptr Api::sendPoll(std::int64_t chatId, const std::string& question, con return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendPoll", args)); } -Message::Ptr Api::sendDice(std::int64_t chatId, const std::string& emoji, bool disableNotification, - std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup) const { +Message::Ptr Api::sendDice(std::int64_t chatId, + const std::string& emoji, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(5); + args.reserve(6); args.emplace_back("chat_id", chatId); - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } if (!emoji.empty()) { args.emplace_back("emoji", emoji); } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId != 0) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } @@ -642,11 +918,14 @@ bool Api::kickChatMember(std::int64_t chatId, std::int64_t userId, std::uint64_t return sendRequest("kickChatMember", args).get("", false); } -bool Api::unbanChatMember(std::int64_t chatId, std::int64_t userId) const { +bool Api::unbanChatMember(std::int64_t chatId, std::int64_t userId, bool onlyIfBanned) const { vector args; - args.reserve(2); + args.reserve(3); + args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); + args.emplace_back("only_if_banned", onlyIfBanned); + return sendRequest("unbanChatMember", args).get("", false); } @@ -664,12 +943,18 @@ bool Api::restrictChatMember(std::int64_t chatId, std::int64_t userId, TgBot::Ch return sendRequest("restrictChatMember", args).get("", false); } -bool Api::promoteChatMember(std::int64_t chatId, std::int64_t userId, bool canChangeInfo, bool canPostMessages, - bool canEditMessages, bool canDeleteMessages, bool canInviteUsers, bool canPinMessages, bool canPromoteMembers) const { +bool Api::promoteChatMember(std::int64_t chatId, std::int64_t userId, bool isAnonymous, + bool canChangeInfo, bool canPostMessages, bool canEditMessages, + bool canDeleteMessages, bool canInviteUsers, bool canRestrictMembers, + bool canPinMessages, bool canPromoteMembers) const { vector args; - args.reserve(9); + args.reserve(11); + args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); + if (isAnonymous) { + args.emplace_back("is_anonymous", isAnonymous); + } if (canChangeInfo) { args.emplace_back("can_change_info", canChangeInfo); } @@ -685,12 +970,16 @@ bool Api::promoteChatMember(std::int64_t chatId, std::int64_t userId, bool canCh if (canInviteUsers) { args.emplace_back("can_invite_users", canInviteUsers); } + if (canRestrictMembers) { + args.emplace_back("can_restrict_members", canRestrictMembers); + } if (canPinMessages) { args.emplace_back("can_pin_messages", canPinMessages); } if (canPromoteMembers) { args.emplace_back("can_promote_members", canPromoteMembers); } + return sendRequest("promoteChatMember", args).get("", false); } @@ -762,13 +1051,25 @@ bool Api::pinChatMessage(std::int64_t chatId, std::int32_t messageId, bool disab return sendRequest("pinChatMessage", args).get("", false); } -bool Api::unpinChatMessage(std::int64_t chatId) const { +bool Api::unpinChatMessage(std::int64_t chatId, std::int32_t messageId) const { vector args; - args.reserve(1); + args.reserve(2); + args.emplace_back("chat_id", chatId); + args.emplace_back("message_id", messageId); + return sendRequest("unpinChatMessage", args).get("", false); } +bool Api::unpinAllChatMessages(std::int64_t chatId) const { + vector args; + args.reserve(1); + + args.emplace_back("chat_id", chatId); + + return sendRequest("unpinAllChatMessages", args).get("", false); +} + bool Api::leaveChat(std::int64_t chatId) const { vector args; args.reserve(1); @@ -779,7 +1080,9 @@ bool Api::leaveChat(std::int64_t chatId) const { Chat::Ptr Api::getChat(std::int64_t chatId) const { vector args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return _tgTypeParser.parseJsonAndGetChat(sendRequest("getChat", args)); } @@ -853,12 +1156,17 @@ std::vector Api::getMyCommands() const { return _tgTypeParser.parseJsonAndGetArray(&TgTypeParser::parseJsonAndGetBotCommand, sendRequest("getMyCommands")); } -Message::Ptr Api::editMessageText(const string& text, std::int64_t chatId, std::int32_t messageId, const string& inlineMessageId, - const string& parseMode, bool disableWebPagePreview, const GenericReply::Ptr replyMarkup) const { - +Message::Ptr Api::editMessageText(const std::string& text, + std::int64_t chatId, + std::int32_t messageId, + const std::string& inlineMessageId, + const std::string& parseMode, + const std::vector& entities, + bool disableWebPagePreview, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(7); - args.emplace_back("text", text); + args.reserve(8); + if (chatId) { args.emplace_back("chat_id", chatId); } @@ -868,15 +1176,20 @@ Message::Ptr Api::editMessageText(const string& text, std::int64_t chatId, std:: if (!inlineMessageId.empty()) { args.emplace_back("inline_message_id", inlineMessageId); } + args.emplace_back("text", text); if (!parseMode.empty()) { args.emplace_back("parse_mode", parseMode); } + if (!entities.empty()) { + args.emplace_back("entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, entities)); + } if (disableWebPagePreview) { args.emplace_back("disable_web_page_preview", disableWebPagePreview); } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } + ptree p = sendRequest("editMessageText", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); @@ -885,25 +1198,38 @@ Message::Ptr Api::editMessageText(const string& text, std::int64_t chatId, std:: } } -Message::Ptr Api::editMessageCaption(std::int64_t chatId, std::int32_t messageId, const string& caption, - const string& inlineMessageId, const GenericReply::Ptr replyMarkup) const { +Message::Ptr Api::editMessageCaption(std::int64_t chatId, + std::int32_t messageId, + const std::string& inlineMessageId, + const std::string& caption, + const std::string& parseMode, + const std::vector& captionEntities, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(5); + args.reserve(7); + if (chatId) { args.emplace_back("chat_id", chatId); } if (messageId) { args.emplace_back("message_id", messageId); } + if (!inlineMessageId.empty()) { + args.emplace_back("inline_message_id", inlineMessageId); + } if (!caption.empty()) { args.emplace_back("caption", caption); } - if (!inlineMessageId.empty()) { - args.emplace_back("inline_message_id", inlineMessageId); + if (!parseMode.empty()) { + args.emplace_back("parse_mode", parseMode); + } + if (!captionEntities.empty()) { + args.emplace_back("caption_entities", _tgTypeParser.parseArray(&TgTypeParser::parseMessageEntity, captionEntities)); } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } + ptree p = sendRequest("editMessageCaption", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); @@ -978,9 +1304,15 @@ void Api::deleteMessage(std::int64_t chatId, std::int32_t messageId) const { sendRequest("deleteMessage", { HttpReqArg("chat_id", chatId), HttpReqArg("message_id", messageId) }); } -Message::Ptr Api::sendSticker(std::int64_t chatId, boost::variant sticker, std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, bool disableNotification) const { +Message::Ptr Api::sendSticker(std::int64_t chatId, + boost::variant sticker, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { vector args; - args.reserve(5); + args.reserve(6); + args.emplace_back("chat_id", chatId); if (sticker.which() == 0 /* InputFile::Ptr */) { auto file = boost::get(sticker); @@ -988,15 +1320,19 @@ Message::Ptr Api::sendSticker(std::int64_t chatId, boost::variant(sticker)); } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendSticker", args)); } @@ -1130,15 +1466,33 @@ bool Api::answerInlineQuery(const string& inlineQueryId, const std::vector("", false); } -Message::Ptr Api::sendInvoice(std::int64_t chatId, const std::string& title, const std::string& description, const std::string& payload, - const std::string& providerToken, const std::string& startParameter, const std::string& currency, const std::vector& prices, - const std::string& providerData, const std::string& photoUrl, std::int32_t photoSize, - std::int32_t photoWidth, std::int32_t photoHeight, bool needName, - bool needPhoneNumber, bool needEmail, bool needShippingAddress, - bool sendPhoneNumberToProvider, bool sendEmailToProvider, bool isFlexible, - std::int32_t replyToMessageId, const GenericReply::Ptr replyMarkup, bool disableNotification) const { - vector args; - args.reserve(23); +Message::Ptr Api::sendInvoice(std::int64_t chatId, + const std::string& title, + const std::string& description, + const std::string& payload, + const std::string& providerToken, + const std::string& startParameter, + const std::string& currency, + const std::vector& prices, + const std::string& providerData, + const std::string& photoUrl, + std::int32_t photoSize, + std::int32_t photoWidth, + std::int32_t photoHeight, + bool needName, + bool needPhoneNumber, + bool needEmail, + bool needShippingAddress, + bool sendPhoneNumberToProvider, + bool sendEmailToProvider, + bool isFlexible, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + GenericReply::Ptr replyMarkup) const { + vector args; + args.reserve(24); + args.emplace_back("chat_id", chatId); args.emplace_back("title", title); args.emplace_back("description", description); @@ -1183,15 +1537,19 @@ Message::Ptr Api::sendInvoice(std::int64_t chatId, const std::string& title, con if (isFlexible) { args.emplace_back("is_flexible", isFlexible); } + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendInvoice", args)); } @@ -1230,20 +1588,30 @@ bool Api::setPassportDataErrors(std::int64_t userId, const std::vector("", false); } -Message::Ptr Api::sendGame(std::int64_t chatId, const std::string& gameShortName, std::int32_t replyToMessageId, const InlineKeyboardMarkup::Ptr replyMarkup, bool disableNotification) const { +Message::Ptr Api::sendGame(std::int64_t chatId, + const std::string& gameShortName, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + InlineKeyboardMarkup::Ptr replyMarkup) const { vector args; - args.reserve(5); + args.reserve(6); + args.emplace_back("chat_id", chatId); args.emplace_back("game_short_name", gameShortName); + if (disableNotification) { + args.emplace_back("disable_notification", disableNotification); + } if (replyToMessageId) { args.emplace_back("reply_to_message_id", replyToMessageId); } + if (allowSendingWithoutReply) { + args.emplace_back("allow_sending_without_reply", allowSendingWithoutReply); + } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - if (disableNotification) { - args.emplace_back("disable_notification", disableNotification); - } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendGame", args)); } diff --git a/src/TgTypeParser.cpp b/src/TgTypeParser.cpp index 89cdd4c..60a2c54 100644 --- a/src/TgTypeParser.cpp +++ b/src/TgTypeParser.cpp @@ -3,15 +3,12 @@ #include #include -using namespace std; -using namespace boost::property_tree; - namespace TgBot { -Chat::Ptr TgTypeParser::parseJsonAndGetChat(const ptree& data) const { - auto result(make_shared()); - result->id = data.get("id", 0); - string type = data.get("type", ""); +Chat::Ptr TgTypeParser::parseJsonAndGetChat(const boost::property_tree::ptree& data) const { + auto result(std::make_shared()); + result->id = data.get("id", 0); + std::string type = data.get("type", ""); if (type == "private") { result->type = Chat::Type::Private; } else if (type == "group") { @@ -21,26 +18,29 @@ Chat::Ptr TgTypeParser::parseJsonAndGetChat(const ptree& data) const { } else if (type == "channel") { result->type = Chat::Type::Channel; } - result->title = data.get("title", ""); - result->username = data.get("username", ""); - result->firstName = data.get("first_name", ""); - result->lastName = data.get("last_name", ""); + result->title = data.get("title", ""); + result->username = data.get("username", ""); + result->firstName = data.get("first_name", ""); + result->lastName = data.get("last_name", ""); result->photo = tryParseJson(&TgTypeParser::parseJsonAndGetChatPhoto, data, "photo"); - result->description = data.get("description", ""); - result->inviteLink = data.get("invite_link", ""); + result->bio = data.get("bio", ""); + result->description = data.get("description", ""); + result->inviteLink = data.get("invite_link", ""); result->pinnedMessage = tryParseJson(&TgTypeParser::parseJsonAndGetMessage, data, "pinned_message"); result->permissions = tryParseJson(&TgTypeParser::parseJsonAndGetChatPermissions, data, "permissions"); - result->slowModeDelay = data.get("slow_mode_delay", 0); - result->stickerSetName = data.get("sticker_set_name", ""); + result->slowModeDelay = data.get("slow_mode_delay", 0); + result->stickerSetName = data.get("sticker_set_name", ""); result->canSetStickerSet = data.get("can_set_sticker_set", false); + result->linkedChatId = data.get("linked_chat_id", 0); + result->location = tryParseJson(&TgTypeParser::parseJsonAndGetChatLocation, data, "location"); return result; } -string TgTypeParser::parseChat(const Chat::Ptr& object) const { +std::string TgTypeParser::parseChat(const Chat::Ptr& object) const { if (!object) { return ""; } - string result; + std::string result; result += '{'; appendToJson(result, "id", object->id); if (object->type == Chat::Type::Private) { @@ -57,6 +57,7 @@ string TgTypeParser::parseChat(const Chat::Ptr& object) const { appendToJson(result, "first_name", object->firstName); appendToJson(result, "last_name", object->lastName); appendToJson(result, "photo", parseChatPhoto(object->photo)); + appendToJson(result, "bio", object->bio); appendToJson(result, "description", object->description); appendToJson(result, "invite_link", object->inviteLink); appendToJson(result, "pinned_message", parseMessage(object->pinnedMessage)); @@ -64,30 +65,32 @@ string TgTypeParser::parseChat(const Chat::Ptr& object) const { appendToJson(result, "slow_mode_delay", object->slowModeDelay); appendToJson(result, "sticker_set_name", object->stickerSetName); appendToJson(result, "can_set_sticker_set", object->canSetStickerSet); + appendToJson(result, "linked_chat_id", object->linkedChatId); + appendToJson(result, "location", parseChatLocation(object->location)); removeLastComma(result); result += '}'; return result; } -User::Ptr TgTypeParser::parseJsonAndGetUser(const ptree& data) const { - auto result(make_shared()); - result->id = data.get("id", 0); +User::Ptr TgTypeParser::parseJsonAndGetUser(const boost::property_tree::ptree& data) const { + auto result(std::make_shared()); + result->id = data.get("id", 0); result->isBot = data.get("is_bot", false); - result->firstName = data.get("first_name", ""); - result->lastName = data.get("last_name", ""); - result->username = data.get("username", ""); - result->languageCode = data.get("language_code", ""); + result->firstName = data.get("first_name", ""); + result->lastName = data.get("last_name", ""); + result->username = data.get("username", ""); + result->languageCode = data.get("language_code", ""); result->canJoinGroups = data.get("can_join_groups", false); result->canReadAllGroupMessages = data.get("can_read_all_group_messages", false); result->supportsInlineQueries = data.get("supports_inline_queries", false); return result; } -string TgTypeParser::parseUser(const User::Ptr& object) const { +std::string TgTypeParser::parseUser(const User::Ptr& object) const { if (!object) { return ""; } - string result; + std::string result; result += '{'; appendToJson(result, "id", object->id); appendToJson(result, "is_bot", object->isBot); @@ -103,22 +106,22 @@ string TgTypeParser::parseUser(const User::Ptr& object) const { return result; } -MessageEntity::Ptr TgTypeParser::parseJsonAndGetMessageEntity(const ptree& data) const{ - auto result(make_shared()); - result->type = data.get("type", ""); - result->offset = data.get("offset", 0); - result->length = data.get("length", 0); - result->url = data.get("url", ""); +MessageEntity::Ptr TgTypeParser::parseJsonAndGetMessageEntity(const boost::property_tree::ptree& data) const{ + auto result(std::make_shared()); + result->type = data.get("type", ""); + result->offset = data.get("offset", 0); + result->length = data.get("length", 0); + result->url = data.get("url", ""); result->user = tryParseJson(&TgTypeParser::parseJsonAndGetUser, data, "user"); - result->language = data.get("language", ""); + result->language = data.get("language", ""); return result; } -string TgTypeParser::parseMessageEntity(const MessageEntity::Ptr& object) const { +std::string TgTypeParser::parseMessageEntity(const MessageEntity::Ptr& object) const { if (!object) { return ""; } - string result; + std::string result; result += '{'; appendToJson(result, "type", object->type); appendToJson(result, "offset", object->offset); @@ -131,69 +134,73 @@ string TgTypeParser::parseMessageEntity(const MessageEntity::Ptr& object) const return result; } -Message::Ptr TgTypeParser::parseJsonAndGetMessage(const ptree& data) const { - auto result(make_shared()); - result->messageId = data.get("message_id", 0); +Message::Ptr TgTypeParser::parseJsonAndGetMessage(const boost::property_tree::ptree& data) const { + auto result(std::make_shared()); + result->messageId = data.get("message_id", 0); result->from = tryParseJson(&TgTypeParser::parseJsonAndGetUser, data, "from"); - result->date = data.get("date", 0); + result->senderChat = tryParseJson(&TgTypeParser::parseJsonAndGetChat, data, "sender_chat"); + result->date = data.get("date", 0); result->chat = parseJsonAndGetChat(data.find("chat")->second); result->forwardFrom = tryParseJson(&TgTypeParser::parseJsonAndGetUser, data, "forward_from"); result->forwardFromChat = tryParseJson(&TgTypeParser::parseJsonAndGetChat, data, "forward_from_chat"); - result->forwardFromMessageId = data.get("forward_from_message_id", 0); - result->forwardSignature = data.get("forward_signature", ""); - result->forwardSenderName = data.get("forward_sender_name", ""); - result->forwardDate = data.get("forward_date", 0); + result->forwardFromMessageId = data.get("forward_from_message_id", 0); + result->forwardSignature = data.get("forward_signature", ""); + result->forwardSenderName = data.get("forward_sender_name", ""); + result->forwardDate = data.get("forward_date", 0); result->replyToMessage = tryParseJson(&TgTypeParser::parseJsonAndGetMessage, data, "reply_to_message"); result->viaBot = tryParseJson(&TgTypeParser::parseJsonAndGetUser, data, "via_bot"); - result->editDate = data.get("edit_date", 0); - result->mediaGroupId = data.get("media_group_id", ""); - result->authorSignature = data.get("author_signature", ""); - result->text = data.get("text", ""); + result->editDate = data.get("edit_date", 0); + result->mediaGroupId = data.get("media_group_id", ""); + result->authorSignature = data.get("author_signature", ""); + result->text = data.get("text", ""); result->entities = parseJsonAndGetArray(&TgTypeParser::parseJsonAndGetMessageEntity, data, "entities"); - result->captionEntities = parseJsonAndGetArray(&TgTypeParser::parseJsonAndGetMessageEntity, data, "caption_entities"); + result->animation = tryParseJson(&TgTypeParser::parseJsonAndGetAnimation, data, "animation"); result->audio = tryParseJson