diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | include/tgbot/Api.h | 38 | ||||
-rw-r--r-- | include/tgbot/TgTypeParser.h | 4 | ||||
-rw-r--r-- | include/tgbot/types/ChatInviteLink.h | 15 | ||||
-rw-r--r-- | include/tgbot/types/ChatJoinRequest.h | 51 | ||||
-rw-r--r-- | include/tgbot/types/Update.h | 7 | ||||
-rw-r--r-- | src/Api.cpp | 50 | ||||
-rw-r--r-- | src/TgTypeParser.cpp | 34 |
8 files changed, 191 insertions, 10 deletions
@@ -13,7 +13,7 @@ Documentation is located [here](http://reo7sp.github.io/tgbot-cpp). - [x] Bot API 3.0 ~ 3.6 - [x] Bot API 4.0 ~ 4.9 -- [x] Bot API 5.0 ~ 5.3 (Implemented all APIs except 'Run Your Own Bot API Server') +- [x] Bot API 5.0 ~ 5.4 (Implemented all APIs except 'Run Your Own Bot API Server') ## Sample diff --git a/include/tgbot/Api.h b/include/tgbot/Api.h index 51717db..428c8b2 100644 --- a/include/tgbot/Api.h +++ b/include/tgbot/Api.h @@ -612,7 +612,7 @@ public: * We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive. * * @param chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername) - * @param action Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_voice or upload_voice for voice notes, upload_document for general files, find_location for location data, record_video_note or upload_video_note for video notes. + * @param action Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_voice or upload_voice for voice notes, upload_document for general files, choose_sticker for stickers, find_location for location data, record_video_note or upload_video_note for video notes. * * @return True on success. */ @@ -763,12 +763,16 @@ public: * @param chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername) * @param expireDate Optional. Point in time (Unix timestamp) when the link will expire * @param memberLimit Optional. Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 + * @param name Optional. Invite link name; 0-32 characters + * @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 * * @return the new invite link as ChatInviteLink object. */ ChatInviteLink::Ptr createChatInviteLink(std::int64_t chatId, std::int32_t expireDate = 0, - std::int32_t memberLimit = 0) const; + std::int32_t memberLimit = 0, + const std::string& name = "", + bool createsJoinRequest = false) const; /** * @brief Use this method to edit a non-primary invite link created by the bot. @@ -778,13 +782,17 @@ public: * @param inviteLink The invite link to edit * @param expireDate Optional. Point in time (Unix timestamp) when the link will expire * @param memberLimit Optional. Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 + * @param name Optional. Invite link name; 0-32 characters + * @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 * * @return the edited invite link as a ChatInviteLink object. */ ChatInviteLink::Ptr editChatInviteLink(std::int64_t chatId, std::string inviteLink, std::int32_t expireDate = 0, - std::int32_t memberLimit = 0) const; + std::int32_t memberLimit = 0, + const std::string& name = "", + bool createsJoinRequest = false) const; /** * @brief Use this method to revoke an invite link created by the bot. @@ -800,6 +808,30 @@ public: std::string inviteLink) const; /** + * @brief Use this method to approve a chat join request. + * The bot must be an administrator in the chat for this to work and must have the canInviteUsers administrator right. + * + * @param chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername) + * @param userId Unique identifier of the target user + * + * @return True on success. + */ + bool approveChatJoinRequest(std::int64_t chatId, + std::int64_t userId) const; + + /** + * @brief Use this method to decline a chat join request. + * The bot must be an administrator in the chat for this to work and must have the canInviteUsers administrator right. + * + * @param chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername) + * @param userId Unique identifier of the target user + * + * @return True on success. + */ + bool declineChatJoinRequest(std::int64_t chatId, + std::int64_t userId) const; + + /** * @brief Use this method to set a new profile photo for the chat. * * Photos can't be changed for private chats. diff --git a/include/tgbot/TgTypeParser.h b/include/tgbot/TgTypeParser.h index 58b11d9..db96a0b 100644 --- a/include/tgbot/TgTypeParser.h +++ b/include/tgbot/TgTypeParser.h @@ -45,6 +45,7 @@ #include "tgbot/types/ChatMemberLeft.h" #include "tgbot/types/ChatMemberBanned.h" #include "tgbot/types/ChatMemberUpdated.h" +#include "tgbot/types/ChatJoinRequest.h" #include "tgbot/types/ChatPhoto.h" #include "tgbot/types/ResponseParameters.h" #include "tgbot/types/GenericReply.h" @@ -303,6 +304,9 @@ public: ChatMemberUpdated::Ptr parseJsonAndGetChatMemberUpdated(const boost::property_tree::ptree& data) const; std::string parseChatMemberUpdated(const ChatMemberUpdated::Ptr& object) const; + ChatJoinRequest::Ptr parseJsonAndGetChatJoinRequest(const boost::property_tree::ptree& data) const; + std::string parseChatJoinRequest(const ChatJoinRequest::Ptr& object) const; + ChatPhoto::Ptr parseJsonAndGetChatPhoto(const boost::property_tree::ptree& data) const; std::string parseChatPhoto(const ChatPhoto::Ptr& object) const; diff --git a/include/tgbot/types/ChatInviteLink.h b/include/tgbot/types/ChatInviteLink.h index 22de714..b0fb840 100644 --- a/include/tgbot/types/ChatInviteLink.h +++ b/include/tgbot/types/ChatInviteLink.h @@ -31,6 +31,11 @@ public: User::Ptr creator; /** + * @brief True, if users joining the chat via the link need to be approved by chat administrators + */ + bool createsJoinRequest; + + /** * @brief True, if the link is primary */ bool isPrimary; @@ -41,6 +46,11 @@ public: bool isRevoked; /** + * @brief Optional. Invite link name + */ + std::string name; + + /** * @brief Optional. Point in time (Unix timestamp) when the link will expire or has been expired */ std::uint32_t expireDate; @@ -49,6 +59,11 @@ public: * @brief Optional. Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 */ std::uint32_t memberLimit; + + /** + * @brief Optional. Number of pending join requests created using this link + */ + std::uint32_t pendingJoinRequestCount; }; } diff --git a/include/tgbot/types/ChatJoinRequest.h b/include/tgbot/types/ChatJoinRequest.h new file mode 100644 index 0000000..bcd3e4e --- /dev/null +++ b/include/tgbot/types/ChatJoinRequest.h @@ -0,0 +1,51 @@ +#ifndef TGBOT_CPP_CHATJOINREQUEST_H +#define TGBOT_CPP_CHATJOINREQUEST_H + +#include "tgbot/types/Chat.h" +#include "tgbot/types/User.h" +#include "tgbot/types/ChatInviteLink.h" + +#include <cstdint> +#include <memory> +#include <string> + +namespace TgBot { + +/** + * @brief Represents a join request sent to a chat. + * + * @ingroup types + */ +class ChatJoinRequest { + +public: + typedef std::shared_ptr<ChatJoinRequest> Ptr; + + /** + * @brief Chat to which the request was sent + */ + Chat::Ptr chat; + + /** + * @brief User that sent the join request + */ + User::Ptr from; + + /** + * @brief Date the request was sent in Unix time + */ + std::int32_t date; + + /** + * @brief Optional. Bio of the user. + */ + std::string bio; + + /** + * @brief Optional. Chat invite link that was used by the user to send the join request + */ + ChatInviteLink::Ptr inviteLink; +}; +} + +#endif //TGBOT_CPP_CHATJOINREQUEST_H diff --git a/include/tgbot/types/Update.h b/include/tgbot/types/Update.h index 3f15c46..6294ff5 100644 --- a/include/tgbot/types/Update.h +++ b/include/tgbot/types/Update.h @@ -10,6 +10,7 @@ #include "tgbot/types/Poll.h" #include "tgbot/types/PollAnswer.h" #include "tgbot/types/ChatMemberUpdated.h" +#include "tgbot/types/ChatJoinRequest.h" #include <cstdint> #include <memory> @@ -106,6 +107,12 @@ public: * The bot must be an administrator in the chat and must explicitly specify “chatMember” in the list of allowedUpdates to receive these updates. */ ChatMemberUpdated::Ptr chatMember; + + /** + * @brief Optional. A request to join the chat has been sent. + * The bot must have the canInviteUsers administrator right in the chat to receive these updates. + */ + ChatJoinRequest::Ptr chatJoinRequest; }; } diff --git a/src/Api.cpp b/src/Api.cpp index 9fdf290..ad9f544 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -1058,36 +1058,52 @@ string Api::exportChatInviteLink(std::int64_t chatId) const { ChatInviteLink::Ptr Api::createChatInviteLink(std::int64_t chatId, std::int32_t expireDate, - std::int32_t memberLimit) const { + std::int32_t memberLimit, + const std::string& name, + bool createsJoinRequest) const { vector<HttpReqArg> args; - args.reserve(3); + args.reserve(5); args.emplace_back("chat_id", chatId); + if (!name.empty()) { + args.emplace_back("name", name); + } if (expireDate != 0) { args.emplace_back("expire_date", expireDate); } if (memberLimit != 0) { args.emplace_back("member_limit", memberLimit); } + if (createsJoinRequest) { + args.emplace_back("createsJoinRequest", createsJoinRequest); + } return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("createChatInviteLink", args)); } ChatInviteLink::Ptr Api::editChatInviteLink(std::int64_t chatId, - std::string inviteLink, - std::int32_t expireDate, - std::int32_t memberLimit) const { + std::string inviteLink, + std::int32_t expireDate, + std::int32_t memberLimit, + const std::string& name, + bool createsJoinRequest) const { vector<HttpReqArg> args; - args.reserve(4); + args.reserve(6); args.emplace_back("chat_id", chatId); args.emplace_back("invite_link", inviteLink); + if (!name.empty()) { + args.emplace_back("name", name); + } if (expireDate != 0) { args.emplace_back("expire_date", expireDate); } if (memberLimit != 0) { args.emplace_back("member_limit", memberLimit); } + if (createsJoinRequest) { + args.emplace_back("createsJoinRequest", createsJoinRequest); + } return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("editChatInviteLink", args)); } @@ -1103,6 +1119,28 @@ ChatInviteLink::Ptr Api::revokeChatInviteLink(std::int64_t chatId, return _tgTypeParser.parseJsonAndGetChatInviteLink(sendRequest("revokeChatInviteLink", args)); } +bool Api::approveChatJoinRequest(std::int64_t chatId, + std::int64_t userId) const { + vector<HttpReqArg> args; + args.reserve(2); + + args.emplace_back("chat_id", chatId); + args.emplace_back("user_id", userId); + + return sendRequest("approveChatJoinRequest", args).get<bool>("", false); +} + +bool Api::declineChatJoinRequest(std::int64_t chatId, + std::int64_t userId) const { + vector<HttpReqArg> args; + args.reserve(2); + + args.emplace_back("chat_id", chatId); + args.emplace_back("user_id", userId); + + return sendRequest("declineChatJoinRequest", args).get<bool>("", false); +} + bool Api::setChatPhoto(std::int64_t chatId, const InputFile::Ptr photo) const { vector<HttpReqArg> args; args.reserve(2); diff --git a/src/TgTypeParser.cpp b/src/TgTypeParser.cpp index 330278a..ed75e21 100644 --- a/src/TgTypeParser.cpp +++ b/src/TgTypeParser.cpp @@ -997,6 +997,7 @@ Update::Ptr TgTypeParser::parseJsonAndGetUpdate(const boost::property_tree::ptre result->pollAnswer = tryParseJson<PollAnswer>(&TgTypeParser::parseJsonAndGetPollAnswer, data, "poll_answer"); result->myChatMember = tryParseJson<ChatMemberUpdated>(&TgTypeParser::parseJsonAndGetChatMemberUpdated, data, "my_chat_member"); result->chatMember = tryParseJson<ChatMemberUpdated>(&TgTypeParser::parseJsonAndGetChatMemberUpdated, data, "chat_member"); + result->chatJoinRequest = tryParseJson<ChatJoinRequest>(&TgTypeParser::parseJsonAndGetChatJoinRequest, data, "chat_join_request"); return result; } @@ -1020,6 +1021,7 @@ std::string TgTypeParser::parseUpdate(const Update::Ptr& object) const { appendToJson(result, "poll_answer", parsePollAnswer(object->pollAnswer)); appendToJson(result, "my_chat_member", parseChatMemberUpdated(object->myChatMember)); appendToJson(result, "chat_member", parseChatMemberUpdated(object->chatMember)); + appendToJson(result, "chat_join_request", parseChatJoinRequest(object->chatJoinRequest)); removeLastComma(result); result += '}'; return result; @@ -1598,6 +1600,32 @@ std::string TgTypeParser::parseChatMemberUpdated(const ChatMemberUpdated::Ptr& o return result; } +ChatJoinRequest::Ptr TgTypeParser::parseJsonAndGetChatJoinRequest(const boost::property_tree::ptree& data) const { + auto result(std::make_shared<ChatJoinRequest>()); + result->chat = tryParseJson<Chat>(&TgTypeParser::parseJsonAndGetChat, data, "chat"); + result->from = tryParseJson<User>(&TgTypeParser::parseJsonAndGetUser, data, "from"); + result->date = data.get<std::int32_t>("date", 0); + result->bio = data.get<std::string>("bio", ""); + result->inviteLink = tryParseJson<ChatInviteLink>(&TgTypeParser::parseJsonAndGetChatInviteLink, data, "invite_link"); + return result; +} + +std::string TgTypeParser::parseChatJoinRequest(const ChatJoinRequest::Ptr& object) const { + if (!object) { + return ""; + } + std::string result; + result += '{'; + appendToJson(result, "chat", parseChat(object->chat)); + appendToJson(result, "from", parseUser(object->from)); + appendToJson(result, "date", object->date); + appendToJson(result, "bio", object->bio); + appendToJson(result, "invite_link", parseChatInviteLink(object->inviteLink)); + removeLastComma(result); + result += '}'; + return result; +} + ChatPhoto::Ptr TgTypeParser::parseJsonAndGetChatPhoto(const boost::property_tree::ptree& data) const { auto result(std::make_shared<ChatPhoto>()); result->smallFileId = data.get<std::string>("small_file_id", ""); @@ -1626,10 +1654,13 @@ ChatInviteLink::Ptr TgTypeParser::parseJsonAndGetChatInviteLink(const boost::pro auto result(std::make_shared<ChatInviteLink>()); result->inviteLink = data.get<std::string>("invite_link", ""); result->creator = tryParseJson<User>(&TgTypeParser::parseJsonAndGetUser, data, "creator"); + result->createsJoinRequest = data.get<bool>("creates_join_request", false); result->isPrimary = data.get<bool>("is_primary", false); result->isRevoked = data.get<bool>("is_revoked", false); + result->name = data.get<std::string>("name", ""); result->expireDate = data.get<std::int32_t>("expire_date", 0); result->memberLimit = data.get<std::int32_t>("member_limit", 0); + result->pendingJoinRequestCount = data.get<std::int32_t>("pending_join_request_count", 0); return result; } @@ -1641,10 +1672,13 @@ std::string TgTypeParser::parseChatInviteLink(const ChatInviteLink::Ptr& object) result += '{'; appendToJson(result, "invite_link", object->inviteLink); appendToJson(result, "creator", parseUser(object->creator)); + appendToJson(result, "creates_join_request", object->createsJoinRequest); appendToJson(result, "is_primary", object->isPrimary); appendToJson(result, "is_revoked", object->isRevoked); + appendToJson(result, "name", object->name); appendToJson(result, "expire_date", object->expireDate); appendToJson(result, "member_limit", object->memberLimit); + appendToJson(result, "pending_join_request_count", object->pendingJoinRequestCount); removeLastComma(result); result += '}'; return result; |