mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 18:45:11 +00:00
[ADD/WIP] Start receiptwerk
This commit is contained in:
parent
bb836789b2
commit
0fc0fdd6f4
9 changed files with 144 additions and 8 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
32
src/AS.c
32
src/AS.c
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue