# @karti-ai/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
```bash
npm install @karti-ai/openclaw-mattermost
```
### PNPM Installation
```bash
pnpm add @karti-ai/openclaw-mattermost
```
### Yarn Installation
```bash
yarn add @karti-ai/openclaw-mattermost
```
## Quick Start
### 1. Create a Bot Account in Mattermost
1. Go to **System Console > Integrations > Bot Accounts**
2. Click **Add Bot Account**
3. Set username (e.g., `openclaw-bot`)
4. Choose role (usually **System Admin** for full access, or **Member** for restricted)
5. Save the generated **Bot Token**
### 2. Configure Environment Variables
```bash
export MATTERMOST_URL="https://chat.yourcompany.com"
export MATTERMOST_BOT_TOKEN="your-bot-token-here"
```
### 3. Basic Configuration
```json
{
"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:
```bash
export MATTERMOST_PAT="your-personal-access-token"
```
```json
{
"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
```json
{
"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
1. **Log in to Mattermost** as the user who will own the PAT
2. Go to **Account Settings > Security > Personal Access Tokens**
3. Click **Create New Token**
4. Enter a description (e.g., "OpenClaw Integration")
5. Click **Save**
6. **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
```typescript
import { sendMessage } from '@karti-ai/openclaw-mattermost';
await sendMessage({
cfg: openclawConfig,
channelId: 'channel-id-here',
message: 'Hello from OpenClaw!'
});
```
### Interactive Buttons
```typescript
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
```typescript
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
```typescript
import { editMessage } from '@karti-ai/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
```typescript
import { deleteMessage } from '@karti-ai/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
```typescript
import { downloadFile } from '@karti-ai/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
```typescript
import { collectMattermostSecurityAuditFindings } from '@karti-ai/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**:
1. Verify `baseUrl` uses HTTPS (not HTTP)
2. Check the server is accessible: `curl https://your-server/api/v4/system/ping`
3. For self-hosted servers, set `allowPrivateNetwork: true`
4. Check firewall rules
### Authentication Errors
**Problem**: 401 Unauthorized errors
**Solutions**:
1. Verify the bot token is correct
2. Check the bot account is enabled in Mattermost
3. Ensure the bot has required permissions
4. For PAT, verify the user account is active
### Rate Limiting
**Problem**: 429 Too Many Requests
**Solutions**:
1. The extension has built-in retry logic
2. Increase `dmChannelRetry.maxDelayMs` for longer waits
3. Contact your Mattermost admin to increase rate limits
4. Reduce message frequency
### File Download Failures
**Problem**: Cannot download files
**Solutions**:
1. Check file size against `maxSize` limit (default 100MB)
2. Verify file type is allowed (not executable)
3. Ensure bot has file access permissions
4. Check disk space at destination
### Interactive Components Not Working
**Problem**: Buttons/selects don't appear
**Solutions**:
1. Verify `interactions.callbackBaseUrl` is set with HTTPS
2. Check `allowedSourceIps` includes your Mattermost server
3. Ensure the directive syntax is correct
4. Check browser console for JavaScript errors
### Message Edit/Delete Failures
**Problem**: Cannot edit or delete messages
**Solutions**:
1. Can only edit/delete bot's own messages
2. System messages cannot be modified
3. Check PAT permissions if using PAT
4. Verify the post ID and channel ID are correct
### Security Audit Warnings
**Problem**: Security audit shows warnings
**Solutions**:
1. Move hardcoded tokens to environment variables
2. Switch to HTTPS if using HTTP
3. Configure `allowFrom` for restricted access
4. Review `dmPolicy` and `groupPolicy` settings
## Development
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution guidelines.
## API Reference
See [docs/API.md](docs/API.md) for detailed API documentation.
## Migration Guide
If you're migrating from the stock Mattermost extension, see [docs/MIGRATION.md](docs/MIGRATION.md).
## License
This project is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.
## Support
- **Issues**: [GitHub Issues](https://github.com/karti-ai/openclaw-extentions-mattermost/issues)
- **Discussions**: [GitHub Discussions](https://github.com/karti-ai/openclaw-extentions-mattermost/discussions)
---
Built with ❤️ by Karti AI