mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 15:15:10 +00:00
[MOD] Carve the way to XMPP rich replies
Bifrost could *never*!
This commit is contained in:
parent
10e140e2a2
commit
fe77906cde
10 changed files with 126 additions and 18 deletions
13
src/AS.c
13
src/AS.c
|
|
@ -169,16 +169,17 @@ ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask
|
|||
HttpClientContextFree(ctx);
|
||||
JsonFree(state);
|
||||
}
|
||||
void
|
||||
char *
|
||||
ASSend(const ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
||||
{
|
||||
HttpClientContext *ctx = NULL;
|
||||
char *path, *params;
|
||||
char *txn;
|
||||
char *txn, *ret;
|
||||
HashMap *reply;
|
||||
if (!conf || !id || !type || !user || !c)
|
||||
{
|
||||
JsonFree(c);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
txn = StrRandom(16);
|
||||
|
|
@ -193,9 +194,15 @@ ASSend(const ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
|||
Free(path);
|
||||
ASAuthenticateRequest(conf, ctx);
|
||||
ParseeSetRequestJSON(ctx, c);
|
||||
|
||||
reply = JsonDecode(HttpClientStream(ctx));
|
||||
ret = StrDuplicate(JsonValueAsString(HashMapGet(reply, "event_id")));
|
||||
JsonFree(reply);
|
||||
|
||||
HttpClientContextFree(ctx);
|
||||
JsonFree(c);
|
||||
|
||||
return ret;
|
||||
}
|
||||
char *
|
||||
ASCreateRoom(const ParseeConfig *conf, char *by, char *alias)
|
||||
|
|
|
|||
15
src/Events.c
15
src/Events.c
|
|
@ -114,3 +114,18 @@ MatrixCreateMedia(char *mxc, char *body, char *mime)
|
|||
|
||||
return map;
|
||||
}
|
||||
|
||||
char *
|
||||
MatrixGetReply(HashMap *event)
|
||||
{
|
||||
if (!event)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return StrDuplicate(JsonValueAsString(
|
||||
JsonGet(event, 4, "content",
|
||||
"m.relates_to", "m.in_reply_to",
|
||||
"event_id")
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,16 +69,24 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
|||
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);
|
||||
|
||||
bool direct = false;
|
||||
|
||||
if (ParseeIsPuppet(data->config, sender))
|
||||
{
|
||||
Free(reply_id);
|
||||
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"));
|
||||
|
|
@ -89,9 +97,10 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
|||
char *user = GrabString(json, 1, "xmpp_user");
|
||||
char *local = ParseeEncodeMXID(sender);
|
||||
|
||||
XMPPSendPlain(jabber, local, user, body, NULL);
|
||||
XMPPSendPlain(jabber, local, user, body, NULL, NULL, NULL);
|
||||
|
||||
Free(local);
|
||||
Free(reply_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +109,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
|||
muc_id = ParseeGetMUCID(data, chat_id);
|
||||
if (!chat_id)
|
||||
{
|
||||
Free(reply_id);
|
||||
return;
|
||||
}
|
||||
jid = ParseeEncodeMXID(sender);
|
||||
|
|
@ -107,14 +117,24 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
|||
/* 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, body, "groupchat");
|
||||
XMPPSendPlain(jabber, jid, muc_id, body, "groupchat", stanza, sender);
|
||||
Free(rev);
|
||||
Free(name);
|
||||
Free(stanza);
|
||||
Free(sender);
|
||||
}
|
||||
Free(chat_id);
|
||||
Free(muc_id);
|
||||
Free(jid);
|
||||
Free(reply_id);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -541,14 +541,14 @@ ParseeGetMUCID(ParseeData *data, char *chat_id)
|
|||
}
|
||||
|
||||
void
|
||||
ParseePushStanza(ParseeData *data, char *chat_id, char *stanza_id)
|
||||
ParseePushStanza(ParseeData *data, char *chat_id, char *stanza_id, char *ev, char *sender)
|
||||
{
|
||||
DbRef *ref;
|
||||
HashMap *j;
|
||||
HashMap *stanzas, *obj;
|
||||
bool new_stanzas = false;
|
||||
HashMap *stanzas, *obj, *events;
|
||||
bool new_stanzas = false, new_events = false;
|
||||
uint64_t age = UtilTsMillis();
|
||||
if (!data || !chat_id || !stanza_id)
|
||||
if (!data || !chat_id || !stanza_id || !ev || !sender)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -576,6 +576,20 @@ ParseePushStanza(ParseeData *data, char *chat_id, char *stanza_id)
|
|||
HashMapSet(j, "stanzas", JsonValueObject(stanzas));
|
||||
}
|
||||
|
||||
events = JsonValueAsObject(HashMapGet(j, "events"));
|
||||
if (!events)
|
||||
{
|
||||
events = HashMapCreate();
|
||||
new_events = true;
|
||||
}
|
||||
obj = HashMapCreate();
|
||||
HashMapSet(obj, "stanza", JsonValueString(stanza_id));
|
||||
HashMapSet(obj, "sender", JsonValueString(sender));
|
||||
JsonValueFree(HashMapSet(events, ev, JsonValueObject(obj)));
|
||||
if (new_events)
|
||||
{
|
||||
HashMapSet(j, "events", JsonValueObject(events));
|
||||
}
|
||||
DbUnlock(data->db, ref);
|
||||
}
|
||||
|
||||
|
|
@ -636,3 +650,38 @@ ParseeSendPresence(ParseeData *data)
|
|||
}
|
||||
DbUnlock(data->db, ref);
|
||||
}
|
||||
bool
|
||||
ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char **se)
|
||||
{
|
||||
DbRef *ref = NULL;
|
||||
HashMap *j = NULL;
|
||||
HashMap *event = NULL;
|
||||
bool ret = false;
|
||||
if (!data || !chat_id || !ev || !st || !se)
|
||||
{
|
||||
Log(LOG_INFO, "%p %p %p %p %p", data, chat_id, ev, st, se);
|
||||
return false;
|
||||
}
|
||||
|
||||
ref = DbLock(data->db, 2, "chats", chat_id);
|
||||
j = DbJson(ref);
|
||||
if (!ref)
|
||||
{
|
||||
Log(LOG_INFO, "LF");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
event = JsonValueAsObject(JsonGet(j, 2, "events", ev));
|
||||
if (!event)
|
||||
{
|
||||
Log(LOG_INFO, "EF %s", ev);
|
||||
goto end;
|
||||
}
|
||||
*st = StrDuplicate(JsonValueAsString(HashMapGet(event, "stanza")));
|
||||
*se = StrDuplicate(JsonValueAsString(HashMapGet(event, "sender")));
|
||||
ret = true;
|
||||
end:
|
||||
DbUnlock(data->db, ref);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <XML.h>
|
||||
|
||||
void
|
||||
XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type)
|
||||
XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse)
|
||||
{
|
||||
XMLElement *message, *body, *data, *parsee;
|
||||
char *from;
|
||||
|
|
@ -50,6 +50,15 @@ XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type)
|
|||
/* TODO: Add custom fields depending on the caller's wishes */
|
||||
}
|
||||
|
||||
if (rst && rse)
|
||||
{
|
||||
XMLElement *reply = XMLCreateTag("reply");
|
||||
XMLAddAttr(reply, "to", rse);
|
||||
XMLAddAttr(reply, "id", rst);
|
||||
XMLAddAttr(reply, "xmlns", "urn:xmpp:reply:0");
|
||||
XMLAddChild(message, reply);
|
||||
}
|
||||
|
||||
XMLAddChild(message, body);
|
||||
XMLAddChild(message, parsee);
|
||||
XMLAddChild(body, data);
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ ParseeWakeupThread(void)
|
|||
static void
|
||||
ParseeDMHandler(char *room, char *from, XMLElement *data, const ParseeConfig *c)
|
||||
{
|
||||
ASSend(
|
||||
Free(ASSend(
|
||||
c, room, from,
|
||||
"m.room.message", MatrixCreateMessage(data->data)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -71,6 +71,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
char *res = ParseeGetResource(from);
|
||||
char *encoded = ParseeEncodeJID(args->config, from, false);
|
||||
char *s_id_str = HashMapGet(stanza_id->attrs, "id");
|
||||
char *event_id;
|
||||
|
||||
/* TODO: Create smarter puppet names */
|
||||
if (ParseeVerifyStanza(args, chat_id, s_id_str))
|
||||
|
|
@ -93,7 +94,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
mxc = ASReupload(args->config, oob_data->data, &mime);
|
||||
content = MatrixCreateMedia(mxc, data->data, mime);
|
||||
|
||||
ASSend(
|
||||
event_id = ASSend(
|
||||
args->config, mroom_id, encoded,
|
||||
"m.room.message", content
|
||||
);
|
||||
|
|
@ -102,12 +103,13 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
}
|
||||
else
|
||||
{
|
||||
ASSend(
|
||||
event_id = ASSend(
|
||||
args->config, mroom_id, encoded,
|
||||
"m.room.message", MatrixCreateMessage(data->data)
|
||||
);
|
||||
}
|
||||
ParseePushStanza(args, chat_id, s_id_str);
|
||||
ParseePushStanza(args, chat_id, s_id_str, event_id, from);
|
||||
Free(event_id);
|
||||
}
|
||||
|
||||
Free(res);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ extern void ASJoin(const ParseeConfig *, char *, char *);
|
|||
|
||||
/* Sends a message event with a specific type and body.
|
||||
* Said body is freed during the function's execution. */
|
||||
extern void ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
||||
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
||||
|
||||
/* Sets a state event with a specific type and body */
|
||||
extern void ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *event);
|
||||
|
|
|
|||
|
|
@ -20,4 +20,7 @@ extern HashMap * MatrixCreateNameState(char *name);
|
|||
|
||||
/* Creates a join membership with a specific nickname */
|
||||
extern HashMap * MatrixCreateNickChange(char *nick);
|
||||
|
||||
/* Get the event ID of the reply if existent */
|
||||
extern char * MatrixGetReply(HashMap *event);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -145,11 +145,14 @@ extern char * ParseeGetRoomID(ParseeData *, char *chat_id);
|
|||
extern char * ParseeGetMUCID(ParseeData *, char *chat_id);
|
||||
|
||||
/* Pushes a stanza ID to a chat ID */
|
||||
extern void ParseePushStanza(ParseeData *, char *chat_id, char *stanza_id);
|
||||
extern void ParseePushStanza(ParseeData *, char *chat_id, char *stanza_id, char *event, char *sender);
|
||||
|
||||
/* Checks if a stanza is not duplicated in a chat ID */
|
||||
extern bool ParseeVerifyStanza(ParseeData *, char *chat_id, char *stanza_id);
|
||||
|
||||
/* Gets the stanza ID and sender of an event */
|
||||
extern bool ParseeGetStanzaInfo(ParseeData *, char *c_id, char *e, char **st, char **se);
|
||||
|
||||
/* Sends presence requests for every MUC around as a fake JID */
|
||||
extern void ParseeSendPresence(ParseeData *);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
|||
extern void XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc);
|
||||
|
||||
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
|
||||
extern void XMPPSendPlain(XMPPComponent *c, char *f, char *t, char *m, char *type);
|
||||
extern void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse);
|
||||
extern void XMPPSendMUC(XMPPComponent *comp, char *fr, char *as, char *to, char *msg, char *type);
|
||||
|
||||
/* Closes a raw component stream. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue