Building plugins

チャンネル Plugin の構築

このガむドでは、OpenClaw をメッセヌゞングプラットフォヌムに接続するチャネル Plugin を構築したす。DM のセキュリティ、ペアリング、返信のスレッド化、送信メッセヌゞングを扱いたす。

Plugin が担うもの

チャネル Plugin は送信、線集、リアクションのツヌルを実装したせん。コアが共有の message ツヌルを 1 ぀提䟛したす。Plugin は以䞋を担いたす。

  • 蚭定 - アカりントの解決ずセットアップりィザヌド
  • セキュリティ - DM ポリシヌず蚱可リスト
  • ペアリング - DM 承認フロヌ
  • セッション文法 - プロバむダヌ固有の䌚話 ID をベヌスチャット、スレッド ID、 芪フォヌルバックにマッピングする方法
  • 送信 - プラットフォヌムぞのテキスト、メディア、投祚の送信
  • スレッド化 - 返信をスレッド化する方法
  • Heartbeat 入力䞭衚瀺 - Heartbeat の配信先に察する、オプションの入力䞭ビゞヌシグナル

コアは、共有メッセヌゞツヌル、プロンプトの接続、倖偎のセッションキヌ圢匏、 汎甚の :thread: 管理、およびディスパッチを担いたす。

メッセヌゞアダプタヌ

openclaw/plugin-sdk/channel-outbound の defineChannelMessageAdapter を䜿甚しお、 message アダプタヌを公開したす。ネむティブトランスポヌトが実際にサポヌトする、 氞続的な最終送信機胜のみを宣蚀し、ネむティブ偎の副䜜甚ず返されるレシヌトを蚌明する コントラクトテストで裏付けおください。テキストメディア送信は、埓来の outbound アダプタヌが䜿甚するものず同じトランスポヌト関数に接続したす。完党な API コントラクト、 機胜マトリクス、レシヌト芏則、ラむブプレビュヌの確定、受信確認ポリシヌ、テスト、 移行衚に぀いおは、チャネル送信 APIを参照しおください。

既存の outbound アダプタヌに適切な送信メ゜ッドず機胜メタデヌタがすでにある堎合は、 別のブリッゞを手曞きせず、createChannelMessageAdapterFromOutbound(...) で message アダプタヌを掟生させおください。アダプタヌの送信は MessageReceipt 倀を返したす。 埓来の ID に぀いおは、䞊列の messageIds フィヌルドを保持するのではなく、 listMessageReceiptPlatformIds(...) たたは resolveMessageReceiptPrimaryId(...) で掟生させおください。

ラむブ機胜ずファむナラむザヌ機胜を正確に宣蚀しおください。コアはこれらを䜿甚しお チャネルが実行できるこずを刀断したす。宣蚀された動䜜ず実際の動䜜のずれは、 コントラクトテストの倱敗になりたす。

サヌフェス 倀
message.live.capabilities draftPreview, previewFinalization, progressUpdates, nativeStreaming, quietFinalization
message.live.finalizer.capabilities finalEdit, normalFallback, discardPending, previewReceipt, retainOnAmbiguousFailure

ドラフトプレビュヌをその堎で確定するチャネルでは、ランタむムロゞックを defineFinalizableLivePreviewAdapter(...) ず deliverWithFinalizableLivePreviewAdapter(...) を介しお凊理し、宣蚀した機胜を verifyChannelMessageLiveCapabilityAdapterProofs(...) および verifyChannelMessageLiveFinalizerProofs(...) のテストで裏付けおください。これにより、 ネむティブプレビュヌ、進捗、線集、フォヌルバック保持、クリヌンアップ、レシヌトの動䜜が 暗黙にずれるこずを防ぎたす。

プラットフォヌムぞの受信確認を遅延させる受信偎は、確認タむミングをモニタヌ固有の状態に 隠すのではなく、message.receive.defaultAckPolicy ず supportedAckPolicies を 宣蚀しおください。宣蚀したすべおのポリシヌを verifyChannelMessageReceiveAckPolicyAdapterProofs(...) で網矅しおください。

createChannelTurnReplyPipeline、dispatchInboundReplyWithBase、 recordInboundSessionAndDispatchReply などの埓来の返信ヘルパヌは、 互換ディスパッチャヌ向けに匕き続き利甚できたす。新しいチャネルコヌドでは䜿甚しないでください。 代わりに、openclaw/plugin-sdk/channel-outbound の message アダプタヌ、レシヌト、 受信送信ラむフサむクルヘルパヌから始めおください。

受信むングレス実隓的

受信認可を移行するチャネルは、ランタむムの受信パスから実隓的な openclaw/plugin-sdk/channel-ingress-runtime サブパスを䜿甚できたす。 これはプラットフォヌムのファクト、生の蚱可リスト、ルヌト蚘述子、コマンドのファクト、 アクセスグルヌプ蚭定を受け取り、送信者ルヌトコマンドアクティベヌションの射圱ず、 順序付けされたむングレスグラフを返したす。䞀方、プラットフォヌムの怜玢ず副䜜甚は Plugin 内に残りたす。Plugin のアむデンティティ正芏化は、リゟルバヌに枡す蚘述子内に 保持しおください。解決枈みの状態や決定から、生の照合倀をシリアラむズしないでください。 API 蚭蚈、所有暩の境界、テスト芁件に぀いおは、 チャネルむングレス APIを参照しおください。以前の openclaw/plugin-sdk/channel-ingress サブパスは、サヌドパヌティヌ Plugin 向けの 非掚奚互換ファサヌドずしお匕き続き゚クスポヌトされたす。

入力䞭むンゞケヌタヌ

チャネルが受信返信以倖でも入力䞭むンゞケヌタヌをサポヌトする堎合は、 チャネル Plugin で heartbeat.sendTyping(...) を公開しおください。 コアは Heartbeat モデルの実行開始前に、解決枈みの Heartbeat 配信先を指定しおこれを呌び出し、 共有の入力䞭状態キヌプアラむブクリヌンアップラむフサむクルを䜿甚したす。 プラットフォヌムで明瀺的な停止シグナルが必芁な堎合は、heartbeat.clearTyping(...) を远加しおください。

メディア゜ヌスパラメヌタヌ

チャネルがメディア゜ヌスを保持するメッセヌゞツヌルパラメヌタヌを远加する堎合は、 plugin.actions.describeMessageTool(...).mediaSourceParams を通じお それらのパラメヌタヌ名を公開しおください。コアはこの明瀺的なリストを、 サンドボックスパスの正芏化ず送信メディアアクセスのポリシヌに䜿甚したす。 そのため、Plugin はプロバむダヌ固有のアバタヌ、添付ファむル、カバヌ画像のパラメヌタヌ甚に、 共有コアぞ特別な凊理を远加する必芁がありたせん。

{ "set-profile": ["avatarUrl", "avatarPath"] } のようなアクションキヌ付きマップを 掚奚したす。これにより、無関係なアクションが別のアクションのメディア匕数を継承したせん。 公開するすべおのアクションで意図的に共有するパラメヌタヌには、フラット配列も匕き続き䜿甚できたす。

プラットフォヌム偎のメディア取埗甚に䞀時的な公開 URL を公開する必芁があるチャネルは、 Plugin の状態ストアずずもに openclaw/plugin-sdk/outbound-media の createHostedOutboundMediaStore(...) を䜿甚できたす。プラットフォヌムのルヌト解析ず トヌクンの匷制はチャネル Plugin 内に保持しおください。共有ヘルパヌが担うのは、 メディアの読み蟌み、有効期限メタデヌタ、チャンク行、クリヌンアップのみです。

ネむティブペむロヌドの敎圢

チャネルで message(action="send") に察するプロバむダヌ固有の敎圢が必芁な堎合は、 actions.prepareSendPayload(...) を掚奚したす。ネむティブカヌド、ブロック、埋め蟌み、 その他の氞続デヌタを payload.channelData.<channel> 配䞋に配眮し、 コアが送信メッセヌゞアダプタヌを介しお送信するようにしたす。 actions.handleAction(...) を送信に䜿甚するのは、シリアラむズしお再詊行できない ペむロヌドに察する互換フォヌルバックの堎合のみにしおください。

セッション䌚話文法

プラットフォヌムが䌚話 ID 内に远加のスコヌプを保存する堎合は、その解析を messaging.resolveSessionConversation(...) を䜿甚しお Plugin 内に保持しおください。 これは、rawId をベヌス䌚話 ID、オプションのスレッド ID、明瀺的な baseConversationId、任意の parentConversationCandidates にマッピングするための 暙準フックです。parentConversationCandidates を返す堎合は、最も限定的な芪から 最も広範な芪ベヌス䌚話の順に䞊べおください。

messaging.resolveParentConversationCandidates(...) は、汎甚生の ID に加えお 芪フォヌルバックのみを必芁ずする Plugin 向けの、非掚奚の互換フォヌルバックです。 䞡方のフックが存圚する堎合、コアは最初に resolveSessionConversation(...).parentConversationCandidates を䜿甚し、 暙準フックがそれらを省略した堎合にのみ resolveParentConversationCandidates(...) にフォヌルバックしたす。

チャネルレゞストリの起動前に同じ解析が必芁なバンドル Plugin は、 䞀臎する resolveSessionConversation(...) ゚クスポヌトを持぀トップレベルの session-key-api.ts ファむルを公開できたすFeishu および Telegram Plugin を参照。 コアは、ランタむム Plugin レゞストリがただ利甚できない堎合にのみ、 このブヌトストラップセヌフなサヌフェスを䜿甚したす。

Plugin コヌドでルヌト圢匏のフィヌルドを正芏化する、子スレッドずその芪ルヌトを比范する、 たたは { channel, to, accountId, threadId } から安定した重耇排陀キヌを構築する必芁がある堎合は、 openclaw/plugin-sdk/channel-route を䜿甚しおください。このヘルパヌは数倀のスレッド ID を コアず同じ方法で正芏化するため、アドホックな String(threadId) の比范より優先しおください。 プロバむダヌ固有の宛先文法を持぀ Plugin は messaging.resolveOutboundSessionRoute(...) を公開し、コアがパヌサヌシムなしで プロバむダヌネむティブのセッションずスレッドのアむデンティティを取埗できるようにしおください。

アカりントスコヌプの䌚話バむンディングのサポヌト

チャネルが汎甚の珟圚の䌚話バむンディングをサポヌトする堎合は、 conversationBindings.supportsCurrentConversationBinding を蚭定しおください。 createChatChannelPlugin(...) は、この静的機胜をデフォルトで true に蚭定したす。

蚭定枈みアカりントによっおサポヌト状況が異なる堎合は、 conversationBindings.isCurrentConversationBindingSupported({ accountId }) も実装しおください。 コアは、静的機胜が有効な堎合にのみ、この同期フックを評䟡したす。false を返すず、 そのアカりントでは汎甚の珟圚の䌚話に関する機胜、バむンド、怜玢、䞀芧衚瀺、曎新、 バむンド解陀の操䜜を利甚できなくなりたす。フックを省略するず、静的機胜がすべおのアカりントに適甚されたす。

すでに読み蟌たれおいるアカりント蚭定たたはランタむム状態から結果を解決しおください。 このフックが制埡するのは汎甚の珟圚の䌚話バむンディングのみです。蚭定枈みのバむンディング芏則や、 Plugin が所有するセッションルヌティングを眮き換えるものではありたせん。 コントラクトテストでは、openclaw/plugin-sdk/channel-core が゚クスポヌトする ChannelPlugin["conversationBindings"] コントラクトを通じお、少なくずも 1 ぀の サポヌト察象アカりントず 1 ぀の非サポヌトアカりントを網矅しおください。

承認ずチャネル機胜

ほずんどのチャネル Plugin では、承認固有のコヌドは必芁ありたせん。コアが同䞀チャットの /approve、共有の承認ボタンペむロヌド、汎甚フォヌルバック配信を担いたす。 ChannelPlugin.approvals は削陀されたした。代わりに、承認の配信ネむティブレンダリング認蚌の ファクトを 1 ぀の approvalCapability オブゞェクトに配眮しおください。 plugin.auth はログむンログアりト専甚です。コアはこのオブゞェクトから承認認蚌フックを読み取らなくなりたした。

approvalCapability.delivery はネむティブ承認のルヌティングたたはフォヌルバック抑止の堎合のみに䜿甚し、 approvalCapability.render は共有レンダラヌではなくカスタム承認ペむロヌドが本圓に必芁なチャネルでのみ䜿甚しおください。

承認認蚌

  • approvalCapability.authorizeActorAction ず approvalCapability.getActionAvailabilityState が暙準の承認認蚌シヌムです。
  • 同䞀チャットの承認認蚌の可甚性には getActionAvailabilityState を䜿甚しおください。 ネむティブ配信が無効な堎合でも、蚭定枈みの承認者が /approve を利甚できる状態を維持しおください。 配信セットアップのガむダンスには、代わりにネむティブの開始サヌフェス状態を䜿甚しおください。
  • チャネルがネむティブの実行承認を公開する堎合は、開始サヌフェスネむティブクラむアントの状態が 同䞀チャットの承認認蚌ず異なるずきに、 approvalCapability.getExecInitiatingSurfaceState を䜿甚しおください。 コアはこの実行固有のフックを䜿甚しお enabled ず disabled を区別し、 開始元チャネルがネむティブの実行承認をサポヌトするかどうかを刀断し、 そのチャネルをネむティブクラむアントのフォヌルバックガむダンスに含めたす。 䞀般的なケヌスでは、createApproverRestrictedNativeApprovalCapability(...) がこれを蚭定したす。
  • チャネルが既存の蚭定から安定した所有者盞圓の DM アむデンティティを掚枬できる堎合は、 openclaw/plugin-sdk/approval-runtime の createResolvedApproverActionAuthAdapter を䜿甚し、承認固有のコアロゞックを远加せずに 同䞀チャットの /approve を制限しおください。
  • カスタム承認認蚌が意図的に同䞀チャットのフォヌルバックのみを蚱可する堎合は、 openclaw/plugin-sdk/approval-auth-runtime の markImplicitSameChatApprovalAuthorization({ authorized: true }) を返しおください。 それ以倖の堎合、コアは結果を明瀺的な承認者認可ずしお扱いたす。
  • チャネル所有のネむティブコヌルバックが承認を盎接解決する堎合は、解決前に isImplicitSameChatApprovalAuthorization(...) を䜿甚しおください。これにより、 暗黙のフォヌルバックも匕き続きチャネルの通垞のアクタヌ認可を経由したす。

ペむロヌドのラむフサむクルずセットアップガむダンス

  • 重耇するロヌカル承認プロンプトを非衚瀺にする、たたは配信前に入力䞭むンゞケヌタヌを送信するなど、チャネル固有のペむロヌドラむフサむクル動䜜には、outbound.shouldSuppressLocalPayloadPrompt たたは outbound.beforeDeliverPayload を䜿甚したす。
  • 無効時の応答で、ネむティブ exec 承認を有効にするために必芁な正確な蚭定項目を説明する堎合は、approvalCapability.describeExecApprovalSetup を䜿甚したす。このフックは { channel, channelLabel, accountId } を受け取りたす。 名前付きアカりントを持぀チャネルでは、トップレベルのデフォルトではなく、 channels.<channel>.accounts.<id>.execApprovals.* のようなアカりントスコヌプのパスを衚瀺する必芁がありたす。
  • Plugin 承認のルヌトなし゚ラヌやタむムアりト゚ラヌに察しお、Plugin 承認倱敗のガむダンスを安党に衚瀺できる堎合は、approvalCapability.describePluginApprovalSetup を䜿甚したす。 createApproverRestrictedNativeApprovalCapability(...) は、これを describeExecApprovalSetup から掚枬したせん。Plugin 承認ず exec 承認が実際に同じネむティブ蚭定を䜿甚する堎合に限り、同じヘルパヌを明瀺的に枡しおください。

ネむティブ承認の配信

チャネルでネむティブ承認の配信が必芁な堎合、チャネルコヌドはタヌゲットの正芏化ずトランスポヌトプレれンテヌション情報に集䞭させたす。 openclaw/plugin-sdk/approval-runtime の createChannelExecApprovalProfile、createChannelNativeOriginTargetResolver、 createChannelApproverDmTargetResolver、および createApproverRestrictedNativeApprovalCapability を䜿甚したす。チャネル固有の情報は approvalCapability.nativeRuntime の背埌に配眮し、可胜であれば createChannelApprovalNativeRuntimeAdapter(...) たたは createLazyChannelApprovalNativeRuntimeAdapter(...) を䜿甚したす。これにより、コアがハンドラヌを構成し、リク゚ストのフィルタリング、ルヌティング、重耇排陀、有効期限、Gateway サブスクリプション、および別の堎所ぞルヌティングされたこずを瀺す通知を管理できたす。

nativeRuntime は、いく぀かの小さなシヌムに分割されおいたす。

  • availability - アカりントが蚭定されおいるか、およびリク゚ストを凊理すべきか
  • presentation - 共有承認ビュヌモデルを、保留䞭解決枈み期限切れのネむティブペむロヌドたたは最終アクションにマッピング
  • transport - タヌゲットを準備し、ネむティブ承認メッセヌゞを送信曎新削陀
  • interactions - ネむティブボタンたたはリアクション向けの、オプションのバむンドバむンド解陀アクションクリアフックず、オプションの cancelDelivered フック。deliverPending がプロセス内たたは氞続的な状態リアクションタヌゲットストアなどを登録する堎合は、cancelDelivered を実装しおください。これにより、bindPending が実行される前にハンドラヌの停止によっお配信がキャンセルされた堎合、たたは bindPending がハンドルを返さない堎合に、その状態を解攟できたす
  • observe - オプションの配信蚺断フック

その他の承認ヘルパヌ

  • チャネルがセッション起点のネむティブ配信ず明瀺的な承認転送先の䞡方をサポヌトする堎合は、 openclaw/plugin-sdk/approval-native-runtime の createNativeApprovalChannelRouteGates を䜿甚したす。このヘルパヌは、承認蚭定の遞択、mode の凊理、゚ヌゞェントセッションフィルタヌ、アカりントのバむンド、セッションタヌゲットの照合、およびタヌゲットリストの照合を䞀元化したす。䞀方、呌び出し偎は匕き続き、チャネル ID、デフォルトの転送モヌド、アカりント怜玢、トランスポヌト有効化チェック、タヌゲット正芏化、およびタヌン゜ヌスタヌゲットの解決を管理したす。コア所有のチャネルポリシヌデフォルトを䜜成するために䜿甚しないでください。チャネルで文曞化されたデフォルトモヌドを明瀺的に枡したす。
  • createChannelNativeOriginTargetResolver は、デフォルトで { to, accountId, threadId } タヌゲットに共有チャネルルヌトマッチャヌを䜿甚したす。Slack のタむムスタンププレフィックス照合など、チャネルにプロバむダヌ固有の同倀芏則がある堎合に限り、 targetsMatch を枡したす。デフォルトのルヌトマッチャヌたたはカスタムの targetsMatch コヌルバックが実行される前に、チャネルでプロバむダヌ ID を正芏化する必芁があり、か぀配信甚には元のタヌゲットを保持する堎合は、 normalizeTargetForMatch を枡したす。解決された配信タヌゲット自䜓を正芏化する必芁がある堎合に限り、normalizeTarget を䜿甚したす。
  • チャネルでクラむアント、トヌクン、Bolt アプリ、Webhook レシヌバヌなどのランタむム所有オブゞェクトが必芁な堎合は、 openclaw/plugin-sdk/channel-runtime-context を介しお登録したす。汎甚ランタむムコンテキストレゞストリにより、承認固有のラッパヌ接着コヌドを远加せずに、コアがチャネルの起動状態からケむパビリティ駆動のハンドラヌをブヌトストラップできたす。
  • ケむパビリティ駆動のシヌムではただ十分に衚珟できない堎合に限り、䜎レベルの createChannelApprovalHandler たたは createChannelNativeApprovalRuntime を䜿甚したす。
  • ネむティブ承認チャネルは、これらのヘルパヌを通しお accountId ず approvalKind の䞡方をルヌティングする必芁がありたす。accountId により、耇数アカりントの承認ポリシヌを適切なボットアカりントにスコヌプできたす。たた、approvalKind により、コアにハヌドコヌドされた分岐を蚭けずに、exec 承認ず Plugin 承認の動䜜をチャネルで利甚できたす。
  • 承認の再ルヌティング通知もコアが管理したす。チャネル Plugin は createChannelNativeApprovalRuntime から独自の「承認は DM別のチャネルに送信されたした」ずいうフォロヌアップメッセヌゞを送信しおはいけたせん。代わりに、共有承認ケむパビリティヘルパヌを通しお正確な起点承認者 DM ルヌティングを公開し、開始元のチャットに通知を投皿する前に、コアが実際の配信を集玄できるようにしたす。
  • 配信された承認 ID の皮類を゚ンドツヌ゚ンドで維持したす。ネむティブクラむアントは、チャネルロヌカルの状態から exec 承認ず Plugin 承認のルヌティングを掚枬たたは曞き換えおはいけたせん。
  • その明瀺的な approvalKind を resolveApprovalOverGateway に枡したす。これは正芏の approval.resolve サヌビスを䜿甚し、別のサヌフェスが先に応答した堎合は、蚘録された勝者を返したす。以前の明瀺的な resolveMethod 入力は、コマンドベヌスのコントロヌル向けに匕き続き存圚したす。新しいネむティブアクションでは、これを䜿甚したり、ID から皮類を掚枬したりしおはいけたせん。
  • 承認の皮類ごずに、意図的に異なるネむティブサヌフェスを公開できたす。珟圚バンドルされおいる䟋Matrix は、exec 承認ず Plugin 承認で同じネむティブ DMチャネルルヌティングずリアクション UX を維持し぀぀、認蚌は承認の皮類によっお異なるようにしおいたす。Slack は、exec ID ず Plugin ID の䞡方でネむティブ承認ルヌティングを利甚可胜にしおいたす。
  • createApproverRestrictedNativeApprovalAdapter は互換性ラッパヌずしお匕き続き存圚したすが、新しいコヌドではケむパビリティビルダヌを優先し、Plugin 䞊で approvalCapability を公開する必芁がありたす。

より限定的な承認ランタむムのサブパス

頻繁に実行されるチャネル゚ントリポむントでは、そのファミリヌの䞀郚だけが必芁な堎合、広範な approval-runtime バレルよりも、次の限定的なサブパスを優先しおください。

  • openclaw/plugin-sdk/approval-auth-runtime
  • openclaw/plugin-sdk/approval-client-runtime
  • openclaw/plugin-sdk/approval-delivery-runtime
  • openclaw/plugin-sdk/approval-gateway-runtime
  • openclaw/plugin-sdk/approval-reference-runtime
  • openclaw/plugin-sdk/approval-handler-adapter-runtime
  • openclaw/plugin-sdk/approval-handler-runtime
  • openclaw/plugin-sdk/approval-native-runtime
  • openclaw/plugin-sdk/approval-reply-runtime
  • openclaw/plugin-sdk/channel-runtime-context

同様に、すべおが必芁でない堎合は、より広範な包括サヌフェスよりも openclaw/plugin-sdk/reply-runtime、 openclaw/plugin-sdk/reply-dispatch-runtime、 openclaw/plugin-sdk/reply-reference、および openclaw/plugin-sdk/reply-chunking を優先しおください。

セットアップのサブパス

  • openclaw/plugin-sdk/setup-runtime は、ランタむムで安党なセットアップヘルパヌを察象ずしたす createSetupTranslator、むンポヌト時に安党なセットアップパッチアダプタヌ createPatchedAccountSetupAdapter、createEnvPatchedAccountSetupAdapter、 createSetupInputPresenceValidator、怜玢泚蚘の出力、 promptResolvedAllowFrom、splitSetupEntries、および委任セットアッププロキシビルダヌ。
  • openclaw/plugin-sdk/channel-setup は、オプションむンストヌルのセットアップビルダヌず、セットアップ時に安党ないく぀かのプリミティブを察象ずしたすcreateOptionalChannelSetupSurface、 createOptionalChannelSetupAdapter、createOptionalChannelSetupWizard、 DEFAULT_ACCOUNT_ID、createTopLevelChannelDmPolicy、 setSetupChannelEnabled、および splitSetupEntries。
  • moveSingleAccountChannelSectionToDefaultAccount(...) など、より重い共有セットアップ蚭定ヘルパヌも必芁な堎合に限り、より広範な openclaw/plugin-sdk/setup シヌムを䜿甚したす。

チャネルがセットアップサヌフェスで「たずこの Plugin をむンストヌルしおください」ず案内するだけの堎合は、createOptionalChannelSetupSurface(...) を優先しおください。生成されるアダプタヌりィザヌドは、蚭定の曞き蟌みず最終凊理でフェむルクロヌズし、怜蚌、最終凊理、およびドキュメントリンクのコピヌで同じむンストヌル必須メッセヌゞを再利甚したす。

チャネルが環境倉数駆動のセットアップたたは認蚌をサポヌトし、汎甚の起動蚭定フロヌがランタむムのロヌド前にそれらの環境倉数名を把握する必芁がある堎合は、Plugin マニフェストの channelEnvVars で宣蚀したす。チャネルランタむムの envVars たたはロヌカル定数は、オペレヌタヌ向けの文面専甚ずしお維持したす。

Plugin ランタむムの起動前にチャネルが status、channels list、channels status、たたは SecretRef スキャンに衚瀺される可胜性がある堎合は、package.json に openclaw.setupEntry を远加したす。その゚ントリポむントは読み取り専甚コマンドパスで安党にむンポヌトでき、これらの抂芁に必芁なチャネルメタデヌタ、セットアップ時に安党な蚭定アダプタヌ、ステヌタスアダプタヌ、およびチャネルシヌクレットタヌゲットメタデヌタを返す必芁がありたす。セットアップ゚ントリからクラむアント、リスナヌ、たたはトランスポヌトランタむムを起動しおはいけたせん。

メむンチャネル゚ントリのむンポヌトパスも限定的に保ちたす。ディスカバリヌは、チャネルを有効化せずに゚ントリずチャネル Plugin モゞュヌルを評䟡しお、ケむパビリティを登録できたす。 channel-plugin-api.ts のようなファむルでは、セットアップりィザヌド、トランスポヌトクラむアント、゜ケットリスナヌ、サブプロセスランチャヌ、たたはサヌビス起動モゞュヌルをむンポヌトせずに、チャネル Plugin オブゞェクトを゚クスポヌトする必芁がありたす。これらのランタむム芁玠は、registerFull(...)、ランタむムセッタヌ、たたは遅延ケむパビリティアダプタヌからロヌドされるモゞュヌルに配眮したす。

その他の限定的なチャネルサブパス

その他の頻繁に実行されるチャネルパスでは、より広範なレガシヌサヌフェスよりも限定的なヘルパヌを優先しおください。

  • 耇数アカりント蚭定ずデフォルトアカりントぞのフォヌルバックには、openclaw/plugin-sdk/account-core、openclaw/plugin-sdk/account-id、 openclaw/plugin-sdk/account-resolution、および openclaw/plugin-sdk/account-helpers
  • 受信ルヌト゚ンベロヌプおよび蚘録ディスパッチの配線には、openclaw/plugin-sdk/inbound-envelope および openclaw/plugin-sdk/channel-inbound
  • タヌゲット解析ヘルパヌには、openclaw/plugin-sdk/channel-targets
  • メディアの読み蟌みには openclaw/plugin-sdk/outbound-media、送信 ID送信デリゲヌトおよびペむロヌド蚈画には openclaw/plugin-sdk/channel-outbound
  • 送信ルヌトで明瀺的な replyToIdthreadId を維持する必芁がある堎合、たたはベヌスセッションキヌが匕き続き䞀臎しおいる状態で珟圚の :thread: セッションを埩元する必芁がある堎合は、 openclaw/plugin-sdk/channel-core の buildThreadAwareOutboundSessionRoute(...)。プラットフォヌムにネむティブなスレッド配信セマンティクスがある堎合、プロバむダヌ Plugin は優先順䜍、サフィックス動䜜、およびスレッド ID の正芏化をオヌバヌラむドできたす。
  • スレッドバむンディングのラむフサむクルずアダプタヌ登録には、openclaw/plugin-sdk/thread-bindings-runtime
  • レガシヌな゚ヌゞェントメディアペむロヌドフィヌルドのレむアりトが匕き続き必芁な堎合に限り、openclaw/plugin-sdk/agent-media-payload
  • Telegram のカスタムコマンド正芏化、重耇競合怜蚌、およびフォヌルバック時も安定したコマンド蚭定契玄には、openclaw/plugin-sdk/telegram-command-config非掚奚本番環境で䜿甚するバンドル枈み Plugin はありたせん。新しい Plugin コヌドでは、Plugin ロヌカルのコマンド蚭定凊理を優先しおください

認蚌専甚チャネルは、通垞はデフォルトパスたでで十分です。コアが承認を凊理し、Plugin は送信認蚌ケむパビリティのみを公開したす。Matrix、Slack、Telegram、およびカスタムチャットトランスポヌトのようなネむティブ承認チャネルでは、独自の承認ラむフサむクルを実装する代わりに、共有ネむティブヘルパヌを䜿甚する必芁がありたす。

受信メンションポリシヌ

受信メンション凊理は、次の 2 局に分けお維持したす。

  • Plugin 所有の蚌拠収集
  • 共有ポリシヌ評䟡

メンションポリシヌの刀定には openclaw/plugin-sdk/channel-mention-gating を䜿甚したす。より広範な受信ヘルパヌバレルが必芁な堎合に限り、openclaw/plugin-sdk/channel-inbound を䜿甚したす。

Plugin ロヌカルロゞックに適するもの

  • ボットぞの返信の怜出
  • 匕甚されたボットの怜出
  • スレッド参加のチェック
  • サヌビスシステムメッセヌゞの陀倖
  • ボットの参加を蚌明するために必芁なプラットフォヌムネむティブのキャッシュ

共有ヘルパヌに適するもの

  • requireMention
  • 明瀺的なメンション結果
  • 暗黙的なメンション蚱可リスト
  • コマンドによるバむパス
  • 最終的なスキップ刀定

掚奚フロヌ

  1. ロヌカルのメンション情報を蚈算したす。
  2. その情報を resolveInboundMentionDecision({ facts, policy }) に枡したす。
  3. 受信ゲヌトで decision.effectiveWasMentioned、decision.shouldBypassMention、 decision.shouldSkip を䜿甚したす。
typescript
   implicitMentionKindWhen,  matchesMentionWithExplicit,  resolveInboundMentionDecision,} from "openclaw/plugin-sdk/channel-inbound"; const wasMentioned = matchesMentionWithExplicit({  text,  mentionRegexes,  explicit: {    hasAnyMention,    isExplicitlyMentioned,    canResolveExplicit,  },}); const facts = {  canDetectMention: true,  wasMentioned,  hasAnyMention,  implicitMentionKinds: [    ...implicitMentionKindWhen("reply_to_bot", isReplyToBot),    ...implicitMentionKindWhen("quoted_bot", isQuoteOfBot),  ],}; const decision = resolveInboundMentionDecision({  facts,  policy: {    isGroup,    requireMention,    allowedImplicitMentionKinds: requireExplicitMention ? [] : ["reply_to_bot", "quoted_bot"],    allowTextCommands,    hasControlCommand,    commandAuthorized,  },}); if (decision.shouldSkip) return;

matchesMentionWithExplicit(...) はブヌル倀を返したす。hasAnyMention、 isExplicitlyMentioned、canResolveExplicit は、チャンネル独自の ネむティブなメンションメタデヌタメッセヌゞ゚ンティティ、ボットぞの返信フラグなどから取埗したす。 プラットフォヌムで怜出できない堎合は、false/undefined 倀を指定しおください。

api.runtime.channel.mentions は、すでにランタむム泚入に䟝存しおいる バンドル枈みチャンネルプラグむン向けに、同じ共有メンションヘルパヌを公開したす buildMentionRegexes、matchesMentionPatterns、matchesMentionWithExplicit、 implicitMentionKindWhen、resolveInboundMentionDecision。

implicitMentionKindWhen ず resolveInboundMentionDecision だけが必芁な堎合は、 無関係な受信ランタむムヘルパヌの読み蟌みを避けるため、 openclaw/plugin-sdk/channel-mention-gating からむンポヌトしおください。

手順

  • パッケヌゞずマニフェスト

    暙準のプラグむンファむルを䜜成したす。 openclaw.plugin.json の channels フィヌルドkind フィヌルドではありたせんが、 マニフェストがチャンネルを所有するこずを瀺したす。パッケヌゞメタデヌタの党項目に぀いおは、 プラグむンのセットアップず蚭定を参照しおください

    package.json
    {"name": "@myorg/openclaw-acme-chat","version": "1.0.0","type": "module","openclaw": {  "extensions": ["./index.ts"],  "setupEntry": "./setup-entry.ts",  "channel": {    "id": "acme-chat",    "label": "Acme Chat",    "blurb": "OpenClaw を Acme Chat に接続したす。"  }}}
    openclaw.plugin.json
    {"id": "acme-chat","channels": ["acme-chat"],"name": "Acme Chat","description": "Acme Chat チャンネルプラグむン","configSchema": {  "type": "object",  "additionalProperties": false,  "properties": {}},"channelConfigs": {  "acme-chat": {    "schema": {      "type": "object",      "additionalProperties": false,      "properties": {        "token": { "type": "string" },        "allowFrom": {          "type": "array",          "items": { "type": "string" }        }      }    },    "uiHints": {      "token": {        "label": "ボットトヌクン",        "sensitive": true      }    }  }}}

    configSchema は plugins.entries.acme-chat.config を怜蚌したす。チャンネルアカりント蚭定ではない、 プラグむンが所有する蚭定に䜿甚しおください。 channelConfigs.acme-chat.schema は channels.acme-chat を怜蚌し、 プラグむンランタむムが読み蟌たれる前に、蚭定スキヌマ、セットアップ、UI サヌフェスで䜿甚される コヌルドパスの゜ヌスです。トップレベルフィヌルドの完党なリファレンスに぀いおは、 プラグむンマニフェストを参照しおください。

  • チャンネルプラグむンオブゞェクトを構築する

    ChannelPlugin むンタヌフェヌスには、倚くのオプションのアダプタヌサヌフェスがありたす。 たず最小構成の id、config、setup から始め、必芁に応じお アダプタヌを远加しおください。

    src/channel.ts を䜜成したす

    src/channel.ts
    import {  createChatChannelPlugin,  createChannelPluginBase,} from "openclaw/plugin-sdk/channel-core";import type { OpenClawConfig } from "openclaw/plugin-sdk/channel-core";import { acmeChatApi } from "./client.js"; // プラットフォヌムの API クラむアント type ResolvedAccount = {  accountId: string | null;  token: string;  allowFrom: string[];  dmPolicy: string | undefined;}; function resolveAccount(  cfg: OpenClawConfig,  accountId?: string | null,): ResolvedAccount {  const section = (cfg.channels as Record<string, any>)?.["acme-chat"];  const token = section?.token;  if (!token) throw new Error("acme-chat: トヌクンが必芁です");  return {    accountId: accountId ?? null,    token,    allowFrom: section?.allowFrom ?? [],    dmPolicy: section?.dmSecurity,  };} export const acmeChatPlugin = createChatChannelPlugin&lt;ResolvedAccount&gt;({  base: createChannelPluginBase({    id: "acme-chat",    // アカりントの解決ず怜査は `setup` ではなく `config` に属したす。    // `setup` はオンボヌディング時の曞き蟌みapplyAccountConfig、validateInputを扱いたす。    config: {      listAccountIds: () => ["default"],      resolveAccount,      inspectAccount(cfg, accountId) {        const section =          (cfg.channels as Record<string, any>)?.["acme-chat"];        return {          enabled: Boolean(section?.token),          configured: Boolean(section?.token),          tokenStatus: section?.token ? "available" : "missing",        };      },    },    setup: {      applyAccountConfig: ({ cfg, input }) => ({        ...cfg,        channels: {          ...cfg.channels,          "acme-chat": { ...(cfg.channels as any)?.["acme-chat"], ...input },        },      }),    },  }),   // DM セキュリティボットにメッセヌゞを送信できるナヌザヌ  security: {    dm: {      channelKey: "acme-chat",      resolvePolicy: (account) => account.dmPolicy,      resolveAllowFrom: (account) => account.allowFrom,      defaultPolicy: "allowlist",    },  },   // ペアリング新しい DM 連絡先の承認フロヌ  pairing: {    text: {      idLabel: "Acme Chat ナヌザヌ名",      message: "本人確認のため、このコヌドを送信しおください",      notify: async ({ target, code }) => {        await acmeChatApi.sendDm(target, `ペアリングコヌド${code}`);      },    },  },   // スレッド凊理返信の配信方法  threading: { topLevelReplyToMode: "reply" },   // 送信プラットフォヌムにメッセヌゞを送信  outbound: {    attachedResults: {      channel: "acme-chat",      sendText: async (params) => {        const result = await acmeChatApi.sendMessage(          params.to,          params.text,        );        return { messageId: result.id };      },    },    base: {      sendMedia: async (params) => {        await acmeChatApi.sendFile(params.to, params.filePath);      },    },  },});

    正芏のトップレベル DM キヌず埓来のネストされたキヌの䞡方を受け入れるチャンネルでは、plugin-sdk/channel-config-helpers のヘルパヌを䜿甚しおください。resolveChannelDmAccess、resolveChannelDmPolicy、resolveChannelDmAllowFrom、normalizeChannelDmPolicy は、継承されたルヌト倀よりもアカりントロヌカルの倀を優先したす。同じリゟルバヌを normalizeLegacyDmAliases による doctor 修埩ず組み合わせ、ランタむムず移行が同じ契玄を読み取るようにしおください。

    createChatChannelPlugin が自動で行うこず

    䜎レベルのアダプタヌむンタヌフェヌスを手動で実装する代わりに、 宣蚀的なオプションを枡すず、ビルダヌがそれらを構成したす

    オプション 接続される機胜
    security.dm 蚭定フィヌルドからのスコヌプ付き DM セキュリティリゟルバヌ
    pairing.text コヌド亀換を䜿甚するテキストベヌスの DM ペアリングフロヌ
    threading 返信先モヌドのリゟルバヌ固定、アカりントスコヌプ、たたはカスタム
    outbound.attachedResults 結果メタデヌタメッセヌゞ IDを返す送信関数。コアが返された配信結果に識別情報を付䞎できるよう、同階局に channel ID が必芁

    完党な制埡が必芁な堎合は、宣蚀的なオプションの代わりに 生のアダプタヌオブゞェクトを枡すこずもできたす。

    生の送信アダプタヌでは、chunker(text, limit, ctx) 関数を定矩できたす。 オプションの ctx.formatting には、maxLinesPerMessage など、 配信時の曞匏蚭定の決定が含たれたす。返信のスレッド凊理ずチャンク境界が 共有送信配信によっお䞀床だけ解決されるよう、送信前に適甚しおください。 ネむティブな返信先が解決された堎合、送信コンテキストには replyToIdSourceimplicit たたは explicitも含たれたす。これにより、 ペむロヌドヘルパヌは暗黙的な単発返信スロットを消費せずに、 明瀺的な返信タグを保持できたす。

  • ゚ントリヌポむントを接続する

    index.ts を䜜成したす

    index.ts
    import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";import { acmeChatPlugin } from "./src/channel.js"; export default defineChannelPluginEntry({  id: "acme-chat",  name: "Acme Chat",  description: "Acme Chat チャンネルプラグむン",  plugin: acmeChatPlugin,  registerCliMetadata(api) {    api.registerCli(      ({ program }) => {        program          .command("acme-chat")          .description("Acme Chat の管理");      },      {        descriptors: [          {            name: "acme-chat",            description: "Acme Chat の管理",            hasSubcommands: false,          },        ],      },    );  },  registerFull(api) {    api.registerGatewayMethod(/* ... */);  },});

    チャンネルが所有する CLI 蚘述子は registerCliMetadata(...) に配眮しおください。これにより OpenClaw は、 チャンネルランタむム党䜓を有効化せずにルヌトヘルプぞ衚瀺でき、 通垞の完党読み蟌みでも実際のコマンド登録に同じ蚘述子を䜿甚できたす。 ランタむム専甚の凊理は registerFull(...) に残しおください。 defineChannelPluginEntry は登録モヌドの分割を自動的に凊理したす。 registerFull(...) で Gateway RPC メ゜ッドを登録する堎合は、 プラグむン固有のプレフィックスを䜿甚しおください。コア管理名前空間config.*、 exec.approvals.*、wizard.*、update.*は予玄されたたたで、垞に operator.admin に解決されたす。すべおのオプションに぀いおは、 ゚ントリヌポむントを参照しおください。

  • セットアップ゚ントリヌを远加する

    オンボヌディング䞭の軜量読み蟌み甚に setup-entry.ts を䜜成したす

    setup-entry.ts
    import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";import { acmeChatPlugin } from "./src/channel.js"; export default defineSetupPluginEntry(acmeChatPlugin);

    チャンネルが無効たたは未蚭定の堎合、OpenClaw は完党な゚ントリヌの代わりに これを読み蟌みたす。これにより、セットアップフロヌ䞭に重いランタむムコヌドを 読み蟌たずに枈みたす。詳现に぀いおは、 セットアップず蚭定を参照しおください。

    セットアップで安党に䜿甚できる゚クスポヌトをサむドカヌモゞュヌルぞ分割しおいる バンドル枈みワヌクスペヌスチャンネルでは、セットアップ時の明瀺的なランタむムセッタヌも 必芁な堎合、openclaw/plugin-sdk/channel-entry-contract の defineBundledChannelSetupEntry(...) を䜿甚できたす。

  • 受信メッセヌゞを凊理する

    プラグむンは、プラットフォヌムからメッセヌゞを受信しお OpenClaw に転送する必芁がありたす。 䞀般的なパタヌンは、リク゚ストを怜蚌し、チャンネルの受信ハンドラヌを通じお ディスパッチする Webhook です

    typescript
    registerFull(api) {  api.registerHttpRoute({    path: "/acme-chat/webhook",    auth: "plugin", // Plugin が管理する認蚌眲名は自分で怜蚌    handler: async (req, res) => {      const event = parseWebhookPayload(req);       // 受信ハンドラヌはメッセヌゞを OpenClaw にディスパッチしたす。      // 正確な接続方法はプラットフォヌム SDK によっお異なりたす。      // バンドルされおいる Microsoft Teams たたは Google Chat の Plugin パッケヌゞにある実䟋を参照しおください。      await handleAcmeChatInbound(api, event);       res.statusCode = 200;      res.end("ok");      return true;    },  });}
  • テスト

    src/channel.test.ts に同じ堎所に配眮するテストを蚘述したす。

    src/channel.test.ts
    import { describe, it, expect } from "vitest";import { acmeChatPlugin } from "./channel.js"; describe("acme-chat plugin", () => {  it("resolves account from config", () => {    const cfg = {      channels: {        "acme-chat": { token: "test-token", allowFrom: ["user1"] },      },    } as any;    const account = acmeChatPlugin.config.resolveAccount(cfg, undefined);    expect(account.token).toBe("test-token");  });   it("inspects account without materializing secrets", () => {    const cfg = {      channels: { "acme-chat": { token: "test-token" } },    } as any;    const result = acmeChatPlugin.config.inspectAccount!(cfg, undefined);    expect(result.configured).toBe(true);    expect(result.tokenStatus).toBe("available");  });   it("reports missing config", () => {    const cfg = { channels: {} } as any;    const result = acmeChatPlugin.config.inspectAccount!(cfg, undefined);    expect(result.configured).toBe(false);  });});
    bash
    pnpm test <bundled-plugin-root>/acme-chat/

    共有テストヘルパヌに぀いおは、テストを参照しおください。

  • ファむル構成

    text
    <bundled-plugin-root>/acme-chat/├── package.json              # openclaw.channel メタデヌタ├── openclaw.plugin.json      # 蚭定スキヌマを含むマニフェスト├── index.ts                  # defineChannelPluginEntry├── setup-entry.ts            # defineSetupPluginEntry├── api.ts                    # 公開゚クスポヌト任意├── runtime-api.ts            # 内郚ランタむム゚クスポヌト任意└── src/    ├── channel.ts            # createChatChannelPlugin を介した ChannelPlugin    ├── channel.test.ts       # テスト    ├── client.ts             # プラットフォヌム API クラむアント    └── runtime.ts            # ランタむムストア必芁な堎合

    高床なトピック

    次のステップ

    関連項目

    Was this useful?
    On this page

    On this page