ffcpe-app-builder-actions について
Adobe App Builder で FFCPE SDK を使い、Workflow Builder のカスタムアクションを開発するチーム向けのスキルです。Web アクションと非同期 Worker のルート、入出力、デプロイ設定、カタログ登録を扱います。
主な機能
- 01Hono Web アクションのルート設定
- 02非同期 Worker ハンドラーの実装
- 03入力の読み取りと出力の生成
- 04OpenWhisk アクションマニフェスト設定
- 05デプロイとカタログ登録
活用シーン
- 01Workflow Builder 向けカスタムアクションの開発
- 02App Builder での非同期ジョブ処理
- 03ノード用 Web・Worker ペアの設定
- 04デプロイ済みアクションのカタログ登録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ adobe/ ffcpe-custom-node-sdk --skill ffcpe-app-builder-actionsインストール後、Claude Code で/ffcpe-app-builder-actionsを入力して読み込まれたか確認します。
詳細
FFCPE App Builder アクション(@adobe/ffcpe-custom-node-core、@adobe/ffcpe-custom-node-app-builder)
@adobe/ffcpe-custom-node-core と @adobe/ffcpe-custom-node-app-builder を使用して、Adobe App Builder(OpenWhisk)リポジトリで Workflow Builder カスタムアクションを実装または拡張する場合に、このスキルを使用します。
HTTP のフィールドレベルの契約の詳細については、この SDK リポジトリの docs/custom-action-requests.md を参照してください。利用者向けのインストール方法と例については、README.md を参照してください。パッケージのインストール、ローカルでのリンク、セキュリティに関するガイダンスについては、ffcpe-custom-node-sdk を参照してください。catalog-entry.json と aio ffcpe catalog については、adobe/aio-cli-plugin-ffcpe の ffcpe-catalog-entry-json と aio-ffcpe-cli を使用してください:
npx skills add adobe/aio-cli-plugin-ffcpe --all -y
パッケージとピア依存関係
@adobe/ffcpe-custom-node-core— 契約の型、handleFfcpeSubmit/handleFfcpeStatus、runWorkerJob、入力/出力ヘルパー、IMS インバウンド認証ヘルパー。@adobe/ffcpe-custom-node-app-builder—mountFfcpeNodeRoutes、createFfcpeNodeWorker、AIOJobStore、OpenWhisk オーケストレーター、buildStatusUrl、createAioLogger。
hono をピア依存関係として宣言してください(アプリでバージョンを選択します)。一般的な App Builder のピア依存関係には、@adobe/aio-lib-state、@adobe/aio-lib-ims、@adobe/aio-lib-core-logging、openwhisk も含まれます。テンプレートの package.json に記載されているバージョンに合わせてください。
Web アクション(Hono)
Hono、hono-openwhisk-adapterのToOpenWhiskAction、@adobe/ffcpe-custom-node-app-builderのmountFfcpeNodeRoutesをインポートします。const app = new Hono()を実行し、続けてmountFfcpeNodeRoutes(app, { worker: { package, name }, web: { package, name } })を呼び出します。webとworkerは、マニフェスト内の OpenWhisk の package 名と action 名に一致している必要があります(statusUrlと非同期呼び出しに使用されます)。- デフォルトのルートは
POST /submitとGET /statusです。パスがデフォルトと異なる場合を除き、routesは省略してください。 export const main = ToOpenWhiskAction(app)を指定します(または、バンドラーが想定するエントリー形式を使用します)。
*.config.yaml / ext.config.yaml 内の web アクションでは、対応する Node ランタイム(例:nodejs:22)に加えて、web: "raw" と require-adobe-auth: false を指定する必要があります:
runtimeManifest:
packages:
my-ffcpe-app:
actions:
my-web-action:
function: actions/my-web-action.ts
web: "raw"
runtime: nodejs:22
annotations:
require-adobe-auth: false
my-worker:
function: actions/my-worker.ts
runtime: nodejs:22
Worker アクション
FfcpeNodeWorkerHandlerを実装します。ctxにはjobId、inputs(FfcpeInput[])、params(submit のparameters)、logger、省略可能なauthContext、およびargs(main(args)全体)が含まれます。{ status: "completed", outputs?: Output[] }または{ status: "failed", error: string }を返します。createTextOutput、createImageOutput、createVideoOutput、createJsonOutputを使用してください。export const main = createFfcpeNodeWorker(handler, options?)を指定します。requiredInputNamesが参照するのは、各入力の表示用nameではなくportです。
ctx.inputs とともに getTextInput、getImageInput などを使用してください(ヘルパーが受け取るのは入力配列であり、submit 本文全体ではありません)。
マニフェストの inputs(シークレット): 通常は環境変数です。ctx.inputs ではなく process.env を使用してください。シークレットをログに出力しないでください。
init-bare で最初から始める
App Builder プロジェクトがまだない場合、最も手早い方法は aio app init --standalone-app(または init-bare スクリプトラッパー)です。警告:このジェネレーターは、最小限の骨組み以上のものを生成します。ヘッドレス FFCPE アクションには不要な web-src/、actions/generic/、actions/publish-events/、test/、e2e/ をスキャフォールディングします。以下の手順を順番に実行してください:
1. Console プロジェクトとワークスペースを作成する
# Create the project
aio console project create -n myproject -t "My Project Title" --json
# Stage workspace is created automatically; select it (use the project ID from the create output)
aio console project select myproject
aio console workspace select Stage --projectId <PROJECT_ID>
Console プロジェクト名の制約(実際のセットアップ時の失敗例に基づく):
| ルール | 詳細 |
|---|---|
| 英数字のみ | ハイフンや特殊文字は拒否されます(demo-qr-custom-ffcpe-nodes → Project name … is invalid)。キャメルケースまたは短いスラッグを使用してください:demoQrFfcpe。 |
| 最大 20 文字 | それより長い名前は Project name length must be less than 20 で失敗します。 |
| 名前 ≠ OpenWhisk パッケージ | Console プロジェクト名(例:demoQrFfcpe)は、app.config.yaml の runtimeManifest パッケージ名(例:demo-qr-custom-ffcpe-nodes)と異なっていてもかまいません。YAML のパッケージ名やアクション名にはハイフンを使用できます。 |
| ステージは自動作成 | プロジェクトとともに Production および Stage ワークスペースが作成されるため、通常、初回のデプロイで aio console workspace create を実行する必要はありません。 |
Console CLI のフラグリファレンス — フラグはコマンドによって異なります。不一致があると NonExistentFlagsError が発生します:
| コマンド | 主なフラグ |
|---|---|
aio console workspace create | --projectName <name>(必須)、--name <name>(必須) |
aio console workspace select | 位置引数 [WORKSPACEIDORNAME] + --projectId <id> |
aio console workspace list | --projectId <id>(--projectName ではありません) |
aio console workspace download | 位置引数 [DESTINATION] + --projectId <id> |
2. プロジェクトを初期化する
aio app init -y --no-login --standalone-app --no-install
3. ローカルアプリを Console ワークスペースに接続する
aio app use --no-input だけでは失敗します。init-bare の後は、ローカルの .aio ファイルに組織/プロジェクト/ワークスペースのコンテキストがまだないためです。正しい手順は次のとおりです:
# Download the workspace credentials/config from Console
aio console workspace download # saves e.g. <orgId>-<project>-Stage.json
# Import that config — this populates .aio and .env
aio app use <orgId>-<project>-Stage.json --overwrite --no-input
.env がすでに存在する場合(aio app init の後によくある状態)、引数なしの aio app use <file>.json は対話形式での入力を求めるため、非対話型またはエージェントのセッションでは処理が停止することがあります。ダウンロードしたワークスペース設定をスキャフォールド済みのプロジェクトにインポートする場合は、必ず --overwrite --no-input を指定してください。
ダウンロードした JSON ファイルにはシークレット(クライアント認証情報、API キー)が含まれます。 ダウンロード後、git add を実行する前に、すぐに .gitignore に追加してください。生成された .gitignore ではこのファイルは自動的に除外されません:
# Add the specific file, or use the pattern [0-9]*-*-*.json to cover all workspaces
echo '<orgId>-<project>-Stage.json' >> .gitignore
.env も無視されることを確認してください(生成された .gitignore では .env* によって除外されますが、実際に設定されていることを確認してください)。
4. スキャフォールドされたファイルを整理する
ジェネレーターが、ヘッドレス FFCPE アクションと競合するファイルを作成します。削除してください:
rm -rf web-src actions/generic actions/publish-events test e2e
5. app.config.yaml を修正する
生成された YAML にはアプリケーションレベルで web: web-src が含まれており、ヘッドレスプロジェクトでフロントエンドのビルド手順が実行されて失敗する原因になります。この行を削除し、スキャフォールドされたアクションを FFCPE のペアに置き換えてください:
application:
actions: actions
runtimeManifest:
packages:
my-ffcpe-app:
license: Apache-2.0
actions:
my-action-web:
function: actions/my-action/my-action.web.ts
web: "raw"
runtime: nodejs:22
annotations:
require-adobe-auth: false
my-action-worker:
function: actions/my-action/my-action.worker.ts
runtime: nodejs:22
inputs:
LOG_LEVEL: debug
6. webpack-config.js を置き換える
ジェネレーターが出力する設定は ts-loader を使用し、libraryTarget: "commonjs2" がありません。完全に置き換えてください(マージではありません。生成された出力セクションが不適切です):
// webpack-config.js
module.exports = {
output: {
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.[jt]sx?$/,
loader: 'esbuild-loader',
options: { target: 'es2020' },
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
}
ローダーをインストールします:
npm install -D esbuild-loader
# or: pnpm add -D esbuild-loader
7. FFCPE パッケージをインストールする
npm view @adobe/ffcpe-custom-node-core version
npm view @adobe/ffcpe-custom-node-app-builder version
npm view hono-openwhisk-adapter version
npm install @adobe/ffcpe-custom-node-core@latest @adobe/ffcpe-custom-node-app-builder@latest hono hono-openwhisk-adapter@latest
公開済みの最新バージョンを使用してください — インストール前に npm view <package> version を実行するか、上記のように @latest を指定してインストールします。0.1.x など、古いバージョン範囲を想定したり固定したりしないでください。レジストリに存在しない場合があります。バージョンを省略しても最新バージョンが解決されますが、ドキュメントやスクリプトでは @latest を指定することで意図が明確になります。インストール後は、再現性を確保するために package-lock.json に正確なバージョンが固定されます。
画像出力: createImageOutput が想定するのは、画像データそのものではなく HTTPS URL です。@adobe/aio-lib-files(init()、write()、generatePresignURL())を使ってアップロードしてください — SDK の README.md にあるサムネイルの例を参照してください。
1 つのアプリに複数のカスタムアクションを含める
各 FFCPE ノードには、独自の web + worker ペアと、同じ場所に配置する <action-name>.entry.json が必要です。すべてのペアを 1 つの runtimeManifest パッケージの下に宣言してください(組織の方針に応じて、複数のパッケージに分割してもかまいません)。ノードが 2 つある場合の例:
runtimeManifest:
packages:
my-ffcpe-app:
actions:
generate-foo-web: { function: actions/generate-foo/generate-foo.web.ts, web: "raw", … }
generate-foo-worker: { function: actions/generate-foo/generate-foo.worker.ts, … }
decode-foo-web: { function: actions/decode-foo/decode-foo.web.ts, web: "raw", … }
decode-foo-worker: { function: actions/decode-foo/decode-foo.worker.ts, … }
各 .web.ts では mountFfcpeNodeRoutes を呼び出し、YAML のアクションキーに一致する独自の worker.name/web.name を指定します。
既存の App Builder リポジトリにアクションを追加する
1. 同じ場所にファイルを配置する(推奨)
各カスタムアクションでは、web、worker、カタログエントリー JSONを同じディレクトリに配置し、同じ**<action-name>**プレフィックスを付けます。
<action-name>.web.tsまたは.js— Hono の送信/ステータス用 web アクション<action-name>.worker.tsまたは.js— 非同期 worker<action-name>.entry.json— run-workflow のカタログエントリー(aio ffcpe catalog validate/**register**に渡すものと同じドキュメント)
配置例:
actions/
resize-image/
resize-image.web.ts
resize-image.worker.ts
resize-image.entry.json
.entry.jsonファイルは独立したテンプレート成果物ではなく、カタログ登録ペイロードそのものです(handlerType: "custom-action"、ポート、customActionConfig、ディスカバリーフィールド)。スキル ffcpe-catalog-entry-json を使って作成してください。
同じフォルダーにサブディレクトリを作らずに配置する形でも問題ありません。リポジトリですでに actions/resize-image.web.ts と actions/resize-image.worker.ts を隣り合わせに配置している場合は、カタログファイル resize-image.entry.json もその隣に配置してください。
2. *.config.yaml
runtimeManifest(または同等の設定)を更新します。web アクションには web: "raw" と annotations.require-adobe-auth: false を指定し、worker アクションも宣言してください。function のパスはビルド出力と一致している必要があります。mountFfcpeNodeRoutes の package/name は、この YAML の値と一致させてください。
3. TypeScript + webpack(dist 用の CJS)
インストールします。
npm install -D esbuild-loader
# or
pnpm add -D esbuild-loader
プロジェクトを init-bare で初期化した場合は、webpack-config.js を丸ごと置き換えてください。生成されたファイルは ts-loader を使用し、libraryTarget: "commonjs2" がありません。その他の既存プロジェクトでは、*webpack-config.js に設定をマージしてください(既存のルールは webpack-merge または慎重な Object.assign で保持します)。
output: {
libraryTarget: "commonjs2", // Important for CommonJS output
},
module: {
rules: [
{
// Match `.js`, `.jsx`, `.ts` or `.tsx` files
test: /\.[jt]sx?$/,
loader: "esbuild-loader",
options: {
// JavaScript version to compile to
target: "es2020",
},
},
],
},
resolve: {
extensions: [".ts", ".js"], // Add .ts and .js to the list of extensions to resolve
},
デプロイされた Runtime のバンドルは CommonJS ですが、ソースでは引き続き ESM 形式の TypeScript を使用できます。
カタログに登録する(デプロイ後)
-
web アクションと worker アクションをデプロイします。
aio app build aio app deployデプロイ出力には、次のような web アクションのベース URL が表示されます。
https://3326322-myproject-stage.adobeioruntime.net/api/v1/web/my-ffcpe-app/my-action-web -
ベース URL からカタログエンドポイントを導出します(
mountFfcpeNodeRoutesのデフォルトの Hono ルート)。フィールド パターン submitEndpoint{web-action-base-url}/submitstatusEndpoint{web-action-base-url}/status/api/v1/web/を使用してください(/apis/v1/ではありません)。ホスト名の Runtime 名前空間は小文字です(例:Console のプロジェクト名がdemoQrFfcpeでも、3326322-demoqrffcpe-stageとなります)。 -
<action-name>.entry.jsonを記入します。handlerType: "custom-action"を指定し、worker と一致するポート名、手順 2 のエンドポイント、customActionConfig.authenticationを設定してください。web アクションでmountFfcpeNodeRoutesのデフォルト認証を使用する場合(authenticate: nullがない場合)は、"authentication": { "type": "ims_service_token" }を設定してください。noneではありません。ffcpe-catalog-entry-jsonを参照してください。 -
CLI プラグインをインストールして認証します。
npm install -g @adobe/aio-cli aio plugins:install @adobe/aio-cli-plugin-ffcpe aio login aio console org select -
検証して登録します。生の curl は使用しないでください(パスは同じ場所に配置した
.entry.jsonのものです)。aio console org select # catalog API の呼び出し前に必須 aio ffcpe catalog validate --file ./actions/resize-image/resize-image.entry.json aio ffcpe catalog register --file ./actions/resize-image/resize-image.entry.jsonアクションタイプがすでに存在する場合は、
registerの代わりにaio ffcpe catalog update <actionType> --file …を使用してください。
エージェントのチェックリスト
- 新規プロジェクト:
init-bareを実行 → ワークスペース設定をダウンロード →aio app use <file>.json --overwrite --no-inputを実行 →web-src/、actions/generic/、actions/publish-events/、test/、e2e/を削除します。 - コンソールのプロジェクト名: 英数字で20文字以内にします。
runtimeManifestパッケージ名と異なっていてもかまいません。 app.config.yaml:web: web-srcの行は含めません。FFCPE の web と worker のペアを宣言します(カスタムアクションごとに1ペア)。webpack-config.js:libraryTarget: "commonjs2"、esbuild-loader、.ts/.js拡張子を指定します。init-bareが生成したファイルはマージせず、置き換えてください。- web と worker の名前は、
mountFfcpeNodeRoutesおよび YAML の名前と一致させます。 - Web:
web: "raw"、annotations.require-adobe-auth: falseを指定します。 - Worker:FFCPE のデータは
ctx.inputsから取得し、シークレットにはprocess.envのみを使用します。画像の出力にはaio-lib-filesの署名付き URL を使用します。 - カタログ:
<action-name>.entry.jsonを同じディレクトリに配置し、ポート名を worker のポート名と一致させます。submitEndpoint/statusEndpointには、デプロイ出力の値に/submit//statusを付加したものを設定します。デフォルトのルート認証を使用する場合は、認証にims_service_tokenを指定します。続けてaio ffcpe catalog validateを実行してから、register(またはupdate)を実行します。