15 KiB
@lumbridgecorp/openclaw-mattermost
Enhanced Mattermost Extension for OpenClaw
A powerful, secure, and feature-rich self-hosted Slack-style chat integration
Overview
This enhanced Mattermost extension brings advanced capabilities to OpenClaw, enabling seamless integration with your self-hosted Mattermost server. It supports both bot tokens and Personal Access Tokens (PAT), interactive message components, file operations, and comprehensive security auditing.
Features
Authentication
- Dual Token Support: Use bot tokens, Personal Access Tokens (PAT), or both
- PAT for Enhanced Security: Separate read and write permissions with token selection strategy
- Environment Variable Support: Secure token management without hardcoding
Message Operations
- Send Messages: Post to channels and DMs with rich formatting
- Edit Messages: Update bot messages with full permission controls
- Delete Messages: Remove messages with safety checks
- Reactions: Add emoji reactions to messages
Interactive Components
- Button Directives:
[[mattermost_buttons: Label:value:style, ...]] - Select/Dropdown Directives:
[[mattermost_select: Placeholder | Label:value, ...]] - Style Support: default, primary, danger button styles
File Operations
- Download Files: Secure file downloads with:
- MIME type validation
- Executable file blocking
- Size limits (default 100MB)
- Streaming download for large files
Security
- Security Audit: Automated security configuration scanning
- SSRF Protection: Guarded outbound requests
- HTTPS Enforcement: Warnings for insecure connections
- IP Allowlisting: Restrict interaction callbacks
- Private Network Support: For LAN/VPN deployments
Error Handling
- Structured Errors: Typed error classes with context
- Automatic Retry: Exponential backoff with jitter
- Rate Limit Handling: Respects Mattermost rate limits
- User-Friendly Messages: Clear error descriptions
Installation
Prerequisites
- Node.js 22 or higher
- Mattermost server (self-hosted or cloud)
- OpenClaw 1.0.0 or higher
NPM Installation
npm install @lumbridgecorp/openclaw-mattermost
PNPM Installation
pnpm add @lumbridgecorp/openclaw-mattermost
Yarn Installation
yarn add @lumbridgecorp/openclaw-mattermost
Quick Start
1. Create a Bot Account in Mattermost
- Go to System Console > Integrations > Bot Accounts
- Click Add Bot Account
- Set username (e.g.,
openclaw-bot) - Choose role (usually System Admin for full access, or Member for restricted)
- Save the generated Bot Token
2. Configure Environment Variables
export MATTERMOST_URL="https://chat.yourcompany.com"
export MATTERMOST_BOT_TOKEN="your-bot-token-here"
3. Basic Configuration
{
"channels": {
"mattermost": {
"baseUrl": "https://chat.yourcompany.com",
"botToken": "${MATTERMOST_BOT_TOKEN}",
"dmPolicy": "pairing",
"allowFrom": ["your-mattermost-user-id"]
}
}
}
4. Using PAT (Optional but Recommended)
For enhanced security with separate read/write permissions:
export MATTERMOST_PAT="your-personal-access-token"
{
"channels": {
"mattermost": {
"baseUrl": "https://chat.yourcompany.com",
"botToken": "${MATTERMOST_BOT_TOKEN}",
"pat": "${MATTERMOST_PAT}",
"dmPolicy": "pairing"
}
}
}
Configuration Reference
Core Settings
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
baseUrl |
string | Yes | - | Mattermost server URL (HTTPS recommended) |
botToken |
string | Yes | - | Bot account token |
pat |
string | No | - | Personal Access Token for write operations |
enabled |
boolean | No | true | Enable/disable this account |
name |
string | No | - | Display name for the account |
Access Control
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
dmPolicy |
enum | No | pairing |
DM access: open, allowlist, or pairing |
allowFrom |
array | No | [] | User IDs allowed to DM the bot |
groupPolicy |
enum | No | allowlist |
Group channel access: open or allowlist |
groupAllowFrom |
array | No | [] | User IDs allowed in group channels |
requireMention |
boolean | No | false | Require @mention to trigger bot |
Chat Modes
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
chatmode |
enum | No | onmessage |
Trigger mode: oncall, onmessage, onchar |
oncharPrefixes |
array | No | [] | Prefixes for onchar mode (e.g., ["!", "/") |
Message Settings
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
textChunkLimit |
number | No | - | Max characters per message chunk |
chunkMode |
enum | No | length |
Chunking: length or newline |
blockStreaming |
boolean | No | false | Enable streaming responses |
replyToMode |
enum | No | off |
Reply threading: off, first, all |
responsePrefix |
string | No | - | Text prepended to all responses |
Slash Commands
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
commands.native |
boolean|"auto" | No | auto |
Enable native slash commands |
commands.nativeSkills |
boolean|"auto" | No | auto |
Enable skill-based commands |
commands.callbackPath |
string | No | - | Custom callback endpoint path |
commands.callbackUrl |
string | No | - | Explicit callback URL |
Interactions
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
interactions.callbackBaseUrl |
string | No | - | HTTPS URL for button callbacks |
interactions.allowedSourceIps |
array | No | [] | IP allowlist for callbacks |
Security Settings
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
allowPrivateNetwork |
boolean | No | false | Allow private IP connections |
configWrites |
boolean | No | false | Allow bot to write config |
dangerouslyAllowNameMatching |
boolean | No | false | Match users by name (not ID) |
Retry Configuration
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
dmChannelRetry.maxRetries |
number | No | 3 | Max DM creation retries |
dmChannelRetry.initialDelayMs |
number | No | 1000 | Initial retry delay |
dmChannelRetry.maxDelayMs |
number | No | 10000 | Maximum retry delay |
dmChannelRetry.timeoutMs |
number | No | 30000 | Request timeout |
Action Controls
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
actions.reactions |
boolean | No | true | Enable emoji reactions |
actions.downloadFile |
boolean | No | true | Enable file downloads |
actions.delete |
boolean | No | true | Enable message deletion |
Group-Specific Settings
{
"channels": {
"mattermost": {
"groups": {
"channel-id-1": {
"requireMention": true
},
"*": {
"requireMention": false
}
}
}
}
}
Personal Access Token (PAT) Setup Guide
Why Use PAT?
Personal Access Tokens provide several advantages:
- Separate Permissions: Use bot token for reads, PAT for writes
- User Context: Actions appear as the user, not a bot
- Audit Trail: Better tracking in Mattermost logs
- Granular Control: Revoke without affecting bot
Creating a PAT in Mattermost
- Log in to Mattermost as the user who will own the PAT
- Go to Account Settings > Security > Personal Access Tokens
- Click Create New Token
- Enter a description (e.g., "OpenClaw Integration")
- Click Save
- Copy the token immediately (it won't be shown again)
Required Permissions
The user creating the PAT needs these permissions:
- Create Posts - to send messages
- Edit Own Posts - to edit bot messages
- Delete Own Posts - to delete bot messages
- Upload Files - to upload attachments
- Create Direct Channels - for DM support
Token Selection Strategy
The extension automatically selects the right token:
| Operation Type | Token Used |
|---|---|
| Read (fetch user, channel info) | Bot Token |
| Write (send message) | PAT (if set) or Bot Token |
| Edit | PAT (if set) or Bot Token |
| Delete | PAT (if set) or Bot Token |
| File Download | Bot Token |
Feature Comparison: Enhanced vs Stock Extension
| Feature | Stock Extension | Enhanced Extension |
|---|---|---|
| Bot Token Only | ✅ | ✅ |
| Personal Access Token (PAT) | ❌ | ✅ |
| Message Editing | ❌ | ✅ |
| Message Deletion | ❌ | ✅ |
| File Download | ❌ | ✅ |
| Interactive Buttons | ❌ | ✅ |
| Interactive Selects | ❌ | ✅ |
| Security Audit | ❌ | ✅ |
| Structured Error Handling | Basic | ✅ Advanced |
| Automatic Retry Logic | ❌ | ✅ |
| Rate Limit Handling | Basic | ✅ Full |
| SSRF Protection | ❌ | ✅ |
| Multi-Account Support | ❌ | ✅ |
| Slash Commands | Basic | ✅ Advanced |
Usage Examples
Sending Messages
import { sendMessage } from '@lumbridgecorp/openclaw-mattermost';
await sendMessage({
cfg: openclawConfig,
channelId: 'channel-id-here',
message: 'Hello from OpenClaw!'
});
Interactive Buttons
const message = `
Please select an action:
[[mattermost_buttons: Approve:approve:primary, Reject:reject:danger, Review Later:review]]
`;
await sendMessage({
cfg: openclawConfig,
channelId: 'channel-id',
message
});
Interactive Select/Dropdown
const message = `
Choose a priority:
[[mattermost_select: Select Priority | Low:low, Medium:medium, High:high, Critical:critical]]
`;
await sendMessage({
cfg: openclawConfig,
channelId: 'channel-id',
message
});
Editing Messages
import { editMessage } from '@lumbridgecorp/openclaw-mattermost';
const result = await editMessage({
cfg: openclawConfig,
postId: 'post-id-to-edit',
channelId: 'channel-id',
message: 'Updated message content'
});
if (!result.ok) {
console.error('Edit failed:', result.error);
}
Deleting Messages
import { deleteMessage } from '@lumbridgecorp/openclaw-mattermost';
const result = await deleteMessage({
cfg: openclawConfig,
postId: 'post-id-to-delete',
channelId: 'channel-id'
});
if (result.ok) {
console.log('Message deleted');
}
Downloading Files
import { downloadFile } from '@lumbridgecorp/openclaw-mattermost';
const result = await downloadFile({
cfg: openclawConfig,
fileId: 'file-id-from-mattermost',
destinationPath: '/tmp/downloads/report.pdf',
maxSize: 50 * 1024 * 1024 // 50MB limit
});
if (result.ok) {
console.log('Downloaded to:', result.filePath);
console.log('File metadata:', result.metadata);
}
Running Security Audit
import { collectMattermostSecurityAuditFindings } from '@lumbridgecorp/openclaw-mattermost';
const findings = await collectMattermostSecurityAuditFindings({
cfg: openclawConfig,
accountId: 'default',
account: resolvedAccount
});
for (const finding of findings) {
console.log(`[${finding.severity}] ${finding.title}`);
console.log(` ${finding.detail}`);
if (finding.remediation) {
console.log(` Fix: ${finding.remediation}`);
}
}
Troubleshooting
Connection Issues
Problem: Cannot connect to Mattermost server
Solutions:
- Verify
baseUrluses HTTPS (not HTTP) - Check the server is accessible:
curl https://your-server/api/v4/system/ping - For self-hosted servers, set
allowPrivateNetwork: true - Check firewall rules
Authentication Errors
Problem: 401 Unauthorized errors
Solutions:
- Verify the bot token is correct
- Check the bot account is enabled in Mattermost
- Ensure the bot has required permissions
- For PAT, verify the user account is active
Rate Limiting
Problem: 429 Too Many Requests
Solutions:
- The extension has built-in retry logic
- Increase
dmChannelRetry.maxDelayMsfor longer waits - Contact your Mattermost admin to increase rate limits
- Reduce message frequency
File Download Failures
Problem: Cannot download files
Solutions:
- Check file size against
maxSizelimit (default 100MB) - Verify file type is allowed (not executable)
- Ensure bot has file access permissions
- Check disk space at destination
Interactive Components Not Working
Problem: Buttons/selects don't appear
Solutions:
- Verify
interactions.callbackBaseUrlis set with HTTPS - Check
allowedSourceIpsincludes your Mattermost server - Ensure the directive syntax is correct
- Check browser console for JavaScript errors
Message Edit/Delete Failures
Problem: Cannot edit or delete messages
Solutions:
- Can only edit/delete bot's own messages
- System messages cannot be modified
- Check PAT permissions if using PAT
- Verify the post ID and channel ID are correct
Security Audit Warnings
Problem: Security audit shows warnings
Solutions:
- Move hardcoded tokens to environment variables
- Switch to HTTPS if using HTTP
- Configure
allowFromfor restricted access - Review
dmPolicyandgroupPolicysettings
Development
See CONTRIBUTING.md for development setup and contribution guidelines.
API Reference
See docs/API.md for detailed API documentation.
Migration Guide
If you're migrating from the stock Mattermost extension, see docs/MIGRATION.md.
License
This project is licensed under the Apache License 2.0. See LICENSE for details.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with ❤️ by Karti AI