Skip to content

[Feature]: Native slash command support for Mattermost plugin #16515

@echo931

Description

@echo931

Summary

Add native slash command support to the Mattermost plugin, bringing it to parity with Discord, Telegram, and Slack which already register native commands. This would give Mattermost users autocomplete, discoverability, and a proper UX for OpenClaw commands instead of relying on text-only parsing.

Current behavior

The Mattermost plugin declares nativeCommands: false in its capabilities. All slash commands (/status, /model, /think, /help, etc.) work only via text parsing — OpenClaw intercepts the raw message text and matches against known command patterns.

This means:

  • No autocomplete — users must know command names by heart
  • No argument suggestions/model and /think can't offer dynamic choices
  • No discoverability — new users have no way to find available commands
  • Commands conflict with Mattermost built-ins — if MM has a built-in /status, it may shadow OpenClaw's

Discord and Telegram both have nativeCommands: true and register commands via their respective platform APIs at startup.

Mattermost slash command API

Mattermost supports custom slash commands via its REST API:

  • POST /api/v4/commands — register a custom command with trigger word, callback URL, autocomplete hints
  • GET /teams/{team_id}/commands/autocomplete — list autocomplete-enabled commands
  • GET /teams/{team_id}/commands/autocomplete_suggestions — dynamic autocomplete suggestions
  • DELETE /api/v4/commands/{id} — cleanup on shutdown

Architecture: Mattermost slash commands use a webhook callback model — when a user invokes a command, MM sends an HTTP POST to a configured URL with the command context (channel, user, text args, trigger_id). The endpoint responds with JSON containing the reply.

This is different from Discord (interaction API) and Telegram (inline in message stream), but similar to Slack's slash command model.

Proposed implementation

1. HTTP callback endpoint (main effort)

The Mattermost plugin currently only uses WebSocket for inbound events. It needs a new HTTP listener to receive slash command callbacks from the MM server.

Options:

  • Reuse OpenClaw's existing HTTP server (if the gateway already binds a port) and add a route like /hooks/mattermost/command
  • Standalone listener within the plugin on a configurable port

The callback handler would:

  1. Validate the command token (MM sends a verification token with each request)
  2. Parse the trigger word and text arguments
  3. Route to the existing command handler (same path as text commands)
  4. Format the response as MM-compatible JSON (response_type, text, optional attachments)

2. Command registration at startup

On plugin init (when commands.native is enabled):

  1. Call GET /api/v4/commands?team_id=X&custom_only=true to list existing commands
  2. For each OpenClaw command, check if already registered; if not, call POST /api/v4/commands
  3. Enable auto_complete: true with hint and description for each command
  4. Store command IDs for cleanup

Required permission: manage_slash_commands on the bot account's team.

3. Dynamic autocomplete

For commands with dynamic arguments (/model, /think, /reasoning, /verbose, /elevated, /exec):

  • MM supports autocomplete_suggestions endpoint but requires a separate HTTP callback
  • Alternative: use static auto_complete_hint strings (simpler, covers most cases)
  • Advanced: implement the suggestions callback for /model (list available models) and /think (list levels)

4. Cleanup on shutdown

On graceful shutdown, delete registered commands via DELETE /api/v4/commands/{id} to avoid orphaned entries. Similar to how Discord clears commands when commands.native: false.

5. Configuration

Add to the Mattermost config schema:

{
  channels: {
    mattermost: {
      commands: {
        native: "auto",         // "auto" | true | false
        nativeSkills: "auto",   // register skill commands too
        callbackPort: 0,        // 0 = use gateway HTTP server; >0 = dedicated port
        callbackHost: "localhost",
        callbackUrl: "",        // explicit override (e.g. behind reverse proxy)
      }
    }
  }
}

Key considerations

Network reachability

The callback URL must be reachable from the Mattermost server. If OpenClaw and MM run on the same host or LAN, this is trivial. For remote setups, the callback URL needs to be exposed (reverse proxy, tunnel, etc.). The callbackUrl config override handles this.

Bot permissions

The bot account needs manage_slash_commands permission. This is typically granted via a system admin role or custom role. The plugin should detect and warn if the permission is missing.

Command name conflicts

Mattermost reserves certain command names (/join, /leave, /away, etc.). The registration logic should skip or rename conflicting commands. OpenClaw already handles this for Discord.

Multi-account support

If multiple MM accounts are configured, commands should be registered per-team for each account.

Effort estimate

Component Effort Notes
HTTP callback listener Medium New pattern for MM plugin; can potentially reuse gateway HTTP
Command registration (CRUD) Low Standard REST API calls at startup
Routing callback → handler Low Plumbing exists for text commands
Dynamic autocomplete Medium Optional enhancement for /model, /think
Cleanup on shutdown Trivial DELETE calls
Config schema additions Trivial Add commands.native etc.
Tests Medium Callback parsing, registration, cleanup

Overall: medium-sized feature, estimated 2-3 days for someone familiar with the plugin architecture.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions