#ifndef TGBOT_EVENTBROADCASTER_H #define TGBOT_EVENTBROADCASTER_H #include "tgbot/export.h" #include "tgbot/types/Message.h" #include "tgbot/types/InlineQuery.h" #include "tgbot/types/ChosenInlineResult.h" #include "tgbot/types/CallbackQuery.h" #include "tgbot/types/ShippingQuery.h" #include "tgbot/types/PreCheckoutQuery.h" #include "tgbot/types/Poll.h" #include "tgbot/types/PollAnswer.h" #include "tgbot/types/ChatMemberUpdated.h" #include "tgbot/types/ChatJoinRequest.h" #include #include #include #include #include namespace TgBot { class EventHandler; /** * @brief This class holds all event listeners. * * @ingroup general */ class TGBOT_API EventBroadcaster { friend EventHandler; public: typedef std::function MessageListener; typedef std::function InlineQueryListener; typedef std::function ChosenInlineResultListener; typedef std::function CallbackQueryListener; typedef std::function ShippingQueryListener; typedef std::function PreCheckoutQueryListener; typedef std::function PollListener; typedef std::function PollAnswerListener; typedef std::function ChatMemberUpdatedListener; typedef std::function ChatJoinRequestListener; /** * @brief Registers listener which receives new incoming message of any kind - text, photo, sticker, etc. * @param listener Listener. */ inline void onAnyMessage(const MessageListener& listener) { _onAnyMessageListeners.push_back(listener); } /** * @brief Registers listener which receives all messages with commands (messages with leading '/' char). * @param commandName Command name which listener can handle. * @param listener Listener. Pass nullptr to remove listener of command */ inline void onCommand(const std::string& commandName, const MessageListener& listener) { if (listener) { _onCommandListeners[commandName] = listener; } else { _onCommandListeners.erase(commandName); } } /** * @brief Registers listener which receives all messages with commands (messages with leading '/' char). * @param commandsList Commands names which listener can handle. * @param listener Listener. Pass nullptr to remove listener of commands */ inline void onCommand(const std::initializer_list& commandsList, const MessageListener& listener) { if (listener) { for (const auto& command : commandsList) { _onCommandListeners[command] = listener; } } else { for (const auto& command : commandsList) { _onCommandListeners.erase(command); } } } /** * @brief Registers listener which receives all messages with commands (messages with leading '/' char) which haven't been handled by other listeners. * @param listener Listener. */ inline void onUnknownCommand(const MessageListener& listener) { _onUnknownCommandListeners.push_back(listener); } /** * @brief Registers listener which receives all messages without commands (messages with no leading '/' char) * @param listener Listener. */ inline void onNonCommandMessage(const MessageListener& listener) { _onNonCommandMessageListeners.push_back(listener); } /** * @brief Registers listener which receives new versions of a message that is known to the bot and was edited * @param listener Listener. */ inline void onEditedMessage(const MessageListener& listener) { _onEditedMessageListeners.push_back(listener); } /** * @brief Registers listener which receives new incoming inline queries * @param listener Listener. */ inline void onInlineQuery(const InlineQueryListener& listener) { _onInlineQueryListeners.push_back(listener); } /** * @brief Registers listener which receives the results of an inline query that was chosen by a user and sent to their chat partner. * Please see https://core.telegram.org/bots/inline#collecting-feedback for details on how to enable these updates for your bot. * * @param listener Listener. */ inline void onChosenInlineResult(const ChosenInlineResultListener& listener){ _onChosenInlineResultListeners.push_back(listener); } /** * @brief Registers listener which receives new incoming callback queries * @param listener Listener. */ inline void onCallbackQuery(const CallbackQueryListener& listener){ _onCallbackQueryListeners.push_back(listener); } /** * @brief Registers listener which receives new incoming shipping queries. * Only for invoices with flexible price * * @param listener Listener. */ inline void onShippingQuery(const ShippingQueryListener& listener){ _onShippingQueryListeners.push_back(listener); } /** * @brief Registers listener which receives new incoming pre-checkout queries. * Contains full information about checkout * * @param listener Listener. */ inline void onPreCheckoutQuery(const PreCheckoutQueryListener& listener){ _onPreCheckoutQueryListeners.push_back(listener); } /** * @brief Registers listener which receives new poll states. * Bots receive only updates about stopped polls and polls, which are sent by the bot * * @param listener Listener. */ inline void onPoll(const PollListener& listener){ _onPollListeners.push_back(listener); } /** * @brief Registers listener which receives an answer if a user changed their answer in a non-anonymous poll. * Bots receive new votes only in polls that were sent by the bot itself. * * @param listener Listener. */ inline void onPollAnswer(const PollAnswerListener& listener){ _onPollAnswerListeners.push_back(listener); } /** * @brief Registers listener which receives the bot's chat member status if it was updated in a chat. * For private chats, this update is received only when the bot is blocked or unblocked by the user. * * @param listener Listener. */ inline void onMyChatMember(const ChatMemberUpdatedListener& listener){ _onMyChatMemberListeners.push_back(listener); } /** * @brief Registers listener which receives a status if a chat member's status was updated in a chat. * The bot must be an administrator in the chat and must explicitly specify “chat_member” in the list of allowedUpdates to receive these updates. * * @param listener Listener. */ inline void onChatMember(const ChatMemberUpdatedListener& listener){ _onChatMemberListeners.push_back(listener); } /** * @brief Registers listener which receives requests to join the chat. * The bot must have the canInviteUsers administrator right in the chat to receive these updates. * * @param listener Listener. */ inline void onChatJoinRequest(const ChatJoinRequestListener& listener){ _onChatJoinRequestListeners.push_back(listener); } private: template inline void broadcast(const std::vector& listeners, const ObjectType object) const { if (!object) return; for (const ListenerType& item : listeners) { item(object); } } inline void broadcastAnyMessage(const Message::Ptr& message) const { broadcast(_onAnyMessageListeners, message); } inline bool broadcastCommand(const std::string& command, const Message::Ptr& message) const { auto iter = _onCommandListeners.find(command); if (iter == _onCommandListeners.end()) { return false; } iter->second(message); return true; } inline void broadcastUnknownCommand(const Message::Ptr& message) const { broadcast(_onUnknownCommandListeners, message); } inline void broadcastNonCommandMessage(const Message::Ptr& message) const { broadcast(_onNonCommandMessageListeners, message); } inline void broadcastEditedMessage(const Message::Ptr& message) const { broadcast(_onEditedMessageListeners, message); } inline void broadcastInlineQuery(const InlineQuery::Ptr& query) const { broadcast(_onInlineQueryListeners, query); } inline void broadcastChosenInlineResult(const ChosenInlineResult::Ptr& result) const { broadcast(_onChosenInlineResultListeners, result); } inline void broadcastCallbackQuery(const CallbackQuery::Ptr& result) const { broadcast(_onCallbackQueryListeners, result); } inline void broadcastShippingQuery(const ShippingQuery::Ptr& result) const { broadcast(_onShippingQueryListeners, result); } inline void broadcastPreCheckoutQuery(const PreCheckoutQuery::Ptr& result) const { broadcast(_onPreCheckoutQueryListeners, result); } inline void broadcastPoll(const Poll::Ptr& result) const { broadcast(_onPollListeners, result); } inline void broadcastPollAnswer(const PollAnswer::Ptr& result) const { broadcast(_onPollAnswerListeners, result); } inline void broadcastMyChatMember(const ChatMemberUpdated::Ptr& result) const { broadcast(_onMyChatMemberListeners, result); } inline void broadcastChatMember(const ChatMemberUpdated::Ptr& result) const { broadcast(_onChatMemberListeners, result); } inline void broadcastChatJoinRequest(const ChatJoinRequest::Ptr& result) const { broadcast(_onChatJoinRequestListeners, result); } std::vector _onAnyMessageListeners; std::unordered_map _onCommandListeners; std::vector _onUnknownCommandListeners; std::vector _onNonCommandMessageListeners; std::vector _onEditedMessageListeners; std::vector _onInlineQueryListeners; std::vector _onChosenInlineResultListeners; std::vector _onCallbackQueryListeners; std::vector _onShippingQueryListeners; std::vector _onPreCheckoutQueryListeners; std::vector _onPollListeners; std::vector _onPollAnswerListeners; std::vector _onMyChatMemberListeners; std::vector _onChatMemberListeners; std::vector _onChatJoinRequestListeners; }; } #endif //TGBOT_EVENTBROADCASTER_H