diff options
| -rw-r--r-- | localization/english.json | 5 | ||||
| -rw-r--r-- | localization/russian.json | 5 | ||||
| -rw-r--r-- | src/commands/command.cpp | 2 | ||||
| -rw-r--r-- | src/localization/line_id.cpp | 6 | ||||
| -rw-r--r-- | src/localization/line_id.hpp | 5 | ||||
| -rw-r--r-- | src/modules/notify.hpp | 131 |
6 files changed, 151 insertions, 3 deletions
diff --git a/localization/english.json b/localization/english.json index b086f6d..29b9858 100644 --- a/localization/english.json +++ b/localization/english.json @@ -20,5 +20,8 @@ "ping.response": "{sender.alias_name}: Pong! Uptime: %s · Used memory: %sMB", "event.on": "{sender.alias_name}: New event \"%s\" has been successfully created!", - "event.off": "{sender.alias_name}: The event \"%s\" has been deleted!" + "event.off": "{sender.alias_name}: The event \"%s\" has been deleted!", + + "notify.sub": "{sender.alias_name}: You have been successfully subscribed to the \"%s\" event!", + "notify.unsub": "{sender.alias_name}: You have been unsubscribed from the \"%s\" event!" } diff --git a/localization/russian.json b/localization/russian.json index f0cce77..a29068c 100644 --- a/localization/russian.json +++ b/localization/russian.json @@ -20,5 +20,8 @@ "ping.response": "{sender.alias_name}: Понг! Время сессии: %s · ОЗУ: %sМБ", "event.on": "{sender.alias_name}: Событие \"%s\" успешно создано!", - "event.off": "{sender.alias_name}: Событие \"%s\" удалено!" + "event.off": "{sender.alias_name}: Событие \"%s\" удалено!", + + "notify.sub": "{sender.alias_name}: Вы успешно подписались на событие \"%s\"!", + "notify.unsub": "{sender.alias_name}: Вы отписались от события \"%s\"!" } diff --git a/src/commands/command.cpp b/src/commands/command.cpp index 46dc03b..dfb1fbf 100644 --- a/src/commands/command.cpp +++ b/src/commands/command.cpp @@ -11,6 +11,7 @@ #include "../bundle.hpp" #include "../modules/event.hpp" #include "../modules/massping.hpp" +#include "../modules/notify.hpp" #include "../modules/ping.hpp" #include "../utils/chrono.hpp" #include "request.hpp" @@ -21,6 +22,7 @@ namespace bot { this->add_command(std::make_unique<mod::Ping>()); this->add_command(std::make_unique<mod::Massping>()); this->add_command(std::make_unique<mod::Event>()); + this->add_command(std::make_unique<mod::Notify>()); } void CommandLoader::add_command(std::unique_ptr<Command> command) { diff --git a/src/localization/line_id.cpp b/src/localization/line_id.cpp index d2a2af9..2eca697 100644 --- a/src/localization/line_id.cpp +++ b/src/localization/line_id.cpp @@ -50,6 +50,12 @@ namespace bot { return LineId::EventOff; } + else if (str == "notify.sub") { + return LineId::NotifySub; + } else if (str == "notify.unsub") { + return LineId::NotifyUnsub; + } + else { return std::nullopt; } diff --git a/src/localization/line_id.hpp b/src/localization/line_id.hpp index 3cd46c0..264be15 100644 --- a/src/localization/line_id.hpp +++ b/src/localization/line_id.hpp @@ -27,7 +27,10 @@ namespace bot { PingResponse, EventOn, - EventOff + EventOff, + + NotifySub, + NotifyUnsub }; std::optional<LineId> string_to_line_id(const std::string &str); diff --git a/src/modules/notify.hpp b/src/modules/notify.hpp new file mode 100644 index 0000000..3587e73 --- /dev/null +++ b/src/modules/notify.hpp @@ -0,0 +1,131 @@ +#pragma once + +#include <string> +#include <variant> +#include <vector> + +#include "../bundle.hpp" +#include "../commands/command.hpp" +#include "../commands/response_error.hpp" +#include "../schemas/stream.hpp" + +namespace bot { + namespace mod { + class Notify : public command::Command { + std::string get_name() const override { return "notify"; } + + std::vector<std::string> get_subcommand_ids() const override { + return {"sub", "unsub"}; + } + + std::variant<std::vector<std::string>, std::string> run( + const InstanceBundle &bundle, + const command::Request &request) const override { + if (!request.subcommand_id.has_value()) { + throw ResponseException<NOT_ENOUGH_ARGUMENTS>( + request, bundle.localization, command::SUBCOMMAND); + } + + const std::string &subcommand_id = request.subcommand_id.value(); + + if (!request.message.has_value()) { + throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( + request, bundle.localization, command::CommandArgument::TARGET); + } + + const std::string &message = request.message.value(); + std::vector<std::string> s = utils::string::split_text(message, ' '); + + std::string target; + schemas::EventType type; + + std::vector<std::string> target_and_type = + utils::string::split_text(s[0], ':'); + + if (target_and_type.size() != 2) { + throw ResponseException<ResponseError::INCORRECT_ARGUMENT>( + request, bundle.localization, s[0]); + } + + s.erase(s.begin()); + + target = target_and_type[0]; + type = schemas::string_to_event_type(target_and_type[1]); + + std::string t = target_and_type[0] + ":" + target_and_type[1]; + + auto channels = bundle.helix_client.get_users({target}); + api::twitch::schemas::User channel; + + if (channels.empty() && type != schemas::EventType::CUSTOM) { + throw ResponseException<ResponseError::NOT_FOUND>( + request, bundle.localization, t); + } + + pqxx::work work(request.conn); + std::string query; + + if (type != schemas::CUSTOM) { + channel = channels[0]; + + query = "SELECT id FROM events WHERE channel_id = " + + std::to_string(request.channel.get_id()) + + " AND target_alias_id = " + std::to_string(channel.id) + + " AND event_type = " + std::to_string(type); + } else { + query = "SELECT id FROM events WHERE channel_id = " + + std::to_string(request.channel.get_id()) + + " AND custom_alias_id = '" + target + + "' AND event_type = " + std::to_string(type); + } + + pqxx::result events = work.exec(query); + + if (events.empty()) { + throw ResponseException<ResponseError::NOT_FOUND>( + request, bundle.localization, t); + } + + pqxx::row event = events[0]; + + pqxx::result subs = + work.exec("SELECT id FROM event_subscriptions WHERE event_id = " + + std::to_string(event[0].as<int>()) + " AND user_id = " + + std::to_string(request.user.get_id())); + + if (subcommand_id == "sub") { + if (!subs.empty()) { + throw ResponseException<ResponseError::NAMESAKE_CREATION>( + request, bundle.localization, t); + } + + work.exec( + "INSERT INTO event_subscriptions(event_id, user_id) VALUES (" + + std::to_string(event[0].as<int>()) + ", " + + std::to_string(request.user.get_id())); + work.commit(); + + return bundle.localization + .get_formatted_line(request, loc::LineId::NotifySub, {t}) + .value(); + } else if (subcommand_id == "unsub") { + if (subs.empty()) { + throw ResponseException<ResponseError::NOT_FOUND>( + request, bundle.localization, t); + } + + work.exec("DELETE FROM event_subscriptions WHERE id = " + + std::to_string(subs[0][0].as<int>())); + work.commit(); + + return bundle.localization + .get_formatted_line(request, loc::LineId::NotifyUnsub, {t}) + .value(); + } + + throw ResponseException<ResponseError::SOMETHING_WENT_WRONG>( + request, bundle.localization); + } + }; + } +} |
