fix(journal): ignore message edits so they stop recording duplicates
An edited `!journal ...` message was recorded as a brand-new entry, so one message edited five times produced five near-identical rows. Matrix delivers an edit as a fresh m.room.message, and mautrix swaps its content for `m.new_content` during deserialization (mautrix/types/event/message.py:393-396), stripping the "* " fallback prefix. The handler therefore saw something byte-identical to a new command. Neither @command.passive nor @command.new filters edits, so guard on evt.content.get_edit() in the plugin. Also corrects the README quirk that claimed edits could never reach the bot — it asserted the opposite of the actual behavior. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019wNB1sgkcBGijWjKTjtwG8
This commit is contained in:
parent
b1c37161dd
commit
3dc7eab2ab
3 changed files with 32 additions and 6 deletions
|
|
@ -58,11 +58,26 @@ rather keep IDs monotonic across resets.)
|
||||||
|
|
||||||
## Known quirks
|
## Known quirks
|
||||||
|
|
||||||
- **Edited messages don't re-trigger the bot.** Matrix sends edits as
|
- **Editing a recorded entry does nothing.** Edits are deliberately
|
||||||
a separate `m.replace` event that bots don't react to. If you typed
|
ignored (since v0.2.1), so fixing a typo in a `!journal` message
|
||||||
`!journal` then edited the message to add content, the bot saw only
|
leaves the stored entry unchanged. Send a fresh `!journal` message
|
||||||
the empty `!journal` and won't record. Send a fresh message instead
|
instead of editing.
|
||||||
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 <random text>` runs the show query with that text
|
- **`!journal show <random text>` runs the show query with that text
|
||||||
as the user filter.** If it doesn't match any MXID, you get
|
as the user filter.** If it doesn't match any MXID, you get
|
||||||
"No entries." Use a fully-qualified MXID like `@pat:ariege.io`.
|
"No entries." Use a fully-qualified MXID like `@pat:ariege.io`.
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,17 @@ class JournalBot(Plugin):
|
||||||
|
|
||||||
@command.passive(regex=_JOURNAL_RE)
|
@command.passive(regex=_JOURNAL_RE)
|
||||||
async def journal(self, evt: MessageEvent, match) -> None:
|
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()
|
rest = (match[1] or "").strip()
|
||||||
|
|
||||||
if not rest:
|
if not rest:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
maubot: 0.1.0
|
maubot: 0.1.0
|
||||||
id: dev.aiolabs.journal
|
id: dev.aiolabs.journal
|
||||||
version: 0.2.0
|
version: 0.2.1
|
||||||
license: AGPL-3.0-or-later
|
license: AGPL-3.0-or-later
|
||||||
modules:
|
modules:
|
||||||
- journal
|
- journal
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue