Configure Mattermost Interactive Message Buttons via Outgoing Webhooks
Learn how to configure Mattermost Interactive Message Buttons using outgoing webhooks, handle button clicks with a Node.js service, and avoid common pitfalls such as content‑type errors and timeout limits.
18 Oct 2025, 13:32 UTC

Why Use Interactive Buttons?
Interactive Message Buttons let you attach actionable controls to a Mattermost post. When a user clicks a button, Mattermost sends an HTTP POST to a configured webhook URL, allowing you to trigger custom logic without leaving the channel. This is ideal for quick approvals, ticket creation, or any workflow that benefits from a single click.
Set Up the Outgoing Webhook
1. Log in as a system administrator. 2. Navigate to System Console > Integrations > Outgoing Webhooks. 3. Click Add outgoing webhook and fill in the form:
- Name: e.g.,
Help Button - Channel: Choose the channel(s) where the button should appear.
- Trigger Words: Set a keyword such as
!help. - Callback URL: The endpoint that will receive the button click payload, e.g.,
https://example.com/mattermost/webhook. - Content Type:
application/json(required). - Response Type: For an immediate reply, leave as
in_channelorephemeraldepending on visibility.
After saving, note the Webhook Token displayed. It will be used to verify incoming requests.
Craft the Post with a Button
When a user posts the trigger word (!help), Mattermost will send a payload to your webhook URL. Your service must respond with a JSON object that includes an attachments array containing an actions array. Each action defines a button.
{
"response_type": "ephemeral",
"text": "Need help?",
"attachments": [
{
"actions": [
{
"name": "help_button",
"integration": {
"url": "https://example.com/mattermost/webhook",
"context": {
"action": "request_help"
}
},
"type": "button",
"value": "request_help"
}
]
}
]
}
Key points:
response_typecontrols who sees the reply.ephemeralshows only the user who triggered the button.- The
integration.urlmust match the webhook URL configured in the console. - Button text is limited to 30 characters.
- A post can contain up to 5 actions.
Handle the Button Click
When a user clicks the button, Mattermost sends a POST to the webhook URL with a JSON payload that includes the button’s value and the original message context. Below is a minimal Node.js Express handler that validates the signature, logs the payload, and returns an ephemeral confirmation.
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const WEBHOOK_TOKEN = process.env.MATTERMOST_WEBHOOK_TOKEN;
function verifySignature(req) {
const signature = req.headers['mattermost-token'];
return signature === WEBHOOK_TOKEN;
}
app.post('/mattermost/webhook', (req, res) => {
if (!verifySignature(req)) {
return res.status(401).send('Invalid token');
}
console.log('Received payload:', JSON.stringify(req.body, null, 2));
// Example: if the button value is 'request_help', respond accordingly
if (req.body.actions && req.body.actions[0].value === 'request_help') {
return res.json({
response_type: 'ephemeral',
text: 'Your help request has been logged. We will assist you shortly.'
});
}
res.json({
response_type: 'ephemeral',
text: 'Unknown action.'
});
});
app.listen(3000, () => console.log('Webhook listening on port 3000'));
Run this service behind HTTPS and expose the public URL to Mattermost. The webhook will now respond to button clicks.
Limitations & Common Pitfalls
| Aspect | Limit |
|---|---|
| Maximum actions per post | 5 |
| Button text length | 30 characters |
| Webhook timeout | 10 seconds (default) |
Typical mistakes:
- Using
application/x-www-form-urlencodedinstead ofapplication/json– Mattermost expects JSON. - Not URL‑encoding the payload – button values containing spaces or special characters can break the request.
- Ignoring the
response_typefield – without it, the reply may appear publicly. - Performing heavy processing in the handler – exceeding the timeout will return a generic error to the user.
Verification Checklist
- Deploy the webhook service and confirm it accepts HTTPS
POSTrequests. - Post the trigger word (
!help) in the configured channel. - Verify the button appears and click it.
- Check the service logs for the received payload.
- Ensure the user sees the expected
ephemeralconfirmation. - Test a non‑existent button value to see the fallback response.
When to Use This Pattern
Use interactive buttons when you want a quick, in‑channel trigger that initiates server‑side logic. Examples include:
- Ticket escalation or assignment.
- Pull request review requests.
- Automated reminders or polls.
For more complex interactions (e.g., multi‑step forms), consider using Mattermost’s Modal Dialogs or Slash Commands instead.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.