jdev - 2026-03-23


  1. kousu

    I'm trying to under <delay>s from XEP-0203. I'm writing some bots with the assumption that a <delay> should be ignored; I don't want to be triggering e.g. CI, or scanning my monitored systems, or uploading anything redundantly. I first ignored <delay> messages because every time I restarted by bots they were re-running all the commands I had sent them in MUCs. MUC join history is distinguished by <delay> tags, as far as I can tell. I disabled MUC history by joining with maxstanzas=0, so that solves that immediate problem. But I am worried there are other cases that generate duplicated messages. Is there anything in the specs that guarantees <delay>s mean I can ignore? Or on the other hand, should I ignore the delay tags completely because the only duplicate messages possible come from MUC history which I've already ignored?

  2. kousu

    I'm trying to understand <delay>s from XEP-0203. I'm writing some bots with the assumption that a <delay> should be ignored; I don't want to be triggering e.g. CI, or scanning my monitored systems, or uploading anything redundantly. I first ignored <delay> messages because every time I restarted by bots they were re-running all the commands I had sent them in MUCs. MUC join history is distinguished by <delay> tags, as far as I can tell. I disabled MUC history by joining with maxstanzas=0, so that solves that immediate problem. But I am worried there are other cases that generate duplicated messages. Is there anything in the specs that guarantees <delay>s mean I can ignore? Or on the other hand, should I ignore the delay tags completely because the only duplicate messages possible come from MUC history which I've already ignored?

  3. Link Mauve

    kousu, delay means the message has been sent in the past and might be less relevant to you right now than when it was sent, but it doesn’t imply anything about duplication or such.

  4. Link Mauve

    You can tell which entity delayed the message, but that also doesn’t help with that.

    🤔 1
  5. Link Mauve

    I wouldn’t ignore delayed messages even for a bot though.

  6. kousu

    Great, thanks for the answer

  7. kousu

    How do I filter out duplication? I don't want to build a local database if message IDs, that sounds fraught.

  8. Link Mauve

    You should hopefully not get duplicated messages.

  9. Link Mauve

    In which situation do you expect them?

  10. kousu

    I don't know that's why I'm worried

  11. kousu

    The only case I've actually hit so far is on joining MUCs

  12. Link Mauve

    Then you shouldn’t worry.

  13. kousu

    Is there a way to detect when a MUC is done sending it's initial scrollback?

  14. Link Mauve

    You set it to 0 so that should be it.

  15. kousu

    I'm trying to code defensively. What if someone takes my code and forgets to set 0, or I want to be construct chained commands by looking at replies that came in before the bot joined?

  16. Link Mauve

    Then you can detect the end of the history with the <subject/> being defined, see: https://xmpp.org/extensions/xep-0045.html#enter-subject

  17. kousu

    ah okay, yes that works, thank you !

  18. kousu

    Thanks so much Link Mauve.

  19. Link Mauve

    You’re welcome. :)

  20. Link Mauve

    Reading specifications and remembering such details is something that gives me great joy. ^^

  21. lovetox

    kousu, you should not receive duplicates, except you implement MAM

  22. kousu

    Ah right. And even if I did that, it looks like MAM wraps the dupes in <result> and <forwarded> if I'm not mistaken. There's no top-level <body> so my code won't get confused.

  23. kousu

    This seems to work well, maybe I'll try to get it into slixmpp: ``` def __init__(self, jid, password=None): # ... self._xep_0045_joined = set() self.add_event_handler("groupchat_presence", self.groupchat_presence) self.add_event_handler("groupchat_subject", self.groupchat_subject) self.add_event_handler("message", self.message) async def groupchat_presence(self, event): if event['type'] == 'unavailable' and 110 in event['muc']['status_codes']: self._xep_0045_joined.remove(event['from'].bare) async def groupchat_subject(self, event): self._xep_0045_joined.add(event['from'].bare) async def message(self, msg): if msg["type"] == "groupchat" and msg["from"].bare not in self._xep_0045_joined: return await self._respond(msg) ```

  24. kousu

    I wonder if I can shorten it still though. The spec says > Discussion history messages MUST be stamped with Delayed Delivery [...] The 'from' attribute MUST be set to the JID of the room itself. history => JID == room doesn't mean JID == room => history, but maybe that's true in practice? Does anyone know? It sort of makes sense to me that the only delays a MUC would send are scrollback (and e.g. in the MAM case there is no delay["from"]). If so the check could be: ``` async def message(self, msg): if msg["type"] == "groupchat" and msg["delay"]["stamp"] and msg["delay"]["from"] == msg["from"].bare: return await self._respond(msg) ```

  25. singpolyma

    If you don't want history messages just ask the MUC not to send them. Don't need to ignore them

  26. jjj333_p (any pronouns)

    kousu, slixmpp is great, i use it for my project. also slixmpp has a default history value of 0 set in the function so unless you explicitly set a nonzero value it wont return history

  27. jjj333_p (any pronouns)

    https://downloadable.pain.agency/file_share/019d1cc9-6c45-774b-a448-b9ce54192adf/2336cb06-b008-4b72-a575-c302744dfd64.png

  28. jjj333_p (any pronouns)

    aaa wrong paste

  29. mathieui

    kousu, clients can send a delay that will be kept by the MUC

  30. jjj333_p (any pronouns) retracted a previous message, but it's unsupported by your client.

  31. mathieui

    e.g. you type a message on your phone, send it but it gets queued because you have no network

  32. mathieui

    some (most?) clients will add a delay tag there

  33. jjj333_p (any pronouns)

    https://slixmpp.readthedocs.io/en/latest/_modules/slixmpp/plugins/xep_0045/muc.html#XEP_0045.join_muc_wait

    👍 1
  34. jjj333_p (any pronouns)

    its actually none it seems, i remember it being 0 at some point

  35. mathieui

    jjj333_p (any pronouns), the historical join_muc had a default of "0", yes

  36. jjj333_p (any pronouns)

    > jjj333_p (any pronouns), the historical join_muc had a default of "0", yes does none in this case function the same (i can assume it defaults to no history even if the muc has a default history value?)

  37. kousu

    Let me double check. I think None means it's undefined and defaults to the MUC's configuration which is usually 20

    👍 1
  38. jjj333_p (any pronouns)

    if its not 0, i should change it in my bridge since i have no use for messages sent to puppets and need not cause more traffic

    😄 1
  39. kousu

    yes, None means I get scrollback

    👍 1
  40. jjj333_p (any pronouns)

    > kousu, slixmpp is great, i use it for my project. also slixmpp has a default history value of 0 set in the function so unless you explicitly set a nonzero value it wont return history alright, so i was wrong

  41. kousu

    i appreciate getting to share in all the wisdom here. thanks jjj333_p (any pronouns), and mathieui, andsingpolyma, andLink Mauve 😊

    ❤ 1