[ADD/WIP] Start receiptwerk

This commit is contained in:
LDA 2024-07-06 00:38:10 +02:00
commit 0fc0fdd6f4
9 changed files with 144 additions and 8 deletions

View file

@ -9,6 +9,8 @@ Somewhat implemented XEPs:
systems don't seem *too* restrictive on one-another (unlike some systems don't seem *too* restrictive on one-another (unlike some
IM platforms I won't mention), so this doesn't sound too bad to do IM platforms I won't mention), so this doesn't sound too bad to do
HALF-IMPLEMENTED: Removing reacts won't work. HALF-IMPLEMENTED: Removing reacts won't work.
~ https://xmpp.org/extensions/xep-0184.html
no one wants to send me receipts :(((((((((((((
For future XEPs: For future XEPs:
- https://xmpp.org/extensions/xep-0421.html - https://xmpp.org/extensions/xep-0421.html

View file

@ -732,6 +732,38 @@ ASType(const ParseeConfig *c, char *user, char *room, bool status)
Free(user); Free(user);
} }
void
ASPresence(const ParseeConfig *c, char *user, char *room, char *ev)
{
HttpClientContext *ctx = NULL;
HashMap *json;
char *path;
if (!c || !user || !room || !ev)
{
return;
}
user = HttpUrlEncode(user);
room = HttpUrlEncode(room);
ev = HttpUrlEncode(ev);
path = StrConcat(6,
"/_matrix/client/v3/rooms/",
room, "/receipt/m.read/", ev,
"?user_id=", user
);
json = HashMapCreate();
ctx = ParseeCreateRequest(c, HTTP_POST, path);
Free(path);
ASAuthenticateRequest(c, ctx);
ParseeSetRequestJSON(ctx, json);
JsonFree(json);
HttpClientContextFree(ctx);
Free(user);
Free(room);
Free(ev);
}
HashMap * HashMap *
ASGetUserConfig(const ParseeConfig *c, char *user, char *key) ASGetUserConfig(const ParseeConfig *c, char *user, char *key)

View file

@ -62,8 +62,9 @@ Main(void)
} }
} }
Log(LOG_NOTICE, "Creating JID table..."); Log(LOG_NOTICE, "Creating volatile tables...");
ParseeInitialiseJIDTable(); ParseeInitialiseJIDTable();
ParseeInitialiseHeadTable();
Log(LOG_NOTICE, "Setting up local Matrix user..."); Log(LOG_NOTICE, "Setting up local Matrix user...");
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart); ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
@ -112,6 +113,7 @@ end:
CronStop(cron); CronStop(cron);
CronFree(cron); CronFree(cron);
ParseeFreeData(conf.handlerArgs); ParseeFreeData(conf.handlerArgs);
ParseeDestroyHeadTable();
ParseeDestroyJIDTable(); ParseeDestroyJIDTable();
return 0; return 0;
} }

View file

@ -266,13 +266,17 @@ end:
void void
ParseeEventHandler(ParseeData *data, HashMap *event) ParseeEventHandler(ParseeData *data, HashMap *event)
{ {
char *event_type; char *event_type, *event_id, *room_id;
if (!data || !event) if (!data || !event)
{ {
return; return;
} }
event_type = GrabString(event, 1, "type"); event_type = GrabString(event, 1, "type");
event_id = GrabString(event, 1, "event_id");
room_id = GrabString(event, 1, "room_id");
ParseePushHeadTable(room_id, event_id);
if (StrEquals(event_type, "m.room.member")) if (StrEquals(event_type, "m.room.member"))
{ {
ParseeMemberHandler(data, event); ParseeMemberHandler(data, event);

View file

@ -69,3 +69,63 @@ ParseeDestroyJIDTable(void)
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
pthread_mutex_destroy(&lock); pthread_mutex_destroy(&lock);
} }
static pthread_mutex_t head_lock;
static HashMap *head_table = NULL;
void
ParseeInitialiseHeadTable(void)
{
if (head_table)
{
return;
}
pthread_mutex_init(&head_lock, NULL);
pthread_mutex_lock(&head_lock);
head_table = HashMapCreate();
pthread_mutex_unlock(&head_lock);
}
void
ParseePushHeadTable(char *room, char *event)
{
if (!room || !event || !head_table)
{
return;
}
pthread_mutex_lock(&head_lock);
event = StrDuplicate(event);
Free(HashMapSet(head_table, room, event));
pthread_mutex_unlock(&head_lock);
}
char *
ParseeLookupHead(char *room)
{
char *event;
if (!room || !head_table)
{
return NULL;
}
pthread_mutex_lock(&head_lock);
event = StrDuplicate(HashMapGet(head_table, room));
pthread_mutex_unlock(&head_lock);
return event;
}
void
ParseeDestroyHeadTable(void)
{
char *key;
void *val;
if (!head_table)
{
return;
}
pthread_mutex_lock(&head_lock);
while (HashMapIterate(head_table, &key, &val))
{
Free(val);
}
HashMapFree(head_table);
head_table = NULL;
pthread_mutex_unlock(&head_lock);
pthread_mutex_destroy(&head_lock);
}

View file

@ -82,6 +82,12 @@ XMPPSendPlainID(XMPPComponent *comp, char *fr, char *to, char *msg, char *type,
XMLAddChild(message, xedit); XMLAddChild(message, xedit);
} }
{
XMLElement *request = XMLCreateTag("request");
XMLAddAttr(request, "xmlns", "urn:xmpp:receipts");
XMLAddChild(message, request);
}
if (oob) if (oob)
{ {
XMLElement *xoob, *oob_data, *oob_url; XMLElement *xoob, *oob_data, *oob_url;

View file

@ -29,6 +29,7 @@
AdvertiseSimple("urn:xmpp:message-correct:0") \ AdvertiseSimple("urn:xmpp:message-correct:0") \
AdvertiseSimple("urn:xmpp:reactions:0") \ AdvertiseSimple("urn:xmpp:reactions:0") \
AdvertiseSimple("urn:xmpp:styling:0") \ AdvertiseSimple("urn:xmpp:styling:0") \
AdvertiseSimple("urn:xmpp:receipts") \
AdvertiseSimple("urn:xmpp:reply:0") \ AdvertiseSimple("urn:xmpp:reply:0") \
AdvertiseSimple("jabber:x:oob") \ AdvertiseSimple("jabber:x:oob") \
AdvertiseSimple("vcard-temp") \ AdvertiseSimple("vcard-temp") \
@ -443,21 +444,48 @@ MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
decode_from = NULL; decode_from = NULL;
from_matrix = NULL; from_matrix = NULL;
} }
else if (XMLookForTKV(stanza, "active", "xmlns", CHAT_STATES)) if (XMLookForTKV(stanza, "active", "xmlns", CHAT_STATES))
{ {
char *latest = NULL;
decode_from = ParseeLookupJID(from); decode_from = ParseeLookupJID(from);
from_matrix = ParseeEncodeJID(args->config, decode_from, true); from_matrix = ParseeEncodeJID(args->config, decode_from, true);
mroom_id = ParseeGetBridgedRoom(args, stanza); mroom_id = ParseeGetBridgedRoom(args, stanza);
latest = ParseeLookupHead(mroom_id);
ASType(args->config, from_matrix, mroom_id, false); ASType(args->config, from_matrix, mroom_id, false);
ASPresence(args->config, from_matrix, mroom_id, latest);
Free(decode_from); Free(decode_from);
Free(from_matrix); Free(from_matrix);
Free(latest);
Free(mroom_id); Free(mroom_id);
mroom_id = NULL; mroom_id = NULL;
decode_from = NULL; decode_from = NULL;
from_matrix = NULL; from_matrix = NULL;
} }
if (XMLookForTKV(stanza, "paused", "xmlns", CHAT_STATES) ||
XMLookForTKV(stanza, "received", "xmlns", "urn:xmpp:receipts"))
{
/* TODO: Use stanza ID if possible */
char *latest = NULL;
decode_from = ParseeLookupJID(from);
from_matrix = ParseeEncodeJID(args->config, decode_from, true);
mroom_id = ParseeGetBridgedRoom(args, stanza);
latest = ParseeLookupHead(mroom_id);
ASPresence(args->config, from_matrix, mroom_id, latest);
Free(decode_from);
Free(from_matrix);
Free(latest);
Free(mroom_id);
mroom_id = NULL;
decode_from = NULL;
from_matrix = NULL;
}
#undef CHAT_STATES #undef CHAT_STATES
body = XMLookForUnique(stanza, "body"); body = XMLookForUnique(stanza, "body");
if (!body) if (!body)
@ -978,10 +1006,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
char *from_matrix = ParseeDecodeMXID(decode_from); char *from_matrix = ParseeDecodeMXID(decode_from);
char *affiliation = HashMapGet(item->attrs, "affiliation"); char *affiliation = HashMapGet(item->attrs, "affiliation");
Log(LOG_INFO, "Acting on %s", from_matrix);
Log(LOG_INFO, "OID=%s DF=%s", oid, decode_from);
if (StrEquals(affiliation, "outcast")) if (StrEquals(affiliation, "outcast"))
{ {
ASBan(args->config, room, from_matrix); ASBan(args->config, room, from_matrix);

View file

@ -40,6 +40,7 @@ extern HashMap * ASFind(const ParseeConfig *, char *, char *);
* Said body is freed during the function's execution. */ * Said body is freed during the function's execution. */
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *); extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
extern void ASType(const ParseeConfig *, char *, char *, bool); extern void ASType(const ParseeConfig *, char *, char *, bool);
extern void ASPresence(const ParseeConfig *, char *, char *, char *);
/* Sets a state event with a specific type and body */ /* 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); extern void ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *event);

View file

@ -202,6 +202,11 @@ extern void ParseePushJIDTable(char *muc, char *bare);
extern char *ParseeLookupJID(char *muc); extern char *ParseeLookupJID(char *muc);
extern void ParseeDestroyJIDTable(void); extern void ParseeDestroyJIDTable(void);
extern void ParseeInitialiseHeadTable(void);
extern void ParseePushHeadTable(char *room, char *id);
extern char *ParseeLookupHead(char *room);
extern void ParseeDestroyHeadTable(void);
/* Globally bans a Matrix user from ever interacting with Parsee, and bans /* Globally bans a Matrix user from ever interacting with Parsee, and bans
* them from bridged rooms where the bot has administrator. */ * them from bridged rooms where the bot has administrator. */
extern void ParseeGlobalBan(ParseeData *, char *user, char *reason); extern void ParseeGlobalBan(ParseeData *, char *user, char *reason);