0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zoho WidgetとLambdaの連携 第1回:Lambdaの3分割と公開URLの整理

0
Last updated at Posted at 2026-07-15

本シリーズでは、Zoho CRMの商談画面に埋め込むWidgetから、入力確認、PDFプレビューと保存、外部送信APIへの依頼、結果の追跡までを行う構成を扱います。

UIとマスタデータの正はZoho CRMに置き、PDF生成や外部API呼び出し、結果の定期照会はAWS Lambdaに出します。フロントはSvelteのWidgetで、通常の業務APIはZoho関数(Deluge)経由でLambdaへ届けます。

この記事では、その構成でLambdaを入口・副作用・確認用の3つに分ける構成と、各Function URLの公開範囲を記載します。

次回: Zoho WidgetとLambdaの連携 第2回:HMAC署名とDelugeのJSON運搬

Lambdaを1本にまとめると困る理由

処理をZohoだけに閉じると制約が強いです。ブラウザからAWSへ直接呼び出すと、共有鍵がiframe側に露出します。ではAWS側を1関数にまとめるか、という選択になります。

ここで困るのは次です。

  • UI入口と外部送信を同じ関数にすると、送信の一時エラーを画面操作と同じ感覚で自動retryしたくなります
  • 公開HTTPと定期確認を混ぜると、結果確認まで公開攻撃面になります
  • 入力保存と取消しにくい処理を同居させると、デプロイ単位と障害影響範囲が同時に広がります

そのため3関数に分けました。

呼び名 役割 Function URL
入口Lambda Widget配信、入力保存、許可の発行、後段呼び出し あり(公開)
副作用Lambda PDFの生成・保存、外部送信、履歴の状態更新 あり(プレビューGET用)。業務の保存・送信POSTは入口経由
確認用Lambda 結果の定期確認 なし(SchedulerからのIAM Invokeのみ)

入口Lambdaは静的なWidget配信も担当します。画面配信と通常APIが同じ公開エンドポイントになりやすい点に注意してください。

本稿では、取消しにくい外部送信やPDF保存を「副作用」、書き込み責任があるデータの置き場所を「正本」と呼びます。

Function URLと認可NONE

Function URLは、Lambdaに付与する専用のHTTPSエンドポイントです。固有URLが発行され、ブラウザやHTTPクライアントから呼び出せます。認可タイプは主に次の2つです。

  • AWS_IAM: IAMで呼び出し元を制限する
  • NONE: Function URL手前のIAM認証を付けない

NONE は、URLに到達したリクエストを関数が受け付けうる公開寄りの設定です。URL秘匿を防衛手段とはみなしません。入口の通常APIはHMACや短命tokenで認可します。確認用LambdaにはFunction URLを付けず、SchedulerからのIAM Invokeのみにしました。

どのURLが公開されるか

公開HTTP 用途 業務POST
入口のFunction URL あり 通常API、直送、Widget配信 する(HMACまたは直送token)
副作用のFunction URL ありうる プレビューPDFのGETが主 しない(サーバ間HMACは入口から)
確認用 なし Scheduler起動のみ なし

要約すると、入口は公開、副作用URLはプレビューGET用に公開しうる、確認用は公開HTTPなし、です。

CORSとorigin

originはスキーム・ホスト・ポートの組です。ブラウザは、ページのoriginと異なる先への応答読取を、サーバが許可しない限り制限します。その許可仕組みがCORSです。CORSは呼び出し元の本人確認(認証)ではありません。

許可originは、Widgetが動作するexactなHTTPS originのみとし、wildcardは使いません。直送も入口Function URL配下のため、CORS未設定だとiframeからの直送がブラウザ段階で失敗します。詳細は第3回です。

Widgetからの処理の流れ

画面は導入、入力、確認、送信方法の選択、プレビュー、処理中、完了、と進みます。

通常操作と入力保存は、Deluge経由で入口へHMAC付きPOSTします。DelugeはZoho側のサーバスクリプトで、ブラウザに共有鍵を置かない中継です。同等の中継であれば、設計の核は同じです。

プレビューPDFは副作用側URLへGETします。見たPDFの保存は、メタデータをHMAC経路、本体を直送に分けます(第3回)。外部送信は保存済み履歴IDへの要求です(第4回)。最終結果は画面の要求完了表示の外で、確認用Lambdaが履歴を更新します。結果の正本は履歴側です(第5回)。

Widgetは共有鍵も操作者IDの正本も持ちません。DelugeがOrg Variableの鍵でHMACします。共有鍵のもう一端はSecrets Manager(相当)に置き、ブラウザには出しません。

主な構成要素の対応は次のとおりです。

要素 役割
Widget CRMに埋め込むUI。入力・プレビュー・送信操作の起点
Deluge 共有鍵を保持し、外部HTTPへ中継する
入口/副作用/確認用Lambda 上記の3分割
Function URL Lambda用のHTTPSエンドポイント
商談レコード フォーム入力の正本
履歴レコード PDF・送信状態・進行情報の正本

データの正本

データ 正本 入口Lambda 副作用/確認用
原稿・フォーム入力 商談レコード 読取・書込 業務正本としては書かない
PDF・送信状態・進行JSON 履歴レコード 呼び出し・許可(正本書込なし) 読取・書込
画面の一時状態 ブラウザ 触らない 触らない
秘密 Secrets/env 使用 使用

商談は入力データの正本、履歴はPDFと送信進行の正本です。正本が曖昧だと、入口と副作用が同一フィールドを更新し合います。進行管理にDynamoDBを追加する方法もありますが、正本を増やさない方針とし、確認用の進行情報は履歴上のJSONに載せました(第5回)。

商談保存は更新時刻による楽観的ロックで、競合時は上書きしません。履歴更新も競合時は上書きしません(確認用はskip)。楽観的ロックは、読取時点の前提が有効なときだけ更新する方式です。前提が崩れている場合はHTTP 412 Precondition Failedなどで拒否します。

経路ごとの認可

経路 認可
Widget → Deluge → 入口(通常API) HMAC(共有鍵とraw body)
大きいPDFの直送 短命tokenとSHA-256(第3回
プレビューGET 業務POSTではない。短命URL(第3回
入口 → 副作用(サーバ間) HMAC。ブラウザから業務POSTさせない
確認用 SchedulerからのIAM Invokeのみ

AWSではCognitoによる利用者認証や、SigV4(IAM資格情報による署名)も選択肢です。今回はDelugeからそれらを安定実装できない制約が先にあり、採用しませんでした。

WidgetからZoho関数を呼ぶ部分は次の形です。フロント側の責任範囲はここまでです。

ZOHO.CRM.FUNCTIONS.execute(fnName, {
  arguments: JSON.stringify(payload),
});

Lambdaへ届く最終文字列はDelugeが組み立てます。共通ライブラリは通信と形式変換までに限定し、状態遷移や送信clientは含めませんでした。

設計上やらないこと

  • Delugeから実装困難なAWS認証を前提にしない
  • 入口・副作用・定期確認を1関数に混ぜない
  • 進行用の正本をAWS側に増やさない
  • フロント申告の操作者IDを信用しない
  • 巨大PDFをZoho関数に載せない
  • 外部送信の一時エラーを自動retryしない

既知の制限(replay台帳なし、プレビューURL漏洩時の読取リスクなど)は第5回末の一覧にまとめています。

次回は入口のHMACです。署名式ではなく、Deluge経由のJSON文字列化が失敗原因だった件を扱います。

シリーズの記事一覧

  1. 本記事(第1回)
  2. 第2回:HMAC署名とDelugeのJSON運搬
  3. 第3回:PDFプレビューと直送保存の分離
  4. 第4回:外部送信の受付判定と自動retry抑止
  5. 第5回:CRM上の進行管理と結果確認Poller
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?