From c725a7c1d3abea688567239ec0a6bc7880a3bfb3 Mon Sep 17 00:00:00 2001 From: Bader Date: Sat, 14 Oct 2023 13:46:34 +0100 Subject: [PATCH] added ForumTopic object implemented Api methods --- include/tgbotxx/Api.hpp | 117 ++++++++++++++++-- include/tgbotxx/objects/ForumTopic.hpp | 44 +++++++ include/tgbotxx/tgbotxx.hpp | 1 + src/Api.cpp | 165 +++++++++++++++++++------ 4 files changed, 280 insertions(+), 47 deletions(-) create mode 100644 include/tgbotxx/objects/ForumTopic.hpp diff --git a/include/tgbotxx/Api.hpp b/include/tgbotxx/Api.hpp index 5047e29fa..d34b36bc2 100644 --- a/include/tgbotxx/Api.hpp +++ b/include/tgbotxx/Api.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -871,7 +872,7 @@ namespace tgbotxx { /// @param customTitle New custom title for the administrator; 0-16 characters, emoji are not allowed /// @returns True on success. /// @throws Exception on failure - /// @related unbanChatSenderChat + /// @relatedalso unbanChatSenderChat /// @ref https://core.telegram.org/bots/api#banchatsenderchat bool banChatSenderChat(std::int64_t chatId, std::int64_t senderChatId) const; @@ -884,7 +885,7 @@ namespace tgbotxx { /// @param customTitle New custom title for the administrator; 0-16 characters, emoji are not allowed /// @returns True on success. /// @throws Exception on failure - /// @related banChatSenderChat + /// @relatedalso banChatSenderChat /// @ref https://core.telegram.org/bots/api#unbanchatsenderchat bool unbanChatSenderChat(std::int64_t chatId, std::int64_t senderChatId) const; @@ -933,7 +934,7 @@ namespace tgbotxx { /// @param createsJoinRequest Optional. True, if users joining the chat via the link need to be approved by chat administrators. If True, memberLimit can't be specified /// @returns the new invite link as ChatInviteLink object on success. /// @throws Exception on failure - /// @related editChatInviteLink revokeChatInviteLink + /// @relatedalso editChatInviteLink revokeChatInviteLink /// @ref https://core.telegram.org/bots/api#createchatinvitelink Ptr createChatInviteLink(std::int64_t chatId, const std::string& name = "", @@ -952,7 +953,7 @@ namespace tgbotxx { /// @param createsJoinRequest Optional. True, if users joining the chat via the link need to be approved by chat administrators. If True, memberLimit can't be specified /// @returns The edited invite link as a ChatInviteLink object on success. /// @throws Exception on failure - /// @related createChatInviteLink revokeChatInviteLink + /// @relatedalso createChatInviteLink revokeChatInviteLink /// @ref https://core.telegram.org/bots/api#editchatinvitelink Ptr editChatInviteLink(std::int64_t chatId, const std::string& inviteLink, @@ -968,7 +969,7 @@ namespace tgbotxx { /// @param inviteLink The invite link to revoke /// @returns The revoked invite link as ChatInviteLink object on success. /// @throws Exception on failure - /// @related createChatInviteLink editChatInviteLink + /// @relatedalso createChatInviteLink editChatInviteLink /// @ref https://core.telegram.org/bots/api#revokechatinvitelink Ptr revokeChatInviteLink(std::int64_t chatId, const std::string& inviteLink) const; @@ -979,7 +980,7 @@ namespace tgbotxx { /// @param userId Unique identifier of the target user /// @returns True on success. /// @throws Exception on failure - /// @related declineChatJoinRequest + /// @relatedalso declineChatJoinRequest /// @ref https://core.telegram.org/bots/api#approvechatjoinrequest bool approveChatJoinRequest(std::int64_t chatId, std::int64_t userId) const; @@ -990,7 +991,7 @@ namespace tgbotxx { /// @param userId Unique identifier of the target user /// @returns True on success. /// @throws Exception on failure - /// @related approveChatJoinRequest + /// @relatedalso approveChatJoinRequest /// @ref https://core.telegram.org/bots/api#declinechatjoinrequest bool declineChatJoinRequest(std::int64_t chatId, std::int64_t userId) const; @@ -1001,7 +1002,7 @@ namespace tgbotxx { /// @param photo New chat photo, uploaded using multipart/form-data /// @returns True on success. /// @throws Exception on failure - /// @related deleteChatPhoto + /// @relatedalso deleteChatPhoto /// @ref https://core.telegram.org/bots/api#setchatphoto bool setChatPhoto(std::int64_t chatId, const cpr::File& photo) const; @@ -1011,7 +1012,7 @@ namespace tgbotxx { /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) /// @returns True on success. /// @throws Exception on failure - /// @related setChatPhoto + /// @relatedalso setChatPhoto /// @ref https://core.telegram.org/bots/api#deletechatphoto bool deleteChatPhoto(std::int64_t chatId) const; @@ -1045,7 +1046,7 @@ namespace tgbotxx { /// Notifications are always disabled in channels and private chats. /// @returns True on success. /// @throws Exception on failure - /// @related unpinChatMessage unpinAllChatMessages + /// @relatedalso unpinChatMessage unpinAllChatMessages /// @ref https://core.telegram.org/bots/api#pinchatmessage bool pinChatMessage(std::int64_t chatId, std::int32_t messageId, @@ -1059,7 +1060,7 @@ namespace tgbotxx { /// @param messageId Optional. Identifier of a message to unpin. If not specified, the most recent pinned message (by sending date) will be unpinned. /// @returns True on success. /// @throws Exception on failure - /// @related pinChatMessage unpinAllChatMessages + /// @relatedalso pinChatMessage unpinAllChatMessages /// @ref https://core.telegram.org/bots/api#unpinchatmessage bool unpinChatMessage(std::int64_t chatId, std::int32_t messageId = 0) const; @@ -1070,11 +1071,103 @@ namespace tgbotxx { /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) /// @returns True on success. /// @throws Exception on failure - /// @related pinChatMessage unpinChatMessage + /// @relatedalso pinChatMessage unpinChatMessage /// @ref https://core.telegram.org/bots/api#unpinallchatmessages bool unpinAllChatMessages(std::int64_t chatId) const; + /// @brief Use this method for your bot to leave a group, supergroup or channel. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns True on success. + /// @throws Exception on failure + /// @ref https://core.telegram.org/bots/api#leavechat + bool leaveChat(std::int64_t chatId) const; + + + /// @brief Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.). + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns a Chat object on success. + /// @throws Exception on failure + /// @ref https://core.telegram.org/bots/api#getchat + Ptr getChat(std::int64_t chatId) const; + + + /// @brief Use this method to get a list of administrators in a chat, which aren't bots. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns an Array of ChatMember objects. + /// @throws Exception on failure + /// @ref https://core.telegram.org/bots/api#getchatadministrators + std::vector> getChatAdministrators(std::int64_t chatId) const; + + + /// @brief Use this method to get the number of members in a chat. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns std::int32_t on success. + /// @throws Exception on failure + /// @ref https://core.telegram.org/bots/api#getchatmembercount + std::int32_t getChatMemberCount(std::int64_t chatId) const; + + + /// @brief Use this method to get information about a member of a chat. + /// The method is only guaranteed to work for other users if the bot is an administrator in the chat. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @param userId Unique identifier of the target user + /// @returns a ChatMember object on success. + /// @throws Exception on failure + /// @ref https://core.telegram.org/bots/api#getchatmember + Ptr getChatMember(std::int64_t chatId, std::int64_t userId) const; + + + /// @brief Use this method to set a new group sticker set for a supergroup. + /// The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. + /// Use the field canSetStickerSet optionally returned in getChat requests to check if the bot can use this method. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @param stickerSetName Name of the sticker set to be set as the group sticker set + /// @returns True on success. + /// @throws Exception on failure + /// @relatedalso deleteChatStickerSet getForumTopicIconStickers Sticker::setName + /// @ref https://core.telegram.org/bots/api#setchatstickerset + bool setChatStickerSet(std::int64_t chatId, const std::string& stickerSetName) const; + + + /// @brief Use this method to delete a group sticker set from a supergroup. + /// The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. + /// Use the field canSetStickerSet optionally returned in getChat requests to check if the bot can use this method. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns True on success. + /// @throws Exception on failure + /// @relatedalso setChatStickerSet getForumTopicIconStickers Sticker::setName + /// @ref https://core.telegram.org/bots/api#deletechatstickerset + bool deleteChatStickerSet(std::int64_t chatId) const; + + + /// @brief Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user. + /// Requires no parameters. + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @returns an Array of Sticker objects. + /// @throws Exception on failure + /// @relatedalso setChatStickerSet deleteChatStickerSet + /// @ref https://core.telegram.org/bots/api#getforumtopiciconstickers + std::vector> getForumTopicIconStickers() const; + + + /// @brief Use this method to create a topic in a forum supergroup chat. + /// The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights. + /// https://core.telegram.org/bots/api#forumtopic + /// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername) + /// @param name Topic name, 1-128 characters + /// @param iconColor Optional. Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F) + /// @param iconCustomEmojiId Optional. Unique identifier of the custom emoji shown as the topic icon. Use getForumTopicIconStickers to get all allowed custom emoji identifiers. https://core.telegram.org/bots/api#getforumtopiciconstickers + /// @returns information about the created topic as a ForumTopic object. + /// @throws Exception on failure + /// @relatedalso editForumTopic closeForumTopic reopenForumTopic deleteForumTopic + /// @ref https://core.telegram.org/bots/api#createforumtopic + Ptr createForumTopic(std::int64_t chatId, + const std::string& name, + std::int32_t iconColor = 0x000000, + const std::string& iconCustomEmojiId = "") const; + + /// @brief Use this method to remove webhook integration if you decide to switch back to getUpdates. /// @param dropPendingUpdates: Pass True to drop all pending updates. /// @returns True on success. diff --git a/include/tgbotxx/objects/ForumTopic.hpp b/include/tgbotxx/objects/ForumTopic.hpp new file mode 100644 index 000000000..af7b56a18 --- /dev/null +++ b/include/tgbotxx/objects/ForumTopic.hpp @@ -0,0 +1,44 @@ +#pragma once +#include + +namespace tgbotxx { + /// @brief This object represents a forum topic. + /// @ref https://core.telegram.org/bots/api#forumtopic + struct ForumTopic { + ForumTopic() = default; + explicit ForumTopic(const nl::json& json) { + fromJson(json); + } + + /// @brief Unique identifier of the forum topic + std::int32_t messageThreadId{}; + + /// @brief Name of the topic + std::string name; + + /// @brief Color of the topic icon in RGB format + std::int32_t iconColor{}; + + /// @brief Optional. Unique identifier of the custom emoji shown as the topic icon + std::int32_t iconCustomEmojiId{}; + + /// @brief Serializes this object to JSON + /// @returns JSON representation of this object + nl::json toJson() const { + nl::json json = nl::json::object(); + OBJECT_SERIALIZE_FIELD(json, "message_thread_id", messageThreadId); + OBJECT_SERIALIZE_FIELD(json, "name", name); + OBJECT_SERIALIZE_FIELD(json, "icon_color", iconColor); + OBJECT_SERIALIZE_FIELD(json, "icon_custom_emoji_id", iconCustomEmojiId); + return json; + } + + /// @brief Deserializes this object from JSON + void fromJson(const nl::json& json) { + OBJECT_DESERIALIZE_FIELD(json, "message_thread_id", messageThreadId, 0, false); + OBJECT_DESERIALIZE_FIELD(json, "name", name, "", false); + OBJECT_DESERIALIZE_FIELD(json, "icon_color", iconColor, 0x000000, false); + OBJECT_DESERIALIZE_FIELD(json, "icon_custom_emoji_id", iconCustomEmojiId, 0, true); + } + }; +} \ No newline at end of file diff --git a/include/tgbotxx/tgbotxx.hpp b/include/tgbotxx/tgbotxx.hpp index 9dd80e176..d8c0c70df 100644 --- a/include/tgbotxx/tgbotxx.hpp +++ b/include/tgbotxx/tgbotxx.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Api.cpp b/src/Api.cpp index 58124ff28..43eb80ff0 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -239,7 +239,7 @@ Ptr Api::sendPhoto(std::int64_t chatId, std::variant& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(12); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (photo.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(photo); data.parts.emplace_back("photo", cpr::Files{file}); @@ -292,7 +292,7 @@ Ptr Api::sendAudio(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(15); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (audio.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(audio); data.parts.emplace_back("audio", cpr::Files{file}); @@ -356,7 +356,7 @@ Ptr Api::sendDocument(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(12); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (document.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(document); data.parts.emplace_back("document", cpr::Files{file}); @@ -456,7 +456,7 @@ Ptr Api::sendVideo(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(17); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (video.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(video); data.parts.emplace_back("video", cpr::Files{file}); @@ -529,7 +529,7 @@ Ptr Api::sendAnimation(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(16); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (animation.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(animation); data.parts.emplace_back("animation", cpr::Files{file}); @@ -596,7 +596,7 @@ Ptr Api::sendVoice(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(12); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (voice.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(voice); data.parts.emplace_back("voice", cpr::Files{file}); @@ -647,7 +647,7 @@ Ptr Api::sendVideoNote(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(11); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (videoNote.index() == 0) /* cpr::File */ { const cpr::File& file = std::get(videoNote); data.parts.emplace_back("video_note", cpr::Files{file}); @@ -695,7 +695,7 @@ std::vector> Api::sendMediaGroup(std::int64_t chatId, bool allowSendingWithoutReply) const { cpr::Multipart data{}; data.parts.reserve(7); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (media.size() > 10 or media.size() < 2) throw Exception("Api::sendMediaGroup(): media must include 2-10 items. See https://core.telegram.org/bots/api#sendmediagroup"); nl::json mediaJson = nl::json::array(); @@ -738,7 +738,7 @@ Ptr Api::sendLocation(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(13); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("latitude", latitude); data.parts.emplace_back("longitude", longitude); if (messageThreadId) @@ -784,7 +784,7 @@ Ptr Api::sendVenue(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(15); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("latitude", latitude); data.parts.emplace_back("longitude", longitude); data.parts.emplace_back("title", title); @@ -828,7 +828,7 @@ Ptr Api::sendContact(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(11); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("phone_number", phoneNumber); data.parts.emplace_back("first_name", firstName); if (not lastName.empty()) @@ -874,7 +874,7 @@ Ptr Api::sendPoll(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(19); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("question", question); data.parts.emplace_back("options", nl::json(options).dump()); if (not isAnonymous) @@ -929,7 +929,7 @@ Ptr Api::sendDice(std::int64_t chatId, const Ptr& replyMarkup) const { cpr::Multipart data{}; data.parts.reserve(8); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (not emoji.empty()) data.parts.emplace_back("emoji", emoji); if (messageThreadId) @@ -955,7 +955,7 @@ bool Api::sendChatAction(std::int64_t chatId, std::int32_t messageThreadId) const { cpr::Multipart data{}; data.parts.reserve(3); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("action", action); if (messageThreadId) data.parts.emplace_back("message_thread_id", messageThreadId); @@ -985,7 +985,7 @@ bool Api::banChatMember(std::int64_t chatId, bool revokeMessages) const { cpr::Multipart data{}; data.parts.reserve(4); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); if (untilDate) data.parts.emplace_back("until_date", untilDate); @@ -1000,7 +1000,7 @@ bool Api::unbanChatMember(std::int64_t chatId, bool onlyIfBanned) const { cpr::Multipart data{}; data.parts.reserve(3); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); if (onlyIfBanned) data.parts.emplace_back("only_if_banned", onlyIfBanned); @@ -1015,7 +1015,7 @@ bool Api::restrictChatMember(std::int64_t chatId, std::time_t untilDate) const { cpr::Multipart data{}; data.parts.reserve(5); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); data.parts.emplace_back("permissions", permissions->toJson().dump()); if (useIndependentChatPermissions) @@ -1045,7 +1045,7 @@ bool Api::promoteChatMember(std::int64_t chatId, bool canManageTopics) const { cpr::Multipart data{}; data.parts.reserve(17); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); if (isAnonymous) data.parts.emplace_back("is_anonymous", isAnonymous); @@ -1085,7 +1085,7 @@ bool Api::setChatAdministratorCustomTitle(std::int64_t chatId, const std::string& customTitle) const { cpr::Multipart data{}; data.parts.reserve(3); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); data.parts.emplace_back("custom_title", customTitle); return sendRequest("setChatAdministratorCustomTitle", data); @@ -1095,7 +1095,7 @@ bool Api::banChatSenderChat(std::int64_t chatId, std::int64_t senderChatId) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("sender_chat_id", std::to_string(senderChatId)); return sendRequest("banChatSenderChat", data); } @@ -1104,7 +1104,7 @@ bool Api::unbanChatSenderChat(std::int64_t chatId, std::int64_t senderChatId) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("sender_chat_id", std::to_string(senderChatId)); return sendRequest("unbanChatSenderChat", data); } @@ -1114,7 +1114,7 @@ bool Api::setChatPermissions(std::int64_t chatId, bool useIndependentChatPermissions) const { cpr::Multipart data{}; data.parts.reserve(3); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("permissions", permissions->toJson().dump()); if (useIndependentChatPermissions) data.parts.emplace_back("use_independent_chat_permissions", useIndependentChatPermissions); @@ -1124,7 +1124,7 @@ bool Api::setChatPermissions(std::int64_t chatId, std::string Api::exportChatInviteLink(std::int64_t chatId) const { cpr::Multipart data{}; data.parts.reserve(1); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); return sendRequest("exportChatInviteLink", data); } @@ -1135,7 +1135,7 @@ Ptr Api::createChatInviteLink(std::int64_t chatId, bool createsJoinRequest) const { cpr::Multipart data{}; data.parts.reserve(5); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (not name.empty()) data.parts.emplace_back("name", name); if (expireDate) @@ -1158,7 +1158,7 @@ Ptr Api::editChatInviteLink(std::int64_t chatId, bool createsJoinRequest) const { cpr::Multipart data{}; data.parts.reserve(6); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("invite_link", inviteLink); if (not name.empty()) data.parts.emplace_back("name", name); @@ -1178,7 +1178,7 @@ Ptr Api::revokeChatInviteLink(std::int64_t chatId, const std::string& inviteLink) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("invite_link", inviteLink); nl::json chatInviteLinkObj = sendRequest("revokeChatInviteLink", data); @@ -1189,7 +1189,7 @@ Ptr Api::revokeChatInviteLink(std::int64_t chatId, bool Api::approveChatJoinRequest(std::int64_t chatId, std::int64_t userId) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); return sendRequest("approveChatJoinRequest", data); } @@ -1197,7 +1197,7 @@ bool Api::approveChatJoinRequest(std::int64_t chatId, std::int64_t userId) const bool Api::declineChatJoinRequest(std::int64_t chatId, std::int64_t userId) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("user_id", std::to_string(userId)); return sendRequest("declineChatJoinRequest", data); } @@ -1205,7 +1205,7 @@ bool Api::declineChatJoinRequest(std::int64_t chatId, std::int64_t userId) const bool Api::setChatPhoto(std::int64_t chatId, const cpr::File& photo) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("photo", cpr::Files{photo}); return sendRequest("setChatPhoto", data); } @@ -1213,14 +1213,14 @@ bool Api::setChatPhoto(std::int64_t chatId, const cpr::File& photo) const { bool Api::deleteChatPhoto(std::int64_t chatId) const { cpr::Multipart data{}; data.parts.reserve(1); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); return sendRequest("deleteChatPhoto", data); } bool Api::setChatTitle(std::int64_t chatId, const std::string& title) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("title", title); return sendRequest("setChatTitle", data); } @@ -1228,7 +1228,7 @@ bool Api::setChatTitle(std::int64_t chatId, const std::string& title) const { bool Api::setChatDescription(std::int64_t chatId, const std::string& description) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (not description.empty()) data.parts.emplace_back("description", description); return sendRequest("setChatDescription", data); @@ -1239,7 +1239,7 @@ bool Api::pinChatMessage(std::int64_t chatId, bool disableNotification) const { cpr::Multipart data{}; data.parts.reserve(3); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); data.parts.emplace_back("message_id", messageId); if (disableNotification) data.parts.emplace_back("disable_notification", disableNotification); @@ -1249,7 +1249,7 @@ bool Api::pinChatMessage(std::int64_t chatId, bool Api::unpinChatMessage(std::int64_t chatId, std::int32_t messageId) const { cpr::Multipart data{}; data.parts.reserve(2); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); if (messageId) data.parts.emplace_back("message_id", messageId); return sendRequest("unpinChatMessage", data); @@ -1258,6 +1258,101 @@ bool Api::unpinChatMessage(std::int64_t chatId, std::int32_t messageId) const { bool Api::unpinAllChatMessages(std::int64_t chatId) const { cpr::Multipart data{}; data.parts.reserve(1); - data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found + data.parts.emplace_back("chat_id", std::to_string(chatId)); return sendRequest("unpinAllChatMessages", data); } + + +bool Api::leaveChat(std::int64_t chatId) const { + cpr::Multipart data{}; + data.parts.reserve(1); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + return sendRequest("leaveChat", data); +} + +Ptr Api::getChat(std::int64_t chatId) const { + cpr::Multipart data{}; + data.parts.reserve(1); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + + nl::json chatObj = sendRequest("getChat", data); + Ptr chat(new Chat(chatObj)); + return chat; +} + +std::vector> Api::getChatAdministrators(std::int64_t chatId) const { + cpr::Multipart data{}; + data.parts.reserve(1); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + + nl::json chatMembersArray = sendRequest("getChatAdministrators", data); + std::vector> chatMembers; + chatMembers.reserve(chatMembersArray.size()); + for (const nl::json& chatMemberObj: chatMembersArray) { + Ptr chatMember(new ChatMember(chatMemberObj)); + chatMembers.push_back(std::move(chatMember)); + } + return chatMembers; +} + +std::int32_t Api::getChatMemberCount(std::int64_t chatId) const { + cpr::Multipart data{}; + data.parts.reserve(1); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + return sendRequest("getChatMemberCount", data); +} + +Ptr Api::getChatMember(std::int64_t chatId, std::int64_t userId) const { + cpr::Multipart data{}; + data.parts.reserve(2); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + data.parts.emplace_back("user_id", std::to_string(userId)); + + nl::json chatMemberObj = sendRequest("getChatMember", data); + Ptr chatMember(new ChatMember(chatMemberObj)); + return chatMember; +} + +bool Api::setChatStickerSet(std::int64_t chatId, const std::string& stickerSetName) const { + cpr::Multipart data{}; + data.parts.reserve(2); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + data.parts.emplace_back("sticker_set_name", stickerSetName); + return sendRequest("setChatStickerSet", data); +} + +bool Api::deleteChatStickerSet(std::int64_t chatId) const { + cpr::Multipart data{}; + data.parts.reserve(1); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + return sendRequest("deleteChatStickerSet", data); +} + +std::vector> Api::getForumTopicIconStickers() const { + nl::json stickersArray = sendRequest("getForumTopicIconStickers"); + std::vector> stickers; + stickers.reserve(stickersArray.size()); + for (const nl::json& stickerObj: stickersArray) { + Ptr sticker(new Sticker(stickerObj)); + stickers.push_back(std::move(sticker)); + } + return stickers; +} + +Ptr Api::createForumTopic(std::int64_t chatId, + const std::string& name, + std::int32_t iconColor, + const std::string& iconCustomEmojiId) const { + cpr::Multipart data{}; + data.parts.reserve(4); + data.parts.emplace_back("chat_id", std::to_string(chatId)); + data.parts.emplace_back("name", name); + if (iconColor) + data.parts.emplace_back("icon_color", iconColor); + if (not iconCustomEmojiId.empty()) + data.parts.emplace_back("icon_custom_emoji_id", iconCustomEmojiId); + + nl::json forumTopicObj = sendRequest("createForumTopic", data); + Ptr forumTopic(new ForumTopic(forumTopicObj)); + return forumTopic; +}