#include #include #include #include #include #include #include #define GrabString(obj, ...) JsonValueAsString(JsonGet(obj, __VA_ARGS__)) static void ParseeMemberHandler(ParseeData *data, HashMap *event) { char *state_key = GrabString(event, 1, "state_key"); char *membership = GrabString(event, 2, "content", "membership"); char *room_id = GrabString(event, 1, "room_id"); char *sender = GrabString(event, 1, "sender"); char *chat_id; const ParseeConfig *conf = data->config; Log(LOG_INFO, "Membership '%s'->'%s'", state_key, membership); if (StrEquals(membership, "invite") && ParseeIsPuppet(conf, state_key)) { DbRef *ref; HashMap *json; char *jid; ASJoin(conf, room_id, state_key); jid = ParseeDecodeLocalJID(conf, state_key); ref = DbCreate(data->db, 3, "rooms", room_id, "data"); json = DbJson(ref); HashMapSet(json, "is_direct", JsonValueBoolean(true)); HashMapSet(json, "xmpp_user", JsonValueString(jid)); DbUnlock(data->db, ref); ParseePushDMRoom(data, sender, jid, room_id); /* Pretend everything is a dm, ignoring is_direct */ if (jid) { Free(jid); } } else if (StrEquals(membership, "join") && !ParseeIsPuppet(conf, state_key)) { char *jid = ParseeEncodeMXID(state_key); chat_id = ParseeGetFromRoomID(data, room_id); if (chat_id) { char *muc = ParseeGetMUCID(data, chat_id); char *rev = StrConcat(2, muc, "/parsee"); /* Make the user join the MUC */ XMPPJoinMUC(data->jabber, jid, rev); Free(rev); Free(muc); } Free(jid); Free(chat_id); } } static void ParseeMessageHandler(ParseeData *data, HashMap *event) { XMPPComponent *jabber = data->jabber; DbRef *ref; HashMap *json; char *msgtype = GrabString(event, 2, "content", "msgtype"); char *body = GrabString(event, 2, "content", "body"); char *id = GrabString(event, 1, "room_id"); char *ev_id = GrabString(event, 1, "event_id"); char *sender = GrabString(event, 1, "sender"); char *chat_id, *muc_id, *jid; char *reply_id = MatrixGetReply(event); char *xepd = ParseeXMPPify(event); bool direct = false; if (ParseeIsPuppet(data->config, sender)) { Free(reply_id); Free(xepd); return; } if (reply_id) { Log(LOG_INFO, "reply=%s", reply_id); } ref = DbLock(data->db, 3, "rooms", id, "data"); json = DbJson(ref); direct = JsonValueAsBoolean(HashMapGet(json, "is_direct")); DbUnlock(data->db, ref); if (direct) { char *user = GrabString(json, 1, "xmpp_user"); char *local = ParseeEncodeMXID(sender); XMPPSendPlain(jabber, local, user, body, NULL, NULL, NULL); Free(local); Free(reply_id); Free(xepd); return; } /* Try to find the chat ID */ chat_id = ParseeGetFromRoomID(data, id); muc_id = ParseeGetMUCID(data, chat_id); if (!chat_id) { Free(reply_id); Free(xepd); return; } jid = ParseeEncodeMXID(sender); { /* TODO: Check the name's validity */ char *name = ASGetName(data->config, NULL, sender); char *rev = StrConcat(3, muc_id, "/", name); char *stanza = NULL, *sender = NULL; if (reply_id) { ParseeGetStanzaInfo(data, chat_id, reply_id, &stanza, &sender); Log(LOG_INFO, "Replying to %s by %s", stanza, sender); } XMPPJoinMUC(jabber, jid, rev); XMPPSendPlain( jabber, jid, muc_id, xepd ? xepd : body, "groupchat", stanza, sender ); Free(rev); Free(name); Free(stanza); Free(sender); } Free(chat_id); Free(muc_id); Free(jid); Free(reply_id); Free(xepd); } void ParseeEventHandler(ParseeData *data, HashMap *event) { char *event_type; if (!data || !event) { return; } event_type = GrabString(event, 1, "type"); if (StrEquals(event_type, "m.room.member")) { ParseeMemberHandler(data, event); return; } if (StrEquals(event_type, "m.room.message")) { ParseeMessageHandler(data, event); return; } }