Mattermost
ステータス: バンドルされたプラグイン(ボットトークン + WebSocket イベント)。チャネル、グループ、DM をサポートしています。 Mattermost はセルフホスト可能なチーム向けメッセージングプラットフォームです。製品の詳細とダウンロードについては、公式サイト mattermost.com を参照してください。バンドルされたプラグイン
Mattermost は現在の OpenClaw リリースではバンドルされたプラグインとして同梱されているため、通常の パッケージ版ビルドでは別途インストールは不要です。 古いビルドまたは Mattermost を含まないカスタムインストールを使用している場合は、 手動でインストールしてください。 CLI でインストール(npm レジストリ):クイックセットアップ
- Mattermost プラグインが利用可能であることを確認します。
- 現在のパッケージ版 OpenClaw リリースにはすでに同梱されています。
- 古い/カスタムインストールでは、上記のコマンドで手動追加できます。
- Mattermost のボットアカウントを作成し、bot token をコピーします。
- Mattermost の base URL をコピーします(例:
https://chat.example.com)。 - OpenClaw を設定して Gateway を起動します。
ネイティブスラッシュコマンド
ネイティブスラッシュコマンドはオプトインです。有効にすると、OpenClaw は Mattermost API 経由でoc_* スラッシュコマンドを登録し、Gateway HTTP サーバー上で
コールバック POST を受信します。
native: "auto"は Mattermost ではデフォルトで無効です。有効にするにはnative: trueを設定してください。callbackUrlを省略した場合、OpenClaw は Gateway の host/port とcallbackPathから導出します。- マルチアカウント構成では、
commandsは最上位またはchannels.mattermost.accounts.<id>.commandsの下に設定できます(アカウント値が最上位フィールドを上書きします)。 - コマンドコールバックは、OpenClaw が
oc_*コマンドを登録した際に Mattermost から返される コマンドごとのトークンで検証されます。 - スラッシュコールバックは、登録に失敗した場合、起動が部分的にしか完了しなかった場合、 またはコールバックトークンが登録済みコマンドのいずれにも一致しない場合にフェイルクローズします。
- 到達可能性の要件: コールバックエンドポイントは Mattermost サーバーから到達可能である必要があります。
- Mattermost が OpenClaw と同じホスト/ネットワーク名前空間で動作していない限り、
callbackUrlにlocalhostを設定しないでください。 - その URL が
/api/channels/mattermost/commandを OpenClaw にリバースプロキシしていない限り、callbackUrlに Mattermost の base URL を設定しないでください。 - 簡単な確認方法は
curl https://<gateway-host>/api/channels/mattermost/commandです。GET は404ではなく OpenClaw から405 Method Not Allowedを返す必要があります。
- Mattermost が OpenClaw と同じホスト/ネットワーク名前空間で動作していない限り、
- Mattermost の送信先許可リスト要件:
- コールバックがプライベート/Tailnet/内部アドレスを対象にする場合は、Mattermost の
ServiceSettings.AllowedUntrustedInternalConnectionsにコールバックホスト/ドメインを含めてください。 - 完全な URL ではなく、ホスト/ドメインのエントリを使用してください。
- 良い例:
gateway.tailnet-name.ts.net - 悪い例:
https://gateway.tailnet-name.ts.net
- 良い例:
- コールバックがプライベート/Tailnet/内部アドレスを対象にする場合は、Mattermost の
環境変数(デフォルトアカウント)
環境変数を使いたい場合は、Gateway ホストで次を設定します。MATTERMOST_BOT_TOKEN=...MATTERMOST_URL=https://chat.example.com
default)にのみ適用されます。他のアカウントでは設定値を使用する必要があります。
チャットモード
Mattermost は DM には自動で応答します。チャネルでの挙動はchatmode で制御されます。
oncall(デフォルト): チャネルでは @メンションされたときだけ応答します。onmessage: すべてのチャネルメッセージに応答します。onchar: メッセージがトリガープレフィックスで始まると応答します。
oncharは明示的な @メンションにも引き続き応答します。channels.mattermost.requireMentionは従来の設定との互換性のために尊重されますが、chatmodeの使用が推奨されます。
スレッド化とセッション
channels.mattermost.replyToMode を使用すると、チャネルおよびグループへの返信を
メインチャネルに保持するか、トリガーとなった投稿の下でスレッドを開始するかを制御できます。
off(デフォルト): 受信した投稿がすでにスレッド内にある場合にのみスレッドで返信します。first: 最上位のチャネル/グループ投稿に対して、その投稿の下にスレッドを開始し、 会話をスレッドスコープのセッションにルーティングします。all: 現在の Mattermost ではfirstと同じ動作です。- ダイレクトメッセージはこの設定を無視し、スレッド化されません。
- スレッドスコープのセッションは、トリガーとなった投稿 ID をスレッドルートとして使用します。
firstとallは現在同等です。Mattermost にスレッドルートが一度できると、 後続のチャンクとメディアは同じスレッド内で継続されるためです。
アクセス制御(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 推奨)。- チャネルごとのメンション上書きは
channels.mattermost.groups.<channelId>.requireMentionまたはデフォルト用のchannels.mattermost.groups["*"].requireMentionにあります。 @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 経由で解決されます)
64ifufp... のようなもの)は、Mattermost では 曖昧 です(ユーザー ID かチャネル ID か)。
OpenClaw はこれを ユーザー優先 で解決します。
- その ID がユーザーとして存在する場合(
GET /api/v4/users/<id>が成功)、OpenClaw は/api/v4/channels/directでダイレクトチャネルを解決して DM を送信します。 - それ以外の場合、その ID は チャネル ID として扱われます。
user:<id> / channel:<id>)を使用してください。
DM チャネル再試行
OpenClaw が Mattermost の DM ターゲットに送信し、最初にダイレクトチャネルを解決する必要がある場合、 デフォルトで一時的なダイレクトチャネル作成失敗を再試行します。 この挙動を Mattermost プラグイン全体で調整するにはchannels.mattermost.dmChannelRetry を、
1 つのアカウントだけに適用するには channels.mattermost.accounts.<id>.dmChannelRetry を使います。
- これはすべての Mattermost API 呼び出しではなく、DM チャネル作成(
/api/v4/channels/direct)にのみ適用されます。 - 再試行は、レート制限、5xx 応答、ネットワークエラー、タイムアウトエラーなどの一時的失敗に適用されます。
429以外の 4xx クライアントエラーは恒久的な失敗として扱われ、再試行されません。
リアクション(message ツール)
channel=mattermostとともにmessage action=reactを使用します。messageIdは Mattermost の投稿 ID です。emojiはthumbsupや:+1:のような名前を受け付けます(コロンは省略可能です)。- リアクションを削除するには
remove=true(boolean)を設定します。 - リアクションの追加/削除イベントは、ルーティングされたエージェントセッションにシステムイベントとして転送されます。
channels.mattermost.actions.reactions: リアクション操作を有効/無効にします(デフォルトは true)。- アカウントごとの上書き:
channels.mattermost.accounts.<id>.actions.reactions。
インタラクティブボタン(message ツール)
クリック可能なボタン付きメッセージを送信します。ユーザーがボタンをクリックすると、エージェントが 選択内容を受け取り、応答できます。 チャネル機能にinlineButtons を追加してボタンを有効化します。
buttons パラメータ付きで message action=send を使用します。ボタンは 2 次元配列(ボタンの行)です。
text(必須): 表示ラベル。callback_data(必須): クリック時に送り返される値(アクション ID として使用)。style(省略可):"default"、"primary"、または"danger"。
- すべてのボタンが確認行に置き換えられます(例: 「✓ Yes selected by @user」)。
- エージェントが選択内容を受信メッセージとして受け取り、応答します。
- ボタンコールバックは HMAC-SHA256 検証を使用します(自動、設定不要)。
- Mattermost は API 応答から callback data を削除するため(セキュリティ機能)、 クリック時にはすべてのボタンが削除されます。部分削除はできません。
- ハイフンやアンダースコアを含むアクション ID は自動的にサニタイズされます (Mattermost のルーティング制限)。
channels.mattermost.capabilities: 機能文字列の配列。ボタンツールの説明をエージェントのシステムプロンプトで有効にするには"inlineButtons"を追加します。channels.mattermost.interactions.callbackBaseUrl: ボタンコールバック用の省略可能な外部 base URL (例:https://gateway.example.com)。Mattermost が bind host 上の Gateway に直接到達できない場合に使用します。- マルチアカウント構成では、同じフィールドを
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 を投稿する場合は、次のルールに従ってください。
ペイロード構造:
- attachments は最上位の
attachmentsではなくprops.attachmentsに入れます(そうしないと黙って無視されます)。 - すべての action に
type: "button"が必要です。これがないとクリックは黙って飲み込まれます。 - すべての action に
idフィールドが必要です。Mattermost は ID のない action を無視します。 - action の
idは 英数字のみ([a-zA-Z0-9])でなければなりません。ハイフンとアンダースコアは Mattermost のサーバー側 action ルーティングを壊します(404 を返します)。使用前に除去してください。 - 確認メッセージに生の ID ではなくボタン名(例: 「Approve」)を表示するには、
context.action_idをボタンのidと一致させる必要があります。 context.action_idは必須です。これがないと interaction handler は 400 を返します。
- ボットトークンからシークレットを導出します:
HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken) _tokenを除くすべてのフィールドを含む context オブジェクトを構築します。- キーをソートし、スペースなしでシリアライズします(Gateway は
キーをソートした
JSON.stringifyを使用し、コンパクトな出力を生成します)。 - 署名します:
HMAC-SHA256(key=secret, data=serializedContext) - 結果の 16 進ダイジェストを
_tokenとして context に追加します。
- Python の
json.dumpsはデフォルトでスペースを追加します({"key": "val"})。 JavaScript のコンパクトな出力({"key":"val"})に合わせるにはseparators=(",", ":")を使用してください。 - 必ず すべて の context フィールド(
_tokenを除く)に署名してください。Gateway は_tokenを取り除いた後、 残りすべてに署名します。一部だけに署名すると検証は黙って失敗します。 sort_keys=Trueを使ってください。Gateway は署名前にキーをソートし、Mattermost は ペイロード保存時に context フィールドを並べ替える場合があります。- ランダムバイトではなく、ボットトークンからシークレットを導出してください(決定的です)。シークレットは、 ボタンを作成するプロセスと Gateway 側で検証するプロセスで同一でなければなりません。
ディレクトリアダプター
Mattermost プラグインには、Mattermost API 経由でチャネル名とユーザー名を解決する ディレクトリアダプターが含まれています。これにより、openclaw message send や cron/webhook 配信で #channel-name と @username ターゲットを使用できます。
設定は不要です。このアダプターはアカウント設定のボットトークンを使用します。
マルチアカウント
Mattermost はchannels.mattermost.accounts 配下で複数アカウントをサポートします。
トラブルシューティング
- チャネルで返信がない: ボットがチャネルに参加していることを確認し、メンションする(oncall)、トリガープレフィックスを使う(onchar)、または
chatmode: "onmessage"を設定してください。 - 認証エラー: ボットトークン、base URL、アカウントが有効かどうかを確認してください。
- マルチアカウントの問題: 環境変数は
defaultアカウントにのみ適用されます。 - ネイティブスラッシュコマンドが
Unauthorized: invalid command token.を返す: OpenClaw が コールバックトークンを受け入れませんでした。典型的な原因:- スラッシュコマンド登録が失敗した、または起動時に部分的にしか完了しなかった
- コールバックが誤った Gateway/アカウントに到達している
- Mattermost に以前のコールバックターゲットを指す古いコマンドが残っている
- Gateway がスラッシュコマンドを再有効化せずに再起動した
- ネイティブスラッシュコマンドが動かなくなった場合は、ログで
mattermost: failed to register slash commandsまたはmattermost: native slash commands enabled but no commands could be registeredを確認してください。 callbackUrlを省略し、ログにコールバックがhttp://127.0.0.1:18789/...に解決されたという警告が出る場合、その URL は Mattermost が OpenClaw と同じホスト/ネットワーク名前空間で動作している場合にのみ到達可能である可能性が高いです。 外部から到達可能なcommands.callbackUrlを明示的に設定してください。- ボタンが白いボックスとして表示される: エージェントが不正なボタンデータを送っている可能性があります。各ボタンに
textとcallback_dataの両方があることを確認してください。 - ボタンは表示されるがクリックしても何も起きない: Mattermost サーバー設定の
AllowedUntrustedInternalConnectionsに127.0.0.1 localhostが含まれていること、および ServiceSettings のEnablePostActionIntegrationがtrueであることを確認してください。 - クリック時にボタンが 404 を返す: ボタンの
idにハイフンまたはアンダースコアが含まれている可能性があります。Mattermost の action router は英数字以外の ID で壊れます。[a-zA-Z0-9]のみを使用してください。 - Gateway ログに
invalid _tokenが出る: HMAC 不一致です。すべての context フィールドに署名していること(一部ではない)、キーをソートしていること、コンパクトな JSON(スペースなし)を使っていることを確認してください。上記の HMAC セクションを参照してください。 - Gateway ログに
missing _token in contextが出る:_tokenフィールドがボタンの context にありません。integration ペイロード構築時に含めていることを確認してください。 - 確認表示にボタン名ではなく生の ID が出る:
context.action_idがボタンのidと一致していません。両方に同じサニタイズ済みの値を設定してください。 - エージェントがボタンを認識しない: Mattermost チャネル設定に
capabilities: ["inlineButtons"]を追加してください。
関連
- Channels Overview — サポートされているすべてのチャネル
- Pairing — DM 認証とペアリングフロー
- Groups — グループチャットの挙動とメンションゲート
- Channel Routing — メッセージのセッションルーティング
- Security — アクセスモデルとハードニング