diff options
Diffstat (limited to 'src/Api.cpp')
-rw-r--r-- | src/Api.cpp | 717 |
1 files changed, 429 insertions, 288 deletions
diff --git a/src/Api.cpp b/src/Api.cpp index 4107a4e..9eefc09 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -1,53 +1,46 @@ #include "tgbot/Api.h" -#include "tgbot/tools/StringTools.h" - -#include "tgbot/TgException.h" -#include "tgbot/TgTypeParser.h" - -#include <cstdint> -#include <string> -#include <vector> -#include <utility> - -using namespace std; -using namespace boost::property_tree; - namespace TgBot { -Api::Api(string token, const HttpClient& httpClient, const std::string& url) +Api::Api(std::string token, const HttpClient& httpClient, const std::string& url) : _token(std::move(token)), _httpClient(httpClient), _tgTypeParser(), _url(url) { } -vector<Update::Ptr> Api::getUpdates(std::int32_t offset, std::int32_t limit, std::int32_t timeout, const StringArrayPtr& allowedUpdates) const { - vector<HttpReqArg> args; +std::vector<Update::Ptr> Api::getUpdates(std::int32_t offset, + std::int32_t limit, + std::int32_t timeout, + const StringArrayPtr& allowedUpdates) const { + std::vector<HttpReqArg> args; args.reserve(4); - if (offset) { + + if (offset != 0) { args.emplace_back("offset", offset); } - limit = max(1, min(100, limit)); - args.emplace_back("limit", limit); - if (timeout) { + if (limit != 100) { + args.emplace_back("limit", std::max(1, std::min(100, limit))); + } + if (timeout != 0) { args.emplace_back("timeout", timeout); } if (allowedUpdates != nullptr) { - string allowedUpdatesJson = _tgTypeParser.parseArray<string>( - [] (const string& s)->string { + std::string allowedUpdatesJson = _tgTypeParser.parseArray<std::string>( + [] (const std::string& s)->std::string { return s; }, *allowedUpdates); args.emplace_back("allowed_updates", allowedUpdatesJson); } + return _tgTypeParser.parseJsonAndGetArray<Update>(&TgTypeParser::parseJsonAndGetUpdate, sendRequest("getUpdates", args)); } bool Api::setWebhook(const std::string& url, InputFile::Ptr certificate, - std::int32_t maxConnection, + std::int32_t maxConnections, const StringArrayPtr& allowedUpdates, const std::string& ipAddress, bool dropPendingUpdates, const std::string& secretToken) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); args.emplace_back("url", url); @@ -57,12 +50,12 @@ bool Api::setWebhook(const std::string& url, if (!ipAddress.empty()) { args.emplace_back("ip_address", ipAddress); } - if (maxConnection != 40) { - args.emplace_back("max_connections", maxConnection); + if (maxConnections != 40) { + args.emplace_back("max_connections", std::max(1, std::min(100, maxConnections))); } if (allowedUpdates != nullptr) { - auto allowedUpdatesJson = _tgTypeParser.parseArray<string>( - [] (const string& s)->string { + auto allowedUpdatesJson = _tgTypeParser.parseArray<std::string>( + [] (const std::string& s)->std::string { return s; }, *allowedUpdates); args.emplace_back("allowed_updates", allowedUpdatesJson); @@ -78,7 +71,7 @@ bool Api::setWebhook(const std::string& url, } bool Api::deleteWebhook(bool dropPendingUpdates) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(1); if (dropPendingUpdates) { @@ -89,12 +82,13 @@ bool Api::deleteWebhook(bool dropPendingUpdates) const { } WebhookInfo::Ptr Api::getWebhookInfo() const { - ptree p = sendRequest("getWebhookInfo"); + boost::property_tree::ptree p = sendRequest("getWebhookInfo"); if (!p.get_child_optional("url")) { return nullptr; } - if (p.get<string>("url", "") != string("")) { + + if (p.get<std::string>("url", "") != std::string("")) { return _tgTypeParser.parseJsonAndGetWebhookInfo(p); } else { return nullptr; @@ -105,7 +99,15 @@ User::Ptr Api::getMe() const { return _tgTypeParser.parseJsonAndGetUser(sendRequest("getMe")); } -Message::Ptr Api::sendMessage(boost::variant<std::int64_t, const std::string&> chatId, +bool Api::logOut() const { + return sendRequest("logOut").get<bool>("", false); +} + +bool Api::close() const { + return sendRequest("close").get<bool>("", false); +} + +Message::Ptr Api::sendMessage(boost::variant<std::int64_t, std::string> chatId, const std::string& text, bool disableWebPagePreview, std::int32_t replyToMessageId, @@ -115,7 +117,7 @@ Message::Ptr Api::sendMessage(boost::variant<std::int64_t, const std::string&> c const std::vector<MessageEntity::Ptr>& entities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(10); args.emplace_back("chat_id", chatId); @@ -135,7 +137,7 @@ Message::Ptr Api::sendMessage(boost::variant<std::int64_t, const std::string&> c if (protectContent) { args.emplace_back("protect_content", protectContent); } - if (replyToMessageId) { + if (replyToMessageId != 0) { args.emplace_back("reply_to_message_id", replyToMessageId); } if (allowSendingWithoutReply) { @@ -148,12 +150,12 @@ Message::Ptr Api::sendMessage(boost::variant<std::int64_t, const std::string&> c return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendMessage", args)); } -Message::Ptr Api::forwardMessage(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<std::int64_t, const std::string&> fromChatId, +Message::Ptr Api::forwardMessage(boost::variant<std::int64_t, std::string> chatId, + boost::variant<std::int64_t, std::string> fromChatId, std::int32_t messageId, bool disableNotification, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(5); args.emplace_back("chat_id", chatId); @@ -169,8 +171,8 @@ Message::Ptr Api::forwardMessage(boost::variant<std::int64_t, const std::string& return _tgTypeParser.parseJsonAndGetMessage(sendRequest("forwardMessage", args)); } -MessageId::Ptr Api::copyMessage(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<std::int64_t, const std::string&> fromChatId, +MessageId::Ptr Api::copyMessage(boost::variant<std::int64_t, std::string> chatId, + boost::variant<std::int64_t, std::string> fromChatId, std::int32_t messageId, const std::string& caption, const std::string& parseMode, @@ -180,7 +182,7 @@ MessageId::Ptr Api::copyMessage(boost::variant<std::int64_t, const std::string&> bool allowSendingWithoutReply, GenericReply::Ptr replyMarkup, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(11); args.emplace_back("chat_id", chatId); @@ -214,8 +216,8 @@ MessageId::Ptr Api::copyMessage(boost::variant<std::int64_t, const std::string&> return _tgTypeParser.parseJsonAndGetMessageId(sendRequest("copyMessage", args)); } -Message::Ptr Api::sendPhoto(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> photo, +Message::Ptr Api::sendPhoto(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> photo, const std::string& caption, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, @@ -224,15 +226,15 @@ Message::Ptr Api::sendPhoto(boost::variant<std::int64_t, const std::string&> cha const std::vector<MessageEntity::Ptr>& captionEntities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(10); args.emplace_back("chat_id", chatId); if (photo.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(photo); args.emplace_back("photo", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("photo", boost::get<const std::string&>(photo)); + } else { // std::string + args.emplace_back("photo", boost::get<std::string>(photo)); } if (!caption.empty()) { args.emplace_back("caption", caption); @@ -262,13 +264,13 @@ Message::Ptr Api::sendPhoto(boost::variant<std::int64_t, const std::string&> cha return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendPhoto", args)); } -Message::Ptr Api::sendAudio(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> audio, +Message::Ptr Api::sendAudio(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> audio, const std::string& caption, std::int32_t duration, const std::string& performer, const std::string& title, - boost::variant<InputFile::Ptr, const std::string&> thumb, + boost::variant<InputFile::Ptr, std::string> thumb, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, const std::string& parseMode, @@ -276,15 +278,15 @@ Message::Ptr Api::sendAudio(boost::variant<std::int64_t, const std::string&> cha const std::vector<MessageEntity::Ptr>& captionEntities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(14); args.emplace_back("chat_id", chatId); if (audio.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(audio); args.emplace_back("audio", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("audio", boost::get<const std::string&>(audio)); + } else { // std::string + args.emplace_back("audio", boost::get<std::string>(audio)); } if (!caption.empty()) { args.emplace_back("caption", caption); @@ -307,8 +309,8 @@ Message::Ptr Api::sendAudio(boost::variant<std::int64_t, const std::string&> cha if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - auto thumbStr = boost::get<const std::string&>(thumb); + } else { // std::string + auto thumbStr = boost::get<std::string>(thumb); if (!thumbStr.empty()) { args.emplace_back("thumb", thumbStr); } @@ -332,9 +334,9 @@ Message::Ptr Api::sendAudio(boost::variant<std::int64_t, const std::string&> cha return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendAudio", args)); } -Message::Ptr Api::sendDocument(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> document, - boost::variant<InputFile::Ptr, const std::string&> thumb, +Message::Ptr Api::sendDocument(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> document, + boost::variant<InputFile::Ptr, std::string> thumb, const std::string& caption, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, @@ -344,21 +346,21 @@ Message::Ptr Api::sendDocument(boost::variant<std::int64_t, const std::string&> bool disableContentTypeDetection, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(12); args.emplace_back("chat_id", chatId); if (document.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(document); args.emplace_back("document", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("document", boost::get<const std::string&>(document)); + } else { // std::string + args.emplace_back("document", boost::get<std::string>(document)); } if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - auto thumbStr = boost::get<const std::string&>(thumb); + } else { // std::string + auto thumbStr = boost::get<std::string>(thumb); if (!thumbStr.empty()) { args.emplace_back("thumb", thumbStr); } @@ -394,13 +396,13 @@ Message::Ptr Api::sendDocument(boost::variant<std::int64_t, const std::string&> return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendDocument", args)); } -Message::Ptr Api::sendVideo(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> video, +Message::Ptr Api::sendVideo(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> video, bool supportsStreaming, std::int32_t duration, std::int32_t width, std::int32_t height, - boost::variant<InputFile::Ptr, const std::string&> thumb, + boost::variant<InputFile::Ptr, std::string> thumb, const std::string& caption , std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, @@ -409,15 +411,15 @@ Message::Ptr Api::sendVideo(boost::variant<std::int64_t, const std::string&> cha const std::vector<MessageEntity::Ptr>& captionEntities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(15); args.emplace_back("chat_id", chatId); if (video.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(video); args.emplace_back("video", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("video", boost::get<const std::string&>(video)); + } else { // std::string + args.emplace_back("video", boost::get<std::string>(video)); } if (duration) { args.emplace_back("duration", duration); @@ -431,8 +433,8 @@ Message::Ptr Api::sendVideo(boost::variant<std::int64_t, const std::string&> cha if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - auto thumbStr = boost::get<const std::string&>(thumb); + } else { // std::string + auto thumbStr = boost::get<std::string>(thumb); if (!thumbStr.empty()) { args.emplace_back("thumb", thumbStr); } @@ -468,12 +470,12 @@ Message::Ptr Api::sendVideo(boost::variant<std::int64_t, const std::string&> cha return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVideo", args)); } -Message::Ptr Api::sendAnimation(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> animation, +Message::Ptr Api::sendAnimation(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> animation, std::int32_t duration, std::int32_t width, std::int32_t height, - boost::variant<InputFile::Ptr, const std::string&> thumb, + boost::variant<InputFile::Ptr, std::string> thumb, const std::string& caption, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, @@ -482,15 +484,15 @@ Message::Ptr Api::sendAnimation(boost::variant<std::int64_t, const std::string&> const std::vector<MessageEntity::Ptr>& captionEntities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(14); args.emplace_back("chat_id", chatId); if (animation.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(animation); args.emplace_back("animation", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("animation", boost::get<const std::string&>(animation)); + } else { // std::string + args.emplace_back("animation", boost::get<std::string>(animation)); } if (duration) { args.emplace_back("duration", duration); @@ -504,8 +506,8 @@ Message::Ptr Api::sendAnimation(boost::variant<std::int64_t, const std::string&> if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - auto thumbStr = boost::get<const std::string&>(thumb); + } else { // std::string + auto thumbStr = boost::get<std::string>(thumb); if (!thumbStr.empty()) { args.emplace_back("thumb", thumbStr); } @@ -538,8 +540,8 @@ Message::Ptr Api::sendAnimation(boost::variant<std::int64_t, const std::string&> return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendAnimation", args)); } -Message::Ptr Api::sendVoice(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> voice, +Message::Ptr Api::sendVoice(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> voice, const std::string& caption, std::int32_t duration, std::int32_t replyToMessageId, @@ -549,15 +551,15 @@ Message::Ptr Api::sendVoice(boost::variant<std::int64_t, const std::string&> cha const std::vector<MessageEntity::Ptr>& captionEntities, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(11); args.emplace_back("chat_id", chatId); if (voice.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(voice); args.emplace_back("voice", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("voice", boost::get<const std::string&>(voice)); + } else { // std::string + args.emplace_back("voice", boost::get<std::string>(voice)); } if (!caption.empty()) { args.emplace_back("caption", caption); @@ -590,25 +592,25 @@ Message::Ptr Api::sendVoice(boost::variant<std::int64_t, const std::string&> cha return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVoice", args)); } -Message::Ptr Api::sendVideoNote(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> videoNote, +Message::Ptr Api::sendVideoNote(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> videoNote, std::int64_t replyToMessageId, bool disableNotification, std::int32_t duration, std::int32_t length, - boost::variant<InputFile::Ptr, const std::string&> thumb, + boost::variant<InputFile::Ptr, std::string> thumb, GenericReply::Ptr replyMarkup, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(10); args.emplace_back("chat_id", chatId); if (videoNote.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(videoNote); args.emplace_back("video_note", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("video_note", boost::get<const std::string&>(videoNote)); + } else { // std::string + args.emplace_back("video_note", boost::get<std::string>(videoNote)); } if (duration) { args.emplace_back("duration", duration); @@ -619,8 +621,8 @@ Message::Ptr Api::sendVideoNote(boost::variant<std::int64_t, const std::string&> if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - auto thumbStr = boost::get<const std::string&>(thumb); + } else { // std::string + auto thumbStr = boost::get<std::string>(thumb); if (!thumbStr.empty()) { args.emplace_back("thumb", thumbStr); } @@ -644,13 +646,13 @@ Message::Ptr Api::sendVideoNote(boost::variant<std::int64_t, const std::string&> return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVideoNote", args)); } -vector<Message::Ptr> Api::sendMediaGroup(boost::variant<std::int64_t, const std::string&> chatId, - const std::vector<InputMedia::Ptr>& media, - bool disableNotification, - std::int32_t replyToMessageId, - bool allowSendingWithoutReply, - bool protectContent) const { - vector<HttpReqArg> args; +std::vector<Message::Ptr> Api::sendMediaGroup(boost::variant<std::int64_t, std::string> chatId, + const std::vector<InputMedia::Ptr>& media, + bool disableNotification, + std::int32_t replyToMessageId, + bool allowSendingWithoutReply, + bool protectContent) const { + std::vector<HttpReqArg> args; args.reserve(6); args.emplace_back("chat_id", chatId); @@ -671,7 +673,7 @@ vector<Message::Ptr> Api::sendMediaGroup(boost::variant<std::int64_t, const std: return _tgTypeParser.parseJsonAndGetArray<Message>(&TgTypeParser::parseJsonAndGetMessage, sendRequest("sendMediaGroup", args)); } -Message::Ptr Api::sendLocation(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendLocation(boost::variant<std::int64_t, std::string> chatId, float latitude, float longitude, std::int32_t livePeriod, @@ -683,7 +685,7 @@ Message::Ptr Api::sendLocation(boost::variant<std::int64_t, const std::string&> std::int32_t proximityAlertRadius, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(12); args.emplace_back("chat_id", chatId); @@ -693,13 +695,13 @@ Message::Ptr Api::sendLocation(boost::variant<std::int64_t, const std::string&> args.emplace_back("horizontal_accuracy", horizontalAccuracy); } if (livePeriod) { - args.emplace_back("live_period", livePeriod); + args.emplace_back("live_period", std::max(60, std::min(86400, livePeriod))); } if (heading) { - args.emplace_back("heading", heading); + args.emplace_back("heading", std::max(1, std::min(360, heading))); } if (proximityAlertRadius) { - args.emplace_back("proximity_alert_radius", proximityAlertRadius); + args.emplace_back("proximity_alert_radius", std::max(1, std::min(100000, proximityAlertRadius))); } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); @@ -722,23 +724,23 @@ Message::Ptr Api::sendLocation(boost::variant<std::int64_t, const std::string&> Message::Ptr Api::editMessageLiveLocation(float latitude, float longitude, - std::int64_t chatId, + boost::variant<std::int64_t, std::string> chatId, std::int32_t messageId, - std::int32_t inlineMessageId, + const std::string& inlineMessageId, InlineKeyboardMarkup::Ptr replyMarkup, float horizontalAccuracy, std::int32_t heading, std::int32_t proximityAlertRadius) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(9); - if (chatId) { + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { args.emplace_back("message_id", messageId); } - if (inlineMessageId) { + if (!inlineMessageId.empty()) { args.emplace_back("inline_message_id", inlineMessageId); } args.emplace_back("latitude", latitude); @@ -759,25 +761,30 @@ Message::Ptr Api::editMessageLiveLocation(float latitude, return _tgTypeParser.parseJsonAndGetMessage(sendRequest("editMessageLiveLocation", args)); } -Message::Ptr Api::stopMessageLiveLocation(std::int64_t chatId, std::int32_t messageId, std::int32_t inlineMessageId, const InlineKeyboardMarkup::Ptr replyMarkup) const { - vector<HttpReqArg> args; +Message::Ptr Api::stopMessageLiveLocation(boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId, + const std::string& inlineMessageId, + InlineKeyboardMarkup::Ptr replyMarkup) const { + std::vector<HttpReqArg> args; args.reserve(4); - if (chatId) { + + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { args.emplace_back("message_id", messageId); } - if (inlineMessageId) { + if (!inlineMessageId.empty()) { args.emplace_back("inline_message_id", inlineMessageId); } if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseInlineKeyboardMarkup(replyMarkup)); } - return _tgTypeParser.parseJsonAndGetMessage(sendRequest("editMessageLiveLocation", args)); + + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("stopMessageLiveLocation", args)); } -Message::Ptr Api::sendVenue(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendVenue(boost::variant<std::int64_t, std::string> chatId, float latitude, float longitude, const std::string& title, @@ -791,7 +798,7 @@ Message::Ptr Api::sendVenue(boost::variant<std::int64_t, const std::string&> cha const std::string& googlePlaceType, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(14); args.emplace_back("chat_id", chatId); @@ -830,7 +837,7 @@ Message::Ptr Api::sendVenue(boost::variant<std::int64_t, const std::string&> cha return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendVenue", args)); } -Message::Ptr Api::sendContact(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendContact(boost::variant<std::int64_t, std::string> chatId, const std::string& phoneNumber, const std::string& firstName, const std::string& lastName , @@ -840,7 +847,7 @@ Message::Ptr Api::sendContact(boost::variant<std::int64_t, const std::string&> c GenericReply::Ptr replyMarkup, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(10); args.emplace_back("chat_id", chatId); @@ -871,7 +878,7 @@ Message::Ptr Api::sendContact(boost::variant<std::int64_t, const std::string&> c return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendContact", args)); } -Message::Ptr Api::sendPoll(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendPoll(boost::variant<std::int64_t, std::string> chatId, const std::string& question, const std::vector<std::string>& options, bool disableNotification, @@ -889,13 +896,14 @@ Message::Ptr Api::sendPoll(boost::variant<std::int64_t, const std::string&> chat bool isClosed, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(18); args.emplace_back("chat_id", chatId); args.emplace_back("question", question); - args.emplace_back("options", _tgTypeParser.parseArray<std::string>([] (const std::string& option) -> std::string { - return "\"" + StringTools::urlEncode(option) + "\""; + args.emplace_back("options", _tgTypeParser.parseArray<std::string>( + [](const std::string& option)->std::string { + return "\"" + StringTools::escapeJsonString(option) + "\""; }, options)); if (!isAnonymous) { args.emplace_back("is_anonymous", isAnonymous); @@ -906,7 +914,7 @@ Message::Ptr Api::sendPoll(boost::variant<std::int64_t, const std::string&> chat if (allowsMultipleAnswers) { args.emplace_back("allows_multiple_answers", allowsMultipleAnswers); } - if (correctOptionId != 0) { + if (correctOptionId != -1) { args.emplace_back("correct_option_id", correctOptionId); } if (!explanation.empty()) { @@ -946,14 +954,14 @@ Message::Ptr Api::sendPoll(boost::variant<std::int64_t, const std::string&> chat return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendPoll", args)); } -Message::Ptr Api::sendDice(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendDice(boost::variant<std::int64_t, std::string> chatId, bool disableNotification, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, const std::string& emoji, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); args.emplace_back("chat_id", chatId); @@ -981,7 +989,7 @@ Message::Ptr Api::sendDice(boost::variant<std::int64_t, const std::string&> chat bool Api::sendChatAction(std::int64_t chatId, const std::string& action) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -990,67 +998,73 @@ bool Api::sendChatAction(std::int64_t chatId, return sendRequest("sendChatAction", args).get<bool>("", false); } -UserProfilePhotos::Ptr Api::getUserProfilePhotos(std::int64_t userId, std::int32_t offset, std::int32_t limit) const { - vector<HttpReqArg> args; +UserProfilePhotos::Ptr Api::getUserProfilePhotos(std::int64_t userId, + std::int32_t offset, + std::int32_t limit) const { + std::vector<HttpReqArg> args; args.reserve(3); + args.emplace_back("user_id", userId); if (offset) { args.emplace_back("offset", offset); } - limit = max(1, min(100, limit)); - args.emplace_back("limit", limit); + if (limit != 100) { + args.emplace_back("limit", std::max(1, std::min(100, limit))); + } + return _tgTypeParser.parseJsonAndGetUserProfilePhotos(sendRequest("getUserProfilePhotos", args)); } -File::Ptr Api::getFile(const string& fileId) const { - vector<HttpReqArg> args; +File::Ptr Api::getFile(const std::string& fileId) const { + std::vector<HttpReqArg> args; args.reserve(1); - args.emplace_back("file_id", fileId); - return _tgTypeParser.parseJsonAndGetFile(sendRequest("getFile", args)); -} -string Api::downloadFile(const string& filePath, const std::vector<HttpReqArg>& args) const { - string url(_url); - url += "/file/bot"; - url += _token; - url += "/"; - url += filePath; - - string serverResponse = _httpClient.makeRequest(url, args); + args.emplace_back("file_id", fileId); - return serverResponse; + return _tgTypeParser.parseJsonAndGetFile(sendRequest("getFile", args)); } -bool Api::banChatMember(std::int64_t chatId, +bool Api::banChatMember(boost::variant<std::int64_t, std::string> chatId, std::int64_t userId, - std::uint64_t untilDate, + std::int32_t untilDate, bool revokeMessages) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(4); args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); - args.emplace_back("until_date", untilDate); - args.emplace_back("revoke_messages", revokeMessages); + if (untilDate != 0) { + args.emplace_back("until_date", untilDate); + } + if (revokeMessages) { + args.emplace_back("revoke_messages", revokeMessages); + } return sendRequest("banChatMember", args).get<bool>("", false); } -bool Api::unbanChatMember(std::int64_t chatId, std::int64_t userId, bool onlyIfBanned) const { - vector<HttpReqArg> args; +bool Api::unbanChatMember(boost::variant<std::int64_t, std::string> chatId, + std::int64_t userId, + bool onlyIfBanned) const { + std::vector<HttpReqArg> args; args.reserve(3); args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); - args.emplace_back("only_if_banned", onlyIfBanned); + if (onlyIfBanned) { + args.emplace_back("only_if_banned", onlyIfBanned); + } return sendRequest("unbanChatMember", args).get<bool>("", false); } -bool Api::restrictChatMember(std::int64_t chatId, std::int64_t userId, TgBot::ChatPermissions::Ptr permissions, - std::uint64_t untilDate) const { - vector<HttpReqArg> args; +bool Api::restrictChatMember(boost::variant<std::int64_t, std::string> chatId, + std::int64_t userId, + TgBot::ChatPermissions::Ptr permissions, + std::int64_t untilDate) const { + std::vector<HttpReqArg> args; args.reserve(4); + args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); args.emplace_back("permissions", _tgTypeParser.parseChatPermissions(permissions)); @@ -1061,7 +1075,7 @@ bool Api::restrictChatMember(std::int64_t chatId, std::int64_t userId, TgBot::Ch return sendRequest("restrictChatMember", args).get<bool>("", false); } -bool Api::promoteChatMember(boost::variant<std::int64_t, const std::string&> chatId, +bool Api::promoteChatMember(boost::variant<std::int64_t, std::string> chatId, std::int64_t userId, bool canChangeInfo, bool canPostMessages, @@ -1074,7 +1088,7 @@ bool Api::promoteChatMember(boost::variant<std::int64_t, const std::string&> cha bool canManageChat, bool canManageVideoChats, bool canRestrictMembers) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(13); args.emplace_back("chat_id", chatId); @@ -1116,8 +1130,10 @@ bool Api::promoteChatMember(boost::variant<std::int64_t, const std::string&> cha return sendRequest("promoteChatMember", args).get<bool>("", false); } -bool Api::setChatAdministratorCustomTitle(std::int64_t chatId, std::int64_t userId, const std::string& customTitle) const { - vector<HttpReqArg> args; +bool Api::setChatAdministratorCustomTitle(boost::variant<std::int64_t, std::string> chatId, + std::int64_t userId, + const std::string& customTitle) const { + std::vector<HttpReqArg> args; args.reserve(3); args.emplace_back("chat_id", chatId); @@ -1127,9 +1143,9 @@ bool Api::setChatAdministratorCustomTitle(std::int64_t chatId, std::int64_t user return sendRequest("setChatAdministratorCustomTitle", args).get<bool>("", false); } -bool Api::banChatSenderChat(std::int64_t chatId, - std::int64_t senderChatId) const { - vector<HttpReqArg> args; +bool Api::banChatSenderChat(boost::variant<std::int64_t, std::string> chatId, + std::int64_t senderChatId) const { + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -1138,9 +1154,9 @@ bool Api::banChatSenderChat(std::int64_t chatId, return sendRequest("banChatSenderChat", args).get<bool>("", false); } -bool Api::unbanChatSenderChat(std::int64_t chatId, +bool Api::unbanChatSenderChat(boost::variant<std::int64_t, std::string> chatId, std::int64_t senderChatId) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -1149,27 +1165,32 @@ bool Api::unbanChatSenderChat(std::int64_t chatId, return sendRequest("unbanChatSenderChat", args).get<bool>("", false); } -bool Api::setChatPermissions(std::int64_t chatId, ChatPermissions::Ptr permissions) const { - vector<HttpReqArg> args; +bool Api::setChatPermissions(boost::variant<std::int64_t, std::string> chatId, + ChatPermissions::Ptr permissions) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); args.emplace_back("permissions", _tgTypeParser.parseChatPermissions(permissions)); + return sendRequest("setChatPermissions", args).get<bool>("", false); } -string Api::exportChatInviteLink(std::int64_t chatId) const { - vector<HttpReqArg> args; +std::string Api::exportChatInviteLink(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return sendRequest("exportChatInviteLink", args).get("", ""); } -ChatInviteLink::Ptr Api::createChatInviteLink(std::int64_t chatId, +ChatInviteLink::Ptr Api::createChatInviteLink(boost::variant<std::int64_t, std::string> chatId, std::int32_t expireDate, std::int32_t memberLimit, const std::string& name, bool createsJoinRequest) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(5); args.emplace_back("chat_id", chatId); @@ -1189,13 +1210,13 @@ ChatInviteLink::Ptr Api::createChatInviteLink(std::int64_t chatId, return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("createChatInviteLink", args)); } -ChatInviteLink::Ptr Api::editChatInviteLink(std::int64_t chatId, +ChatInviteLink::Ptr Api::editChatInviteLink(boost::variant<std::int64_t, std::string> chatId, const std::string& inviteLink, std::int32_t expireDate, std::int32_t memberLimit, const std::string& name, bool createsJoinRequest) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(6); args.emplace_back("chat_id", chatId); @@ -1216,9 +1237,9 @@ ChatInviteLink::Ptr Api::editChatInviteLink(std::int64_t chatId, return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("editChatInviteLink", args)); } -ChatInviteLink::Ptr Api::revokeChatInviteLink(std::int64_t chatId, +ChatInviteLink::Ptr Api::revokeChatInviteLink(boost::variant<std::int64_t, std::string> chatId, const std::string& inviteLink) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -1227,9 +1248,9 @@ ChatInviteLink::Ptr Api::revokeChatInviteLink(std::int64_t chatId, return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("revokeChatInviteLink", args)); } -bool Api::approveChatJoinRequest(std::int64_t chatId, +bool Api::approveChatJoinRequest(boost::variant<std::int64_t, std::string> chatId, std::int64_t userId) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -1238,9 +1259,9 @@ bool Api::approveChatJoinRequest(std::int64_t chatId, return sendRequest("approveChatJoinRequest", args).get<bool>("", false); } -bool Api::declineChatJoinRequest(std::int64_t chatId, +bool Api::declineChatJoinRequest(boost::variant<std::int64_t, std::string> chatId, std::int64_t userId) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); @@ -1249,60 +1270,80 @@ bool Api::declineChatJoinRequest(std::int64_t chatId, return sendRequest("declineChatJoinRequest", args).get<bool>("", false); } -bool Api::setChatPhoto(std::int64_t chatId, const InputFile::Ptr photo) const { - vector<HttpReqArg> args; +bool Api::setChatPhoto(boost::variant<std::int64_t, std::string> chatId, + const InputFile::Ptr photo) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); args.emplace_back("photo", photo->data, true, photo->mimeType, photo->fileName); + return sendRequest("setChatPhoto", args).get<bool>("", false); } -bool Api::deleteChatPhoto(std::int64_t chatId) const { - vector<HttpReqArg> args; +bool Api::deleteChatPhoto(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return sendRequest("deleteChatPhoto", args).get<bool>("", false); } -bool Api::setChatTitle(std::int64_t chatId, const string& title) const { - vector<HttpReqArg> args; +bool Api::setChatTitle(boost::variant<std::int64_t, std::string> chatId, + const std::string& title) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); args.emplace_back("title", title); + return sendRequest("setChatTitle", args).get<bool>("", false); } -bool Api::setChatDescription(std::int64_t chatId, const string& description) const { - vector<HttpReqArg> args; +bool Api::setChatDescription(boost::variant<std::int64_t, std::string> chatId, + const std::string& description) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); - args.emplace_back("description", description); + if (!description.empty()) { + args.emplace_back("description", description); + } + return sendRequest("setChatDescription", args).get<bool>("", false); } -bool Api::pinChatMessage(std::int64_t chatId, std::int32_t messageId, bool disableNotification) const { - vector<HttpReqArg> args; +bool Api::pinChatMessage(boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId, + bool disableNotification) const { + std::vector<HttpReqArg> args; args.reserve(3); + args.emplace_back("chat_id", chatId); args.emplace_back("message_id", messageId); if (disableNotification) { args.emplace_back("disable_notification", disableNotification); } + return sendRequest("pinChatMessage", args).get<bool>("", false); } -bool Api::unpinChatMessage(std::int64_t chatId, std::int32_t messageId) const { - vector<HttpReqArg> args; +bool Api::unpinChatMessage(boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId) const { + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("chat_id", chatId); - args.emplace_back("message_id", messageId); + if (messageId != 0) { + args.emplace_back("message_id", messageId); + } return sendRequest("unpinChatMessage", args).get<bool>("", false); } -bool Api::unpinAllChatMessages(std::int64_t chatId) const { - vector<HttpReqArg> args; +bool Api::unpinAllChatMessages(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); args.emplace_back("chat_id", chatId); @@ -1310,15 +1351,17 @@ bool Api::unpinAllChatMessages(std::int64_t chatId) const { return sendRequest("unpinAllChatMessages", args).get<bool>("", false); } -bool Api::leaveChat(std::int64_t chatId) const { - vector<HttpReqArg> args; +bool Api::leaveChat(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return sendRequest("leaveChat", args).get<bool>("", false); } -Chat::Ptr Api::getChat(std::int64_t chatId) const { - vector<HttpReqArg> args; +Chat::Ptr Api::getChat(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); args.emplace_back("chat_id", chatId); @@ -1326,15 +1369,17 @@ Chat::Ptr Api::getChat(std::int64_t chatId) const { return _tgTypeParser.parseJsonAndGetChat(sendRequest("getChat", args)); } -vector<ChatMember::Ptr> Api::getChatAdministrators(std::int64_t chatId) const { - vector<HttpReqArg> args; +std::vector<ChatMember::Ptr> Api::getChatAdministrators(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return _tgTypeParser.parseJsonAndGetArray<ChatMember>(&TgTypeParser::parseJsonAndGetChatMember, sendRequest("getChatAdministrators", args)); } -int32_t Api::getChatMemberCount(std::int64_t chatId) const { - vector<HttpReqArg> args; +int32_t Api::getChatMemberCount(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); args.emplace_back("chat_id", chatId); @@ -1342,32 +1387,45 @@ int32_t Api::getChatMemberCount(std::int64_t chatId) const { return sendRequest("getChatMemberCount", args).get<int32_t>("", 0); } -ChatMember::Ptr Api::getChatMember(std::int64_t chatId, std::int64_t userId) const { - vector<HttpReqArg> args; +ChatMember::Ptr Api::getChatMember(boost::variant<std::int64_t, std::string> chatId, + std::int64_t userId) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); args.emplace_back("user_id", userId); + return _tgTypeParser.parseJsonAndGetChatMember(sendRequest("getChatMember", args)); } -bool Api::setChatStickerSet(std::int64_t chatId, const string& stickerSetName) const { - vector<HttpReqArg> args; +bool Api::setChatStickerSet(boost::variant<std::int64_t, std::string> chatId, + const std::string& stickerSetName) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("chat_id", chatId); args.emplace_back("sticker_set_name ", stickerSetName); + return sendRequest("setChatStickerSet", args).get<bool>("", false); } -bool Api::deleteChatStickerSet(std::int64_t chatId) const { - vector<HttpReqArg> args; +bool Api::deleteChatStickerSet(boost::variant<std::int64_t, std::string> chatId) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); + return sendRequest("deleteChatStickerSet", args).get<bool>("", false); } -bool Api::answerCallbackQuery(const string& callbackQueryId, const string& text, bool showAlert, const string& url, std::int32_t cacheTime) const { - vector<HttpReqArg> args; +bool Api::answerCallbackQuery(const std::string& callbackQueryId, + const std::string& text, + bool showAlert, + const std::string& url, + std::int32_t cacheTime) const { + std::vector<HttpReqArg> args; args.reserve(5); + args.emplace_back("callback_query_id", callbackQueryId); if (!text.empty()) { args.emplace_back("text", text); @@ -1381,13 +1439,14 @@ bool Api::answerCallbackQuery(const string& callbackQueryId, const string& text, if (cacheTime) { args.emplace_back("cache_time", cacheTime); } + return sendRequest("answerCallbackQuery", args).get<bool>("", false); } bool Api::setMyCommands(const std::vector<BotCommand::Ptr>& commands, BotCommandScope::Ptr scope, const std::string& languageCode) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(3); args.emplace_back("commands", _tgTypeParser.parseArray<BotCommand>(&TgTypeParser::parseBotCommand, commands)); @@ -1403,7 +1462,7 @@ bool Api::setMyCommands(const std::vector<BotCommand::Ptr>& commands, bool Api::deleteMyCommands(BotCommandScope::Ptr scope, const std::string& languageCode) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); if (scope != nullptr) { @@ -1418,7 +1477,7 @@ bool Api::deleteMyCommands(BotCommandScope::Ptr scope, std::vector<BotCommand::Ptr> Api::getMyCommands(BotCommandScope::Ptr scope, const std::string& languageCode) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); ; if (scope != nullptr) { @@ -1433,7 +1492,7 @@ std::vector<BotCommand::Ptr> Api::getMyCommands(BotCommandScope::Ptr scope, bool Api::setChatMenuButton(std::int64_t chatId, MenuButton::Ptr menuButton) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); if (chatId != 0) { @@ -1447,7 +1506,7 @@ bool Api::setChatMenuButton(std::int64_t chatId, } MenuButton::Ptr Api::getChatMenuButton(std::int64_t chatId) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(1); if (chatId != 0) { @@ -1458,8 +1517,8 @@ MenuButton::Ptr Api::getChatMenuButton(std::int64_t chatId) const { } bool Api::setMyDefaultAdministratorRights(ChatAdministratorRights::Ptr rights, - bool forChannels) const { - vector<HttpReqArg> args; + bool forChannels) const { + std::vector<HttpReqArg> args; args.reserve(2); if (rights != nullptr) { @@ -1473,7 +1532,7 @@ bool Api::setMyDefaultAdministratorRights(ChatAdministratorRights::Ptr rights, } ChatAdministratorRights::Ptr Api::getMyDefaultAdministratorRights(bool forChannels) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(1); if (forChannels) { @@ -1484,17 +1543,17 @@ ChatAdministratorRights::Ptr Api::getMyDefaultAdministratorRights(bool forChanne } Message::Ptr Api::editMessageText(const std::string& text, - std::int64_t chatId, + boost::variant<std::int64_t, std::string> chatId, std::int32_t messageId, const std::string& inlineMessageId, const std::string& parseMode, bool disableWebPagePreview, GenericReply::Ptr replyMarkup, const std::vector<MessageEntity::Ptr>& entities) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(8); - if (chatId) { + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { @@ -1517,7 +1576,7 @@ Message::Ptr Api::editMessageText(const std::string& text, args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - ptree p = sendRequest("editMessageText", args); + boost::property_tree::ptree p = sendRequest("editMessageText", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); } else { @@ -1525,17 +1584,17 @@ Message::Ptr Api::editMessageText(const std::string& text, } } -Message::Ptr Api::editMessageCaption(std::int64_t chatId, +Message::Ptr Api::editMessageCaption(boost::variant<std::int64_t, std::string> chatId, std::int32_t messageId, const std::string& caption, const std::string& inlineMessageId, GenericReply::Ptr replyMarkup, const std::string& parseMode, const std::vector<MessageEntity::Ptr>& captionEntities) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); - if (chatId) { + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { @@ -1557,7 +1616,7 @@ Message::Ptr Api::editMessageCaption(std::int64_t chatId, args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - ptree p = sendRequest("editMessageCaption", args); + boost::property_tree::ptree p = sendRequest("editMessageCaption", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); } else { @@ -1565,13 +1624,17 @@ Message::Ptr Api::editMessageCaption(std::int64_t chatId, } } -Message::Ptr Api::editMessageMedia(InputMedia::Ptr media, std::int64_t chatId, std::int32_t messageId, const std::string& inlineMessageId, +Message::Ptr Api::editMessageMedia(InputMedia::Ptr media, + boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId, + const std::string& inlineMessageId, GenericReply::Ptr replyMarkup) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(5); + args.emplace_back("media", _tgTypeParser.parseInputMedia(media)); - if (chatId) { + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { @@ -1583,7 +1646,8 @@ Message::Ptr Api::editMessageMedia(InputMedia::Ptr media, std::int64_t chatId, s if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - ptree p = sendRequest("editMessageMedia", args); + + boost::property_tree::ptree p = sendRequest("editMessageMedia", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); } else { @@ -1591,12 +1655,15 @@ Message::Ptr Api::editMessageMedia(InputMedia::Ptr media, std::int64_t chatId, s } } -Message::Ptr Api::editMessageReplyMarkup(std::int64_t chatId, std::int32_t messageId, const string& inlineMessageId, +Message::Ptr Api::editMessageReplyMarkup(boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId, + const std::string& inlineMessageId, const GenericReply::Ptr replyMarkup) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(4); - if (chatId) { + + if ((boost::get<std::int64_t>(chatId) != 0) || (boost::get<std::string>(chatId) != "")) { args.emplace_back("chat_id", chatId); } if (messageId) { @@ -1608,7 +1675,8 @@ Message::Ptr Api::editMessageReplyMarkup(std::int64_t chatId, std::int32_t messa if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } - ptree p = sendRequest("editMessageReplyMarkup", args); + + boost::property_tree::ptree p = sendRequest("editMessageReplyMarkup", args); if (p.get_child_optional("message_id")) { return _tgTypeParser.parseJsonAndGetMessage(p); } else { @@ -1616,37 +1684,48 @@ Message::Ptr Api::editMessageReplyMarkup(std::int64_t chatId, std::int32_t messa } } -Poll::Ptr Api::stopPoll(std::int64_t chatId, std::int64_t messageId, const InlineKeyboardMarkup::Ptr replyMarkup) const { - vector<HttpReqArg> args; +Poll::Ptr Api::stopPoll(boost::variant<std::int64_t, std::string> chatId, + std::int64_t messageId, + const InlineKeyboardMarkup::Ptr replyMarkup) const { + std::vector<HttpReqArg> args; args.reserve(3); + args.emplace_back("chat_id", chatId); args.emplace_back("message_id", messageId); if (replyMarkup) { args.emplace_back("reply_markup", _tgTypeParser.parseGenericReply(replyMarkup)); } + return _tgTypeParser.parseJsonAndGetPoll(sendRequest("stopPoll", args)); } -void Api::deleteMessage(std::int64_t chatId, std::int32_t messageId) const { - sendRequest("deleteMessage", { HttpReqArg("chat_id", chatId), HttpReqArg("message_id", messageId) }); +bool Api::deleteMessage(boost::variant<std::int64_t, std::string> chatId, + std::int32_t messageId) const { + std::vector<HttpReqArg> args; + args.reserve(2); + + args.emplace_back("chat_id", chatId); + args.emplace_back("message_id", messageId); + + return sendRequest("deleteMessage", args).get<bool>("", false); } -Message::Ptr Api::sendSticker(boost::variant<std::int64_t, const std::string&> chatId, - boost::variant<InputFile::Ptr, const std::string&> sticker, +Message::Ptr Api::sendSticker(boost::variant<std::int64_t, std::string> chatId, + boost::variant<InputFile::Ptr, std::string> sticker, std::int32_t replyToMessageId, GenericReply::Ptr replyMarkup, bool disableNotification, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); args.emplace_back("chat_id", chatId); if (sticker.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(sticker); args.emplace_back("sticker", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("sticker", boost::get<const std::string&>(sticker)); + } else { // std::string + args.emplace_back("sticker", boost::get<std::string>(sticker)); } if (disableNotification) { args.emplace_back("disable_notification", disableNotification); @@ -1667,8 +1746,8 @@ Message::Ptr Api::sendSticker(boost::variant<std::int64_t, const std::string&> c return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendSticker", args)); } -StickerSet::Ptr Api::getStickerSet(const string& name) const { - vector<HttpReqArg> args; +StickerSet::Ptr Api::getStickerSet(const std::string& name) const { + std::vector<HttpReqArg> args; args.reserve(1); args.emplace_back("name", name); @@ -1677,21 +1756,24 @@ StickerSet::Ptr Api::getStickerSet(const string& name) const { } std::vector<Sticker::Ptr> Api::getCustomEmojiStickers(const std::vector<std::string>& customEmojiIds) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(1); args.emplace_back("custom_emoji_ids", _tgTypeParser.parseArray<std::string>([] (const std::string& customEmojiId) -> std::string { - return "\"" + StringTools::urlEncode(customEmojiId) + "\""; + return "\"" + StringTools::escapeJsonString(customEmojiId) + "\""; }, customEmojiIds)); return _tgTypeParser.parseJsonAndGetArray<Sticker>(&TgTypeParser::parseJsonAndGetSticker, sendRequest("getCustomEmojiStickers", args)); } -File::Ptr Api::uploadStickerFile(std::int64_t userId, const InputFile::Ptr pngSticker) const { - vector<HttpReqArg> args; +File::Ptr Api::uploadStickerFile(std::int64_t userId, + const InputFile::Ptr pngSticker) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("user_id", userId); args.emplace_back("png_sticker", pngSticker->data, true, pngSticker->mimeType, pngSticker->fileName); + return _tgTypeParser.parseJsonAndGetFile(sendRequest("uploadStickerFile", args)); } @@ -1700,11 +1782,11 @@ bool Api::createNewStickerSet(std::int64_t userId, const std::string& title, const std::string& emojis, MaskPosition::Ptr maskPosition, - boost::variant<InputFile::Ptr, const std::string&> pngSticker, + boost::variant<InputFile::Ptr, std::string> pngSticker, InputFile::Ptr tgsSticker, InputFile::Ptr webmSticker, const std::string& stickerType) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(10); args.emplace_back("user_id", userId); @@ -1713,8 +1795,8 @@ bool Api::createNewStickerSet(std::int64_t userId, if (pngSticker.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(pngSticker); args.emplace_back("png_sticker", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("png_sticker", boost::get<const std::string&>(pngSticker)); + } else { // std::string + args.emplace_back("png_sticker", boost::get<std::string>(pngSticker)); } if (tgsSticker != nullptr) { args.emplace_back("tgs_sticker", tgsSticker->data, true, tgsSticker->mimeType, tgsSticker->fileName); @@ -1737,10 +1819,10 @@ bool Api::addStickerToSet(std::int64_t userId, const std::string& name, const std::string& emojis, MaskPosition::Ptr maskPosition, - boost::variant<InputFile::Ptr, const std::string&> pngSticker, + boost::variant<InputFile::Ptr, std::string> pngSticker, InputFile::Ptr tgsSticker, InputFile::Ptr webmSticker) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); args.emplace_back("user_id", userId); @@ -1749,8 +1831,8 @@ bool Api::addStickerToSet(std::int64_t userId, if (pngSticker.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(pngSticker); args.emplace_back("png_sticker", file->data, true, file->mimeType, file->fileName); - } else { // const std::string& - args.emplace_back("png_sticker", boost::get<const std::string&>(pngSticker)); + } else { // std::string + args.emplace_back("png_sticker", boost::get<std::string>(pngSticker)); } if (tgsSticker != nullptr) { args.emplace_back("tgs_sticker", tgsSticker->data, true, tgsSticker->mimeType, tgsSticker->fileName); @@ -1766,44 +1848,56 @@ bool Api::addStickerToSet(std::int64_t userId, return sendRequest("addStickerToSet", args).get<bool>("", false); } -bool Api::setStickerPositionInSet(const string& sticker, std::uint32_t position) const { - vector<HttpReqArg> args; +bool Api::setStickerPositionInSet(const std::string& sticker, + std::int32_t position) const { + std::vector<HttpReqArg> args; args.reserve(2); + args.emplace_back("sticker", sticker); args.emplace_back("position", position); + return sendRequest("setStickerPositionInSet", args).get<bool>("", false); } -bool Api::deleteStickerFromSet(const string& sticker) const { - vector<HttpReqArg> args; +bool Api::deleteStickerFromSet(const std::string& sticker) const { + std::vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("sticker", sticker); + return sendRequest("deleteStickerFromSet", args).get<bool>("", false); } -bool Api::setStickerSetThumb(const std::string& name, std::int64_t userId, boost::variant<InputFile::Ptr, std::string> thumb) const { - vector<HttpReqArg> args; +bool Api::setStickerSetThumb(const std::string& name, + std::int64_t userId, + boost::variant<InputFile::Ptr, std::string> thumb) const { + std::vector<HttpReqArg> args; args.reserve(3); args.emplace_back("name", name); args.emplace_back("user_id", userId); - if (thumb.which() == 0 /* InputFile::Ptr */) { + if (thumb.which() == 0) { // InputFile::Ptr auto file = boost::get<InputFile::Ptr>(thumb); args.emplace_back("thumb", file->data, true, file->mimeType, file->fileName); - } else /* std::string */ { + } else { // std::string args.emplace_back("thumb", boost::get<std::string>(thumb)); } return sendRequest("setStickerSetThumb", args).get<bool>("", false); } -bool Api::answerInlineQuery(const string& inlineQueryId, const std::vector<InlineQueryResult::Ptr>& results, - std::int32_t cacheTime, bool isPersonal, const string& nextOffset, const string& switchPmText, const string& switchPmParameter) const { - vector<HttpReqArg> args; +bool Api::answerInlineQuery(const std::string& inlineQueryId, + const std::vector<InlineQueryResult::Ptr>& results, + std::int32_t cacheTime, + bool isPersonal, + const std::string& nextOffset, + const std::string& switchPmText, + const std::string& switchPmParameter) const { + std::vector<HttpReqArg> args; args.reserve(7); + args.emplace_back("inline_query_id", inlineQueryId); - string resultsJson = _tgTypeParser.parseArray<InlineQueryResult>(&TgTypeParser::parseInlineQueryResult, results); - args.emplace_back("results", resultsJson); + args.emplace_back("results", _tgTypeParser.parseArray<InlineQueryResult>(&TgTypeParser::parseInlineQueryResult, results)); if (cacheTime) { args.emplace_back("cache_time", cacheTime); } @@ -1819,12 +1913,13 @@ bool Api::answerInlineQuery(const string& inlineQueryId, const std::vector<Inlin if (!switchPmParameter.empty()) { args.emplace_back("switch_pm_parameter", switchPmParameter); } + return sendRequest("answerInlineQuery", args).get<bool>("", false); } SentWebAppMessage::Ptr Api::answerWebAppQuery(const std::string& webAppQueryId, InlineQueryResult::Ptr result) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("web_app_query_id", webAppQueryId); @@ -1833,7 +1928,7 @@ SentWebAppMessage::Ptr Api::answerWebAppQuery(const std::string& webAppQueryId, return _tgTypeParser.parseJsonAndGetSentWebAppMessage(sendRequest("answerWebAppQuery", args)); } -Message::Ptr Api::sendInvoice(boost::variant<std::int64_t, const std::string&> chatId, +Message::Ptr Api::sendInvoice(boost::variant<std::int64_t, std::string> chatId, const std::string& title, const std::string& description, const std::string& payload, @@ -1860,7 +1955,7 @@ Message::Ptr Api::sendInvoice(boost::variant<std::int64_t, const std::string&> c const std::vector<std::int32_t>& suggestedTipAmounts, const std::string& startParameter, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(27); args.emplace_back("chat_id", chatId); @@ -1954,7 +2049,7 @@ std::string Api::createInvoiceLink(const std::string& title, bool sendPhoneNumberToProvider, bool sendEmailToProvider, bool isFlexible) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(20); args.emplace_back("title", title); @@ -2009,9 +2104,13 @@ std::string Api::createInvoiceLink(const std::string& title, return sendRequest("createInvoiceLink", args).get<std::string>("", ""); } -bool Api::answerShippingQuery(const std::string& shippingQueryId, bool ok, const std::vector<ShippingOption::Ptr>& shippingOptions, const std::string& errorMessage) const { - vector<HttpReqArg> args; +bool Api::answerShippingQuery(const std::string& shippingQueryId, + bool ok, + const std::vector<ShippingOption::Ptr>& shippingOptions, + const std::string& errorMessage) const { + std::vector<HttpReqArg> args; args.reserve(4); + args.emplace_back("shipping_query_id", shippingQueryId); args.emplace_back("ok", ok); if (!shippingOptions.empty()) { @@ -2020,22 +2119,28 @@ bool Api::answerShippingQuery(const std::string& shippingQueryId, bool ok, const if (!errorMessage.empty()) { args.emplace_back("error_message", errorMessage); } + return sendRequest("answerShippingQuery", args).get<bool>("", false); } -bool Api::answerPreCheckoutQuery(const std::string& preCheckoutQueryId, bool ok, const std::string& errorMessage) const { - vector<HttpReqArg> args; +bool Api::answerPreCheckoutQuery(const std::string& preCheckoutQueryId, + bool ok, + const std::string& errorMessage) const { + std::vector<HttpReqArg> args; args.reserve(3); + args.emplace_back("pre_checkout_query_id", preCheckoutQueryId); args.emplace_back("ok", ok); if (!errorMessage.empty()) { args.emplace_back("error_message", errorMessage); } + return sendRequest("answerPreCheckoutQuery", args).get<bool>("", false); } -bool Api::setPassportDataErrors(std::int64_t userId, const std::vector<PassportElementError::Ptr>& errors) const { - vector<HttpReqArg> args; +bool Api::setPassportDataErrors(std::int64_t userId, + const std::vector<PassportElementError::Ptr>& errors) const { + std::vector<HttpReqArg> args; args.reserve(2); args.emplace_back("user_id", userId); @@ -2051,7 +2156,7 @@ Message::Ptr Api::sendGame(std::int64_t chatId, bool disableNotification, bool allowSendingWithoutReply, bool protectContent) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(7); args.emplace_back("chat_id", chatId); @@ -2075,9 +2180,16 @@ Message::Ptr Api::sendGame(std::int64_t chatId, return _tgTypeParser.parseJsonAndGetMessage(sendRequest("sendGame", args)); } -Message::Ptr Api::setGameScore(std::int64_t userId, std::int32_t score, bool force, bool disableEditMessage, std::int64_t chatId, std::int32_t messageId, const std::string& inlineMessageId) const { - vector<HttpReqArg> args; +Message::Ptr Api::setGameScore(std::int64_t userId, + std::int32_t score, + bool force, + bool disableEditMessage, + std::int64_t chatId, + std::int32_t messageId, + const std::string& inlineMessageId) const { + std::vector<HttpReqArg> args; args.reserve(7); + args.emplace_back("user_id", userId); args.emplace_back("score", score); if (force) { @@ -2095,14 +2207,15 @@ Message::Ptr Api::setGameScore(std::int64_t userId, std::int32_t score, bool for if (!inlineMessageId.empty()) { args.emplace_back("inline_message_id", inlineMessageId); } + return _tgTypeParser.parseJsonAndGetMessage(sendRequest("setGameScore", args)); } -vector<GameHighScore::Ptr> Api::getGameHighScores(std::int64_t userId, +std::vector<GameHighScore::Ptr> Api::getGameHighScores(std::int64_t userId, std::int64_t chatId, std::int32_t messageId, const std::string& inlineMessageId) const { - vector<HttpReqArg> args; + std::vector<HttpReqArg> args; args.reserve(4); args.emplace_back("user_id", userId); @@ -2119,19 +2232,47 @@ vector<GameHighScore::Ptr> Api::getGameHighScores(std::int64_t userId, return _tgTypeParser.parseJsonAndGetArray<GameHighScore>(&TgTypeParser::parseJsonAndGetGameHighScore, sendRequest("getGameHighScores", args)); } -ptree Api::sendRequest(const string& method, const vector<HttpReqArg>& args) const { - string url(_url); +std::string Api::downloadFile(const std::string& filePath, + const std::vector<HttpReqArg>& args) const { + std::string url(_url); + url += "/file/bot"; + url += _token; + url += "/"; + url += filePath; + + return _httpClient.makeRequest(url, args); +} + +bool Api::blockedByUser(std::int64_t chatId) const { + bool isBotBlocked = false; + + try { + sendChatAction(chatId, "typing"); + + } catch (std::exception& e) { + std::string error = e.what(); + + if (error.compare("Forbidden: bot was blocked by the user") == 0) { + isBotBlocked = true; + } + } + + return isBotBlocked; +} + +boost::property_tree::ptree Api::sendRequest(const std::string& method, const std::vector<HttpReqArg>& args) const { + std::string url(_url); url += "/bot"; url += _token; url += "/"; url += method; - string serverResponse = _httpClient.makeRequest(url, args); + std::string serverResponse = _httpClient.makeRequest(url, args); if (!serverResponse.compare(0, 6, "<html>")) { throw TgException("tgbot-cpp library have got html page instead of json response. Maybe you entered wrong bot token."); } - ptree result = _tgTypeParser.parseJson(serverResponse); + boost::property_tree::ptree result = _tgTypeParser.parseJson(serverResponse); try { if (result.get<bool>("ok", false)) { return result.get_child("result"); @@ -2139,7 +2280,7 @@ ptree Api::sendRequest(const string& method, const vector<HttpReqArg>& args) con throw TgException(result.get("description", "")); } } catch (boost::property_tree::ptree_error& e) { - throw TgException("tgbot-cpp library can't parse json response. " + string(e.what())); + throw TgException("tgbot-cpp library can't parse json response. " + std::string(e.what())); } } } |