diff --git a/driver/web.cpp b/driver/web.cpp index 940c08a..0450a5e 100644 --- a/driver/web.cpp +++ b/driver/web.cpp @@ -21,6 +21,12 @@ using namespace std::literals; namespace { +std::map, const ProjectSettings &, std::string_view, const boost::json::object &)> formatters { + {"push", [](std::shared_ptr webhooks, const ProjectSettings &project, std::string_view full_name, const boost::json::object &body) { + webhooks->send_notice(project.channel, "push"); + }}, +}; + // Used as the completion handler for coroutines in this module to print // failure reasons to the log. auto report_error(std::exception_ptr eptr) -> void @@ -86,7 +92,7 @@ auto announce_event( auto process_event( std::shared_ptr self, const std::string_view notify_user, - const std::string_view event_name, + const std::string event_name, const boost::json::value &json ) -> void { @@ -117,13 +123,16 @@ auto process_event( return; } - if (not settings.enabled || not settings.events.contains(std::string{event_name})) + if (not settings.enabled || not settings.events.contains(event_name)) { // quietly ignore events we don't care about return; } - announce_event(self, settings, std::move(full_name), event_name, std::move(event)); + auto formatter_cursor = formatters.find(event_name); + if (formatter_cursor != formatters.end()) { + formatter_cursor->second(self, settings, full_name, event); + } } // Process the HTTP request validating its structure and signature. @@ -509,6 +518,68 @@ std::map, const myirc::Bot::Comm reply_to(webhooks, cmd, "Disabled project " + name); } }}, + {"add-events", [](std::shared_ptr webhooks, const myirc::Bot::Command &cmd) { + std::istringstream iss{std::string{cmd.arguments}}; + std::string name; + if (iss >> name) + { + auto &project = webhooks->settings_.projects.at(name); + if (not authorized_for_project(cmd, project, cmd.account)) + { + return; + } + + unsigned n_added = 0, n_skipped = 0, n_unknown = 0; + while (iss >> name) { + if (formatters.contains(name)) { + const auto [_, added] = project.events.insert(name); + if (added) { n_added++; } else { n_skipped++; } + } else { + n_unknown++; + } + } + + webhooks->save_settings(); + + std::stringstream ss; + ss << "Events updated."; + if (n_added) { ss << " added: " << n_added; } + if (n_skipped) { ss << " skipped: " << n_skipped; } + if (n_unknown) { ss << " unknown: " << n_unknown; } + reply_to(webhooks, cmd, ss.str()); + } + }}, + {"drop-events", [](std::shared_ptr webhooks, const myirc::Bot::Command &cmd) { + std::istringstream iss{std::string{cmd.arguments}}; + std::string name; + if (iss >> name) + { + auto &project = webhooks->settings_.projects.at(name); + if (not authorized_for_project(cmd, project, cmd.account)) + { + return; + } + + unsigned n_removed = 0, n_skipped = 0, n_unknown = 0; + while (iss >> name) { + if (formatters.contains(name)) { + const auto removed = project.events.erase(name); + if (removed) { n_removed++; } else { n_skipped++; } + } else { + n_unknown++; + } + } + + webhooks->save_settings(); + + std::stringstream ss; + ss << "Events updated."; + if (n_removed) { ss << " removed: " << n_removed; } + if (n_skipped) { ss << " skipped: " << n_skipped; } + if (n_unknown) { ss << " unknown: " << n_unknown; } + reply_to(webhooks, cmd, ss.str()); + } + }}, {"add-access", [](std::shared_ptr webhooks, const myirc::Bot::Command &cmd) { if (cmd.oper.empty()) { @@ -544,10 +615,6 @@ std::map, const myirc::Bot::Comm if (iss >> name >> account) { auto &project = webhooks->settings_.projects.at(name); - if (not authorized_for_project(cmd, project, cmd.account)) - { - return; - } auto removed = project.authorized_accounts.erase(account); if (removed) { webhooks->save_settings(); @@ -557,4 +624,19 @@ std::map, const myirc::Bot::Comm } } }}, + {"set-channel", [](std::shared_ptr webhooks, const myirc::Bot::Command &cmd) { + if (cmd.oper.empty()) + { + return; + } + std::istringstream iss{std::string{cmd.arguments}}; + std::string name, channel; + if (iss >> name >> channel) + { + auto &project = webhooks->settings_.projects.at(name); + project.channel = channel; + webhooks->save_settings(); + reply_to(webhooks, cmd, "Channel assigned"); + } + }}, };