From 27065f2bc2d3c9e56bcdace434d20492c54a3798 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 11 Dec 2019 12:46:54 -0800 Subject: [PATCH] modules/web_hook: Add m.annotation m.reaction replies to push messages based on status. --- modules/web_hook.cc | 100 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/modules/web_hook.cc b/modules/web_hook.cc index 695c60f36..1e48ca104 100644 --- a/modules/web_hook.cc +++ b/modules/web_hook.cc @@ -1022,19 +1022,115 @@ bool github_handle__status(std::ostream &out, const json::object &content) { + const m::user::id::buf _webhook_user + { + string_view{webhook_user}, my_host() + }; + + const auto _webhook_room_id + { + m::room_id(string_view(webhook_room)) + }; + + const m::room _webhook_room + { + _webhook_room_id + }; + const json::string &state { content["state"] }; - if(state == "pending") - return false; + // Find the message resulting from the push and react with the status. + m::event::id::buf push_event_id; + { + const json::string &commit_hash + { + content["sha"] + }; + + m::room::events it + { + _webhook_room + }; + + static const auto type_match + { + [](const string_view &type) + { + return type == "m.room.message"; + } + }; + + const auto user_match + { + [&_webhook_user](const string_view &sender) + { + return sender && sender == _webhook_user; + } + }; + + const auto content_match + { + [&commit_hash](const json::object &content) + { + const json::string &body + { + content["body"] + }; + + return body == commit_hash; + } + }; + + // Limit the search to a maximum of recent messages from the + // webhook user and total messages so we don't run out of control + // and scan the whole room history. + int lim[2] { 512, 32 }; + for(; it && lim[0] > 0 && lim[1] > 0; --it, --lim[0]) + { + if(!m::query(std::nothrow, it.event_idx(), "sender", user_match)) + continue; + + --lim[1]; + if(!m::query(std::nothrow, it.event_idx(), "type", type_match)) + continue; + + if(!m::query(std::nothrow, it.event_idx(), "content", content_match)) + continue; + + push_event_id = m::event_id(it.event_idx(), std::nothrow); + break; + } + } + + if(push_event_id) switch(hash(state)) + { + case "failure"_: + break; + + case "pending"_: + m::annotate(_webhook_room, _webhook_user, push_event_id, "🟨"); + break; + + case "success"_: + m::annotate(_webhook_room, _webhook_user, push_event_id, "🟩"); + break; + } + if(!webhook_status_verbose) switch(hash(state)) { case "failure"_: break; + case "pending"_: + return false; + + case "success"_: + return false; + default: return false; }