added membership event handling

This commit is contained in:
rexy712 2019-04-06 06:50:17 -07:00
parent da028e03fd
commit 0e7a92eb94
4 changed files with 68 additions and 33 deletions

View File

@ -17,6 +17,7 @@ matrix:
list room members
change password
ability to select specification revision
add event type to membership_info
reddit:
handle imgur albums

View File

@ -118,21 +118,21 @@ namespace matrix{
}
};
struct msg_info
struct event_info
{
const raii::rjp_string& roomid;
const raii::rjp_string& sender;
const msgtype type;
const raii::rjp_string& body;
const raii::rjp_string& eventid;
const int age;
};
struct invite_info
struct msg_info : public event_info
{
const raii::rjp_string& roomid;
const raii::rjp_string& sender;
const raii::rjp_string& eventid;
const int age;
const msgtype type;
const raii::rjp_string& body;
};
struct membership_info : public event_info
{
const raii::rjp_string& recipient;
};
//main class
@ -208,7 +208,7 @@ namespace matrix{
raii::rjp_string m_next_batch; //string which tracks where we are in the server history
std::function<void(const bot&,const msg_info&)> m_message_callback;
std::function<void(const bot&, const invite_info&)> m_invite_callback;
std::function<void(const bot&, const membership_info&)> m_membership_callback;
public:
bot(const auth_data& a, const raii::string_base& useragent);
@ -245,8 +245,8 @@ namespace matrix{
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;
bool accept_invite(const membership_info& invite)const;
bool reject_invite(const membership_info& invite)const;
//upload media
file_info upload_file(const raii::string_base& filename)const;
@ -275,13 +275,15 @@ namespace matrix{
m_message_callback = std::forward<Func>(f);
}
template<class Func>
void set_invite_callback(Func&& f){
m_invite_callback = std::forward<Func>(f);
void set_membership_callback(Func&& f){
m_membership_callback = std::forward<Func>(f);
}
raii::string sync(size_t timeout);
void logout(void);
protected:
void _handle_membership_events(RJP_value* rooms);
void _handle_other_membership(RJP_value* join);
void _handle_invites(RJP_value* invites);
void _handle_messages(RJP_value* messages);
void _send_read_receipt(const raii::string_base& roomid, const raii::string_base& eventid)const;

View File

@ -44,8 +44,8 @@ namespace matrix{
auth_data parse_auth_data(RJP_value* root){
static const char* fields[] = {"username", "password", "homeserver", "access_token"};
RJP_search_res details[5];
rjp_search_members(root, 5, fields, details, 0);
RJP_search_res details[4];
rjp_search_members(root, 4, fields, details, 0);
return auth_data{details[0].value,
details[1].value,
details[2].value,
@ -135,10 +135,10 @@ namespace matrix{
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{
bool bot::accept_invite(const membership_info& invite)const{
return join_room(invite.roomid);
}
bool bot::reject_invite(const invite_info& invite)const{
bool bot::reject_invite(const membership_info& invite)const{
return leave_room(invite.roomid);
}
file_info bot::upload_file(const raii::string_base& filename)const{
@ -454,8 +454,8 @@ namespace matrix{
if(res.value){
if(m_message_callback != nullptr)
_handle_messages(res.value);
if(m_invite_callback != nullptr)
_handle_invites(res.value);
if(m_membership_callback != nullptr)
_handle_membership_events(res.value);
}
return reply;
}
@ -465,11 +465,43 @@ namespace matrix{
Internal functions
********************************/
void bot::_handle_membership_events(RJP_value* rooms){
RJP_search_res res = rjp_search_member(rooms, "invite", 0);
if(res.value)
_handle_invites(res.value);
res = rjp_search_member(rooms, "join", 0);
if(res.value)
_handle_other_membership(res.value);
}
void bot::_handle_other_membership(RJP_value* join){
for(RJP_value* roomid = rjp_get_member(join);roomid;roomid = rjp_next_member(roomid)){
RJP_search_res res = rjp_search_member(roomid, "timeline", 0);
if(!res.value) continue;
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 constexpr const char* search_terms[] = {"content", "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 || !results[3].value || !results[4].value) continue;
RJP_search_res age = rjp_search_member(results[4].value, "age", 0);
if(!age.value) continue;
RJP_search_res type = rjp_search_member(results[0].value, "membership", 0);
if(!type.value) continue;
raii::rjp_string event_str = results[1].value;
raii::rjp_string sender_str = results[2].value;
raii::rjp_string rec_str = results[3].value;
raii::rjp_string room_str = rjp_member_name(roomid);
m_membership_callback(*this, membership_info{room_str, sender_str, event_str, rjp_value_integer(age.value), rec_str});
}
}
}
void bot::_handle_invites(RJP_value* invites){
RJP_search_res res = rjp_search_member(invites, "invite", 0);
if(!res.value) return;
for(RJP_value* roomid = rjp_get_member(res.value);roomid;roomid = rjp_next_member(roomid)){
res = rjp_search_member(roomid, "invite_state", 0);
for(RJP_value* roomid = rjp_get_member(invites);roomid;roomid = rjp_next_member(roomid)){
RJP_search_res res = rjp_search_member(roomid, "invite_state", 0);
if(!res.value) continue;
res = rjp_search_member(res.value, "events", 0);
if(!res.value) continue;
@ -479,9 +511,8 @@ namespace matrix{
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 || !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), rjp_value_integer(results[3].value)});
m_membership_callback(*this, membership_info{room_str, raii::rjp_string(results[1].value), raii::rjp_string(results[0].value), rjp_value_integer(results[3].value), raii::rjp_string(results[2].value)});
}
}
}
@ -499,18 +530,18 @@ namespace matrix{
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;
if(!strcmp(rjp_value_string(results[0].value), m_userid)) continue;
RJP_search_res msg = rjp_search_member(results[1].value, "msgtype", 0);
if(!msg.value) continue;
RJP_search_res body = rjp_search_member(results[1].value, "body", 0);
if(!body.value) continue;
RJP_search_res age = rjp_search_member(results[3].value, "age", 0);
if(!age.value) continue;
raii::rjp_string sender_str = results[0].value;
raii::rjp_string room_str = rjp_member_name(roomid);
raii::rjp_string eventid_str = results[2].value;
_send_read_receipt(room_str, eventid_str);
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)});
m_message_callback(*this, msg_info{room_str, sender_str, eventid_str, rjp_value_integer(age.value), msg::from_str(rjp_value_string(msg.value)), raii::rjp_string(body.value)});
}
}
}

View File

@ -445,18 +445,19 @@ int main(){
bot.send_image(msg.roomid, {"mxc://matrix.org/SYkDDTUwcfscliYTuIfYFIrx"_ss, "nipple.jpg"_ss, "image/jpeg"_ss, 40202, 512, 402, {}, 512, 402, 40202});
}
};
auto invite_callback = [&](const matrix::bot& bot, const matrix::invite_info& invite)->bool{
bot.accept_invite(invite);
return true;
auto invite_callback = [&](const matrix::bot& bot, const matrix::membership_info& invite)->void{
printf("membership event:\nsender: %s\nrecipient: %s\n", invite.sender.get(), invite.recipient.get());
if(!strcmp(invite.recipient, "@proghumorbot:matrix.org"))
bot.accept_invite(invite);
};
matbot.set_message_callback(sync_callback);
matbot.set_invite_callback(invite_callback);
matbot.set_membership_callback(invite_callback);
matbot.redact_event("!QeYfNDCRodtNohhnaI:matrix.org"_ss, "$1553965753281066lkKaO:matrix.org"_ss, "too gay"_ss);
while(!should_quit){
sync_reply = matbot.sync(30000);
DEBUG_PRINT("syncing\n");
//DEBUG_PRINT("syncing\n");
//DEBUG_PRINT("%s\n", sync_reply.get());
}