[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

@ -732,6 +732,38 @@ ASType(const ParseeConfig *c, char *user, char *room, bool status)
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 *
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();
ParseeInitialiseHeadTable();
Log(LOG_NOTICE, "Setting up local Matrix user...");
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
@ -112,6 +113,7 @@ end:
CronStop(cron);
CronFree(cron);
ParseeFreeData(conf.handlerArgs);
ParseeDestroyHeadTable();
ParseeDestroyJIDTable();
return 0;
}

View file

@ -266,13 +266,17 @@ end:
void
ParseeEventHandler(ParseeData *data, HashMap *event)
{
char *event_type;
char *event_type, *event_id, *room_id;
if (!data || !event)
{
return;
}
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"))
{
ParseeMemberHandler(data, event);

View file

@ -69,3 +69,63 @@ ParseeDestroyJIDTable(void)
pthread_mutex_unlock(&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);
}
{
XMLElement *request = XMLCreateTag("request");
XMLAddAttr(request, "xmlns", "urn:xmpp:receipts");
XMLAddChild(message, request);
}
if (oob)
{
XMLElement *xoob, *oob_data, *oob_url;

View file

@ -29,6 +29,7 @@
AdvertiseSimple("urn:xmpp:message-correct:0") \
AdvertiseSimple("urn:xmpp:reactions:0") \
AdvertiseSimple("urn:xmpp:styling:0") \
AdvertiseSimple("urn:xmpp:receipts") \
AdvertiseSimple("urn:xmpp:reply:0") \
AdvertiseSimple("jabber:x:oob") \
AdvertiseSimple("vcard-temp") \
@ -443,21 +444,48 @@ MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
decode_from = 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);
from_matrix = ParseeEncodeJID(args->config, decode_from, true);
mroom_id = ParseeGetBridgedRoom(args, stanza);
latest = ParseeLookupHead(mroom_id);
ASType(args->config, from_matrix, mroom_id, false);
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;
}
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
body = XMLookForUnique(stanza, "body");
if (!body)
@ -978,10 +1006,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
char *from_matrix = ParseeDecodeMXID(decode_from);
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"))
{
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. */
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
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 */
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 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
* them from bridged rooms where the bot has administrator. */
extern void ParseeGlobalBan(ParseeData *, char *user, char *reason);