Mattermost
ステータス: プラグイン経由でサポート (ボットトークン + WebSocket イベント)。チャンネル、グループ、DM がサポートされています。Mattermost はセルフホスト可能なチームメッセージングプラットフォームです。製品の詳細とダウンロードについては公式サイト mattermost.com を参照してください。
プラグイン必須
Mattermost はプラグインとして提供され、コアインストールには同梱されていません。CLI (npm レジストリ) 経由でインストールします:
openclaw plugins install @openclaw/mattermost
ローカルチェックアウト (git リポジトリから実行する場合):
openclaw plugins install ./extensions/mattermost
configure/オンボーディング中に Mattermost を選択し、git チェックアウトが検出された場合、OpenClaw は自動的にローカルインストールパスを提供します。詳細: プラグイン
クイックセットアップ
- Mattermost プラグインをインストールします。
- Mattermost ボットアカウントを作成し、ボットトークンをコピーします。
- Mattermost のベース URL (例:
https://chat.example.com) をコピーします。 - OpenClaw を設定し、ゲートウェイを起動します。
最小限の設定:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
ネイティブスラッシュコマンド
ネイティブスラッシュコマンドはオプトインです。有効にすると、OpenClaw は Mattermost API 経由で oc_* スラッシュコマンドを登録し、ゲートウェイ HTTP サーバー上でコールバック POST を受け取ります。
{
channels: {
mattermost: {
commands: {
native: true,
nativeSkills: true,
callbackPath: "/api/channels/mattermost/command",
// Mattermost がゲートウェイに直接到達できない場合 (リバースプロキシ/公開URL) に使用します。
callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
},
},
},
}
注意点:
native: "auto"は Mattermost ではデフォルトで無効です。有効にするにはnative: trueを設定します。callbackUrlが省略された場合、OpenClaw はゲートウェイのホスト/ポート +callbackPathから URL を導出します。- マルチアカウント設定では、
commandsはトップレベルまたはchannels.mattermost.accounts.<id>.commandsの下に設定できます (アカウントの値がトップレベルのフィールドを上書きします)。 - コマンドコールバックはコマンドごとのトークンで検証され、トークンチェックが失敗した場合は閉じた状態で失敗します。
- 到達可能性要件: コールバックエンドポイントは Mattermost サーバーから到達可能でなければなりません。
- Mattermost が OpenClaw と同じホスト/ネットワーク名前空間で実行されていない限り、
callbackUrlをlocalhostに設定しないでください。 - その URL が
/api/channels/mattermost/commandを OpenClaw にリバースプロキシしない限り、callbackUrlを Mattermost のベース URL に設定しないでください。 - 簡単なチェック:
curl https://<gateway-host>/api/channels/mattermost/command; GET リクエストは OpenClaw から405 Method Not Allowedを返すべきで、404ではありません。
- Mattermost が OpenClaw と同じホスト/ネットワーク名前空間で実行されていない限り、
- Mattermost エグレス許可リスト要件:
- コールバックターゲットがプライベート/Tailnet/内部アドレスの場合、Mattermost の
ServiceSettings.AllowedUntrustedInternalConnectionsにコールバックホスト/ドメインを含めるように設定します。 - 完全な URL ではなく、ホスト/ドメインエントリを使用します。
- 良い例:
gateway.tailnet-name.ts.net - 悪い例:
https://gateway.tailnet-name.ts.net
- 良い例:
- コールバックターゲットがプライベート/Tailnet/内部アドレスの場合、Mattermost の
環境変数 (デフォルトアカウント)
環境変数を好む場合は、ゲートウェイホスト上でこれらを設定します:
MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
環境変数はデフォルトアカウント (default) にのみ適用されます。他のアカウントは設定値を使用する必要があります。
チャットモード
Mattermost は DM に自動的に応答します。チャンネルの動作は chatmode で制御されます:
oncall(デフォルト): チャンネルで @メンションされた場合のみ応答します。onmessage: すべてのチャンネルメッセージに応答します。onchar: メッセージがトリガープレフィックスで始まる場合に応答します。
設定例:
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
注意点:
oncharでも明示的な @メンションには応答します。- レガシー設定では
channels.mattermost.requireMentionが尊重されますが、chatmodeが推奨されます。
アクセス制御 (DM)
- デフォルト:
channels.mattermost.dmPolicy = "pairing"(不明な送信者にはペアリングコードが送られます)。 - 承認方法:
openclaw pairing list mattermostopenclaw pairing approve mattermost <CODE>
- 公開 DM:
channels.mattermost.dmPolicy="open"に加えてchannels.mattermost.allowFrom=["*"]。
チャンネル (グループ)
- デフォルト:
channels.mattermost.groupPolicy = "allowlist"(メンションゲート)。 channels.mattermost.groupAllowFromで送信者を許可リストに追加します (ユーザー ID を推奨)。@usernameマッチングは可変であり、channels.mattermost.dangerouslyAllowNameMatching: trueの場合にのみ有効になります。- オープンチャンネル:
channels.mattermost.groupPolicy="open"(メンションゲート)。 - 実行時注意:
channels.mattermostが完全に欠落している場合、ランタイムはグループチェックのためにgroupPolicy="allowlist"にフォールバックします (channels.defaults.groupPolicyが設定されていても)。
アウトバウンド配信のターゲット
openclaw message send または cron/webhook で使用するターゲット形式:
- チャンネルの場合:
channel:<id> - DM の場合:
user:<id> - DM の場合:
@username(Mattermost API 経由で解決)
ベア ID はチャンネルとして扱われます。
リアクション (メッセージツール)
channel=mattermostでmessage action=reactを使用します。messageIdは Mattermost の投稿 ID です。emojiはthumbsupや:+1:のような名前を受け付けます (コロンはオプション)。- リアクションを削除するには
remove=true(ブール値) を設定します。 - リアクションの追加/削除イベントは、ルーティングされたエージェントセッションにシステムイベントとして転送されます。
例:
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true
設定:
channels.mattermost.actions.reactions: リアクションアクションの有効/無効 (デフォルト true)。- アカウントごとの上書き:
channels.mattermost.accounts.<id>.actions.reactions。
インタラクティブボタン (メッセージツール)
クリック可能なボタン付きのメッセージを送信します。ユーザーがボタンをクリックすると、エージェントが選択を受け取り、応答できます。ボタンを有効にするには、チャンネル機能に inlineButtons を追加します:
{
channels: {
mattermost: {
capabilities: ["inlineButtons"],
},
},
}
buttons パラメータを指定して message action=send を使用します。ボタンは 2 次元配列 (ボタンの行) です:
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
ボタンフィールド:
text(必須): 表示ラベル。callback_data(必須): クリック時に送り返される値 (アクション ID として使用)。style(オプション):"default"、"primary"、"danger"。
ユーザーがボタンをクリックすると:
- すべてのボタンが確認行に置き換えられます (例: ”✓ Yes selected by @user”)。
- エージェントは選択をインバウンドメッセージとして受け取り、応答します。
注意点:
- ボタンコールバックは HMAC-SHA256 検証を使用します (自動、設定不要)。
- Mattermost はセキュリティ機能として API レスポンスからコールバックデータを削除するため、クリック時にすべてのボタンが削除されます — 部分的な削除は不可能です。
- ハイフンやアンダースコアを含むアクション ID は自動的にサニタイズされます (Mattermost ルーティング制限)。
設定:
channels.mattermost.capabilities: 機能文字列の配列。エージェントシステムプロンプトにボタンツールの説明を表示するには"inlineButtons"を追加します。channels.mattermost.interactions.callbackBaseUrl: ボタンコールバック用のオプションの外部ベース URL (例:https://gateway.example.com)。Mattermost がゲートウェイのバインドホストに直接到達できない場合に使用します。- マルチアカウント設定では、同じフィールドを
channels.mattermost.accounts.<id>.interactions.callbackBaseUrlの下に設定することもできます。 interactions.callbackBaseUrlが省略された場合、OpenClaw はgateway.customBindHost+gateway.portからコールバック URL を導出し、次にhttp://localhost:<port>にフォールバックします。- 到達可能性ルール: ボタンコールバック URL は Mattermost サーバーから到達可能でなければなりません。
localhostは Mattermost と OpenClaw が同じホスト/ネットワーク名前空間で実行されている場合にのみ機能します。 - コールバックターゲットがプライベート/Tailnet/内部の場合は、そのホスト/ドメインを Mattermost の
ServiceSettings.AllowedUntrustedInternalConnectionsに追加してください。
直接 API 連携 (外部スクリプト)
外部スクリプトや Webhook は、エージェントの message ツールを経由する代わりに、Mattermost REST API を介して直接ボタンを投稿できます。可能な限り拡張機能の buildButtonAttachments() を使用してください。生の JSON を投稿する場合は、以下のルールに従ってください: ペイロード構造:
{
channel_id: "<channelId>",
message: "Choose an option:",
props: {
attachments: [
{
actions: [
{
id: "mybutton01", // 英数字のみ — 下記参照
type: "button", // 必須、ないとクリックが黙って無視されます
name: "Approve", // 表示ラベル
style: "primary", // オプション: "default", "primary", "danger"
integration: {
url: "https://gateway.example.com/mattermost/interactions/default",
context: {
action_id: "mybutton01", // ボタン id と一致する必要あり (名前参照用)
action: "approve",
// ... 任意のカスタムフィールド ...
_token: "<hmac>", // HMAC セクションを参照
},
},
},
],
},
],
},
}
重要なルール:
- 添付ファイルはトップレベルの
attachmentsではなくprops.attachmentsに入れます (黙って無視されます)。 - すべてのアクションに
type: "button"が必要です — これがないと、クリックは黙って飲み込まれます。 - すべてのアクションに
idフィールドが必要です — Mattermost は ID のないアクションを無視します。 - アクション
idは英数字のみ ([a-zA-Z0-9]) でなければなりません。ハイフンやアンダースコアは Mattermost のサーバーサイドアクションルーティングを壊します (404 を返します)。使用前に削除してください。 context.action_idはボタンのidと一致する必要があり、確認メッセージが生の ID ではなくボタン名 (例: "Approve") を表示できるようにします。context.action_idは必須です — これがないとインタラクションハンドラは 400 を返します。
HMAC トークン生成: ゲートウェイは HMAC-SHA256 でボタンクリックを検証します。外部スクリプトはゲートウェイの検証ロジックと一致するトークンを生成する必要があります:
- ボットトークンから秘密鍵を導出:
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken) _tokenを除くすべてのフィールドを含むコンテキストオブジェクトを構築します。- ソートされたキーとスペースなしでシリアライズします (ゲートウェイはソートされたキーで
JSON.stringifyを使用し、コンパクトな出力を生成します)。 - 署名:
HMAC-SHA256(key=secret, data=serializedContext) - 結果の 16 進ダイジェストをコンテキスト内の
_tokenとして追加します。
Python の例:
import hmac, hashlib, json
secret = hmac.new(
b"openclaw-mattermost-interactions",
bot_token.encode(), hashlib.sha256
).hexdigest()
ctx = {"action_id": "mybutton01", "action": "approve"}
payload = json.dumps(ctx, sort_keys=True, separators=(",", ":"))
token = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
context = {**ctx, "_token": token}
一般的な HMAC の落とし穴:
- Python の
json.dumpsはデフォルトでスペースを追加します ({"key": "val"})。JavaScript のコンパクトな出力 ({"key":"val"}) に一致させるにはseparators=(",", ":")を使用します。 - 常にすべてのコンテキストフィールド (
_tokenを除く) に署名します。ゲートウェイは_tokenを削除してから残りのすべてに署名します。サブセットに署名すると、黙って検証が失敗します。 sort_keys=Trueを使用します — ゲートウェイは署名前にキーをソートし、Mattermost はペイロードを保存する際にコンテキストフィールドを並べ替える可能性があります。- 秘密鍵はランダムバイトではなく、ボットトークンから導出します (決定的)。秘密鍵はボタンを作成するプロセスと検証するゲートウェイ間で同じでなければなりません。
ディレクトリアダプター
Mattermost プラグインには、Mattermost API 経由でチャンネル名とユーザー名を解決するディレクトリアダプターが含まれています。これにより、openclaw message send および cron/webhook 配信で #channel-name および @username ターゲットが可能になります。設定は不要です — アダプターはアカウント設定のボットトークンを使用します。
マルチアカウント
Mattermost は channels.mattermost.accounts の下で複数のアカウントをサポートします:
{
channels: {
mattermost: {
accounts: {
default: { name: "プライマリ", botToken: "mm-token", baseUrl: "https://chat.example.com" },
alerts: { name: "アラート", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" },
},
},
},
}
トラブルシューティング
- チャンネルで応答がない: ボットがチャンネルに参加していること、@メンションしていること (oncall)、トリガープレフィックスを使用していること (onchar)、または
chatmode: "onmessage"を設定していることを確認してください。 - 認証エラー: ボットトークン、ベース URL、アカウントが有効かどうかを確認してください。
- マルチアカウントの問題: 環境変数は
defaultアカウントにのみ適用されます。 - ボタンが白いボックスとして表示される: エージェントが不正なボタンデータを送信している可能性があります。各ボタンに
textとcallback_dataの両方のフィールドがあることを確認してください。 - ボタンはレンダリングされるがクリックしても何も起こらない: Mattermost サーバー設定の
AllowedUntrustedInternalConnectionsに127.0.0.1 localhostが含まれていること、および ServiceSettings でEnablePostActionIntegrationがtrueに設定されていることを確認してください。 - クリック時にボタンが 404 を返す: ボタンの
idにハイフンやアンダースコアが含まれている可能性があります。Mattermost のアクションルーターは非英数字 ID で壊れます。[a-zA-Z0-9]のみを使用してください。 - ゲートウェイログに
invalid _token: HMAC 不一致。すべてのコンテキストフィールド (サブセットではない) に署名していること、ソートされたキーを使用していること、コンパクトな JSON (スペースなし) を使用していることを確認してください。上記の HMAC セクションを参照してください。 - ゲートウェイログに
missing _token in context: ボタンのコンテキストに_tokenフィールドがありません。統合ペイロードを構築する際に含まれていることを確認してください。 - 確認メッセージにボタン名ではなく生の ID が表示される:
context.action_idがボタンのidと一致しません。両方を同じサニタイズされた値に設定してください。 - エージェントがボタンについて知らない: Mattermost チャンネル設定に
capabilities: ["inlineButtons"]を追加してください。