diff options
27 files changed, 1130 insertions, 172 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ecb9e0e..f11f6d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,8 @@ set(SRC_LIST src/net/Url.cpp src/tools/FileTools.cpp src/tools/StringTools.cpp + src/types/BotCommandScope.cpp + src/types/ChatMember.cpp src/types/InlineQueryResult.cpp src/types/InputFile.cpp src/types/InputMedia.cpp @@ -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.2 (Implemented all APIs except 'Run Your Own Bot API Server') +- [x] Bot API 5.0 ~ 5.3 (Implemented all APIs except 'Run Your Own Bot API Server') ## Sample diff --git a/include/tgbot/Api.h b/include/tgbot/Api.h index a2de0a9..51717db 100644 --- a/include/tgbot/Api.h +++ b/include/tgbot/Api.h @@ -655,10 +655,10 @@ public: * * @return True on success. */ - bool kickChatMember(std::int64_t chatId, - std::int64_t userId, - std::uint64_t untilDate = 0, - bool revokeMessages = true) const; + bool banChatMember(std::int64_t chatId, + std::int64_t userId, + std::uint64_t untilDate = 0, + bool revokeMessages = true) const; /** * @brief Use this method to unban a previously kicked user in a supergroup or channel. @@ -893,11 +893,13 @@ public: std::vector<ChatMember::Ptr> getChatAdministrators(std::int64_t chatId) const; /** - * @brief Use this method to get the number of members in a chat. Returns Int on success. - * @param chatId Unique identifier for the target chat of the target supergroup or channel. - * @return Int. + * @brief Use this method to get the number of members in a chat. + * + * @param chatId Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) + * + * @return Int on success. */ - std::int32_t getChatMembersCount(std::int64_t chatId) const; + std::int32_t getChatMemberCount(std::int64_t chatId) const; /** * @brief Use this method to get information about a member of a chat. Returns a ChatMember object on success. @@ -935,16 +937,40 @@ public: /** * @brief Use this method to change the list of the bot's commands. + * See https://core.telegram.org/bots#commands for more details about bot commands. + * * @param commands A JSON-serialized list of bot commands to be set as the list of the bot's commands. At most 100 commands can be specified. + * @param scope Optional. A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault. + * @param languageCode Optional. A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands + * * @return True on success. */ - bool setMyCommands(const std::vector<BotCommand::Ptr>& commands) const; + bool setMyCommands(const std::vector<BotCommand::Ptr>& commands, + BotCommandScope::Ptr scope = nullptr, + const std::string& languageCode = "") const; /** - * @brief Use this method to get the current list of the bot's commands. - * @return Array of @ref BotCommand on success. + * @brief Use this method to delete the list of the bot's commands for the given scope and user language. + * After deletion, higher level commands will be shown to affected users. + * + * @param scope Optional. A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault. + * @param languageCode Optional. A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands + * + * @return True on success. + */ + bool deleteMyCommands(BotCommandScope::Ptr scope = nullptr, + const std::string& languageCode = "") const; + + /** + * @brief Use this method to get the current list of the bot's commands for the given scope and user language. + * + * @param scope Optional. A JSON-serialized object, describing scope of users. Defaults to BotCommandScopeDefault. + * @param languageCode Optional. A two-letter ISO 639-1 language code or an empty string + * + * @return Array of BotCommand on success. If commands aren't set, an empty list is returned. */ - std::vector<BotCommand::Ptr> getMyCommands() const; + std::vector<BotCommand::Ptr> getMyCommands(BotCommandScope::Ptr scope = nullptr, + const std::string& languageCode = "") const; /** * @brief Use this method to edit text and game messages. diff --git a/include/tgbot/TgTypeParser.h b/include/tgbot/TgTypeParser.h index a4482f7..58b11d9 100644 --- a/include/tgbot/TgTypeParser.h +++ b/include/tgbot/TgTypeParser.h @@ -38,6 +38,12 @@ #include "tgbot/types/ReplyKeyboardRemove.h" #include "tgbot/types/ForceReply.h" #include "tgbot/types/ChatMember.h" +#include "tgbot/types/ChatMemberOwner.h" +#include "tgbot/types/ChatMemberAdministrator.h" +#include "tgbot/types/ChatMemberMember.h" +#include "tgbot/types/ChatMemberRestricted.h" +#include "tgbot/types/ChatMemberLeft.h" +#include "tgbot/types/ChatMemberBanned.h" #include "tgbot/types/ChatMemberUpdated.h" #include "tgbot/types/ChatPhoto.h" #include "tgbot/types/ResponseParameters.h" @@ -88,6 +94,14 @@ #include "tgbot/types/SuccessfulPayment.h" #include "tgbot/types/LabeledPrice.h" #include "tgbot/types/BotCommand.h" +#include "tgbot/types/BotCommandScope.h" +#include "tgbot/types/BotCommandScopeDefault.h" +#include "tgbot/types/BotCommandScopeAllPrivateChats.h" +#include "tgbot/types/BotCommandScopeAllGroupChats.h" +#include "tgbot/types/BotCommandScopeAllChatAdministrators.h" +#include "tgbot/types/BotCommandScopeChat.h" +#include "tgbot/types/BotCommandScopeChatAdministrators.h" +#include "tgbot/types/BotCommandScopeChatMember.h" #include "tgbot/types/InputMedia.h" #include "tgbot/types/InputMediaPhoto.h" #include "tgbot/types/InputMediaVideo.h" @@ -268,6 +282,24 @@ public: ChatMember::Ptr parseJsonAndGetChatMember(const boost::property_tree::ptree& data) const; std::string parseChatMember(const ChatMember::Ptr& object) const; + ChatMemberOwner::Ptr parseJsonAndGetChatMemberOwner(const boost::property_tree::ptree& data) const; + std::string parseChatMemberOwner(const ChatMemberOwner::Ptr& object) const; + + ChatMemberAdministrator::Ptr parseJsonAndGetChatMemberAdministrator(const boost::property_tree::ptree& data) const; + std::string parseChatMemberAdministrator(const ChatMemberAdministrator::Ptr& object) const; + + ChatMemberMember::Ptr parseJsonAndGetChatMemberMember(const boost::property_tree::ptree& data) const; + std::string parseChatMemberMember(const ChatMemberMember::Ptr& object) const; + + ChatMemberRestricted::Ptr parseJsonAndGetChatMemberRestricted(const boost::property_tree::ptree& data) const; + std::string parseChatMemberRestricted(const ChatMemberRestricted::Ptr& object) const; + + ChatMemberLeft::Ptr parseJsonAndGetChatMemberLeft(const boost::property_tree::ptree& data) const; + std::string parseChatMemberLeft(const ChatMemberLeft::Ptr& object) const; + + ChatMemberBanned::Ptr parseJsonAndGetChatMemberBanned(const boost::property_tree::ptree& data) const; + std::string parseChatMemberBanned(const ChatMemberBanned::Ptr& object) const; + ChatMemberUpdated::Ptr parseJsonAndGetChatMemberUpdated(const boost::property_tree::ptree& data) const; std::string parseChatMemberUpdated(const ChatMemberUpdated::Ptr& object) const; @@ -391,6 +423,30 @@ public: BotCommand::Ptr parseJsonAndGetBotCommand(const boost::property_tree::ptree& data) const; std::string parseBotCommand(const BotCommand::Ptr& object) const; + BotCommandScope::Ptr parseJsonAndGetBotCommandScope(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScope(const BotCommandScope::Ptr& object) const; + + BotCommandScopeDefault::Ptr parseJsonAndGetBotCommandScopeDefault(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeDefault(const BotCommandScopeDefault::Ptr& object) const; + + BotCommandScopeAllPrivateChats::Ptr parseJsonAndGetBotCommandScopeAllPrivateChats(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeAllPrivateChats(const BotCommandScopeAllPrivateChats::Ptr& object) const; + + BotCommandScopeAllGroupChats::Ptr parseJsonAndGetBotCommandScopeAllGroupChats(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeAllGroupChats(const BotCommandScopeAllGroupChats::Ptr& object) const; + + BotCommandScopeAllChatAdministrators::Ptr parseJsonAndGetBotCommandScopeAllChatAdministrators(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeAllChatAdministrators(const BotCommandScopeAllChatAdministrators::Ptr& object) const; + + BotCommandScopeChat::Ptr parseJsonAndGetBotCommandScopeChat(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeChat(const BotCommandScopeChat::Ptr& object) const; + + BotCommandScopeChatAdministrators::Ptr parseJsonAndGetBotCommandScopeChatAdministrators(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeChatAdministrators(const BotCommandScopeChatAdministrators::Ptr& object) const; + + BotCommandScopeChatMember::Ptr parseJsonAndGetBotCommandScopeChatMember(const boost::property_tree::ptree& data) const; + std::string parseBotCommandScopeChatMember(const BotCommandScopeChatMember::Ptr& object) const; + OrderInfo::Ptr parseJsonAndGetOrderInfo(const boost::property_tree::ptree& data) const; std::string parseOrderInfo(const OrderInfo::Ptr& object) const; diff --git a/include/tgbot/types/BotCommandScope.h b/include/tgbot/types/BotCommandScope.h new file mode 100644 index 0000000..47a3ee9 --- /dev/null +++ b/include/tgbot/types/BotCommandScope.h @@ -0,0 +1,31 @@ +#ifndef TGBOT_BOTCOMMANDSCOPE_H +#define TGBOT_BOTCOMMANDSCOPE_H + +#include <memory> +#include <string> + +namespace TgBot { + +/** + * @brief This abstract class is base of all bot command scopes. + * + * This object represents the scope to which bot commands are applied. + * + * @ingroup types + */ +class BotCommandScope { +public: + typedef std::shared_ptr<BotCommandScope> Ptr; + + BotCommandScope() {} + + virtual ~BotCommandScope() {} + + /** + * @brief Scope type + */ + std::string type; +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPE_H diff --git a/include/tgbot/types/BotCommandScopeAllChatAdministrators.h b/include/tgbot/types/BotCommandScopeAllChatAdministrators.h new file mode 100644 index 0000000..bc814bc --- /dev/null +++ b/include/tgbot/types/BotCommandScopeAllChatAdministrators.h @@ -0,0 +1,27 @@ +#ifndef TGBOT_BOTCOMMANDSCOPEALLCHATADMINISTRATORS_H +#define TGBOT_BOTCOMMANDSCOPEALLCHATADMINISTRATORS_H + +#include "tgbot/types/BotCommandScope.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering all group and supergroup chat administrators. + * + * @ingroup types + */ +class BotCommandScopeAllChatAdministrators : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeAllChatAdministrators> Ptr; + + BotCommandScopeAllChatAdministrators() { + this->type = TYPE; + } +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPEALLCHATADMINISTRATORS_H diff --git a/include/tgbot/types/BotCommandScopeAllGroupChats.h b/include/tgbot/types/BotCommandScopeAllGroupChats.h new file mode 100644 index 0000000..8b709d6 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeAllGroupChats.h @@ -0,0 +1,27 @@ +#ifndef TGBOT_BOTCOMMANDSCOPEALLGROUPCHATS_H +#define TGBOT_BOTCOMMANDSCOPEALLGROUPCHATS_H + +#include "tgbot/types/BotCommandScope.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering all group and supergroup chats. + * + * @ingroup types + */ +class BotCommandScopeAllGroupChats : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeAllGroupChats> Ptr; + + BotCommandScopeAllGroupChats() { + this->type = TYPE; + } +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPEALLGROUPCHATS_H diff --git a/include/tgbot/types/BotCommandScopeAllPrivateChats.h b/include/tgbot/types/BotCommandScopeAllPrivateChats.h new file mode 100644 index 0000000..b2e36b8 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeAllPrivateChats.h @@ -0,0 +1,27 @@ +#ifndef TGBOT_BOTCOMMANDSCOPEALLPRIVATECHATS_H +#define TGBOT_BOTCOMMANDSCOPEALLPRIVATECHATS_H + +#include "tgbot/types/BotCommandScope.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering all private chats. + * + * @ingroup types + */ +class BotCommandScopeAllPrivateChats : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeAllPrivateChats> Ptr; + + BotCommandScopeAllPrivateChats() { + this->type = TYPE; + } +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPEALLPRIVATECHATS_H diff --git a/include/tgbot/types/BotCommandScopeChat.h b/include/tgbot/types/BotCommandScopeChat.h new file mode 100644 index 0000000..fd36125 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeChat.h @@ -0,0 +1,33 @@ +#ifndef TGBOT_BOTCOMMANDSCOPECHAT_H +#define TGBOT_BOTCOMMANDSCOPECHAT_H + +#include "tgbot/types/BotCommandScope.h" + +#include <cstdint> +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering a specific chat. + * + * @ingroup types + */ +class BotCommandScopeChat : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeChat> Ptr; + + BotCommandScopeChat() { + this->type = TYPE; + } + + /** + * @brief Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) + */ + std::int64_t chatId; +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPECHAT_H diff --git a/include/tgbot/types/BotCommandScopeChatAdministrators.h b/include/tgbot/types/BotCommandScopeChatAdministrators.h new file mode 100644 index 0000000..f046e31 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeChatAdministrators.h @@ -0,0 +1,33 @@ +#ifndef TGBOT_BOTCOMMANDSCOPECHATADMINISTRATORS_H +#define TGBOT_BOTCOMMANDSCOPECHATADMINISTRATORS_H + +#include "tgbot/types/BotCommandScope.h" + +#include <cstdint> +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering all administrators of a specific group or supergroup chat. + * + * @ingroup types + */ +class BotCommandScopeChatAdministrators : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeChatAdministrators> Ptr; + + BotCommandScopeChatAdministrators() { + this->type = TYPE; + } + + /** + * @brief Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) + */ + std::int64_t chatId; +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPECHATADMINISTRATORS_H diff --git a/include/tgbot/types/BotCommandScopeChatMember.h b/include/tgbot/types/BotCommandScopeChatMember.h new file mode 100644 index 0000000..5beaee6 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeChatMember.h @@ -0,0 +1,38 @@ +#ifndef TGBOT_BOTCOMMANDSCOPECHATMEMBER_H +#define TGBOT_BOTCOMMANDSCOPECHATMEMBER_H + +#include "tgbot/types/BotCommandScope.h" + +#include <cstdint> +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the scope of bot commands, covering a specific member of a group or supergroup chat. + * + * @ingroup types + */ +class BotCommandScopeChatMember : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeChatMember> Ptr; + + BotCommandScopeChatMember() { + this->type = TYPE; + } + + /** + * @brief Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) + */ + std::int64_t chatId; + + /** + * @brief Unique identifier of the target user + */ + std::int64_t userId; +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPECHATMEMBER_H diff --git a/include/tgbot/types/BotCommandScopeDefault.h b/include/tgbot/types/BotCommandScopeDefault.h new file mode 100644 index 0000000..76b8192 --- /dev/null +++ b/include/tgbot/types/BotCommandScopeDefault.h @@ -0,0 +1,28 @@ +#ifndef TGBOT_BOTCOMMANDSCOPEDEFAULT_H +#define TGBOT_BOTCOMMANDSCOPEDEFAULT_H + +#include "tgbot/types/BotCommandScope.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents the default scope of bot commands. + * Default commands are used if no commands with a narrower scope are specified for the user. + * + * @ingroup types + */ +class BotCommandScopeDefault : public BotCommandScope { +public: + static const std::string TYPE; + + typedef std::shared_ptr<BotCommandScopeDefault> Ptr; + + BotCommandScopeDefault() { + this->type = TYPE; + } +}; +} + +#endif //TGBOT_BOTCOMMANDSCOPEDEFAULT_H diff --git a/include/tgbot/types/ChatMember.h b/include/tgbot/types/ChatMember.h index a7ef856..183cb8b 100644 --- a/include/tgbot/types/ChatMember.h +++ b/include/tgbot/types/ChatMember.h @@ -3,14 +3,15 @@ #include "tgbot/types/User.h" -#include <cstdint> #include <memory> #include <string> namespace TgBot { /** - * @brief This object contains information about one member of the chat. + * @brief This abstract class is base of all chat members. + * + * This object contains information about one member of a chat. * * @ingroup types */ @@ -19,117 +20,19 @@ class ChatMember { public: typedef std::shared_ptr<ChatMember> Ptr; - /** - * @brief Information about the user - */ - User::Ptr user; - - /** - * @brief The member's status in the chat. - * Can be “creator”, “administrator”, “member”, “restricted”, “left” or “kicked” - */ - std::string status; - - /** - * @brief Optional. Owner and administrators only. Custom title for this user - */ - std::string customTitle; - - /** - * @brief Optional. Owner and administrators only. True, if the user's presence in the chat is hidden - */ - bool isAnonymous; - - /** - * @brief Optional. Administrators only. True, if the bot is allowed to edit administrator privileges of that user - */ - bool canBeEdited; - - /** - * @brief Optional. Administrators only. True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. - * Implied by any other administrator privilege - */ - bool canManageChat; - - /** - * @brief Optional. Administrators only. True, if the administrator can post in the channel; channels only - */ - bool canPostMessages; - - /** - * @brief Optional. Administrators only. True, if the administrator can edit messages of other users and can pin messages; channels only - */ - bool canEditMessages; - - /** - * @brief Optional. Administrators only. True, if the administrator can delete messages of other users - */ - bool canDeleteMessages; - - /** - * @brief Optional. Administrators only. True, if the administrator can manage voice chats - */ - bool canManageVoiceChats; + ChatMember() {} - /** - * @brief Optional. Administrators only. True, if the administrator can restrict, ban or unban chat members - */ - bool canRestrictMembers; - - /** - * @brief Optional. Administrators only. True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user) - */ - bool canPromoteMembers; - - /** - * @brief Optional. Administrators and restricted only. True, if the user is allowed to change the chat title, photo and other settings - */ - bool canChangeInfo; - - /** - * @brief Optional. Administrators and restricted only. True, if the user is allowed to invite new users to the chat - */ - bool canInviteUsers; - - /** - * @brief Optional. Administrators and restricted only. True, if the user is allowed to pin messages; groups and supergroups only - */ - bool canPinMessages; - - /** - * @brief Optional. Restricted only. True, if the user is a member of the chat at the moment of the request - */ - bool isMember; - - /** - * @brief Optional. Restricted only. True, if the user is allowed to send text messages, contacts, locations and venues - */ - bool canSendMessages; - - /** - * @brief Optional. Restricted only. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes - */ - bool canSendMediaMessages; - - /** - * @brief Optional. Restricted only. True, if the user is allowed to send polls - */ - bool canSendPolls; - - /** - * @brief Optional. Restricted only. True, if the user is allowed to send animations, games, stickers and use inline bots - */ - bool canSendOtherMessages; + virtual ~ChatMember() {} /** - * @brief Optional. Restricted only. True, if the user is allowed to add web page previews to their messages + * @brief The member's status in the chat */ - bool canAddWebPagePreviews; + std::string status; /** - * @brief Optional. Restricted and kicked only. Date when restrictions will be lifted for this user; unix time + * @brief Information about the user */ - std::uint64_t untilDate; + User::Ptr user; }; } diff --git a/include/tgbot/types/ChatMemberAdministrator.h b/include/tgbot/types/ChatMemberAdministrator.h new file mode 100644 index 0000000..1d5ad6f --- /dev/null +++ b/include/tgbot/types/ChatMemberAdministrator.h @@ -0,0 +1,94 @@ +#ifndef TGBOT_CHATMEMBERADMINISTRATOR_H +#define TGBOT_CHATMEMBERADMINISTRATOR_H + +#include "tgbot/types/ChatMember.h" + +#include <memory> +#include <string> + +namespace TgBot { + +/** + * @brief Represents a chat member that has some additional privileges. + * + * @ingroup types + */ +class ChatMemberAdministrator : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberAdministrator> Ptr; + + ChatMemberAdministrator() { + this->status = STATUS; + } + + /** + * @brief True, if the bot is allowed to edit administrator privileges of that user + */ + bool canBeEdited; + + /** + * @brief Custom title for this user + */ + std::string customTitle; + + /** + * @brief True, if the user's presence in the chat is hidden + */ + bool isAnonymous; + + /** + * @brief True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. + * Implied by any other administrator privilege + */ + bool canManageChat; + + /** + * @brief True, if the administrator can post in the channel; channels only + */ + bool canPostMessages; + + /** + * @brief True, if the administrator can edit messages of other users and can pin messages; channels only + */ + bool canEditMessages; + + /** + * @brief True, if the administrator can delete messages of other users + */ + bool canDeleteMessages; + + /** + * @brief True, if the administrator can manage voice chats + */ + bool canManageVoiceChats; + + /** + * @brief True, if the administrator can restrict, ban or unban chat members + */ + bool canRestrictMembers; + + /** + * @brief True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user) + */ + bool canPromoteMembers; + + /** + * @brief True, if the user is allowed to change the chat title, photo and other settings + */ + bool canChangeInfo; + + /** + * @brief True, if the user is allowed to invite new users to the chat + */ + bool canInviteUsers; + + /** + * @brief True, if the user is allowed to pin messages; groups and supergroups only + */ + bool canPinMessages; +}; +} + +#endif //TGBOT_CHATMEMBERADMINISTRATOR_H diff --git a/include/tgbot/types/ChatMemberBanned.h b/include/tgbot/types/ChatMemberBanned.h new file mode 100644 index 0000000..c54385e --- /dev/null +++ b/include/tgbot/types/ChatMemberBanned.h @@ -0,0 +1,33 @@ +#ifndef TGBOT_CHATMEMBERBANNED_H +#define TGBOT_CHATMEMBERBANNED_H + +#include "tgbot/types/ChatMember.h" + +#include <cstdint> +#include <memory> + +namespace TgBot { + +/** + * @brief Represents a chat member that was banned in the chat and can't return to the chat or view chat messages. + * + * @ingroup types + */ +class ChatMemberBanned : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberBanned> Ptr; + + ChatMemberBanned() { + this->status = STATUS; + } + + /** + * @brief Date when restrictions will be lifted for this user; unix time + */ + std::int32_t untilDate; +}; +} + +#endif //TGBOT_CHATMEMBERBANNED_H diff --git a/include/tgbot/types/ChatMemberLeft.h b/include/tgbot/types/ChatMemberLeft.h new file mode 100644 index 0000000..3431aca --- /dev/null +++ b/include/tgbot/types/ChatMemberLeft.h @@ -0,0 +1,27 @@ +#ifndef TGBOT_CHATMEMBERLEFT_H +#define TGBOT_CHATMEMBERLEFT_H + +#include "tgbot/types/ChatMember.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents a chat member that isn't currently a member of the chat, but may join it themselves. + * + * @ingroup types + */ +class ChatMemberLeft : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberLeft> Ptr; + + ChatMemberLeft() { + this->status = STATUS; + } +}; +} + +#endif //TGBOT_CHATMEMBERLEFT_H diff --git a/include/tgbot/types/ChatMemberMember.h b/include/tgbot/types/ChatMemberMember.h new file mode 100644 index 0000000..6bdccd7 --- /dev/null +++ b/include/tgbot/types/ChatMemberMember.h @@ -0,0 +1,27 @@ +#ifndef TGBOT_CHATMEMBERMEMBER_H +#define TGBOT_CHATMEMBERMEMBER_H + +#include "tgbot/types/ChatMember.h" + +#include <memory> + +namespace TgBot { + +/** + * @brief Represents a chat member that has no additional privileges or restrictions. + * + * @ingroup types + */ +class ChatMemberMember : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberMember> Ptr; + + ChatMemberMember() { + this->status = STATUS; + } +}; +} + +#endif //TGBOT_CHATMEMBERMEMBER_H diff --git a/include/tgbot/types/ChatMemberOwner.h b/include/tgbot/types/ChatMemberOwner.h new file mode 100644 index 0000000..2881a33 --- /dev/null +++ b/include/tgbot/types/ChatMemberOwner.h @@ -0,0 +1,38 @@ +#ifndef TGBOT_CHATMEMBEROWNER_H +#define TGBOT_CHATMEMBEROWNER_H + +#include "tgbot/types/ChatMember.h" + +#include <memory> +#include <string> + +namespace TgBot { + +/** + * @brief Represents a chat member that owns the chat and has all administrator privileges. + * + * @ingroup types + */ +class ChatMemberOwner : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberOwner> Ptr; + + ChatMemberOwner() { + this->status = STATUS; + } + + /** + * @brief Custom title for this user + */ + std::string customTitle; + + /** + * @brief True, if the user's presence in the chat is hidden + */ + bool isAnonymous; +}; +} + +#endif //TGBOT_CHATMEMBEROWNER_H diff --git a/include/tgbot/types/ChatMemberRestricted.h b/include/tgbot/types/ChatMemberRestricted.h new file mode 100644 index 0000000..76a9cd7 --- /dev/null +++ b/include/tgbot/types/ChatMemberRestricted.h @@ -0,0 +1,79 @@ +#ifndef TGBOT_CHATMEMBERRESTRICTED_H +#define TGBOT_CHATMEMBERRESTRICTED_H + +#include "tgbot/types/ChatMember.h" + +#include <cstdint> +#include <memory> + +namespace TgBot { + +/** + * @brief Represents a chat member that is under certain restrictions in the chat. + * Supergroups only. + * + * @ingroup types + */ +class ChatMemberRestricted : public ChatMember { +public: + static const std::string STATUS; + + typedef std::shared_ptr<ChatMemberRestricted> Ptr; + + ChatMemberRestricted() { + this->status = STATUS; + } + + /** + * @brief True, if the user is a member of the chat at the moment of the request + */ + bool isMember; + + /** + * @brief True, if the user is allowed to change the chat title, photo and other settings + */ + bool canChangeInfo; + + /** + * @brief True, if the user is allowed to invite new users to the chat + */ + bool canInviteUsers; + + /** + * @brief True, if the user is allowed to pin messages; groups and supergroups only + */ + bool canPinMessages; + + /** + * @brief True, if the user is allowed to send text messages, contacts, locations and venues + */ + bool canSendMessages; + + /** + * @brief True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes + */ + bool canSendMediaMessages; + + /** + * @brief True, if the user is allowed to send polls + */ + bool canSendPolls; + + /** + * @brief True, if the user is allowed to send animations, games, stickers and use inline bots + */ + bool canSendOtherMessages; + + /** + * @brief True, if the user is allowed to add web page previews to their messages + */ + bool canAddWebPagePreviews; + + /** + * @brief Date when restrictions will be lifted for this user; unix time + */ + std::int32_t untilDate; +}; +} + +#endif //TGBOT_CHATMEMBERRESTRICTED_H diff --git a/include/tgbot/types/ChatPhoto.h b/include/tgbot/types/ChatPhoto.h index 8ee25f1..30c702e 100644 --- a/include/tgbot/types/ChatPhoto.h +++ b/include/tgbot/types/ChatPhoto.h @@ -18,7 +18,7 @@ public: /** * @brief File identifier of small (160x160) chat photo. - * This file_id can be used only for photo download and only for as long as the photo is not changed. + * This fileId can be used only for photo download and only for as long as the photo is not changed. */ std::string smallFileId; @@ -30,7 +30,7 @@ public: /** * @brief File identifier of big (640x640) chat photo. - * This file_id can be used only for photo download and only for as long as the photo is not changed. + * This fileId can be used only for photo download and only for as long as the photo is not changed. */ std::string bigFileId; diff --git a/include/tgbot/types/ForceReply.h b/include/tgbot/types/ForceReply.h index bf4fe0a..83a2d0b 100644 --- a/include/tgbot/types/ForceReply.h +++ b/include/tgbot/types/ForceReply.h @@ -4,16 +4,25 @@ #include "tgbot/types/GenericReply.h" #include <memory> +#include <string> namespace TgBot { /** - * @brief Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot‘s message and tapped ’Reply'). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. + * @brief Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot's message and tapped 'Reply'). + * This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. * - * Example: A poll bot for groups runs in privacy mode (only receives commands, replies to its messages and mentions). There could be two ways to create a new poll: - * Explain the user how to send a command with parameters (e.g. /newpoll question answer1 answer2). May be appealing for hardcore users but lacks modern day polish. - * Guide the user through a step-by-step process. ‘Please send me your question’, ‘Cool, now let’s add the first answer option‘, ’Great. Keep adding answer options, then send /done when you‘re ready’. - * The last option is definitely more attractive. And if you use ForceReply in your bot‘s questions, it will receive the user’s answers even if it only receives replies, commands and mentions — without any extra work for the user. + * Example: A poll bot for groups runs in privacy mode (only receives commands, replies to its messages and mentions). + * There could be two ways to create a new poll: + * + * Explain the user how to send a command with parameters (e.g. /newpoll question answer1 answer2). + * May be appealing for hardcore users but lacks modern day polish. + * + * Guide the user through a step-by-step process. + * 'Please send me your question', 'Cool, now let's add the first answer option', 'Great. Keep adding answer options, then send /done when you're ready'. + * + * The last option is definitely more attractive. + * And if you use ForceReply in your bot's questions, it will receive the user's answers even if it only receives replies, commands and mentions — without any extra work for the user. * * @ingroup types */ @@ -23,16 +32,21 @@ public: typedef std::shared_ptr<ForceReply> Ptr; /** - * @brief Shows reply interface to the user, as if they manually selected the bot‘s message and tapped ’Reply' + * @brief Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply' */ const bool forceReply = true; /** - * @brief Optional. Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. + * @brief Optional. The placeholder to be shown in the input field when the reply is active; 1-64 characters + */ + std::string inputFieldPlaceholder; + + /** + * @brief Optional. Use this parameter if you want to force reply from specific users only. + * Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has replyToMessageId), sender of the original message. */ bool selective = false; }; - } #endif //TGBOT_CPP_FORCEREPLY_H diff --git a/include/tgbot/types/PhotoSize.h b/include/tgbot/types/PhotoSize.h index 97fdd84..5087f09 100644 --- a/include/tgbot/types/PhotoSize.h +++ b/include/tgbot/types/PhotoSize.h @@ -8,7 +8,7 @@ namespace TgBot { /** - * @brief This object represents one size of a photo or a @ref File / @ref Sticker thumbnail. + * @brief This object represents one size of a photo or a file / sticker thumbnail. * * @ingroup types */ diff --git a/include/tgbot/types/ReplyKeyboardMarkup.h b/include/tgbot/types/ReplyKeyboardMarkup.h index 2b65b13..f122934 100644 --- a/include/tgbot/types/ReplyKeyboardMarkup.h +++ b/include/tgbot/types/ReplyKeyboardMarkup.h @@ -5,13 +5,13 @@ #include "tgbot/types/KeyboardButton.h" #include <string> -#include <vector> #include <memory> +#include <vector> namespace TgBot { /** - * @brief This object represents a custom keyboard with reply options. + * @brief This object represents a custom keyboard with reply options (see https://core.telegram.org/bots#keyboards for details and examples). * * @ingroup types */ @@ -21,28 +21,37 @@ public: typedef std::shared_ptr<ReplyKeyboardMarkup> Ptr; /** - * @brief Array of button rows, each represented by an Array of KeyboardButton. + * @brief Array of button rows, each represented by an Array of KeyboardButton objects */ std::vector<std::vector<KeyboardButton::Ptr>> keyboard; /** - * @brief Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard. + * @brief Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). + * Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard. */ - bool resizeKeyboard = false; + bool resizeKeyboard; /** - * @brief Optional. Requests clients to hide the keyboard as soon as it's been used. Defaults to false. + * @brief Optional. Requests clients to hide the keyboard as soon as it's been used. + * The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat – the user can press a special button in the input field to see the custom keyboard again. + * Defaults to false */ - bool oneTimeKeyboard = false; + bool oneTimeKeyboard; /** - * @brief Optional. Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. - * - * Example: A user requests to change the bot‘s language, bot replies to the request with a keyboard to select the new language. Other users in the group don’t see the keyboard. + * @brief Optional. The placeholder to be shown in the input field when the keyboard is active; 1-64 characters */ - bool selective = false; -}; + std::string inputFieldPlaceholder; + /** + * @brief Optional. Use this parameter if you want to show the keyboard to specific users only. + * Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has replyToMessageId), sender of the original message. + * + * Example: A user requests to change the bot's language, bot replies to the request with a keyboard to select the new language. + * Other users in the group don't see the keyboard. + */ + bool selective; +}; } #endif //TGBOT_CPP_REPLYKEYBOARDMARKUP_H diff --git a/src/Api.cpp b/src/Api.cpp index 5cdab54..9fdf290 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -935,10 +935,10 @@ string Api::downloadFile(const string& filePath, const std::vector<HttpReqArg>& return serverResponse; } -bool Api::kickChatMember(std::int64_t chatId, - std::int64_t userId, - std::uint64_t untilDate, - bool revokeMessages) const { +bool Api::banChatMember(std::int64_t chatId, + std::int64_t userId, + std::uint64_t untilDate, + bool revokeMessages) const { vector<HttpReqArg> args; args.reserve(4); @@ -947,7 +947,7 @@ bool Api::kickChatMember(std::int64_t chatId, args.emplace_back("until_date", untilDate); args.emplace_back("revoke_messages", revokeMessages); - return sendRequest("kickChatMember", args).get<bool>("", false); + return sendRequest("banChatMember", args).get<bool>("", false); } bool Api::unbanChatMember(std::int64_t chatId, std::int64_t userId, bool onlyIfBanned) const { @@ -1187,11 +1187,13 @@ vector<ChatMember::Ptr> Api::getChatAdministrators(std::int64_t chatId) const { return _tgTypeParser.parseJsonAndGetArray<ChatMember>(&TgTypeParser::parseJsonAndGetChatMember, sendRequest("getChatAdministrators", args)); } -int32_t Api::getChatMembersCount(std::int64_t chatId) const { +int32_t Api::getChatMemberCount(std::int64_t chatId) const { vector<HttpReqArg> args; args.reserve(1); + args.emplace_back("chat_id", chatId); - return sendRequest("getChatMembersCount", args).get<int32_t>("", 0); + + return sendRequest("getChatMemberCount", args).get<int32_t>("", 0); } ChatMember::Ptr Api::getChatMember(std::int64_t chatId, std::int64_t userId) const { @@ -1236,18 +1238,51 @@ bool Api::answerCallbackQuery(const string& callbackQueryId, const string& text, return sendRequest("answerCallbackQuery", args).get<bool>("", false); } -bool Api::setMyCommands(const std::vector<BotCommand::Ptr>& commands) const { +bool Api::setMyCommands(const std::vector<BotCommand::Ptr>& commands, + BotCommandScope::Ptr scope, + const std::string& languageCode) const { vector<HttpReqArg> args; - args.reserve(5); + args.reserve(3); - string commandsJson = _tgTypeParser.parseArray<BotCommand>(&TgTypeParser::parseBotCommand, commands); - args.emplace_back("commands", commandsJson); + args.emplace_back("commands", _tgTypeParser.parseArray<BotCommand>(&TgTypeParser::parseBotCommand, commands)); + if (scope != nullptr) { + args.emplace_back("scope", _tgTypeParser.parseBotCommandScope(scope)); + } + if (!languageCode.empty()) { + args.emplace_back("language_code", languageCode); + } return sendRequest("setMyCommands", args).get<bool>("", false); } -std::vector<BotCommand::Ptr> Api::getMyCommands() const { - return _tgTypeParser.parseJsonAndGetArray<BotCommand>(&TgTypeParser::parseJsonAndGetBotCommand, sendRequest("getMyCommands")); +bool Api::deleteMyCommands(BotCommandScope::Ptr scope, + const std::string& languageCode) const { + vector<HttpReqArg> args; + args.reserve(2); + + if (scope != nullptr) { + args.emplace_back("scope", _tgTypeParser.parseBotCommandScope(scope)); + } + if (!languageCode.empty()) { + args.emplace_back("language_code", languageCode); + } + + return sendRequest("deleteMyCommands", args).get<bool>("", false); +} + +std::vector<BotCommand::Ptr> Api::getMyCommands(BotCommandScope::Ptr scope, + const std::string& languageCode) const { + vector<HttpReqArg> args; + args.reserve(2); +; + if (scope != nullptr) { + args.emplace_back("scope", _tgTypeParser.parseBotCommandScope(scope)); + } + if (!languageCode.empty()) { + args.emplace_back("language_code", languageCode); + } + + return _tgTypeParser.parseJsonAndGetArray<BotCommand>(&TgTypeParser::parseJsonAndGetBotCommand, sendRequest("getMyCommands", args)); } Message::Ptr Api::editMessageText(const std::string& text, diff --git a/src/TgTypeParser.cpp b/src/TgTypeParser.cpp index 48b542a..330278a 100644 --- a/src/TgTypeParser.cpp +++ b/src/TgTypeParser.cpp @@ -1247,6 +1247,7 @@ ReplyKeyboardMarkup::Ptr TgTypeParser::parseJsonAndGetReplyKeyboardMarkup(const } result->resizeKeyboard = data.get<bool>("resize_keyboard", false); result->oneTimeKeyboard = data.get<bool>("one_time_keyboard", false); + result->inputFieldPlaceholder = data.get<std::string>("input_field_placeholder", ""); result->selective = data.get<bool>("selective", false); return result; } @@ -1272,6 +1273,7 @@ std::string TgTypeParser::parseReplyKeyboardMarkup(const ReplyKeyboardMarkup::Pt result += "],"; appendToJson(result, "resize_keyboard", object->resizeKeyboard); appendToJson(result, "one_time_keyboard", object->oneTimeKeyboard); + appendToJson(result, "input_field_placeholder", object->inputFieldPlaceholder); appendToJson(result, "selective", object->selective); removeLastComma(result); result += '}'; @@ -1341,7 +1343,8 @@ std::string TgTypeParser::parseReplyKeyboardRemove(const ReplyKeyboardRemove::Pt ForceReply::Ptr TgTypeParser::parseJsonAndGetForceReply(const boost::property_tree::ptree& data) const { auto result(std::make_shared<ForceReply>()); - result->selective = data.get<bool>("selective"); + result->inputFieldPlaceholder = data.get<std::string>("input_field_placeholder", ""); + result->selective = data.get<bool>("selective", false); return result; } @@ -1352,6 +1355,7 @@ std::string TgTypeParser::parseForceReply(const ForceReply::Ptr& object) const { std::string result; result += '{'; appendToJson(result, "force_reply", object->forceReply); + appendToJson(result, "input_field_placeholder", object->inputFieldPlaceholder); appendToJson(result, "selective", object->selective); removeLastComma(result); result += '}'; @@ -1359,12 +1363,86 @@ std::string TgTypeParser::parseForceReply(const ForceReply::Ptr& object) const { } ChatMember::Ptr TgTypeParser::parseJsonAndGetChatMember(const boost::property_tree::ptree& data) const { - auto result(std::make_shared<ChatMember>()); + std::string status = data.get<std::string>("status", ""); + ChatMember::Ptr result; + + if (status == ChatMemberOwner::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberOwner(data)); + } else if (status == ChatMemberAdministrator::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberAdministrator(data)); + } else if (status == ChatMemberMember::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberMember(data)); + } else if (status == ChatMemberRestricted::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberRestricted(data)); + } else if (status == ChatMemberLeft::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberLeft(data)); + } else if (status == ChatMemberBanned::STATUS) { + result = std::static_pointer_cast<ChatMember>(parseJsonAndGetChatMemberBanned(data)); + } else { + result = std::make_shared<ChatMember>(); + } + + result->status = status; result->user = tryParseJson<User>(&TgTypeParser::parseJsonAndGetUser, data, "user"); - result->status = data.get<std::string>("status", ""); + + return result; +} + +std::string TgTypeParser::parseChatMember(const ChatMember::Ptr& object) const { + if (!object) { + return ""; + } + std::string result; + result += '{'; + appendToJson(result, "status", object->status); + appendToJson(result, "user", parseUser(object->user)); + + if (object->status == ChatMemberOwner::STATUS) { + result += parseChatMemberOwner(std::static_pointer_cast<ChatMemberOwner>(object)); + } else if (object->status == ChatMemberAdministrator::STATUS) { + result += parseChatMemberAdministrator(std::static_pointer_cast<ChatMemberAdministrator>(object)); + } else if (object->status == ChatMemberMember::STATUS) { + result += parseChatMemberMember(std::static_pointer_cast<ChatMemberMember>(object)); + } else if (object->status == ChatMemberRestricted::STATUS) { + result += parseChatMemberRestricted(std::static_pointer_cast<ChatMemberRestricted>(object)); + } else if (object->status == ChatMemberLeft::STATUS) { + result += parseChatMemberLeft(std::static_pointer_cast<ChatMemberLeft>(object)); + } else if (object->status == ChatMemberBanned::STATUS) { + result += parseChatMemberBanned(std::static_pointer_cast<ChatMemberBanned>(object)); + } + + removeLastComma(result); + result += '}'; + return result; +} + +ChatMemberOwner::Ptr TgTypeParser::parseJsonAndGetChatMemberOwner(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberOwner>()); result->customTitle = data.get<std::string>("custom_title", ""); result->isAnonymous = data.get<bool>("is_anonymous", false); + return result; +} + +std::string TgTypeParser::parseChatMemberOwner(const ChatMemberOwner::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. + std::string result; + appendToJson(result, "custom_title", object->customTitle); + appendToJson(result, "is_anonymous", object->isAnonymous); + // The last comma will be erased by parseChatMember(). + return result; +} + +ChatMemberAdministrator::Ptr TgTypeParser::parseJsonAndGetChatMemberAdministrator(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberAdministrator>()); result->canBeEdited = data.get<bool>("can_be_edited", false); + result->customTitle = data.get<std::string>("custom_title", ""); + result->isAnonymous = data.get<bool>("is_anonymous", false); result->canManageChat = data.get<bool>("can_manage_chat", false); result->canPostMessages = data.get<bool>("can_post_messages", false); result->canEditMessages = data.get<bool>("can_edit_messages", false); @@ -1375,27 +1453,19 @@ ChatMember::Ptr TgTypeParser::parseJsonAndGetChatMember(const boost::property_tr result->canChangeInfo = data.get<bool>("can_change_info", false); result->canInviteUsers = data.get<bool>("can_invite_users", false); result->canPinMessages = data.get<bool>("can_pin_messages", false); - result->isMember = data.get<bool>("is_member", false); - result->canSendMessages = data.get<bool>("can_send_messages", false); - result->canSendMediaMessages = data.get<bool>("can_send_media_messages", false); - result->canSendPolls = data.get<bool>("can_send_polls", false); - result->canSendOtherMessages = data.get<bool>("can_send_other_messages", false); - result->canAddWebPagePreviews = data.get<bool>("can_add_web_page_previews", false); - result->untilDate = data.get<uint64_t>("until_date", 0); return result; } -std::string TgTypeParser::parseChatMember(const ChatMember::Ptr& object) const { +std::string TgTypeParser::parseChatMemberAdministrator(const ChatMemberAdministrator::Ptr& object) const { if (!object) { return ""; } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. std::string result; - result += '{'; - appendToJson(result, "user", parseUser(object->user)); - appendToJson(result, "status", object->status); + appendToJson(result, "can_be_edited", object->canBeEdited); appendToJson(result, "custom_title", object->customTitle); appendToJson(result, "is_anonymous", object->isAnonymous); - appendToJson(result, "can_be_edited", object->canBeEdited); appendToJson(result, "can_manage_chat", object->canManageChat); appendToJson(result, "can_post_messages", object->canPostMessages); appendToJson(result, "can_edit_messages", object->canEditMessages); @@ -1406,15 +1476,97 @@ std::string TgTypeParser::parseChatMember(const ChatMember::Ptr& object) const { appendToJson(result, "can_change_info", object->canChangeInfo); appendToJson(result, "can_invite_users", object->canInviteUsers); appendToJson(result, "can_pin_messages", object->canPinMessages); + // The last comma will be erased by parseChatMember(). + return result; +} + +ChatMemberMember::Ptr TgTypeParser::parseJsonAndGetChatMemberMember(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberMember>()); + return result; +} + +std::string TgTypeParser::parseChatMemberMember(const ChatMemberMember::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseChatMember(). + return result; +} + +ChatMemberRestricted::Ptr TgTypeParser::parseJsonAndGetChatMemberRestricted(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberRestricted>()); + result->isMember = data.get<bool>("is_member", false); + result->canChangeInfo = data.get<bool>("can_change_info", false); + result->canInviteUsers = data.get<bool>("can_invite_users", false); + result->canPinMessages = data.get<bool>("can_pin_messages", false); + result->canSendMessages = data.get<bool>("can_send_messages", false); + result->canSendMediaMessages = data.get<bool>("can_send_media_messages", false); + result->canSendPolls = data.get<bool>("can_send_polls", false); + result->canSendOtherMessages = data.get<bool>("can_send_other_messages", false); + result->canAddWebPagePreviews = data.get<bool>("can_add_web_page_previews", false); + result->untilDate = data.get<uint32_t>("until_date", 0); + return result; +} + +std::string TgTypeParser::parseChatMemberRestricted(const ChatMemberRestricted::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. + std::string result; appendToJson(result, "is_member", object->isMember); + appendToJson(result, "can_change_info", object->canChangeInfo); + appendToJson(result, "can_invite_users", object->canInviteUsers); + appendToJson(result, "can_pin_messages", object->canPinMessages); appendToJson(result, "can_send_messages", object->canSendMessages); appendToJson(result, "can_send_media_messages", object->canSendMediaMessages); appendToJson(result, "can_send_polls", object->canSendPolls); appendToJson(result, "can_send_other_messages", object->canSendOtherMessages); appendToJson(result, "can_add_web_page_previews", object->canAddWebPagePreviews); appendToJson(result, "until_date", object->untilDate); - removeLastComma(result); - result += '}'; + // The last comma will be erased by parseChatMember(). + return result; +} + +ChatMemberLeft::Ptr TgTypeParser::parseJsonAndGetChatMemberLeft(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberLeft>()); + return result; +} + +std::string TgTypeParser::parseChatMemberLeft(const ChatMemberLeft::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseChatMember(). + return result; +} + +ChatMemberBanned::Ptr TgTypeParser::parseJsonAndGetChatMemberBanned(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetChatMember(). + auto result(std::make_shared<ChatMemberBanned>()); + result->untilDate = data.get<uint32_t>("until_date", 0); + return result; +} + +std::string TgTypeParser::parseChatMemberBanned(const ChatMemberBanned::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseChatMember(), so I don't add + // curly brackets to the result std::string. + std::string result; + appendToJson(result, "until_date", object->untilDate); + // The last comma will be erased by parseChatMember(). return result; } @@ -2793,6 +2945,189 @@ std::string TgTypeParser::parseBotCommand(const BotCommand::Ptr& object) const { return result; } +BotCommandScope::Ptr TgTypeParser::parseJsonAndGetBotCommandScope(const boost::property_tree::ptree& data) const { + std::string type = data.get<std::string>("type", ""); + BotCommandScope::Ptr result; + + if (type == BotCommandScopeDefault::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeDefault(data)); + } else if (type == BotCommandScopeAllPrivateChats::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeAllPrivateChats(data)); + } else if (type == BotCommandScopeAllGroupChats::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeAllGroupChats(data)); + } else if (type == BotCommandScopeAllChatAdministrators::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeAllChatAdministrators(data)); + } else if (type == BotCommandScopeChat::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeChat(data)); + } else if (type == BotCommandScopeChatAdministrators::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeChatAdministrators(data)); + } else if (type == BotCommandScopeChatMember::TYPE) { + result = std::static_pointer_cast<BotCommandScope>(parseJsonAndGetBotCommandScopeChatMember(data)); + } else { + result = std::make_shared<BotCommandScope>(); + } + + result->type = type; + + return result; +} + +std::string TgTypeParser::parseBotCommandScope(const BotCommandScope::Ptr& object) const { + if (!object) { + return ""; + } + std::string result; + result += '{'; + appendToJson(result, "type", object->type); + + if (object->type == BotCommandScopeDefault::TYPE) { + result += parseBotCommandScopeDefault(std::static_pointer_cast<BotCommandScopeDefault>(object)); + } else if (object->type == BotCommandScopeAllPrivateChats::TYPE) { + result += parseBotCommandScopeAllPrivateChats(std::static_pointer_cast<BotCommandScopeAllPrivateChats>(object)); + } else if (object->type == BotCommandScopeAllGroupChats::TYPE) { + result += parseBotCommandScopeAllGroupChats(std::static_pointer_cast<BotCommandScopeAllGroupChats>(object)); + } else if (object->type == BotCommandScopeAllChatAdministrators::TYPE) { + result += parseBotCommandScopeAllChatAdministrators(std::static_pointer_cast<BotCommandScopeAllChatAdministrators>(object)); + } else if (object->type == BotCommandScopeChat::TYPE) { + result += parseBotCommandScopeChat(std::static_pointer_cast<BotCommandScopeChat>(object)); + } else if (object->type == BotCommandScopeChatAdministrators::TYPE) { + result += parseBotCommandScopeChatAdministrators(std::static_pointer_cast<BotCommandScopeChatAdministrators>(object)); + } else if (object->type == BotCommandScopeChatMember::TYPE) { + result += parseBotCommandScopeChatMember(std::static_pointer_cast<BotCommandScopeChatMember>(object)); + } + + removeLastComma(result); + result += '}'; + return result; +} + +BotCommandScopeDefault::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeDefault(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeDefault>()); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeDefault(const BotCommandScopeDefault::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeAllPrivateChats::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeAllPrivateChats(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeAllPrivateChats>()); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeAllPrivateChats(const BotCommandScopeAllPrivateChats::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeAllGroupChats::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeAllGroupChats(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeAllGroupChats>()); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeAllGroupChats(const BotCommandScopeAllGroupChats::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeAllChatAdministrators::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeAllChatAdministrators(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeAllChatAdministrators>()); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeAllChatAdministrators(const BotCommandScopeAllChatAdministrators::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeChat::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeChat(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeChat>()); + result->chatId = data.get<std::int64_t>("chat_id", 0); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeChat(const BotCommandScopeChat::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + appendToJson(result, "chat_id", object->chatId); + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeChatAdministrators::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeChatAdministrators(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeChatAdministrators>()); + result->chatId = data.get<std::int64_t>("chat_id", 0); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeChatAdministrators(const BotCommandScopeChatAdministrators::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + appendToJson(result, "chat_id", object->chatId); + // The last comma will be erased by parseBotCommandScope(). + return result; +} + +BotCommandScopeChatMember::Ptr TgTypeParser::parseJsonAndGetBotCommandScopeChatMember(const boost::property_tree::ptree& data) const { + // NOTE: This function will be called by parseJsonAndGetBotCommandScope(). + auto result(std::make_shared<BotCommandScopeChatMember>()); + result->chatId = data.get<std::int64_t>("chat_id", 0); + result->userId = data.get<std::int64_t>("user_id", 0); + return result; +} + +std::string TgTypeParser::parseBotCommandScopeChatMember(const BotCommandScopeChatMember::Ptr& object) const { + if (!object) { + return ""; + } + // This function will be called by parseBotCommandScope(), so I don't add + // curly brackets to the result std::string. + std::string result; + appendToJson(result, "chat_id", object->chatId); + appendToJson(result, "user_id", object->userId); + // The last comma will be erased by parseBotCommandScope(). + return result; +} + OrderInfo::Ptr TgTypeParser::parseJsonAndGetOrderInfo(const boost::property_tree::ptree& data) const { auto result(std::make_shared<OrderInfo>()); result->name = data.get<std::string>("name", ""); diff --git a/src/types/BotCommandScope.cpp b/src/types/BotCommandScope.cpp new file mode 100644 index 0000000..0e52dd8 --- /dev/null +++ b/src/types/BotCommandScope.cpp @@ -0,0 +1,19 @@ +#include "tgbot/types/BotCommandScopeDefault.h" +#include "tgbot/types/BotCommandScopeAllPrivateChats.h" +#include "tgbot/types/BotCommandScopeAllGroupChats.h" +#include "tgbot/types/BotCommandScopeAllChatAdministrators.h" +#include "tgbot/types/BotCommandScopeChat.h" +#include "tgbot/types/BotCommandScopeChatAdministrators.h" +#include "tgbot/types/BotCommandScopeChatMember.h" + +#include <string> + +using namespace TgBot; + +const std::string BotCommandScopeDefault::TYPE = "default"; +const std::string BotCommandScopeAllPrivateChats::TYPE = "all_private_chats"; +const std::string BotCommandScopeAllGroupChats::TYPE = "all_group_chats"; +const std::string BotCommandScopeAllChatAdministrators::TYPE = "all_chat_administrators"; +const std::string BotCommandScopeChat::TYPE = "chat"; +const std::string BotCommandScopeChatAdministrators::TYPE = "chat_administrators"; +const std::string BotCommandScopeChatMember::TYPE = "chat_member"; diff --git a/src/types/ChatMember.cpp b/src/types/ChatMember.cpp new file mode 100644 index 0000000..7f5b704 --- /dev/null +++ b/src/types/ChatMember.cpp @@ -0,0 +1,17 @@ +#include "tgbot/types/ChatMemberOwner.h" +#include "tgbot/types/ChatMemberAdministrator.h" +#include "tgbot/types/ChatMemberMember.h" +#include "tgbot/types/ChatMemberRestricted.h" +#include "tgbot/types/ChatMemberLeft.h" +#include "tgbot/types/ChatMemberBanned.h" + +#include <string> + +using namespace TgBot; + +const std::string ChatMemberOwner::STATUS = "creator"; +const std::string ChatMemberAdministrator::STATUS = "administrator"; +const std::string ChatMemberMember::STATUS = "member"; +const std::string ChatMemberRestricted::STATUS = "restricted"; +const std::string ChatMemberLeft::STATUS = "left"; +const std::string ChatMemberBanned::STATUS = "kicked"; |