#pragma once #include #include #include #include #include #include #include "../utils/string.hpp" namespace bot { namespace irc { enum MessageType { Privmsg, Ping, Notice }; std::optional define_message_type(const std::string &msg); struct IRCMessage { std::map tags; std::string prefix, nick, command; std::vector params; static std::optional from_string(std::string msg); }; struct MessageSender { std::string login; std::string display_name; int id; std::map badges; // More fields will be here }; struct MessageSource { std::string login; int id; }; template struct Message; template <> struct Message { MessageSender sender; MessageSource source; std::string message; }; template std::optional> parse_message(const IRCMessage &msg) { if (T == MessageType::Privmsg && msg.command == "PRIVMSG") { MessageSender sender; MessageSource source; sender.login = msg.nick; sender.display_name = msg.tags.at("display-name"); sender.id = std::stoi(msg.tags.at("user-id")); for (const std::string &badge : utils::string::split_text(msg.tags.at("badges"), ',')) { auto b = utils::string::split_text_n(badge, "/", 1); sender.badges.insert_or_assign(b[0], std::stoi(b[1])); } source.login = msg.params.front(); if (source.login[0] == '#') { source.login = source.login.substr(1); } source.id = std::stoi(msg.tags.at("room-id")); Message message; message.sender = sender; message.source = source; message.message = msg.params.at(1); return message; } return std::nullopt; } template struct MessageHandler; template <> struct MessageHandler { using fn = std::function message)>; }; } }