From fa0e0f4faf6a573572b100938c246a45c6a2ae2e Mon Sep 17 00:00:00 2001 From: Kenichiro NOGI Date: Sat, 5 Sep 2026 14:59:56 +0900 Subject: [PATCH] =?UTF-8?q?=E8=A8=88=E7=94=BB=E6=9B=B8Task9-12=E3=82=92?= =?UTF-8?q?=E7=A7=98=E5=AF=86=E6=83=85=E5=A0=B1=E3=81=AEworkflow=5Fconfig?= =?UTF-8?q?=5Fvalues=E5=8F=82=E7=85=A7=E6=96=B9=E5=BC=8F=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ユーザー指摘により、n8nワークフロー内の秘密情報(Pleasanter ApiKey、LINEWORKS Client Secret等)をCodeノードに直接ハードコード する設計(旧計画)から、org-master-sync系ワークフローが実際に 使っている方式(既存n8n Data Table「workflow_config_values」 id:bNkadTyDgDepYx2pから各キーをDataTableノードで都度取得し、 式で参照する)へ全面的に修正した。 あわせて健康診断管理用の新規設定値6件をworkflow_config_valuesへ 実際に登録済み: LW_BOT_CLIENT_ID/LW_BOT_CLIENT_SECRET/ LW_BOT_SERVICE_ACCOUNT(LINEWORKS通知送信ワークフローと同じBot 認証情報)、HEALTHCHECK_SITE_ID(508971)、 LINEWORKS_BOT_MASTER_SITE_ID(484184)、HEALTHCHECK_DATA_TABLE_ID (jqMDa2YZTI4f0iQ7)。HEALTHCHECK_WP_API_KEY(WP Webhook認証用に 新規生成)も追加登録済み。LINEWORKS_BOT_SECRET(署名検証用)は 値未確定のためキーの参照方法のみ計画に反映し、値はTask11着手時に 別途登録する。 Co-Authored-By: Claude Sonnet 5 --- ...-09-05-healthcheck-lineworks-survey-n8n.md | 96 ++++++++++++------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/NodeSrv/docs/superpowers/plans/2026-09-05-healthcheck-lineworks-survey-n8n.md b/NodeSrv/docs/superpowers/plans/2026-09-05-healthcheck-lineworks-survey-n8n.md index f12618f9..d160fd95 100644 --- a/NodeSrv/docs/superpowers/plans/2026-09-05-healthcheck-lineworks-survey-n8n.md +++ b/NodeSrv/docs/superpowers/plans/2026-09-05-healthcheck-lineworks-survey-n8n.md @@ -866,18 +866,29 @@ WP・WAの両方から呼ばれる共通ロジック。「(任意)ProcessIdを - Modify: `NodeSrv/apps/healthcheck-survey-bot/README.md` **Interfaces:** -- Consumes: Task 3〜6のロジック(Codeノードへ書き写す)、Task 8のData Table ID +- Consumes: Task 3〜6のロジック(Codeノードへ書き写す)、Task 8のData Table ID、`workflow_config_values`(id `bNkadTyDgDepYx2p`、既存のorg-master-sync用n8n Data Table)に登録済みの設定値 - Produces: n8n上のワークフロー(Execute Workflow Trigger、入力`{resultId: string, processId: string | null}`)。WP・WAはこのワークフローIDを`Execute Workflow`ノードで呼び出す +**秘密情報・設定値の扱い方針(重要):** org-master-sync系ワークフロー(`n8n-guide.md` 6章参照)と同じ方式に統一する。**PleasanterのApiKeyやLINEWORKS Client Secret等をCodeノードに直接ハードコードしない。** 代わりに`workflow_config_values`(Data Table、id `bNkadTyDgDepYx2p`)から`Data Table`ノード(`operation: "get"`、`filters.conditions: [{keyName: "configKey", keyValue: "<キー名>"}]`)で都度取得し、後続ノードで`{{ $('取得ノード名').item.json.configValue }}`のように参照する。`n8n-guide.md` 7-2の「設定値取得は1キー=1回のGetに限定する」原則に従い、キーごとに個別のGetノードを用意する。 + +このワークフローで使うキー(今回追加登録済み): +- `PLEASANTER_BASE_URL_PROD`(既存) +- `PLEASANTER_API_KEY_PROD`(既存) +- `LW_BOT_CLIENT_ID` / `LW_BOT_CLIENT_SECRET` / `LW_BOT_SERVICE_ACCOUNT`(今回追加。値はLINEWORKS通知送信ワークフローが使っているBotと同じ認証情報) +- `HEALTHCHECK_SITE_ID`(=508971)/ `LINEWORKS_BOT_MASTER_SITE_ID`(=484184)/ `HEALTHCHECK_DATA_TABLE_ID`(=`jqMDa2YZTI4f0iQ7`)(今回追加、SiteId自体は秘密ではないがconfig値に揃えて一元管理する) + **ノード構成:** 1. `Execute Workflow Trigger`(入力: `resultId`, `processId`) -2. `IF`: `processId`が存在するか - - true分岐 → `HTTP Request`「Process実行」: `POST {PLEASANTER_BASE_URL}api/items/{{$json.resultId}}/update`、body `{"ApiVersion":1.1,"ApiKey":"","ProcessId": {{$json.processId}}}` +2. `Data Table`ノード「PLEASANTER_BASE_URL取得」(`configKey: "PLEASANTER_BASE_URL_PROD"`) +3. `Data Table`ノード「PLEASANTER_API_KEY取得」(`configKey: "PLEASANTER_API_KEY_PROD"`) +4. `Data Table`ノード「HEALTHCHECK_SITE_ID取得」(`configKey: "HEALTHCHECK_SITE_ID"`) +5. `IF`: `processId`が存在するか + - true分岐 → `HTTP Request`「Process実行」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{{ $('Execute Workflow Trigger').item.json.resultId }}/update`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}","ProcessId": {{ $('Execute Workflow Trigger').item.json.processId }}}` - false分岐 → そのまま次へ(フォールバック再送のケース) -3. `HTTP Request`「レコード取得」: `POST {PLEASANTER_BASE_URL}api/items/{{$('Execute Workflow Trigger').item.json.resultId}}/get`、body `{"ApiVersion":1.1,"ApiKey":"..."}` -4. `HTTP Request`「サイト設定取得」: `POST {PLEASANTER_BASE_URL}api/items/508971/getsite`、body `{"ApiVersion":1.1,"ApiKey":"..."}` -5. `Code`「選択肢組み立て」: Task 4の`fillTemplate`とTask 5の`extractProcessesForStatus`をそのまま貼り付けて使う +6. `HTTP Request`「レコード取得」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{{ $('Execute Workflow Trigger').item.json.resultId }}/get`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}"}` +7. `HTTP Request`「サイト設定取得」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{{ $('HEALTHCHECK_SITE_ID取得').item.json.configValue }}/getsite`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}"}` +8. `Code`「選択肢組み立て」: Task 4の`fillTemplate`とTask 5の`extractProcessesForStatus`をそのまま貼り付けて使う ```javascript // Codeノード「選択肢組み立て」の中身 @@ -929,16 +940,21 @@ return [{ (`ToolTip`のキー名はTask 2の実機調査結果で確定させ、異なる場合はここだけ修正する) -6. `HTTP Request`「対象者メール解決」: `POST {PLEASANTER_BASE_URL}api/users/get`、body `{"ApiVersion":1.1,"ApiKey":"...","View":{"ApiGetMailAddresses":true},"Where":{"UserId":{{$json.classCUserId}}}}` -7. `Code`「JWTクレーム組み立て」: LINEWORKS通知送信ワークフロー(`Yprojk4JTl1vJPkf`)の`Validate & Prepare`ノードと同じパターンでJWTクレームJSON文字列と、選択肢からLINEWORKS `button_template`のactions配列を組み立てる -8. `JWT`ノード(`operation: sign`, `algorithm: RS256`, Credential: 「LINEWORKS Bot Private Key (v4)」) -9. `HTTP Request`「アクセストークン取得」: `POST https://auth.worksmobile.com/oauth2/v2.0/token`(form-urlencoded、`Yprojk4JTl1vJPkf`の`Get Access Token`ノードと同じパラメータ構成) -10. `HTTP Request`「LINEWORKS送信」: `POST https://www.worksapis.com/v1.0/bots/{BOT_ID}/users/{userId}/messages`、`button_template`形式のcontentを送信 -11. `Data Table`ノード「状態更新」: `healthcheck_bot_state`(id: `jqMDa2YZTI4f0iQ7`)へ`resultId`をキーに`upsert`(`currentStatus`, `pendingProcesses`=JSON化したoptions, `awaitInput: "none"`)。`updatedAt`列は存在しない(Task 8参照)ため送信対象に含めない +9. `Data Table`ノード「LW_BOT_CLIENT_ID取得」(`configKey: "LW_BOT_CLIENT_ID"`) +10. `Data Table`ノード「LW_BOT_CLIENT_SECRET取得」(`configKey: "LW_BOT_CLIENT_SECRET"`) +11. `Data Table`ノード「LW_BOT_SERVICE_ACCOUNT取得」(`configKey: "LW_BOT_SERVICE_ACCOUNT"`) +12. `Data Table`ノード「LINEWORKS_BOT_MASTER_SITE_ID取得」(`configKey: "LINEWORKS_BOT_MASTER_SITE_ID"`) +13. `HTTP Request`「Botマスタ取得」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{{ $('LINEWORKS_BOT_MASTER_SITE_ID取得').item.json.configValue }}/getsite`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}"}`(484184からBotId一覧を取得。どのBotを使うかの解決方法はTask 12で個別Process設計時に確定するため、ここでは1件目のBotを暫定使用するか、`Execute Workflow Trigger`の入力に`botId`を追加して呼び出し元から渡す形にするか、実装時に判断する) +14. `HTTP Request`「対象者メール解決」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/users/get`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}","View":{"ApiGetMailAddresses":true},"Where":{"UserId":{{ $('選択肢組み立て').item.json.classCUserId }}}}` +15. `Code`「JWTクレーム組み立て」: LINEWORKS通知送信ワークフロー(`Yprojk4JTl1vJPkf`)の`Validate & Prepare`ノードと同じパターンでJWTクレームJSON文字列を組み立てる。`iss`/`sub`には`{{ $('LW_BOT_CLIENT_ID取得').item.json.configValue }}` / `{{ $('LW_BOT_SERVICE_ACCOUNT取得').item.json.configValue }}`を使う(Codeノードにこれらの値を直接書かない)。あわせて選択肢からLINEWORKS `button_template`のactions配列を組み立てる +16. `JWT`ノード(`operation: sign`, `algorithm: RS256`, Credential: 「LINEWORKS Bot Private Key (v4)」、id `Hw0qlEaGfLPnQWp1`) +17. `HTTP Request`「アクセストークン取得」: `POST https://auth.worksmobile.com/oauth2/v2.0/token`(form-urlencoded、`Yprojk4JTl1vJPkf`の`Get Access Token`ノードと同じパラメータ構成。`client_id`/`client_secret`は`{{ $('LW_BOT_CLIENT_ID取得').item.json.configValue }}` / `{{ $('LW_BOT_CLIENT_SECRET取得').item.json.configValue }}`を参照) +18. `HTTP Request`「LINEWORKS送信」: `POST https://www.worksapis.com/v1.0/bots/{BOT_ID}/users/{userId}/messages`、`button_template`形式のcontentを送信 +19. `Data Table`ノード「状態更新」: `healthcheck_bot_state`(id: `jqMDa2YZTI4f0iQ7`)へ`resultId`をキーに`upsert`(`currentStatus`, `pendingProcesses`=JSON化したoptions, `awaitInput: "none"`)。`updatedAt`列は存在しない(Task 8参照)ため送信対象に含めない - [ ] **Step 1: ワークフローJSON雛形を作成** -`workflows/hc-sub-run-process-and-notify.json`に、上記11ノードの`nodes`配列と`connections`を、Task 7の`n8n-api.js`が期待する`{name, nodes, connections, settings}`形式で書く。各`HTTP Request`ノードの`parameters`は本タスク内の説明文の通りのURL・bodyを設定する(`n8n-nodes-base.httpRequest`, `n8n-nodes-base.code`, `n8n-nodes-base.jwt`, `n8n-nodes-base.executeWorkflowTrigger`, `n8n-nodes-base.if`, `n8n-nodes-base.dataTable`の各ノードタイプを使う)。Pleasanter APIキーは`Pleasanter/config_production.json`の値をそのままCodeノード内の定数として埋め込む(既存の`LINEWORKS通知送信`ワークフローと同じ方式)。 +`workflows/hc-sub-run-process-and-notify.json`に、上記19ノードの`nodes`配列と`connections`を、Task 7の`n8n-api.js`が期待する`{name, nodes, connections, settings}`形式で書く。各`HTTP Request`ノードの`parameters`は本タスク内の説明文の通りのURL・bodyを設定する(`n8n-nodes-base.httpRequest`, `n8n-nodes-base.code`, `n8n-nodes-base.jwt`, `n8n-nodes-base.executeWorkflowTrigger`, `n8n-nodes-base.if`, `n8n-nodes-base.dataTable`の各ノードタイプを使う)。**秘密情報(PleasanterのApiKey、LINEWORKS Client Secret等)はCodeノードやHTTP Requestノードのパラメータに直接値として書かず、必ず対応する`Data Table`取得ノードの式(`{{ $('ノード名').item.json.configValue }}`)で参照する。** - [ ] **Step 2: デプロイ** @@ -978,21 +994,24 @@ git commit -m "feat: HC-SUBワークフロー(プロセス実行+案内送信) - Consumes: Task 9のワークフローID(`Execute Workflow`ノードで参照) - Produces: Webhook `POST https://n8n32.next-hd.net/webhook/healthcheck-status-push`(`X-Api-Key`ヘッダー認証、body `{resultId, processId}`) +**秘密情報の扱い**: Webhook認証キーはCodeノードに直接書かず、`workflow_config_values`(`bNkadTyDgDepYx2p`)の`HEALTHCHECK_WP_API_KEY`キーを`Data Table`ノードで取得して比較する(Task 9と同じ方針)。 + **ノード構成:** 1. `Webhook`(`httpMethod: POST`, `path: healthcheck-status-push`) -2. `Code`「検証」: `X-Api-Key`ヘッダーとbodyの`resultId`/`processId`必須チェック(不正なら`throw new Error(...)`でワークフローを失敗させる) -3. `Execute Workflow`(Task 9のワークフローIDを指定、入力: `resultId`, `processId`) -4. `Respond to Webhook`(`{"result":"ok"}`を返す) +2. `Data Table`ノード「HEALTHCHECK_WP_API_KEY取得」(`configKey: "HEALTHCHECK_WP_API_KEY"`) +3. `Code`「検証」: `X-Api-Key`ヘッダーとbodyの`resultId`/`processId`必須チェック(不正なら`throw new Error(...)`でワークフローを失敗させる) +4. `Execute Workflow`(Task 9のワークフローIDを指定、入力: `resultId`, `processId`) +5. `Respond to Webhook`(`{"result":"ok"}`を返す) - [ ] **Step 1: ワークフローJSONを作成** -`workflows/hc-wp-status-push.json`を作成。Codeノードの中身: +`workflows/hc-wp-status-push.json`を作成。Codeノード「検証」の中身: ```javascript -const API_KEY = ""; +const expectedApiKey = $('HEALTHCHECK_WP_API_KEY取得').item.json.configValue; const headers = $input.first().json.headers || {}; -if (headers["x-api-key"] !== API_KEY) { +if (headers["x-api-key"] !== expectedApiKey) { throw new Error("Unauthorized: invalid API key"); } const body = $input.first().json.body || {}; @@ -1055,7 +1074,8 @@ git commit -m "feat: HC-WPワークフロー(Statusプッシュ通知)を追加" **ノード構成:** 1. `Webhook`(`httpMethod: POST`, `path: healthcheck-lineworks-response`, `options.rawBody: true`) -2. `Code`「署名検証・送信者解決」: Task 6の`verifySignature`を貼り付けて検証。失敗なら`throw`。成功したら`source.userId`(=メールアドレス)と、`content.type`に応じたテキスト/ファイル情報を抽出する +2. `Data Table`ノード「LINEWORKS_BOT_SECRET取得」(`configKey: "LINEWORKS_BOT_SECRET"`。値はLINEWORKS Developer ConsoleでBot Secretを確認後、`workflow_config_values`へ別途登録する。Task 11着手時点で未登録なら先に登録する) +3. `Code`「署名検証・送信者解決」: Task 6の`verifySignature`を貼り付けて検証。失敗なら`throw`。成功したら`source.userId`(=メールアドレス)と、`content.type`に応じたテキスト/ファイル情報を抽出する ```javascript // Codeノード「署名検証・送信者解決」の中身 @@ -1077,7 +1097,7 @@ function verifySignature(rawBody, headerSignature, botSecret) { return safeEqual(headerSig, expected); } -const LINEWORKS_BOT_SECRET = ""; +const LINEWORKS_BOT_SECRET = $('LINEWORKS_BOT_SECRET取得').item.json.configValue; const item = $input.first(); const headers = item.json.headers || {}; @@ -1103,21 +1123,24 @@ return [{ }]; ``` -3. `HTTP Request`「対象レコード検索」: `POST {PLEASANTER_BASE_URL}api/items/508971/get`、body `{"ApiVersion":1.1,"ApiKey":"...","View":{"ColumnFilterHash":{"ClassC":"<メールからPleasanterUserId解決した値>"},"ColumnFilterSearchTypes":{"ClassC":"ExactMatch"}}}` - - 前段として`api/users/get`で`targetEmail`からPleasanterUserIdを引く`HTTP Request`ノードを1つ挟む +4. `Data Table`ノード「PLEASANTER_BASE_URL取得」(`configKey: "PLEASANTER_BASE_URL_PROD"`) +5. `Data Table`ノード「PLEASANTER_API_KEY取得」(`configKey: "PLEASANTER_API_KEY_PROD"`) +6. `Data Table`ノード「HEALTHCHECK_SITE_ID取得」(`configKey: "HEALTHCHECK_SITE_ID"`) +7. `HTTP Request`「対象者UserId解決」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/users/get`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}","View":{"ApiGetMailAddresses":true}}`でtargetEmailからPleasanterUserIdを引く +8. `HTTP Request`「対象レコード検索」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{{ $('HEALTHCHECK_SITE_ID取得').item.json.configValue }}/get`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}","View":{"ColumnFilterHash":{"ClassC":""},"ColumnFilterSearchTypes":{"ClassC":"ExactMatch"}}}` - 取得結果を`Status`昇順以外(`900`/`910`除外)でフィルタし、`UpdatedTime`降順で1件選ぶ`Code`ノードを挟む。0件/複数件は`throw`でワークフローを失敗させる(6章の異常系方針通り、自動判定しない) -4. `HTTP Request`(`Data Table`ノード, `operation: get`)「待機状態取得」: `healthcheck_bot_state`から`resultId`一致行を取得 -5. `Switch`「awaitInput分岐」: `none` / `date` / `file` の3分岐 - - **none分岐**: `Code`で`pendingProcesses`(JSON文字列)をパースし、Task 5の`matchProcessByLabel`相当のロジックで`text`と一致するか判定 - - 一致 → `Code`でTask 5の`classifyAwaitInput`相当のロジックを実行 - - `awaitInput: "none"` → `Execute Workflow`(Task 9、`processId`=一致したProcessId) - - `awaitInput: "date"` / `"file"` → `Data Table`ノード(`operation: update`)で`awaitInput`/`awaitProcessId`/`awaitColumn`を保存 → `HTTP Request`で「日付を入力してください」等の追加メッセージを送信(Task 9のノード7〜10と同じLINEWORKS送信パターンを再利用) - - 不一致 → `Execute Workflow`(Task 9、`processId: null`)でフォールバック再送 - - **date分岐**: `Code`でTask 3の`parseDateInput`を実行 - - 成功 → `HTTP Request`「該当列update」: `POST api/items/{resultId}/update`、body `{"ApiVersion":1.1,"ApiKey":"...", "DateHash":{"": ""}}` → `Data Table`で`awaitInput`を`none`に戻す → `Execute Workflow`(Task 9、`processId`=`awaitProcessId`) - - 失敗 → エラーメッセージを再送(待機状態は維持、`Data Table`更新なし) - - **file分岐**: `contentType`が`file`でなければ再送要求。`file`なら`HTTP Request`でLINEWORKSファイルダウンロード→`HTTP Request`でPleasanter添付アップロード(具体的なエンドポイントは実装時にPleasanter公式マニュアル`api-attachment`系を確認する)→`Data Table`更新→`Execute Workflow`(Task 9) -6. `Respond to Webhook`(各分岐の末尾で`{"result":"ok"}`を返す) +9. `Data Table`ノード「待機状態取得」(`operation: get`): `healthcheck_bot_state`から`resultId`一致行を取得 +10. `Switch`「awaitInput分岐」: `none` / `date` / `file` の3分岐 + - **none分岐**: `Code`で`pendingProcesses`(JSON文字列)をパースし、Task 5の`matchProcessByLabel`相当のロジックで`text`と一致するか判定 + - 一致 → `Code`でTask 5の`classifyAwaitInput`相当のロジックを実行 + - `awaitInput: "none"` → `Execute Workflow`(Task 9、`processId`=一致したProcessId) + - `awaitInput: "date"` / `"file"` → `Data Table`ノード(`operation: update`)で`awaitInput`/`awaitProcessId`/`awaitColumn`を保存 → `HTTP Request`で「日付を入力してください」等の追加メッセージを送信(Task 9のLINEWORKS送信ノード群と同じパターンを再利用、Data Table取得ノードでconfig値を参照する点も同様) + - 不一致 → `Execute Workflow`(Task 9、`processId: null`)でフォールバック再送 + - **date分岐**: `Code`でTask 3の`parseDateInput`を実行 + - 成功 → `HTTP Request`「該当列update」: `POST {{ $('PLEASANTER_BASE_URL取得').item.json.configValue }}api/items/{resultId}/update`、body `{"ApiVersion":1.1,"ApiKey":"{{ $('PLEASANTER_API_KEY取得').item.json.configValue }}", "DateHash":{"": ""}}` → `Data Table`で`awaitInput`を`none`に戻す → `Execute Workflow`(Task 9、`processId`=`awaitProcessId`) + - 失敗 → エラーメッセージを再送(待機状態は維持、`Data Table`更新なし) + - **file分岐**: `contentType`が`file`でなければ再送要求。`file`なら`HTTP Request`でLINEWORKSファイルダウンロード→`HTTP Request`でPleasanter添付アップロード(具体的なエンドポイントは実装時にPleasanter公式マニュアル`api-attachment`系を確認する)→`Data Table`更新→`Execute Workflow`(Task 9) +11. `Respond to Webhook`(各分岐の末尾で`{"result":"ok"}`を返す) - [ ] **Step 1: ワークフローJSONを作成** @@ -1171,7 +1194,8 @@ git commit -m "feat: HC-WAワークフロー(LINEWORKS応答受信)を追加" ```javascript const WEBHOOK_URL = "https://n8n32.next-hd.net/webhook/healthcheck-status-push"; -const API_KEY = ""; +// n8n Data Table workflow_config_values の HEALTHCHECK_WP_API_KEY と同じ値を使う +const API_KEY = ""; $p.events.on_process = function (processId) { sendStatusPush(processId);