diff --git a/etc/dtranslatebot.json b/etc/dtranslatebot.json index 6a46836..8c43ddc 100644 --- a/etc/dtranslatebot.json +++ b/etc/dtranslatebot.json @@ -1,25 +1,27 @@ { - "token": "bot_token", + "token": "$bot_token", "guilds": { - "guild_1": { - "channel_1": { + "$guild1_id": { + "$channel1_id": { "source": "en", "target": "de", - "webhook": "https://german.webhook" + "webhook": "https://discord.com/api/webhooks/$guild1_de_webhook_id/$guild1_de_webhook_token" }, - "channel_2": { + "$channel2_id": { "source": "de", "target": "en", - "webhook": "https://english.webhook" + "webhook": "https://discord.com/api/webhooks/$guild1_en_webhook_id/$guild1_en_webhook_token" } }, - "guild_2": { - "channel_1": { + "My Discord Guild": { + "id": "$guild2_id", + "General English": { + "id": "$channel3_id", "source": "en", "target": { - "de": "https://german.webhook", - "fr": "https://french.webhook", - "ru": "https://russian.webhook" + "de": "https://discord.com/api/webhooks/$guild2_de_webhook_id/$guild2_de_webhook_token", + "fr": "https://discord.com/api/webhooks/$guild2_fr_webhook_id/$guild2_fr_webhook_token", + "ru": "https://discord.com/api/webhooks/$guild2_ru_webhook_id/$guild2_ru_webhook_token" } } } diff --git a/src/main.cpp b/src/main.cpp index d82b786..f8e0d93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,18 +44,16 @@ int main(int argc, char* argv[]) { return; settings.lock(); - bot::settings::guild *guild = settings.get_guild(event.msg.guild_id); - if (guild) { - bot::settings::channel *channel = settings.get_channel(guild, event.msg.channel_id); - if (channel) { - bot::message message; - message.author = event.msg.author.format_username(); - message.avatar = event.msg.author.avatar.to_string(); - message.message = event.msg.content; - message.source = channel->source; - message.targets = channel->targets; - message_queue.add(message); - } + bot::settings::channel *channel = settings.get_channel(event.msg.guild_id, event.msg.channel_id); + if (channel) { + bot::message message; + message.id = event.msg.id; + message.author = event.msg.author.format_username(); + message.avatar = event.msg.author.avatar.to_string(); + message.message = event.msg.content; + message.source = channel->source; + message.targets = channel->targets; + message_queue.add(message); } settings.unlock(); }); diff --git a/src/message_queue.cpp b/src/message_queue.cpp index 0197bee..1927c7a 100644 --- a/src/message_queue.cpp +++ b/src/message_queue.cpp @@ -51,7 +51,7 @@ void bot::message_queue::run(dpp::cluster *bot, bot::settings::settings *setting dpp::json json_body = { {"q", message.message}, {"source", message.source}, - {"target", target->first}, + {"target", target->target}, {"format", "text"}, }; @@ -72,13 +72,13 @@ void bot::message_queue::run(dpp::cluster *bot, bot::settings::settings *setting } } - dpp::webhook webhook(target->second); + dpp::webhook webhook(target->webhook); webhook.name = message.author; try { bot->execute_webhook_sync(webhook, dpp::message(tr_message)); } - catch (dpp::rest_exception &exception) { + catch (const dpp::rest_exception &exception) { std::cerr << "REST Error: " << exception.what() << std::endl; } } diff --git a/src/message_queue.h b/src/message_queue.h index 8f0ba21..34a1712 100644 --- a/src/message_queue.h +++ b/src/message_queue.h @@ -26,11 +26,12 @@ namespace bot { struct message { + uint64_t id; std::string author; std::string avatar; std::string message; std::string source; - std::vector> targets; + std::vector targets; }; class message_queue { diff --git a/src/settings.cpp b/src/settings.cpp index 3aed006..3fb1151 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "settings.h" bot::settings::channel* bot::settings::settings::get_channel(bot::settings::guild *guild, uint64_t channel_id) @@ -31,6 +30,19 @@ bot::settings::channel* bot::settings::settings::get_channel(bot::settings::guil return nullptr; } +bot::settings::channel* bot::settings::settings::get_channel(uint64_t guild_id, uint64_t channel_id) +{ + for (auto guild = m_guilds.begin(); guild != m_guilds.end(); guild++) { + if (guild->id == guild_id) { + for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) { + if (channel->id == channel_id) + return &(*channel); + } + } + } + return nullptr; +} + bot::settings::guild* bot::settings::settings::get_guild(uint64_t guild_id) { for (auto guild = m_guilds.begin(); guild != m_guilds.end(); guild++) { @@ -66,20 +78,20 @@ bool bot::settings::settings::parse(const std::string &filename) std::string sdata(std::istreambuf_iterator{ifs}, {}); ifs.close(); - dpp::json json = dpp::json::parse(sdata); - if (!json.is_object()) { - std::cerr << "JSON configuration file is corrupt" << std::endl; - return false; - } - - auto json_token = json.find("token"); - if (json_token == json.end()) { - std::cerr << "Bot token can not be found" << std::endl; - return false; - } - - const std::lock_guard guard(m_mutex); try { + dpp::json json = dpp::json::parse(sdata); + if (!json.is_object()) { + std::cerr << "JSON configuration file is corrupt" << std::endl; + return false; + } + + auto json_token = json.find("token"); + if (json_token == json.end()) { + std::cerr << "Bot token can not be found" << std::endl; + return false; + } + + const std::lock_guard guard(m_mutex); m_token = json_token.value(); auto json_translate = json.find("translate"); @@ -131,31 +143,60 @@ bool bot::settings::settings::parse(const std::string &filename) for (auto json_guild = json_guilds.value().begin(); json_guild != json_guilds.value().end(); json_guild++) { if (json_guild.value().is_object()) { bot::settings::guild guild; - guild.id = std::stoull(json_guild.key()); + + auto json_guild_id = json_guild.value().find("id"); + if (json_guild_id != json_guild.value().end()) { + if (json_guild_id->is_number()) + guild.id = json_guild_id.value(); + else if (json_guild_id->is_string()) + guild.id = std::stoull(std::string(json_guild_id.value())); + else + throw std::invalid_argument("Guild id is not a number or a string"); + } + else + guild.id = std::stoull(json_guild.key()); + for (auto json_channel = json_guild.value().begin(); json_channel != json_guild.value().end(); json_channel++) { - bot::settings::channel channel; - channel.id = std::stoull(json_channel.key()); + if (json_channel.value().is_object()) { + bot::settings::channel channel; - auto json_channel_source = json_channel.value().find("source"); - if (json_channel_source != json_channel.value().end()) - channel.source = json_channel_source.value(); - - auto json_channel_target = json_channel.value().find("target"); - if (json_channel_target != json_channel.value().end()) { - if (json_channel_target.value().is_string()) { - const std::string target = json_channel_target.value(); - const std::string webhook = json_channel->at("webhook"); - channel.targets.push_back(std::make_pair(target, webhook)); + auto json_channel_id = json_channel.value().find("id"); + if (json_channel_id != json_channel.value().end()) { + if (json_channel_id->is_number()) + channel.id = json_channel_id.value(); + else if (json_channel_id->is_string()) + channel.id = std::stoull(std::string(json_channel_id.value())); + else + throw std::invalid_argument("Channel id is not a number or a string"); } - else if (json_channel_target.value().is_object()) { - for (auto json_target = json_channel_target.value().begin(); json_target != json_channel_target.value().end(); json_target++) { - channel.targets.push_back(std::make_pair(json_target.key(), json_target.value())); + else + channel.id = std::stoull(json_channel.key()); + + auto json_channel_source = json_channel.value().find("source"); + if (json_channel_source != json_channel.value().end()) + channel.source = json_channel_source.value(); + + auto json_channel_target = json_channel.value().find("target"); + if (json_channel_target != json_channel.value().end()) { + if (json_channel_target.value().is_string()) { + bot::settings::target target; + target.target = json_channel_target.value(); + target.webhook = json_channel->at("webhook"); + channel.targets.push_back(target); + } + else if (json_channel_target.value().is_object()) { + for (auto json_target = json_channel_target.value().begin(); json_target != json_channel_target.value().end(); json_target++) { + bot::settings::target target; + target.target = json_target.key(); + target.webhook = json_target.value(); + channel.targets.push_back(target); + } } } - } - if (!channel.source.empty() && !channel.targets.empty()) - guild.channel.push_back(channel); + if (!channel.source.empty() && !channel.targets.empty()) + guild.channel.push_back(channel); + } } m_guilds.push_back(guild); } @@ -163,6 +204,9 @@ bool bot::settings::settings::parse(const std::string &filename) } return true; } + catch (const dpp::json::exception &exception) { + std::cerr << "Exception thrown while parsing configuration: " << exception.what() << std::endl; + } catch (const std::exception &exception) { std::cerr << "Exception thrown while parsing configuration: " << exception.what() << std::endl; } diff --git a/src/settings.h b/src/settings.h index 6f9cc4b..e359afc 100644 --- a/src/settings.h +++ b/src/settings.h @@ -25,10 +25,14 @@ namespace bot { namespace settings { + struct target { + std::string target; + std::string webhook; + }; struct channel { uint64_t id; std::string source; - std::vector> targets; + std::vector targets; }; struct guild { uint64_t id; @@ -45,6 +49,7 @@ namespace bot { class settings { public: bot::settings::channel* get_channel(bot::settings::guild *guild, uint64_t channel_id); + bot::settings::channel* get_channel(uint64_t guild_id, uint64_t channel_id); bot::settings::guild* get_guild(uint64_t guild_id); bot::settings::translate* get_translate(); const std::string get_token();