diff --git a/journal/README.md b/journal/README.md index e7b84de..79b539c 100644 --- a/journal/README.md +++ b/journal/README.md @@ -58,11 +58,26 @@ rather keep IDs monotonic across resets.) ## Known quirks -- **Edited messages don't re-trigger the bot.** Matrix sends edits as - a separate `m.replace` event that bots don't react to. If you typed - `!journal` then edited the message to add content, the bot saw only - the empty `!journal` and won't record. Send a fresh message instead - of editing. +- **Editing a recorded entry does nothing.** Edits are deliberately + ignored (since v0.2.1), so fixing a typo in a `!journal` message + leaves the stored entry unchanged. Send a fresh `!journal` message + instead of editing. + + This bullet previously claimed the opposite — that edits can't reach + the bot at all. That was wrong, and the bug it hid was noisy: mautrix + swaps an edit's content for `m.new_content` before the plugin sees it + (`mautrix/types/event/message.py:393-396`), stripping the `* ` + fallback prefix. The handler therefore received something identical + to a brand-new command and recorded a **duplicate entry on every + edit** — one journal message edited five times produced five rows. + Neither `@command.passive` nor `@command.new` filters edits, so any + maubot plugin matching on message bodies needs its own + `if evt.content.get_edit(): return` guard. + +- **Reactions are harmless.** They arrive as `m.reaction`, and + `@command.passive` only registers on `EventType.ROOM_MESSAGE` with + `msgtype` in `(m.text,)`, so a 👍 on a `!journal` message can never + trigger a recording. - **`!journal show ` runs the show query with that text as the user filter.** If it doesn't match any MXID, you get "No entries." Use a fully-qualified MXID like `@pat:ariege.io`. diff --git a/journal/journal.py b/journal/journal.py index 2a78fe3..96dff19 100644 --- a/journal/journal.py +++ b/journal/journal.py @@ -58,6 +58,17 @@ class JournalBot(Plugin): @command.passive(regex=_JOURNAL_RE) async def journal(self, evt: MessageEvent, match) -> None: + # Ignore edits. An edit arrives as a *fresh* m.room.message whose + # content mautrix transparently replaces with `m.new_content` + # (mautrix/types/event/message.py:393-396), stripping the "* " + # fallback prefix. The result is byte-identical to a new command, + # so every edit of a `!journal ...` message would record another + # duplicate entry. The relation survives that swap, which is what + # get_edit() reads. Neither @command.passive nor @command.new + # filters edits, so plugins must do it themselves. + if evt.content.get_edit(): + return + rest = (match[1] or "").strip() if not rest: diff --git a/journal/maubot.yaml b/journal/maubot.yaml index 74e2ae3..15a8807 100644 --- a/journal/maubot.yaml +++ b/journal/maubot.yaml @@ -1,6 +1,6 @@ maubot: 0.1.0 id: dev.aiolabs.journal -version: 0.2.0 +version: 0.2.1 license: AGPL-3.0-or-later modules: - journal