Channel Developers

thumbnail

Extension 完全ガイド

Extension は typed app Function を Channel の標準機能に接続する、名前と version を持つ契約です。 アプリが公式 Function name と schema を実装すると、Channel の画面は command、widget、custom tab、hook、OAuth などの機能を discovery して呼び出せます。

Extension は通常、2 種類の Function で構成されます。

Function の種類

役割

Metadata または discovery

機能を説明し、runtime Function を指す

extension.command.metadata.getCommands

Runtime または action

user-facing または background operation を実行する

extension.command.command.execute

Metadata は orders.sync のような standalone app Function を参照することもできます。アプリ固有の business operation は standalone にし、標準契約だけを Extension namespace に置いてください。 Extension 内の relative name は extension.{extensionName}.{relativeName} という full name になります。

Registration はアプリの code を upload・deploy する処理ではありません。アプリ単位の (extensionName, systemVersion) 契約を AppStore に通知し、設定された Function Endpoint から schema を discovery できるようにします。また、個別の Channel への install や機能の有効化でも ありません。Channel install、permission grant、capability activation は別の段階です。

SDK が提供する Extension family、Function name、schema を使ってください。Metadata が action Function を指しても、その Function が自動で作られるわけではありません。Metadata Function と 参照されるすべての runtime Function を app server に登録する必要があります。

@Extension で family と system version を宣言し、@Func に relative name を指定して、decorated class を NestJS provider として登録します。ChannelAppModule が provider を discovery し、HTTP listener の準備後に推奨 registration flow を実行します。

TypeScript

Class が providers に含まれていないと discovery できません。autoRegister が false でも実装済み Function は SDK が dispatch しますが、その Extension registration target は AppStore に公開されません。

Typed extension/{family} builder と app.Use を使います。Builder が Function schema と Extension registration target の両方を宣言します。server.WithAutoRegister() は server が discovery request へ応答できるようになってから registration を開始します。

Go

Deployment policy で custom retry や observability が必要な場合は server.WithAutoRegisterRetryserver.WithAutoRegisterResult を使います。既存 Gin server では server/gin の同等 option を使います。

推奨される自動登録 flow は次のとおりです。

  1. Function server が listening するまで待ちます。

  2. TokenManager から cache 済みの app token を 1 つ取得します。

  3. Discovery された各 Extension name と system version で registerExtension を呼び出します。

  4. 一時的な失敗を bounded exponential backoff で retry します。

  5. AppStore が versioned Function Endpoint から schema と metadata を discovery できるようにします。

Request field は camelCase の appIdextensionNamesystemVersion です。v1 などの systemVersion は Channel Extension contract version であり、アプリの release version ではありません。

Custom bootstrap や deployment system が registration を管理する場合にだけ native Function を 直接呼び出します。

SDK

直接呼び出す場合

TypeScript

nativeClient.registerExtension(appId, extensionName, systemVersion, appToken.accessToken)

Go

nativeClient.RegisterExtension(ctx, appToken.AccessToken, appID, extensionName, systemVersion)

Function request ごとに新しい token を発行したり、registration を実行したりしないでください。 Standalone Function だけのアプリは SDK の core:v1 fallback を使います。ALF task と Notebook は registerExtension が成功すると自動的に sync されるため、別の registration Function は呼び出しません。 Messaging などの advanced family では product setup または family-specific secondary sync が必要な 場合があるため、family recipe に従ってください。

systemVersion は AppStore と app server の間の system contract version です。AppStore が third-party app に送る request の field、schema、または invocation contract に後方互換性を壊す 変更(breaking change)を導入するときに Channel が上げます。App の deployment version、npm/Go SDK package version、developer が定義する Function API version とは異なります。現在の default system contract は v1 です。たとえば AppStore system contract v2 は、そのような breaking change が反映された platform version であり、各 app が作る v2 ではありません。

systemVersion が現れる場所

意味

@Extension または Go Extension registration

App が実装すると AppStore に宣言する system contract

Extension metadata の target systemVersion

その Function の呼び出しに使う同じ AppStore system contract

Request の systemVersion/functions/v1

AppStore が同じ contract を app server に渡す request と route の表現

現在の SDK は version ごとに別の handler set を作りません。そのため、developer が systemVersion: "v2" を任意に指定して独自の Function v2 を運用することはできません。AppStore と SDK が公式 v2 contract を提供した場合だけその値を使ってください。App が所有する standalone Function の互換性を維持する方法は Function 登録を参照してください。標準 Extension Function の公式 name は変更せず、AppStore と SDK が提供する contract を実装します。

  • AppStore は registration 直後に discovery を呼び出す可能性があるため、Function Endpoint を先に deploy します。

  • 通常の startup では自動登録を有効にし、custom infinite loop ではなく SDK の bounded retry を 使います。

  • 複数 replica を deploy する場合は shared token storage を使います。重複する idempotent registration call は許容できますが、各 replica が cache なしで token 発行 loop を持つべきではありません。

  • Extension schema、metadata、Function name、permission、Function Endpoint を変更したら再登録します。 単なる app release のために systemVersion を変更しないでください。

  • Capability を意図的に削除する場合だけ unregisterExtension を使います。Deployment rollback は 最後の compatible server と schema を復元する必要があります。

次の境界を個別に検証してください。

  1. Startup log に期待する Extension name、system version、registration success が表示されます。

  2. getFunctions discovery にすべての metadata と参照先 runtime Function が含まれます。

  3. Install と activation の後、意図した Channel surface に metadata が表示されます。

  4. Test Channel で実際の runtime call が 1 つ成功します。

  5. 不正 input・signature、permission 不足、一時的な registration failure が設計どおり拒否または retry されます。

registerExtension の成功が証明するのは registration request が受理されたことだけです。 Discovery、metadata validation、Channel install・activation、runtime handler の動作までは証明しません。

すべての Extension を次の順序で実装します。

  1. Function が実際に使う最小限の permission だけを有効にします。

  2. SDK schema で metadata Function と参照先 Function を実装します。

  3. App token を使う SDK 自動登録を適用します。

  4. Discovery、正常 call、不正 input、権限不足、retry を test します。

  5. App Secret、Signing Key、app/channel token、provider credential を WAM に入れません。

TypeScript は通常 @Extension@Func を使います。Go は extension/{family} typed builder を優先してください。以下の各 family recipe は両言語の実装、 認証、WAM、信頼性、test を説明し、正確な TypeScript schema と Go Extension reference へ案内します。

最初に Function 登録で共通 wire contract を確認し、UI を開く Extension には WAM ガイドも適用してください。

config は API key、client_credentials、shop identifier、scope ごとの設定に使います。 extension.config.metadata.getConfigSchema を実装し、必要に応じて validation/save/delete Function を追加します。Secret field は credential として扱い、安定した key ではなく label だけを翻訳してください。注入された値は Function context から読み、WAM に渡しません。

Config 詳細

oauth は外部 provider の Authorization Code flow にだけ使います。 extension.oauth.metadata.getAuthConfig を実装して oauth:v1 を登録します。Redirect state と connection は AppStore が管理し、provider token は ctx.authToken に注入されます。API key と client_credentials は OAuth ではなく Config に保存します。

OAuth 詳細

extension.command.metadata.getCommands が Desk command を公開します。各 command は standalone または Extension Function の正確な full name を参照する必要があります。Command は text を 返す、action を実行する、または WAM を開けます。Command discovery と action handler を別々に test してください。

Command 詳細 · WAM ガイド · TypeScript tutorial · Go tutorial

extension.widget.metadata.getWidgets が context ごとの widget を公開します。Metadata は surface と action Function を選び、action は WAM を開けます。Chat、user、manager context は surface によって存在しないため optional として扱い、native action の permission を確認します。

Widget 詳細

extension.customtab.metadata.getCustomTabs が app-owned tab を公開します。Tab identifier を安定 させ、action には正確な Function name を指定し、interactive content は WAM で提供します。 Metadata と wamArgs に token や private record を入れません。

Custom tab 詳細

extension.hook.metadata.getHooks が event-driven Function を宣言します。Handler を idempotent にし、署名済み app Function request だけを処理し、非同期処理できる event には速く response します。公開 webhook.received target には public targetId が必要です。App scope は高 entropy の endpointToken を使い、manager scope は Function context で AppStore 発行 URL を受け取ります。 両 scope とも provider payload validation と replay protection が必要です。

Hook 詳細

extension.polling.metadata.getPollers が scheduled poller を宣言します。Scope ごとの resolver が channel target(target.getChannels)または channel/manager target(target.getManagers)を page 単位で返し、各 poller は呼び出す full Function name を指定します。Cursor を永続化し、retry を idempotent にし、batch size と実行時間を制限して partial failure を test してください。

Polling 詳細

calendar は calendar/event type、availability、booking の作成・取消・変更・照会に使います。 Provider credential は server に置き、time zone を明示的に正規化し、booking mutation を idempotent にします。Slot 選択 UI は WAM、provider call は server Function が担当します。

Calendar 詳細

extension.store.metadata.getStoreProfile が store identity と presentation metadata を公開します。 AppStore は registration/sync 時に profile を読みます。安定した ID と翻訳 label を分離し、 provider credential を profile に含めません。

Store 詳細

DataSource metadata は catalog、table、column、table description を提供します。Query は通常の app Function route ではなく、認証済み DataSource gRPC endpoint で実行します。 x-access-token を検証し、公開 table の認可は AppStore に任せ、app scope credential と read-only SQL、row/time limit を適用し、 Arrow-compatible result を stream してください。SDK は PostgreSQL と BigQuery 向け runner を 提供します。

DataSource 詳細 · Go example

新しい commerce app は redesigned commerce Extension を使います。ID-based order model、 buyer、order lookup、cancel/return/exchange request、exchangeable item、shipping address change、 structured ActionResult を提供します。Mutation 前に provider state を検証し、provider が 対応しない operation は明確な unsupported result にしてください。

Commerce 詳細

wms は warehouse/order-management provider を接続します。Order lookup、 cancel/return/exchange restore flow、shipping-address change には ID-based extension.wms.order.* Function を使います。Shop config を明示的に要求し、mutation は安全な 環境で rollback 可能性まで test してください。

WMS 詳細

Messaging は inbox、prebuilt messaging、follow-up、medium-link、CHX integration を含みます。 他の family より AppStore contract への依存が強く、generic registration と複数の channel-scoped native Function を使います。必要な native claim を先に設計し、外部 conversation/message mapping を保存し、webhook/polling delivery を idempotent にします。 正しい user/manager authorization なしで user を代行してはいけません。

Messaging 詳細

extension.alfTask.alftask.getTasks が versioned automation task を公開します。 registerExtension("alfTask", "v1") で登録すると task sync も開始されます。Task key を安定させ、 behavior change では version を上げ、sync 済み version を確認してください。

ALF task 詳細

extension.notebook.core.getNotebooks が versioned notebook definition を公開します。 registerExtension で Notebook extension を登録すると sync も開始されます。Notebook/cell key を安定させ、definition change では version を上げ、外部 data を render するときは untrusted input として扱います。

Notebook 詳細

mailRelayextension.mailRelay.inbound.onMailReceived で normalized mail event を受けます。 TypeScript 0.17.2 では full name を standalone @Func として登録し、 registerExtension("mailRelay", "v1") を明示的に呼びます。Go には typed builder があります。 Relay token を検証し、attachment/body size を制限し、message ID を deduplicate し、raw mail content を log に残しません。

Mail relay 詳細

  • Metadata が SDK schema と正確な full Function name を使います。

  • Extension provider または Go builder が一度だけ登録されます。

  • Signature がない、または不正な Function request を reject します。

  • App/channel token を cache/refresh し、manager/user authorization は WAM host に任せます。

  • Provider credential は Config/OAuth から注入し、client に返しません。

  • Mutation は idempotent または安全に retry でき、permission failure が明確です。

  • Install 済み test app で discovery と real invocation を一度以上通します。

実装の検証後は、本番運用準備ガイドを security、reliability、deployment、 operation、rollback の最終 gate として使ってください。

このドキュメントは Channel App SDK と一緒に管理されています。最新 package とドキュメント全体の順序は、まず SDK README を確認してください。この Document の基準となる原文は GitHub 原文です。