diff --git a/include/ircd/m/room/message.h b/include/ircd/m/room/message.h index 6bf957949..a69304f47 100644 --- a/include/ircd/m/room/message.h +++ b/include/ircd/m/room/message.h @@ -53,6 +53,12 @@ struct ircd::m::room::message /// must clean that up if required. Empty if not a reply or malformed. string_view reply_to_body() const noexcept; + /// The event ID of the replaced event; empty if not a replace + id::event replace_event() const noexcept; + + /// The new content body; empty if not a replace or replace was empty! + string_view replace_body() const noexcept; + /// C2S v1.3 11.3.1 message body stripped of any reply fallback. This is /// the proper way to read the message rather than reading "body" direct; /// returns "body" if not reply. diff --git a/matrix/room_message.cc b/matrix/room_message.cc index 617b38b1f..1678e386c 100644 --- a/matrix/room_message.cc +++ b/matrix/room_message.cc @@ -35,6 +35,77 @@ const noexcept return body; } +ircd::string_view +ircd::m::room::message::replace_body() +const noexcept +{ + const auto replace_event + { + this->replace_event() + }; + + if(!replace_event) + return {}; + + const json::object m_new_content + { + this->source["m.new_content"] + }; + + if(!json::type(m_new_content, json::OBJECT)) + return {}; + + const json::string body + { + m_new_content["body"] + }; + + return body; +} + +ircd::m::event::id +ircd::m::room::message::replace_event() +const noexcept try +{ + const m::relates_to &m_relates_to + { + json::get<"m.relates_to"_>(*this) + }; + + if(json::get<"rel_type"_>(m_relates_to) != "m.replace") + return {}; + + const auto &event_id + { + json::get<"event_id"_>(m_relates_to) + }; + + if(!event_id || !valid(m::id::EVENT, event_id)) + return {}; + + return event_id; +} +catch(const json::error &e) +{ + log::derror + { + log, "Failed to extract m.relates_to m.replace event_id :%s", + e.what(), + }; + + return {}; +} +catch(const std::exception &e) +{ + log::error + { + log, "Failed to extract m.relates_to m.replace event_id :%s", + e.what(), + }; + + return {}; +} + ircd::string_view ircd::m::room::message::reply_to_body() const noexcept