Skip to content

チャネル概要

Ongrid は チャネル を通じて人間と対話します。チャネルは以下のいずれかです:

  • 通知チャネル —— Ongrid がチャット面にアラートを push。人間は読みますが、 チャネル自身は返信をエージェントに運びません。DB 上は notify_channelsinternal/pkg/notify/webhook.go の Sender 群がこれにあたります。
  • IM チャネル —— Ongrid がワークスペースのチャット面に bot として常駐し、 受信メッセージを読み、Web UI が動かすのと同じエージェント推論を実行、 プレースホルダーメッセージへの編集として回答をストリーミングして返します。 DB 上は im_appsinternal/manager/biz/imbridge/provider/* です。

両者は 独立 です。Telegram アラート(sendMessage 送出)を配線しても、 ユーザーが Telegram 上でエージェントとチャットできるようにはなりませんし、逆もまた然り。

別テーブル、別認証情報、同じ UI

両面とも Web UI の Settings → Channels で設定します。通知チャネルは Notify タブ、IM チャネルは IM bridge タブです。

どれが欲しい?

ゴール使うものファイル
発火アラートを Slack チャネルに pushSlack incoming webhook (Notify)internal/pkg/notify/webhook.go NewSlackSender
発火アラートを Feishu/Lark グループに pushFeishu カスタム bot (Notify)NewFeishuSender
発火アラートを DingTalk グループに pushDingTalk カスタム bot (Notify)NewDingTalkSender
発火アラートを WeCom グループに pushWeCom グループ bot (Notify)NewWeComSender
自社サービスへの汎用 JSON POSTWebhook (Notify)NewGenericWebhookSender
Telegram アラート(片方向)Telegram bot sendMessage (Notify)NewTelegramSender
Slack で bot としてエージェントと対話Slack Socket Mode アプリ (IM bridge)imbridge/provider/slack/
Telegram でエージェントと対話Telegram bot getUpdates (IM bridge)imbridge/provider/telegram/
Feishu/Larksuite でエージェントと対話Feishu 長接続 (IM bridge)imbridge/provider/feishu/

ワークスペースは 両方 を運用できます:例:アラート用 Slack incoming webhook プラス会話用の独立した Slack Socket Mode アプリ。両者は状態を共有しません。

通知チャネル

通知チャネルはステートレスな Send(ctx, Message) Sender です。アラートが発火 (または回復、ダンプニングウィンドウ満了)するたびにアラートパイプラインから呼ばれます。 全チャネルタイプが同じ canonical な notify.Message 形を描画 —— プロバイダーごとに異なるのは ペイロード形式署名プロトコル だけです。

Sender が受け取る共通フィールド

go
type Message struct {
    Severity   Severity            // critical | warning | info
    Subject    string              // alert rule name + target
    Body       string              // human-readable detail
    Source     string              // "alert" | "test" | ...
    Labels     map[string]string   // rule, incident_id, device_id, ...
    DedupeKey  string              // pipeline:rule:label-set
    OccurredAt time.Time
}

Slack sender はこれを attachments 形式に描画し、severity 色のサイドレール、 構造化フィールド(Severity、Source、Rule、Incident、Device、Dedupe)、 ts フッターを付けます。Feishu / DingTalk / WeCom sender は [SEV] subject\nbody\nsource:…\ndedupe:… テキストペイロードに平坦化します —— これらの bot API は v1 で平文のみだからです。

署名モデルの概観

プロバイダー認証方法
Slackwebhook URL 自体がシークレット。追加の署名なし。
FeishuHMAC-SHA256(ts\nsecret)、JSON ボディの sign に配置。
DingTalkHMAC-SHA256(ts\nsecret)、URL クエリの sign に配置。
WeComURL クエリの bot key。追加の署名なし。
Telegrampath に bot token(/bot<TOKEN>/sendMessage)。
Webhookボディ上の任意の X-Ongrid-Signature: sha256=<HMAC>

正確な実装は internal/pkg/notify/webhook.go にあります: signFeishusignDingTalkURLsignGenericWebhook

Slack は secret フィールドを静かに落とす

Slack incoming webhook URL 自体が認証情報です。Slack チャネルの Secret 欄を 埋めると、チャネルビルダーは Sender 構築前にそれを落とします。これは意図的 —— Slack のプロトコルには incoming webhook 用の独立した署名面がありません。

IM チャネル

IM チャネルは長期実行 goroutine で、以下を行います:

  1. プロバイダーへアウトバウンド接続(Feishu/Slack は WebSocket、Telegram は long poll)。manager に インバウンドポートは開きません
  2. 受信ユーザーメッセージを受け、allow_from でフィルタし、 テキストを bizbridge.Bridge.HandleInbound に渡す。
  3. HandleInbound がプレースホルダー返信を投稿、完全なエージェントグラフ (Web UI と同じもの)を実行、プレースホルダーメッセージ id に 編集を逆ストリーミング

同じエージェントカーネル、スキル、persona レジストリが Web UI と IM チャネルの両方を駆動。 「IM 専用エージェント」はありません —— coordinator/chat で見るのと同じです。

受信はプロバイダー固有、送信は均一

プロバイダーの違い(Slack envelope_id ack、Telegram update offset、Feishu encrypt_key)は imbridge/provider/*/stream.go にあります。メッセージが bizbridge.HandleInbound 内に入った後、下流のすべてはプロバイダー非依存です。

default_locale

IM と Notify 両方の行が任意の default_locale を持ちます。バリデーターは 空文字(auto)、enzh のみ受け入れ —— en-US / zh-CN は primary subtag に折り畳まれ、EN-us やタイポされたロケールは AppInput.validate で 事前に拒否されます。

振る舞い
""(auto)ディレクティブなし。LLM がユーザーの言語をミラー。レガシーデフォルト。
enシステムプロンプトに Respond in English ディレクティブを追加。
zhシステムプロンプトに 「请用中文回复」 ディレクティブを追加。

これは UI ロケール(ONGRID_DEFAULT_LOCALE 環境変数またはブラウザ言語)と独立です。 IM チャネルを通じて受信したメッセージは常に IM 側が勝ちます。manager 起動の出力に対する auto-trigger フォールバックルールは AI output locale feedback を参照。

allow_from

送信者許可リスト。Telegram と Slack で必須、Feishu/DingTalk で任意。 ParseAllowFrom で 一度だけ解析され、バリデーターと各プロバイダーの poll/stream ループで 共有されるので、解析ルールは単一の定義を持ちます。

構文。 カンマ、スペース、改行、タブ、セミコロン —— 任意の組み合わせがトークンを分けます。 順序は保たれ、重複は捨てられます。telegram:tg: プレフィックスは静かに剥がされます(OpenClaw 互換)。

プロバイダー別フォーマット。

  • Telegram。 数値ユーザー ID のみ。非数値トークンと負の値(グループ chat ID)は検証時に落とされます。 少なくとも 1 つの ID が必須 —— bot は username で公開発見可能なので、空の許可リストは ツール装備のエージェントを誰でも操作できる状態になります。ADR-031 を参照。
  • Slack。 U で始まるユーザー ID(または Enterprise ゲスト用の W)。少なくとも 1 つ必須。 自分の ID はワークスペースプロフィール → Copy member ID で見つかります。
  • Feishu / DingTalk。 任意。これらのプラットフォームは企業テナントメンバーシップでゲートされ、 組織メンバーだけが bot に到達できます。

Telegram または Slack の空許可リストは拒否

解析リストが空のとき、バリデーターは telegram requires allow_from / slack requires allow_from を返します。「デフォルト拒否、後でセットアップで許可」モードはありません。 bot は公開到達可能なので、オペレーターは意識的にドアを開く必要があります。

失敗モードはサイレントドロップ。 非許可リスト送信者からのメッセージは送信者の user_id 付きで WARN ログされ、ドロップされます。返信なし、プレースホルダーなし、エージェント実行なし。 bot は存在を確認すらしません —— OpenClaw の dmPolicy: allowFrom と同形です。

発火アラート配信の見え方

text
alert evaluator         → produces notify.Message

notify.Sender (per channel)   ↓ buildBody(msg) → JSON payload
                              ↓ signTarget(endpoint, secret, body) → headers / URL params
                              ↓ POST endpoint
                              ↓ resp.StatusCode in [200, 299] → success

                          chat surface

詳細は各チャネルページを参照: