Skip to content

feat(mattermost): add edit and delete message actions#25295

Open
Luna2026-a11y wants to merge 10 commits intoopenclaw:mainfrom
Luna2026-a11y:feat/mattermost-edit-delete
Open

feat(mattermost): add edit and delete message actions#25295
Luna2026-a11y wants to merge 10 commits intoopenclaw:mainfrom
Luna2026-a11y:feat/mattermost-edit-delete

Conversation

@Luna2026-a11y
Copy link
Copy Markdown

@Luna2026-a11y Luna2026-a11y commented Feb 24, 2026

Summary

Adds patchMattermostPost() and deleteMattermostPost() to the Mattermost client, and wires them as edit and delete actions in the channel plugin message action adapter.

What this enables

  • Edit messages via the message tool (action=edit) — foundation for block-streaming edit-in-place (progressive message rendering like Telegram/Discord)
  • Delete messages via the message tool (action=delete)

API endpoints used

  • Edit: PUT /api/v4/posts/{post_id}/patch (partial update)
  • Delete: DELETE /api/v4/posts/{post_id}

Files changed

  • extensions/mattermost/src/mattermost/client.ts — add patchMattermostPost() and deleteMattermostPost()
  • extensions/mattermost/src/channel.ts — register edit and delete in listActions, supportsAction, and handleAction

Testing

  • Tested against a live Mattermost 10.x instance: create → edit → delete cycle works correctly
  • Bot requires edit_post / delete_post permissions (standard bot permissions)

Notes

This is a stepping stone toward full block-streaming support on Mattermost, bringing it closer to feature parity with the Telegram and Discord plugins.

Greptile Summary

Added edit and delete message functionality to the Mattermost plugin by implementing patchMattermostPost() and deleteMattermostPost() in the client, and wiring them through the channel message action adapter.

Changes:

  • Added patchMattermostPost() function supporting partial updates (message, props, fileIds)
  • Added deleteMattermostPost() function for post deletion
  • Registered edit and delete actions in listActions() and supportsAction()
  • Implemented action handlers that validate params, resolve account config, and call the API functions
  • Used standard Mattermost API endpoints (PUT /posts/{id}/patch, DELETE /posts/{id})

Architecture:

  • Follows existing pattern from react action handler (account resolution, validation, error handling)
  • Accepts both messageId and postId parameter names for flexibility
  • Returns structured results with content and details

The implementation is straightforward and brings Mattermost closer to feature parity with Telegram and Discord plugins.

Confidence Score: 4/5

  • This PR is safe to merge with low risk
  • Clean implementation following established patterns. The code correctly validates required parameters, handles account resolution, and uses proper error handling. One minor style suggestion about empty message validation, but this won't cause runtime errors since the Mattermost API will reject empty edits if they're not allowed.
  • No files require special attention

Last reviewed commit: e3df5fa

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

@openclaw-barnacle openclaw-barnacle Bot added channel: mattermost Channel integration: mattermost size: S labels Feb 24, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread extensions/mattermost/src/channel.ts Outdated
Comment on lines +74 to +80
const message =
typeof (params as any)?.message === "string"
? (params as any).message
: typeof (params as any)?.text === "string"
? (params as any).text
: "";
if (!message) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty message is allowed but might cause API errors

The code allows empty strings for the message parameter, but Mattermost API typically requires non-empty message text. If params.message or params.text is an empty string, it will pass the empty string check but could fail at the API level.

Compare with Discord (line 171 in src/channels/plugins/actions/discord/handle-action.ts): requires message with required: true
Compare with Telegram (line 161 in src/channels/plugins/actions/telegram.ts): requires message with required: true, allowEmpty: false

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/mattermost/src/channel.ts
Line: 74-80

Comment:
empty message is allowed but might cause API errors

The code allows empty strings for the `message` parameter, but Mattermost API typically requires non-empty message text. If `params.message` or `params.text` is an empty string, it will pass the empty string check but could fail at the API level.

Compare with Discord (line 171 in `src/channels/plugins/actions/discord/handle-action.ts`): requires message with `required: true`
Compare with Telegram (line 161 in `src/channels/plugins/actions/telegram.ts`): requires message with `required: true, allowEmpty: false`

How can I resolve this? If you propose a fix, please make it concise.

@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 3, 2026
@mukhtharcm mukhtharcm self-assigned this Mar 14, 2026
@mukhtharcm mukhtharcm force-pushed the feat/mattermost-edit-delete branch 2 times, most recently from 6350dbd to b5650e4 Compare March 16, 2026 00:52
@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: M and removed size: S labels Mar 16, 2026
@mukhtharcm mukhtharcm force-pushed the feat/mattermost-edit-delete branch from b5650e4 to 3e7598c Compare March 16, 2026 01:50
@openclaw-barnacle openclaw-barnacle Bot added channel: signal Channel integration: signal and removed commands Command implementations labels Mar 16, 2026
@mukhtharcm mukhtharcm force-pushed the feat/mattermost-edit-delete branch from 54075f1 to 4ec6fb5 Compare March 16, 2026 08:20
@openclaw-barnacle openclaw-barnacle Bot removed the channel: signal Channel integration: signal label Mar 16, 2026
@mukhtharcm mukhtharcm force-pushed the feat/mattermost-edit-delete branch from 4ec6fb5 to bb067c0 Compare March 16, 2026 08:24
Luna and others added 10 commits March 16, 2026 08:26
Add patchMattermostPost() and deleteMattermostPost() to the Mattermost
client, and wire them as 'edit' and 'delete' actions in the channel
plugin's message action adapter.

This enables:
- Editing bot messages via the message tool (action=edit)
- Deleting bot messages via the message tool (action=delete)
- Foundation for block-streaming edit-in-place (progressive message
  rendering like Telegram/Discord)

Uses PATCH /api/v4/posts/{post_id}/patch for edits and
DELETE /api/v4/posts/{post_id} for deletions.

Tested against a live Mattermost 10.x instance.
@mukhtharcm mukhtharcm force-pushed the feat/mattermost-edit-delete branch from bb067c0 to 69b8aef Compare March 16, 2026 08:26
@steipete
Copy link
Copy Markdown
Contributor

steipete commented Apr 26, 2026

Codex review: needs maintainer review before merge.

What this changes:

The PR branch adds Mattermost edit/delete message action support and client helpers, plus tests/docs/changelog, while also carrying unrelated provider-usage, plugin-loader, and bonjour test/infra changes.

Maintainer follow-up before merge:

Maintainer should decide whether to ask for a narrowed branch or replacement PR because this open implementation adds destructive message deletion and carries unrelated infra/test changes; it is not a safe autonomous fix lane as submitted.

Best possible solution:

Land a narrowed Mattermost-only implementation that exposes edit/delete via the channel message action adapter, uses plugin-SDK or local Mattermost helpers, validates account/target/post id and non-empty edit text, updates public CLI and Mattermost docs, and adds focused Mattermost client/action tests without unrelated infra changes.

Acceptance criteria:

  • pnpm test extensions/mattermost/src/channel.test.ts extensions/mattermost/src/mattermost/client.test.ts
  • pnpm exec oxfmt --check --threads=1 extensions/mattermost/src/channel.ts extensions/mattermost/src/channel.test.ts extensions/mattermost/src/mattermost/client.ts extensions/mattermost/src/mattermost/client.test.ts docs/cli/message.md docs/channels/mattermost.md
  • pnpm check:changed in Testbox after the branch is narrowed

What I checked:

  • Current main action discovery omits edit/delete: Mattermost action discovery only pushes send for configured accounts and react when reactions are enabled; supportsAction returns true only for send/react, and handleAction rejects anything else as unsupported. (extensions/mattermost/src/channel.ts:88, 2d53b49b20e1)
  • Current tests cover send/react only: Mattermost channel tests assert configured accounts expose send/react, and a selected account with reactions disabled exposes only send. (extensions/mattermost/src/channel.test.ts:333, 2d53b49b20e1)
  • Mutation helpers exist but are not message actions: Current main has updateMattermostPost and deleteMattermostPost client helpers, used by preview-streaming/cleanup paths rather than exposed through the message tool action adapter. (extensions/mattermost/src/mattermost/client.ts:527, 2d53b49b20e1)
  • Public CLI docs still omit Mattermost edit/delete: The message CLI docs list edit for Discord/Slack/Matrix and delete for Discord/Slack/Telegram/Matrix; Mattermost is not listed for either action. Public docs: docs/cli/message.md. (docs/cli/message.md:107, 2d53b49b20e1)
  • Preview streaming does not supersede this action PR: Mattermost docs describe preview streaming that edits a draft preview post in place, followed by separate message-tool docs for reactions and buttons; they do not document general edit/delete actions. Public docs: docs/channels/mattermost.md. (docs/channels/mattermost.md:270, 2d53b49b20e1)
  • Extension boundary issue in PR diff: The provided PR diff imports readStringParam from ../../../src/agents/tools/common.js in Mattermost extension production code, while the scoped extension rules prohibit importing core src/** internals or escaping the extension package root. (extensions/AGENTS.md:27, 2d53b49b20e1)

Likely related people:

  • steipete: Peter authored the detailed April 26 maintainer review in the PR discussion and authored the latest release snapshot commit that includes the current Mattermost channel/client/docs state used for this review. (role: recent maintainer and reviewer; confidence: high; commits: be8c24633aaa, 2d53b49b20e1; files: extensions/mattermost/src/channel.ts, extensions/mattermost/src/mattermost/client.ts, docs/cli/message.md)
  • vincentkoc: Current blame on the Mattermost action adapter and client helper snapshot points to Vincent-authored work, and the changelog credits vincentkoc on nearby Mattermost delivery/routing and plugin runtime work. (role: recent Mattermost/plugin runtime maintainer; confidence: high; commits: ad2516b1c876; files: extensions/mattermost/src/channel.ts, extensions/mattermost/src/mattermost/client.ts, CHANGELOG.md)
  • echo931: The changelog credits echo931 for Mattermost emoji reaction actions and reaction event notifications, which are the existing message-action surface this PR extends. (role: original adjacent Mattermost action contributor; confidence: medium; commits: be8c24633aaa; files: CHANGELOG.md, extensions/mattermost/src/channel.ts)

Remaining risk / open question:

  • The branch adds a destructive Mattermost delete action, so maintainer review should verify bot permissions, target/account routing, requester trust, auditability, and failure reporting before merge.
  • The provided diff mixes the Mattermost feature with unrelated provider-usage, plugin-loader, and bonjour changes, making normal review and security assessment harder.
  • The extension production import from core src/** violates the bundled plugin boundary and should be replaced with a plugin-SDK or local Mattermost helper.
  • The review comment on the branch notes empty edit text can pass local validation and fail at the Mattermost API boundary; a narrowed implementation should validate non-empty edit content.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 2d53b49b20e1.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 27, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 27, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 28, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels Apr 28, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 29, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 29, 2026

Codex review: found issues before merge.

Summary
The PR adds Mattermost edit/delete message actions and client helpers, updates Mattermost tests/docs/changelog, and also carries unrelated provider-usage, plugin-loader, and bonjour test/infra changes.

Reproducibility: yes. for the PR defects by source inspection: the new action paths import a core internal and create Mattermost clients without forwarding the account private-network opt-in. Current main inspection also confirms the requested edit/delete action surface is still absent.

Next step before merge
Maintainer should decide whether to request a narrowed or replacement branch because the current PR adds destructive deletion and includes unrelated infra/test changes beyond the Mattermost action feature.

Security
Cleared: No concrete secret, dependency, workflow, or supply-chain regression was found; the destructive delete action still needs normal maintainer product/security review.

Review findings

  • [P2] Preserve the private-network opt-in for edit and delete — extensions/mattermost/src/channel.ts:107-133
  • [P2] Use the plugin SDK parameter reader export — extensions/mattermost/src/channel.ts:20
Review details

Best possible solution:

Land a narrowed Mattermost-only implementation that exposes edit/delete through the channel action adapter, reuses the current helper/runtime surface, preserves private-network opt-in, uses SDK exports, and updates focused tests/docs/changelog only.

Do we have a high-confidence way to reproduce the issue?

Yes, for the PR defects by source inspection: the new action paths import a core internal and create Mattermost clients without forwarding the account private-network opt-in. Current main inspection also confirms the requested edit/delete action surface is still absent.

Is this the best way to solve the issue?

No. The feature direction is plausible, but the submitted patch is not the best implementation because it should be narrowed, rebased onto the current Mattermost helpers, preserve SSRF policy config, and stay within plugin SDK boundaries.

Full review comments:

  • [P2] Preserve the private-network opt-in for edit and delete — extensions/mattermost/src/channel.ts:107-133
    The new edit/delete paths construct createMattermostClient({ baseUrl, botToken }) without forwarding allowPrivateNetwork: isPrivateNetworkOptInEnabled(resolved.config). Other Mattermost API paths pass that account opt-in because the client feeds it into the SSRF guard, so self-hosted LAN Mattermost installs with the opt-in set would still have these new actions blocked.
    Confidence: 0.88
  • [P2] Use the plugin SDK parameter reader export — extensions/mattermost/src/channel.ts:20
    Mattermost production code imports readStringParam from ../../../src/agents/tools/common.js, which escapes the plugin package and depends on core internals. Use openclaw/plugin-sdk/channel-actions, openclaw/plugin-sdk/param-readers, or a local helper instead.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.86

What I checked:

Likely related people:

  • vincentkoc: Current blame on the Mattermost action adapter and client helper snapshot points to Vincent Koc, and the PR discussion repeatedly routed Mattermost action review context to vincentkoc. (role: recent Mattermost/channel maintainer; confidence: high; commits: d253392ea2a3; files: extensions/mattermost/src/channel.ts, extensions/mattermost/src/mattermost/client.ts, docs/cli/message.md)
  • steipete: Peter authored the detailed maintainer review in the PR discussion calling for a narrowed branch and identifying the same Mattermost action surface as the review target. (role: recent maintainer reviewer; confidence: medium; files: extensions/mattermost/src/channel.ts, extensions/mattermost/src/mattermost/client.ts)
  • echo931: Prior review context links echo931 to the existing Mattermost reaction action surface that this PR extends. (role: adjacent Mattermost action contributor; confidence: medium; files: extensions/mattermost/src/channel.ts, CHANGELOG.md)

Remaining risk / open question:

  • The branch is stale against current main and carries unrelated infra/test changes, so direct merge likely needs rebase and narrowing before validation.
  • The delete action is destructive; maintainer review should confirm requester trust, bot permission expectations, auditability, and failure reporting.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 58c4f9e190bc.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 30, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels Apr 30, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels May 1, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels May 3, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels May 4, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: mattermost Channel integration: mattermost size: M stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants