-
-
Notifications
You must be signed in to change notification settings - Fork 57.7k
Description
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 —
/modeland/thinkcan'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 hintsGET /teams/{team_id}/commands/autocomplete— list autocomplete-enabled commandsGET /teams/{team_id}/commands/autocomplete_suggestions— dynamic autocomplete suggestionsDELETE /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:
- Validate the command token (MM sends a verification token with each request)
- Parse the trigger word and text arguments
- Route to the existing command handler (same path as text commands)
- Format the response as MM-compatible JSON (
response_type,text, optionalattachments)
2. Command registration at startup
On plugin init (when commands.native is enabled):
- Call
GET /api/v4/commands?team_id=X&custom_only=trueto list existing commands - For each OpenClaw command, check if already registered; if not, call
POST /api/v4/commands - Enable
auto_complete: truewith hint and description for each command - 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_suggestionsendpoint but requires a separate HTTP callback - Alternative: use static
auto_complete_hintstrings (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
- Mattermost Custom Slash Commands docs
- Mattermost API — Commands
- OpenClaw Slash Commands docs
- Discord plugin native commands:
extensions/discord/src/channel.ts(nativeCommands: true) - Telegram plugin native commands:
extensions/telegram/src/channel.ts(nativeCommands: true) - Mattermost plugin current state:
extensions/mattermost/src/channel.ts(nativeCommands: falsein capabilities)