diff --git a/doc/examples/join.cpp b/doc/examples/join.cpp index e6109b3..0c53651 100644 --- a/doc/examples/join.cpp +++ b/doc/examples/join.cpp @@ -32,7 +32,7 @@ int main(){ auto sync_reply = matbot.sync(0); //initial sync matbot.set_invite_callback([&](const matrix::bot& bot, const matrix::invite_info& invite)->void{ - bot.join_room(invite.roomid); + bot.accept_invite(invite); }); while(1){ diff --git a/include/matrix.hpp b/include/matrix.hpp index 6eb0f8e..07c5068 100644 --- a/include/matrix.hpp +++ b/include/matrix.hpp @@ -123,12 +123,14 @@ namespace matrix{ const msgtype type; const raii::rjp_string& body; const raii::rjp_string& eventid; + const int age; }; struct invite_info { const raii::rjp_string& roomid; const raii::rjp_string& sender; const raii::rjp_string& eventid; + const int age; }; class bot @@ -165,6 +167,7 @@ namespace matrix{ const raii::string& profile_picture(void)const; raii::string logout(const raii::string_base& homeserver, const raii::string_base& access_token)const; raii::string join_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; + raii::string leave_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; raii::string sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const; raii::string read_receipt(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid, const raii::string_base& eventid)const; raii::string send(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; @@ -224,6 +227,10 @@ namespace matrix{ //other networked operations raii::string create_room(const raii::string_base& name, const raii::string_base& alias)const; bool join_room(const raii::string_base& roomid)const; + bool leave_room(const raii::string_base& roomid)const; + + bool accept_invite(const invite_info& invite)const; + bool reject_invite(const invite_info& invite)const; //upload media file_info upload_file(const raii::string_base& filename)const; diff --git a/src/matrix.cpp b/src/matrix.cpp index 2bff23a..4728a98 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -126,6 +126,15 @@ namespace matrix{ bool bot::join_room(const raii::string_base& roomid)const{ return _post_curl(raii::string(), m_urls.join_room(m_homeserver, m_access_token, m_curl.encode(roomid)), raii::curl_llist()); } + bool bot::leave_room(const raii::string_base& roomid)const{ + return _post_curl(raii::string(), m_urls.leave_room(m_homeserver, m_access_token, m_curl.encode(roomid)), raii::curl_llist()); + } + bool bot::accept_invite(const invite_info& invite)const{ + return join_room(invite.roomid); + } + bool bot::reject_invite(const invite_info& invite)const{ + return leave_room(invite.roomid); + } file_info bot::upload_file(const raii::string_base& filename)const{ return upload_file(filename, raii::static_string()); } @@ -436,14 +445,14 @@ namespace matrix{ res = rjp_search_member(res.value, "events", 0); if(!res.value) continue; for(RJP_value* event = rjp_get_element(res.value);event;event = rjp_next_element(event)){ - static const char* search_terms[] = {"event_id", "sender", "state_key"}; + static const char* search_terms[] = {"event_id", "sender", "state_key", "unsigned"}; static constexpr size_t num_searches = sizeof(search_terms)/sizeof(search_terms[0]); RJP_search_res results[num_searches] = {}; rjp_search_members(event, num_searches, search_terms, results, 0); - if(!results[0].value || !results[1].value || !results[2].value) continue; + if(!results[0].value || !results[1].value || !results[2].value || !results[3].value) continue; if(strcmp(rjp_value_string(results[2].value), m_userid)) continue; raii::rjp_string room_str = rjp_member_name(roomid); - m_invite_callback(*this, invite_info{room_str, raii::rjp_string(results[1].value), raii::rjp_string(results[0].value)}); + m_invite_callback(*this, invite_info{room_str, raii::rjp_string(results[1].value), raii::rjp_string(results[0].value), rjp_value_integer(results[3].value)}); } } } @@ -456,21 +465,22 @@ namespace matrix{ res = rjp_search_member(res.value, "events", 0); if(!res.value) continue; for(RJP_value* event = rjp_get_element(res.value);event;event = rjp_next_element(event)){ - RJP_search_res sender = rjp_search_member(event, "sender", 0); - if(!sender.value) continue; - raii::rjp_string sender_str = sender.value; + static const char* searches[] = {"sender", "content", "event_id", "unsigned"}; + static constexpr size_t num_searches = sizeof(searches)/sizeof(searches[0]); + RJP_search_res results[num_searches] = {}; + rjp_search_members(event, num_searches, searches, results, 0); + if(!results[0].value || !results[1].value || !results[2].value || !results[3].value) continue; + raii::rjp_string sender_str = results[0].value; if(sender_str == m_userid) continue; - res = rjp_search_member(event, "content", 0); - if(!res.value) continue; - RJP_search_res msg = rjp_search_member(res.value, "msgtype", 0); + RJP_search_res msg = rjp_search_member(results[1].value, "msgtype", 0); if(!msg.value) continue; - RJP_search_res body = rjp_search_member(res.value, "body", 0); + RJP_search_res body = rjp_search_member(results[1].value, "body", 0); if(!body.value) continue; - res = rjp_search_member(event, "event_id", 0); - if(!res.value) continue; + RJP_search_res age = rjp_search_member(results[3].value, "age", 0); + if(!age.value) continue; raii::rjp_string room_str = rjp_member_name(roomid); - raii::rjp_string eventid_str = res.value; - m_message_callback(*this, msg_info{room_str, sender_str, msg::from_str(rjp_value_string(msg.value)), raii::rjp_string(body.value), eventid_str}); + raii::rjp_string eventid_str = results[2].value; + m_message_callback(*this, msg_info{room_str, sender_str, msg::from_str(rjp_value_string(msg.value)), raii::rjp_string(body.value), eventid_str, rjp_value_integer(age.value)}); _send_read_receipt(room_str, eventid_str); } } @@ -722,6 +732,9 @@ namespace matrix{ raii::string bot::mat_url_list::join_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const{ return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/join?access_token=" + access_token); } + raii::string bot::mat_url_list::leave_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const{ + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/leave?access_token=" + access_token); + } raii::string bot::mat_url_list::sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const{ if(!next_batch) return raii::string(s_proto + homeserver + "/_matrix/client/r0/sync?access_token=" + access_token + "&timeout=" + timeout); diff --git a/src/test.cpp b/src/test.cpp index ba1ac76..2b135d6 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -371,7 +371,9 @@ int main(){ bool should_quit = false; auto sync_callback = [&](const matrix::bot& bot, const matrix::msg_info& msg)->void { - printf("%s, %s\n%s\n%s: %s\n", msg.roomid.get(), msg.eventid.get(), msg.type.str(), msg.sender.get(), msg.body.get()); + printf("%s, %s\n%s\n%s: %s\n%d\n", msg.roomid.get(), msg.eventid.get(), msg.type.str(), msg.sender.get(), msg.body.get(), msg.age); + if(msg.age > 10000) + return; if(msg.body == "!exit"_ss){ should_quit = true; bot.send_message(msg.roomid, "[INFO] Shutting down..."_ss); @@ -430,7 +432,7 @@ int main(){ } }; auto invite_callback = [&](const matrix::bot& bot, const matrix::invite_info& invite)->bool{ - bot.join_room(invite.roomid); + bot.accept_invite(invite); return true; }; matbot.set_message_callback(sync_callback);