From df0c836573373aa3683916a2a57df8b89204e96d Mon Sep 17 00:00:00 2001 From: Kenichiro NOGI Date: Sat, 5 Sep 2026 18:13:43 +0900 Subject: [PATCH] =?UTF-8?q?fix(healthcheck-survey-bot):=20LINEWORKS=20toke?= =?UTF-8?q?n=E4=BA=A4=E6=8F=9B=E3=81=AEhttpRequest=E3=83=9C=E3=83=87?= =?UTF-8?q?=E3=82=A3=E6=8C=87=E5=AE=9A=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit URLSearchParamsを.toString()した上でjson:trueを併用すると Content-Typeがapplication/jsonに上書きされうる不整合があり、 LINEWORKSアクセストークン取得が失敗する恐れがあったため、 生のURLSearchParamsをbodyに渡しjson:trueと手動Content-Typeを除去。 レスポンスはtypeofで文字列/オブジェクトを判定しJSON.parseする形に変更。 Co-Authored-By: Claude Sonnet 5 --- .../workflows/hc-sub-run-process-and-notify.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NodeSrv/apps/healthcheck-survey-bot/workflows/hc-sub-run-process-and-notify.json b/NodeSrv/apps/healthcheck-survey-bot/workflows/hc-sub-run-process-and-notify.json index ea1a56c0..60898f98 100644 --- a/NodeSrv/apps/healthcheck-survey-bot/workflows/hc-sub-run-process-and-notify.json +++ b/NodeSrv/apps/healthcheck-survey-bot/workflows/hc-sub-run-process-and-notify.json @@ -102,7 +102,7 @@ 300 ], "parameters": { - "jsCode": "const claims = $('JWTクレーム組み立て').item.json;\nconst config = claims.config;\nconst assertion = $json.token;\n\n// LINEWORKS token/message呼び出しはx-www-form-urlencoded / JSONのどちらも\n// this.helpers.httpRequestのbodyに素の値を渡す形は実機未検証のため、\n// URLSearchParamsで明示的にエンコードしてContent-Typeも明示する。\nconst tokenBody = new URLSearchParams({\n assertion,\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n client_id: config.LW_BOT_CLIENT_ID,\n client_secret: config.LW_BOT_CLIENT_SECRET,\n scope: 'bot',\n}).toString();\n\nconst tokenRes = await this.helpers.httpRequest({\n method: 'POST',\n url: 'https://auth.worksmobile.com/oauth2/v2.0/token',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: tokenBody,\n json: true,\n});\nconst accessToken = tokenRes.access_token;\nif (!accessToken) {\n throw new Error('LINEWORKSアクセストークンの取得に失敗しました。');\n}\n\nconst sendRes = await this.helpers.httpRequest({\n method: 'POST',\n url: claims.apiUrl,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json;charset=UTF-8',\n },\n body: { content: claims.messageContent },\n json: true,\n});\n\nreturn [{\n json: {\n resultId: claims.resultId,\n currentStatus: claims.currentStatus,\n options: claims.options,\n targetEmail: claims.targetEmail,\n lineworksResponse: sendRes,\n },\n}];" + "jsCode": "const claims = $('JWTクレーム組み立て').item.json;\nconst config = claims.config;\nconst assertion = $json.token;\n\n// LINEWORKS tokenエンドポイントはx-www-form-urlencodedのみ受け付ける。\n// this.helpers.httpRequestはbodyにURLSearchParamsインスタンスを渡すと\n// application/x-www-form-urlencodedへの変換とContent-Type設定を自動で\n// 行うため、素のURLSearchParamsを渡す(.toString()しない、ヘッダーも手動指定しない)。\n// jsonオプションは指定しないため、レスポンスは自前でJSON.parseする。\nconst tokenBody = new URLSearchParams({\n assertion,\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n client_id: config.LW_BOT_CLIENT_ID,\n client_secret: config.LW_BOT_CLIENT_SECRET,\n scope: 'bot',\n});\n\nconst tokenRes = await this.helpers.httpRequest({\n method: 'POST',\n url: 'https://auth.worksmobile.com/oauth2/v2.0/token',\n body: tokenBody,\n});\nconst tokenJson = typeof tokenRes === 'string' ? JSON.parse(tokenRes) : tokenRes;\nconst accessToken = tokenJson.access_token;\nif (!accessToken) {\n throw new Error('LINEWORKSアクセストークンの取得に失敗しました。');\n}\n\nconst sendRes = await this.helpers.httpRequest({\n method: 'POST',\n url: claims.apiUrl,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json;charset=UTF-8',\n },\n body: { content: claims.messageContent },\n json: true,\n});\n\nreturn [{\n json: {\n resultId: claims.resultId,\n currentStatus: claims.currentStatus,\n options: claims.options,\n targetEmail: claims.targetEmail,\n lineworksResponse: sendRes,\n },\n}];" } }, {