Mercurial > libervia-backend
comparison libervia/backend/core/xmpp.py @ 4375:42becd4b819f
core (xmpp): add `origin` and `origin_label` to message data:
If a message comes from a gateway, its type is used as `origin` in `extra`, and it has a
name, it's used as `origin_label`.
`is-bot` is also set when the sending entity is advertised as a bot.
rel 459
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 08 Jun 2025 17:16:56 +0200 |
parents | 90d476a80ce9 |
children | 79d463e3fdeb |
comparison
equal
deleted
inserted
replaced
4374:90d476a80ce9 | 4375:42becd4b819f |
---|---|
22 from functools import partial | 22 from functools import partial |
23 import mimetypes | 23 import mimetypes |
24 from pathlib import Path | 24 from pathlib import Path |
25 import sys | 25 import sys |
26 import time | 26 import time |
27 from typing import Callable, Dict, Tuple, Optional | 27 from typing import Callable, Dict, Tuple, Optional, cast |
28 from urllib.parse import unquote, urlparse | 28 from urllib.parse import unquote, urlparse |
29 import uuid | 29 import uuid |
30 | 30 |
31 import shortuuid | 31 import shortuuid |
32 from twisted.internet import defer, error as internet_error, reactor | 32 from twisted.internet import defer, error as internet_error, reactor |
1314 if elt.uri == namespace: | 1314 if elt.uri == namespace: |
1315 elt.defaultUri = elt.uri = C.NS_CLIENT | 1315 elt.defaultUri = elt.uri = C.NS_CLIENT |
1316 for child in elt.elements(): | 1316 for child in elt.elements(): |
1317 self.normalize_ns(child, namespace) | 1317 self.normalize_ns(child, namespace) |
1318 | 1318 |
1319 def parse_message(self, message_elt: domish.Element) -> MessageData: | 1319 async def parse_message(self, message_elt: domish.Element) -> MessageData: |
1320 """Parse a message XML and return message_data | 1320 """Parse a message XML and return message_data |
1321 | 1321 |
1322 @param message_elt(domish.Element): raw <message> xml | 1322 @param message_elt(domish.Element): raw <message> xml |
1323 @param client(SatXMPPClient, None): client to map message id to uid | 1323 @param client(SatXMPPClient, None): client to map message id to uid |
1324 if None, mapping will not be done | 1324 if None, mapping will not be done |
1344 xml=message_elt.toXml() | 1344 xml=message_elt.toXml() |
1345 ) | 1345 ) |
1346 ) | 1346 ) |
1347 ) | 1347 ) |
1348 | 1348 |
1349 client = self.parent | 1349 client = cast(SatXMPPEntity, self.parent) |
1350 assert client is not None | |
1350 | 1351 |
1351 if not message_elt.hasAttribute("to"): | 1352 if not message_elt.hasAttribute("to"): |
1352 message_elt["to"] = client.jid.full() | 1353 message_elt["to"] = client.jid.full() |
1353 | 1354 |
1355 from_jid = jid.JID(message_elt["from"]) | |
1356 from_jid_bare = from_jid.userhostJID() | |
1354 message = {} | 1357 message = {} |
1355 subject = {} | 1358 subject = {} |
1356 extra = {} | 1359 extra = {} |
1357 data = MessageData({ | 1360 data = MessageData({ |
1358 "from": jid.JID(message_elt["from"]), | 1361 "from": from_jid, |
1359 "to": jid.JID(message_elt["to"]), | 1362 "to": jid.JID(message_elt["to"]), |
1360 "uid": message_elt.getAttribute( | 1363 "uid": message_elt.getAttribute( |
1361 "uid", str(uuid.uuid4()) | 1364 "uid", str(uuid.uuid4()) |
1362 ), # XXX: uid is not a standard attribute but may be added by plugins | 1365 ), # XXX: uid is not a standard attribute but may be added by plugins |
1363 "message": message, | 1366 "message": message, |
1370 message_id = extra["message_id"] = message_elt["id"] | 1373 message_id = extra["message_id"] = message_elt["id"] |
1371 except KeyError: | 1374 except KeyError: |
1372 pass | 1375 pass |
1373 else: | 1376 else: |
1374 client.mess_id2uid[(data["from"], message_id)] = data["uid"] | 1377 client.mess_id2uid[(data["from"], message_id)] = data["uid"] |
1378 | |
1379 # origin | |
1380 if not from_jid_bare in (client.jid.userhostJID(), client.server_jid): | |
1381 disco_infos = await self.host.memory.disco.get_infos(client, from_jid_bare) | |
1382 if from_jid_bare.user: | |
1383 domain_disco_infos = await self.host.memory.disco.get_infos( | |
1384 client, jid.JID(from_jid_bare.host) | |
1385 ) | |
1386 else: | |
1387 domain_disco_infos = disco_infos | |
1388 if ("client", "bot") in disco_infos.identities: | |
1389 extra["is-bot"] = True | |
1390 for (category, type_), label in domain_disco_infos.identities.items(): | |
1391 if category == "gateway": | |
1392 extra["origin"] = type_ | |
1393 if label: | |
1394 extra["origin_name"] = label | |
1375 | 1395 |
1376 # message | 1396 # message |
1377 for e in message_elt.elements(C.NS_CLIENT, "body"): | 1397 for e in message_elt.elements(C.NS_CLIENT, "body"): |
1378 message[e.getAttribute((C.NS_XML, "lang"), "")] = str(e) | 1398 message[e.getAttribute((C.NS_XML, "lang"), "")] = str(e) |
1379 | 1399 |
1478 if not trigger_ret_continue: | 1498 if not trigger_ret_continue: |
1479 # trigger returned False, we stop the workflow. | 1499 # trigger returned False, we stop the workflow. |
1480 return | 1500 return |
1481 | 1501 |
1482 try: | 1502 try: |
1483 data = self.parse_message(message_elt) | 1503 data = await self.parse_message(message_elt) |
1484 # we now do all post treatments added by plugins | 1504 # we now do all post treatments added by plugins |
1485 post_treat.callback(data) | 1505 post_treat.callback(data) |
1486 await post_treat | 1506 await post_treat |
1487 | 1507 |
1488 self.complete_attachments(data) | 1508 self.complete_attachments(data) |