システム開発
10
更新

問い合わせフォームをCloudflare Workersで実装する:Turnstile・Resend連携

執筆・編集Malake株式会社
まず押さえたいこと

Cloudflare Workersとは、世界中のエッジサーバーでJavaScriptを実行できるサーバーレス環境です。Pages(フロントエンド)と組み合わせることで、サーバーを常時稼働させずに動的機能(フォーム、認証、API)を実装できます。

この記事の要点

静的サイトのフォームは、ブラウザからメールAPIを直接呼ばず、Workersなどのサーバー側処理で入力検証、スパム判定、送信、記録を行います。Turnstileは対策の一つであり、レート制限、失敗時の通知、ログの保存期間も合わせて設計します。採用するサービスの料金と上限は導入時に確認します。

この記事でわかること

  • なぜ Pages だけでは“問い合わせフォーム”が難所なのか
  • この記事の前提:Workersで実装する
  • アーキテクチャ(Bot排除とメール送信)
  • 実装手順(番号付きガイド)
  • 運用設計(脅威モデルと対策)
  • Vercel と比較(開発者目線)
  • 発展:WAF / CDN / Zero Trust への布石
  • まとめ
  • よくある質問 (FAQ)
  • 参考リンク / 出典

なぜ Pages だけでは“問い合わせフォーム”が難所なのか

Cloudflare Pagesのような「静的サイトホスティング」は、サーバーが存在しないため、「メールを送る」「データベースに保存する」といった処理が単体ではできません。

安易に外部からのJavaScriptだけで処理しようとすると、APIキーが漏洩し、スパムの踏み台にされるリスクがあります。そこで、「フォームの裏側で動く極小のサーバー」が必要になります。

Note: 本記事は実装・運用にフォーカスした技術解説です。Cloudflare Pagesの基本的な構築手順や、Vercelとの料金比較(経営者・Web担当者視点)については、こちらの導入ガイドをご覧ください。

▼ フォーム実装の3つの選択肢

方式 A. 外部SaaS埋込 B. Pages Functions C. Workers (推奨)
概要 Google Forms等をiframeで貼る。 Pagesのリポジトリ内にAPIを書く。 独立したAPIサーバーとして立てる。
メリット 実装ゼロ。 フロントエンドと同じGit管理。 再利用性・拡張性に優れる。
デメリット デザインが崩れる。ドメインが異なる。 デプロイがPagesと連動するため遅い。 別途リポジトリ管理が必要(最初は手間)。
中小企業HPへ × (非推奨) △ (簡易用途なら可) ◎ (推奨構成)

「B: Pages Functions」も悪くありませんが、将来的に「スマホアプリからも送りたい」「他のサイトでも使いたい」となった時、独立した「C: Workers」の方が柔軟性が高いため、本記事ではCを推奨します。

この記事の前提:Workersで実装する

本記事は、フォームの受信処理をCloudflare Workersで実装する前提で手順を示します。Pages Functionsでも同等の処理は書けますが、Secretsをコマンドラインで管理でき、フロントエンドと切り離してデプロイできる点からWorkersを選んでいます。

PagesとWorkersの一般的な使い分け、どちらを選ぶかの判断基準はCloudflare PagesとWorkersの違い:構成を選ぶための判断表で扱っています。Workers側の認証・キャッシュ・運用設計はCloudflare Workersの実装設計を参照してください。

アーキテクチャ(Bot排除とメール送信)

今回構築するシステムの全体像です。

クライアントからは直接メールを送らず、Workerを経由させます。ここで「Turnstileの認証トークン」をチェックすることで、ボットによる大量送信を水際で遮断します。

Loading Diagram...

実装手順(番号付きガイド)

実運用に耐えうる構成での実装ステップです。以下の手順で構築を進めます。

自社の状況を確認する

  • □ TurnstileのSecret KeyとResendのAPI Keyを取り違えていないか
  • □ Workerのデプロイ後、環境変数が反映されているか(反映に数十秒かかる場合あり)
  • □ CORS設定で、自分のサイト(Origin)のみを許可しているか

Cloudflare Turnstile の発行

Cloudflareダッシュボード > Turnstile > [サイトを追加]。
ドメイン名を入力し、ウィジェットモードは「Managed(推奨)」を選択。
「Site Key(公開)」と「Secret Key(非公開)」の2つを取得します。

Resend のAPI Key発行とドメイン設定

Resendでアカウント作成し、API Keyを取得。
[Domains] 設定で自社ドメインを追加し、表示されるDNSレコード(DKIM / SPF)をCloudflareのDNSに追加します。
※これをやらないと、送信したメールがGmail等でスパム扱いされます。必須です。

Workerプロジェクトの作成

ターミナルで `npm create cloudflare@latest contact-api` を実行。
テンプレートは「Hello World」等の最小構成を選択します。

Secrets(環境変数)の設定

コードに直接キーを書いてはいけません。wranglerコマンドで暗号化して保存します。
実行: `npx wrangler secret put TURNSTILE_SECRET_KEY`
実行: `npx wrangler secret put RESEND_API_KEY`

Workerコードの実装(バリデーションと送信)

以下の順序で処理を実装します。1つでも失敗したら即エラーを返します。
1. CORSヘッダーの処理(OPTIONSリクエストへの応答)
2. リクエストボディからのデータ取り出し
3. Turnstile認証APIへの問い合わせ(トークン検証)
4. 入力値のバリデーション(空文字チェック、文字数制限)
5. Resend APIへのPOST送信
6. 成功レスポンスの返却

クライアント側(Pages)の実装

`react-turnstile` 等のライブラリを使い、フォーム送信時にトークンを取得。
取得したトークンをWorkerへのPOSTボディに含めて送信します。

デプロイと動作確認

`npx wrangler deploy` で公開。
実際のフォームから送信し、Resendのログと自分のメールボックス両方で受信を確認します。
← 横にスクロールできます →

運用設計(脅威モデルと対策)

「動けばいい」で作ったフォームは、攻撃者の格好の標的になります。最低限考慮すべき脅威と対策をまとめました。

脅威 (Threat) 具体的な攻撃内容 実装すべき対策
Botスパム 問い合わせフォームから広告や詐欺URLを大量に送りつける。 Turnstile (必須)
Honeypot (隠しフィールド)
DoS攻撃 APIを過剰に叩き、Resendの送信上限を枯渇させる。 Rate Limiting (Cloudflare WAF)
IP制限
なりすまし 自社ドメインを騙ってウイルスメールを撒く。 DKIM / SPF / DMARC設定。
ResendでVerify済みドメインのみ使用。
キー漏洩 GitHubにAPI Keyをコミットしてしまい、悪用される。 Secrets管理 (環境変数)。
コード内ベタ書き厳禁。

特に「Botスパム」は公開後すぐに来ます。Turnstileを入れておけば、ユーザーに「自転車のタイルを選んでください」といった面倒なパズルを強いることなく、ブラウザ検証と振る舞い分析でボット判定が行われます。

Vercel と比較(開発者目線)

同種の構成はVercelでも実装できます。選択に影響する違いは、実行環境と課金軸の2点です。

項目 Vercel Functions Cloudflare Workers
実行環境 Node.jsランタイム V8 Isolate(ブラウザ互換のランタイム)
起動特性 コールドスタートが発生する構成がある コールドスタートが極めて短い
課金軸 CPU時間とメモリ量に基づく従量課金 リクエスト数とCPU時間
Node.js互換 高い 一部互換(特定APIは動かない)

メール送信のような軽い処理には、Workersの短い起動時間が適しています。一方で、重い画像処理やNode.js固有のライブラリに依存する場合はVercelが扱いやすくなります。無料枠と課金条件は変更されるため、金額での比較は各社の料金ページで最新の条件を確認してください。

発展:WAF / CDN / Zero Trust への布石

本構成の真の価値は、フォームを作った後にあります。Cloudflareのエコシステムに乗っているため、以下のようなセキュリティ強化が「管理画面の設定だけ」で可能になります。

  • WAF (Web Application Firewall):特定の国やIPからのアクセスをブロック。
  • Rate Limiting:「1分間に10回以上送信してきたら1時間ブロック」等のルール設定。
  • Zero Trust:社内管理画面を追加で作る際、VPNなしで安全にアクセス制御。

「まずはフォームから」始めた場合でも、WAFやZero Trustなどのセキュリティ基盤へ段階的に拡張できる点がCloudflareの特徴です。

まとめ

「静的サイトだからフォームは諦める(またはGoogleフォームで妥協する)」必要はありません。Cloudflare Workersを使えば、セキュアで高速、かつ運用費の安いフォームが作れます。

自社の状況を確認する

  • □ Turnstileサイトキー/シークレットキーを発行・保全した
  • □ Resendでドメイン認証 (DNS設定) を完了させた
  • □ Workerの環境変数にSecretを設定した
  • □ Cloudflare WAFで異常なレート制限がかかっていないか確認した

よくある質問 (FAQ)

よくある質問

Q. TurnstileはreCAPTCHAと何が違うのですか?

最大の違いは「ユーザー体験」です。reCAPTCHAのような画像選択パズルがほとんど発生せず、ブラウザの挙動から人間かどうかを自動判定します。また、プライバシー重視でトラッキングを行わない点も企業のコンプライアンス的に有利です。

Q. 無料プランでどこまで耐えられますか?

無料枠の上限はサービスごとに異なり、変更される場合があります。通常時とキャンペーン時の送信数を見積もり、Workersとメール配信サービス双方の最新料金、レート制限、超過時の挙動を確認してください。

Q. ResendのFromアドレスはGmailでもいいですか?

いいえ、推奨されません。Gmail等をFromにすると、DMARCポリシーにより受信拒否される確率が高いです。独自ドメイン(例: [email protected])の設定が必要です。

Q. Pages FunctionsとWorkers、結局どっちが良い?

「そのサイト専用の簡易API」ならFunctionsの方が管理が楽です。「複数のサイトから使い回したい」「細かく監視ログを見たい」ならWorkersです。本番運用ではWorkersをおすすめします。

Q. 将来的にWAFを入れるタイミングは?

「スパムが目視で確認できるほど増えた時」または「特定の国からの攻撃ログが見えた時」で構いません。Cloudflareなら後からいつでもオンにできます。

参考リンク / 出典

押さえておきたい点

サーバーレスフォームの主なメリットは、サーバー保守が不要になること(コードと依存関係の保守は残る)とスケーラビリティです。Cloudflare TurnstileとResendの組み合わせによる自動化基盤へ移行すると、スパム対応に割く時間を減らし、本業に集中しやすくなります。

業務に合わせて、使い続けられるシステムを。

要件整理、試作、実装、受入、公開後の運用まで進めます。

システム・アプリ開発について