[ADD/WIP] XMPP->Matrix user statuses

Still untested because of performance reasons around statuses. Also,
how is presence basically a spec feature, and yet somehow manages to be
implemented by _no one_? Please, _implement it_ into yall's clients.
This commit is contained in:
LDA 2024-07-09 15:49:03 +02:00
commit e4c6994f61
3 changed files with 92 additions and 2 deletions

View file

@ -946,3 +946,45 @@ ASRedact(const ParseeConfig *c, char *room, char *user, char *e_id)
return; return;
} }
void
ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg)
{
HttpClientContext *ctx = NULL;
HashMap *request;
char *path;
char *status_str = NULL;
if (!c || !user || !msg)
{
return;
}
switch (status)
{
case USER_STATUS_ONLINE: status_str = "online"; break;
case USER_STATUS_OFFLINE: status_str = "offline"; break;
case USER_STATUS_UNAVAILABLE: status_str = "unavailable"; break;
default: return;
}
user = HttpUrlEncode(user);
path = StrConcat(5,
"/_matrix/client/v3/presence/",user,"/status",
"?user_id=", user
);
Free(user);
request = HashMapCreate();
HashMapSet(request, "presence", JsonValueString(status_str));
if (msg)
{
HashMapSet(request, "status_msg", JsonValueString(msg));
}
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
ASAuthenticateRequest(c, ctx);
ParseeSetRequestJSON(ctx, request);
JsonFree(request);
HttpClientContextFree(ctx);
Free(path);
}

View file

@ -1091,7 +1091,34 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
#define MUC_USER_NS "http://jabber.org/protocol/muc#user" #define MUC_USER_NS "http://jabber.org/protocol/muc#user"
XMLElement *user_info; XMLElement *user_info;
XMLElement *vc = XMLookForTKV(stanza, "x", "xmlns", "vcard-temp:x:update"); XMLElement *vc = XMLookForTKV(stanza, "x", "xmlns", "vcard-temp:x:update");
XMLElement *status = XMLookForUnique(stanza, "status");
char *oid = HashMapGet(stanza->attrs, "from"); char *oid = HashMapGet(stanza->attrs, "from");
if (status)
{
XMLElement *status_data = ArrayGet(status->children, 0);
char *decode_from = ParseeLookupJID(oid);
char *from_matrix = ParseeDecodeMXID(decode_from);
if (!from_matrix || *from_matrix != '@')
{
Free(from_matrix);
from_matrix = ParseeEncodeJID(args->config, decode_from, false);
}
if (status_data)
{
char *status_str = status_data->data;
/* TODO: Verify whenever this code works as soon as I can get
* my own instance (kappach.at) with presence enabled. */
ASSetStatus(
args->config, from_matrix,
USER_STATUS_ONLINE, status_str
);
}
Free(decode_from);
Free(from_matrix);
}
if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS))) if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS)))
{ {
XMLElement *item = XMLookForUnique(user_info, "item"); XMLElement *item = XMLookForUnique(user_info, "item");
@ -1180,7 +1207,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
{ {
ASLeave(args->config, room, from_matrix); ASLeave(args->config, room, from_matrix);
} }
} }
if (jid) if (jid)

View file

@ -57,10 +57,32 @@ extern void ASSetPL(const ParseeConfig *conf, char *id, HashMap *m);
* returns it's ID if it exists. */ * returns it's ID if it exists. */
extern char * ASCreateRoom(const ParseeConfig *c, char *by, char *alias); extern char * ASCreateRoom(const ParseeConfig *c, char *by, char *alias);
/* Sets a user's displayname */ /** Sets the user's global display{name]
* --------
* Returns: NOTHING
* Modifies: [EXT:User status]
* See-Also: ASGetName, ASSetStatus, ASSetAvatar */
extern void ASSetName(const ParseeConfig *c, char *user, char *name); extern void ASSetName(const ParseeConfig *c, char *user, char *name);
/** Sets the {user}'s global avatar, as an {mxc} URI
* --------
* Returns: NOTHING
* Modifies: [EXT:User status]
* See-Also: ASGetName, ASSetStatus */
extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc); extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc);
typedef enum UserStatus {
USER_STATUS_ONLINE,
USER_STATUS_OFFLINE,
USER_STATUS_UNAVAILABLE
} UserStatus;
/** Sets the user's status and message, to be seen by other clients.
* --------
* Returns: NOTHING
* Modifies: [EXT:User status]
* See-Also: https://spec.matrix.org/v1.11/client-server-api/#put_matrixclientv3presenceuseridstatus, ASSetName, ASSetAvatar */
extern void ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg);
/* Returns the user's name in a room, or a copy of the MXID itself, to be /* Returns the user's name in a room, or a copy of the MXID itself, to be
* Free'd. */ * Free'd. */
extern char * ASGetName(const ParseeConfig *c, char *room, char *user); extern char * ASGetName(const ParseeConfig *c, char *room, char *user);