このドキュメントは Channel App SDK と一緒に管理されています。最新 package とドキュメント全体の順序は、まず SDK README を確認してください。この Document の基準となる原文は GitHub 原文です。
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 を指す |
|
Runtime または action | user-facing または background operation を実行する |
|
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 を実行します。
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 を開始します。
Deployment policy で custom retry や observability が必要な場合は
server.WithAutoRegisterRetry と server.WithAutoRegisterResult を使います。既存 Gin server では
server/gin の同等 option を使います。
推奨される自動登録 flow は次のとおりです。
Function server が listening するまで待ちます。
TokenManagerから cache 済みの app token を 1 つ取得します。Discovery された各 Extension name と system version で
registerExtensionを呼び出します。一時的な失敗を bounded exponential backoff で retry します。
AppStore が versioned Function Endpoint から schema と metadata を discovery できるようにします。
Request field は camelCase の appId、extensionName、systemVersion です。v1 などの
systemVersion は Channel Extension contract version であり、アプリの release version ではありません。
Custom bootstrap や deployment system が registration を管理する場合にだけ native Function を 直接呼び出します。
SDK | 直接呼び出す場合 |
|---|---|
TypeScript |
|
Go |
|
Function request ごとに新しい token を発行したり、registration を実行したりしないでください。
Standalone Function だけのアプリは SDK の core:v1 fallback を使います。ALF task、Notebook、
Messaging などの advanced family は generic Extension registration の後に secondary sync または
product setup が必要な場合があるため、family recipe に従ってください。
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 を復元する必要があります。
次の境界を個別に検証してください。
Startup log に期待する Extension name、system version、registration success が表示されます。
getFunctionsdiscovery にすべての metadata と参照先 runtime Function が含まれます。Install と activation の後、意図した Channel surface に metadata が表示されます。
Test Channel で実際の runtime call が 1 つ成功します。
不正 input・signature、permission 不足、一時的な registration failure が設計どおり拒否または retry されます。
registerExtension の成功が証明するのは registration request が受理されたことだけです。
Discovery、metadata validation、Channel install・activation、runtime handler の動作までは証明しません。
すべての Extension を次の順序で実装します。
Function が実際に使う最小限の permission だけを有効にします。
SDK schema で metadata Function と参照先 Function を実装します。
App token を使う SDK 自動登録を適用します。
Discovery、正常 call、不正 input、権限不足、retry を test します。
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 に渡しません。
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 に保存します。
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 を確認します。
extension.customtab.metadata.getCustomTabs が app-owned tab を公開します。Tab identifier を安定
させ、action には正確な Function name を指定し、interactive content は WAM で提供します。
Metadata と wamArgs に token や private record を入れません。
extension.hook.metadata.getHooks が event-driven Function を宣言します。Handler を idempotent
にし、署名済み app Function request だけを処理し、非同期処理できる event には速く response
します。公開 webhook.received target には public targetId、高 entropy の endpointToken、
payload validation、replay protection、secret rotation が必要です。
extension.polling.metadata.getPollers が scheduled poller を宣言します。
target.getChannels のような target resolver が install 済み channel を page 単位で返し、各
poller は呼び出す full Function name を指定します。Cursor を永続化し、retry を idempotent にし、
batch size と実行時間を制限して partial failure を test してください。
calendar は calendar/event type、availability、booking の作成・取消・変更・照会に使います。
Provider credential は server に置き、time zone を明示的に正規化し、booking mutation を
idempotent にします。Slot 選択 UI は WAM、provider call は server Function が担当します。
extension.store.metadata.getStoreProfile が store identity と presentation metadata を公開します。
AppStore は registration/sync 時に profile を読みます。安定した ID と翻訳 label を分離し、
provider credential を profile に含めません。
DataSource metadata は catalog、table、column、table description を提供します。Query は通常の
app Function route ではなく、認証済み DataSource gRPC endpoint で実行します。
x-access-token を検証し、catalog/table allowlist、parameterized SQL、row/time limit を適用し、
Arrow-compatible result を stream してください。SDK は PostgreSQL と BigQuery 向け runner を
提供します。
新しい 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 にしてください。
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 してください。
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 を代行してはいけません。
extension.alfTask.alftask.getTasks が versioned automation task を公開します。Registration は
registerExtension("alfTask", "v1") と registerAlfTasks の 2 段階です。Task key を安定させ、
behavior change では version を上げ、sync 済み version を確認してください。
extension.notebook.core.getNotebooks が versioned notebook definition を公開し、registration 後に
registerAppNotebooks sync が必要です。Notebook/cell key を安定させ、definition change では
version を上げ、外部 data を render するときは untrusted input として扱います。
mailRelay は extension.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 に残しません。
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 として使ってください。