プラグインコンポーネントキャプチャの送信
メソッド
この API は REST の方法論に従います。
HTTP メソッド
POST: プラグインが観測したコンポーネントキャプチャを送信します — component_capture イベントをエンキューし、ワーカーのレジストリマージにルーティングします。
このエンドポイントが存在する理由
POST …/wf2des/components の背後にある REST スイープは、デザインシステムライブラリを読むことができません。リモートコンポーネントはそのインスタンス越しにしか見えないため、スイープは publish key を持たないローカルの双子を断片的なバリアント軸とともに作ってしまいます。そして component_key を持たないレジストリ文書は、プラグインでは一切マテリアライズできません。実プロジェクトでは 279 件のレジストリ文書のうち 106 件がバリアントデータを持たず、そのうち 56 件は軸を宣言しているにもかかわらず、という状態でした。
プラグインは Figma の内部から正規のメインコンポーネントを読めます(getMainComponentAsync は、REST が 403 を返すコンポーネントについてもメインの id・名前・publish key・コンポーネントセット id・バリアント値を返します)。したがってこれらのキャプチャが component_key と variant_properties の 正規のソース です。
ワーカーはこれらを 単調に(monotonically) マージします — より豊富なキャプチャが勝ち、ローカルコンポーネントのスイープ由来フィールド(text_slots / image_slots / default_size)は決して上書きされず、provenance: "plugin-observed" によって後続のスイープがレコードを格下げできないようになります。
命名規則
一貫性と可読性のため、リクエスト / レスポンスの JSON ノードは camelCase、SQS ペイロードのノードは snake_case を使用します。
リクエストとレスポンス
ヘッダー
リクエストヘッダー
AuthorizationContent-TypeAcceptAccept-language
レスポンスヘッダー
Content-Type
コンポーネントキャプチャの送信
URI
パスパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| organization_id | integer | 必須 | 組織 ID |
| project_id | integer | 必須 | プロジェクト ID |
リクエストボディ
リクエストボディは JSON です。
{
"figmaFileKey": "abc123XYZ",
"captures": [
{
"kind": "set",
"nodeId": "10:300",
"setKey": "a1b2c3d4e5f6",
"componentName": "Button",
"componentKeys": ["k1", "k2"],
"axes": { "Size": ["S", "M"], "State": ["default", "disabled"] },
"defaults": { "Size": "M", "State": "default" },
"textProps": ["Label#1:0"],
"variants": [
{
"variantProps": { "Size": "M", "State": "default" },
"size": { "w": 120, "h": 40 },
"textSlots": [{ "layerPath": "Label", "defaultText": "Button" }],
"nestedComponents": ["Icon"],
"appearance": ["fill: #FF6214", "radius: 8"],
"layoutShape": { "units": 2, "columns": 2, "rows": 1 }
}
],
"setName": "Button",
"provenance": "plugin-observed"
}
]
}
リクエストパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| figmaFileKey | string | 必須 | キャプチャ対象コンポーネントが存在するファイル。Figma 逐語。 |
| captures | object[] | 必須 | プラグインの scanSelection() 出力 — 観測した COMPONENT_SET / COMPONENT ごとに 1 件、1 件以上。 |
キャプチャオブジェクト
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| kind | string (enum) | 必須 | set = COMPONENT_SET(バリアント軸は axes)、standalone = 単体 COMPONENT。 |
| nodeId | string | 必須 | COMPONENT_SET(または単体 COMPONENT)のノード ID。 |
| setKey | string | null | 必須 | COMPONENT_SET の publish key。単体または未公開の場合は null。 |
| componentName | string | 必須 | Figma が報告するセット(またはコンポーネント)名。 |
| componentKeys | string[] | 必須 | セット内コンポーネント(または単一コンポーネント)の publish key。 |
| axes | object (string→string[]) | 必須 | バリアント軸名 → 取りうる選択肢。正規(authoritative) — スイープの断片を置き換える。 |
| defaults | object (string→string) | 必須 | バリアント軸名 → デフォルト値。 |
| textProps | string[] | 必須 | バリアント以外の BOOLEAN / TEXT / INSTANCE_SWAP コンポーネントプロパティ名。 |
| variants | object[] | 任意 | バリアントごとの記述。デフォルトは []。部分的である場合がある — 到達可能ならセット全体、そうでなければ観測できたバリアントのみ。 |
| setName | string | null | 任意 | 到達可能な場合の COMPONENT_SET の実名。デフォルトは null。スイープはリモート文書を「見えたインスタンス」の名前で命名するため、実コンポーネント名をレジストリに保持できるのはこのフィールドによる。 |
| provenance | string (literal) | 必須 | 常に plugin-observed。Figma 内部から読まれたことを示し、後続スイープによる格下げを防ぐ。 |
バリアントオブジェクト
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| variantProps | object (string→string) | 必須 | このバリアント自身の軸値。バリアント COMPONENT の名前からパースされる。 |
| size | { w, h } |
必須 | このバリアント自身のバウンディングサイズ。 |
| textSlots | object[] | 必須 | { layerPath, defaultText } — このバリアントの テキストレイヤー。セット内のバリアントは異なるレイヤーを持つ。 |
| nestedComponents | string[] | 必須 | このバリアントが含むインスタンスレイヤー名(各インスタンスで走査は停止)。 |
| appearance | string[] | 任意 | このバリアントの見た目を、自ノードから読んだ事実として列挙 — 塗り、境界線(プレースホルダを慣習的に示す破線を含む)、角丸、そもそも内容を持つか否か。デフォルトは []。 |
| layoutShape | { units, columns, rows } | null |
任意 | このバリアントがセルを並べるグリッド。規則的なタイリングでない場合は null。他のすべてが同一のバリアントを識別できる唯一のフィールド — 同じ 6 セルを一方は 2 列、他方は 3 列で並べるコンテナなど。 |
レスポンス
レスポンスは JSON です(HTTP ステータス: 202 Accepted)。
{
"eventRunId": "0190f3a1-2c4e-7b8d-9e0f-1a2b3c4d5e72",
"figmaFileKey": "abc123XYZ",
"captureCount": 1
}
レスポンスフィールド
| 名前 | 型 | 説明 |
|---|---|---|
| eventRunId | string | GET …/wf2des/events/{eventRunId}/status をポーリングして進行状況を取得する。 |
| figmaFileKey | string | リクエストのエコー。 |
| captureCount | integer | ワーカーへ転送されたキャプチャ件数。 |
認証
認証は Amazon Cognito が発行する JSON Web Token(JWT)で行われます。加えて、呼び出し元はプロジェクトへの Write 権限を保持している必要があります。
エラーハンドリング
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
不正なボディ(captures が空、またはスキーマ不適合のキャプチャ) |
400 | Bad Request |
| 認証情報の欠落 | 401 | Unauthorized |
| 権限不足(プロジェクトへの Write 権限なし) | 403 | Forbidden |
| プロジェクトまたは組織が見つからない | 404 | Not Found |
| SQS 送信の失敗 | 500 | Internal Server Error |
処理フロー
- パスパラメータから組織 ID とプロジェクト ID を、リクエストボディを取得する。
- ユーザーがプロジェクトへの Write 権限を持つことを検証する。
- 新しい
eventRunIdを採番する。 - 各キャプチャを snake_case 化し、
component_captureイベントをwf2des-eventsSQS キューへ送信する。 - ポーリング用ハンドルと転送件数とともに 202 を返す。
非同期処理
component_capture イベントはワーカーのレジストリマージにルーティングされ、各キャプチャを design_component へ upsert します。キャプチャは component_key と variant_properties で 勝ち、ワーカーは軸ごとにマージし、ローカルコンポーネントのスイープ由来スロットデータには触れません。
これは 内部 実行です — ai-status Webhook も PostgreSQL 効果もありません。
SQS ペイロード
フィールド名はワーカーの ComponentCapture / VariantProfile モデルに合わせて snake_case 化されます。
{
"event_type": "component_capture",
"organization_id": 1,
"project_id": 7,
"event_run_id": "0190f3a1-2c4e-7b8d-9e0f-1a2b3c4d5e72",
"figma_file_key": "abc123XYZ",
"captures": [
{
"kind": "set",
"node_id": "10:300",
"set_key": "a1b2c3d4e5f6",
"component_name": "Button",
"component_keys": ["k1", "k2"],
"axes": { "Size": ["S", "M"] },
"defaults": { "Size": "M" },
"text_props": ["Label#1:0"],
"variants": [
{
"variant_props": { "Size": "M" },
"size": { "w": 120, "h": 40 },
"text_slots": [{ "layer_path": "Label", "default_text": "Button" }],
"nested_components": ["Icon"]
}
]
}
]
}