Gravity Formsは、本格的なWordPressサイトの主力フォームプラグインです。複数ページの申込フォーム、会員登録フロー、見積依頼など、あらゆる用途に使われています。しかし、どのフォームにあるメールアドレス欄も、確認するのは形式だけです。Gravity Formsのメールアドレスを検証するために、専用のプラグインをインストールする必要はありません。送信処理にフックし、検証APIを呼び出して、不正なアドレスをその場で拒否するか、後からタグを付けます。このガイドでは、サポートされている3つの方法を取り上げます。1つ目は、エントリーが保存される前に、配信不能なアドレスと使い捨てアドレスをブロックするPHPのバリデーションフィルターです。2つ目は、非同期でタグ付けと除外を行うWebhooks Add-Onです。3つ目は、エントリーテーブルを一括でクリーニングするCSVエクスポートです。
結論:2つの連携ポイントと一括処理#
Gravity Formsには2つの連携ポイントがあります。不正なアドレスを止めたいのか、検知して対応するだけでよいのかによって、使い分けます。
- リアルタイム(インライン):
gform_field_validationフィルターに小さなPHPスニペットを追加します。フォームの検証中にQualisend APIを呼び出し、訪問者に表示されるフィールドエラーを返します。アドレスがエントリーになる前に拒否できるのは、この方法だけです。 - リアルタイム(非同期):Webhooks Add-Onが、保存後の各エントリーを、自分で管理しているURLにPOSTします。インラインのエラーは表示できませんが、配信不能なアドレスがメール配信ツールに届く前に、タグ付け、振り分け、除外を行うのに最適です。
- 一括:保存済みのエントリーをCSVにエクスポートし、Qualisendの一括検証にかけます。定期的に実行できます。コードは不要で、エントリーを保存するライセンスであれば使えます。
この記事は、Contact Form 7とWPFormsを同じパターンで扱う、より広い内容のWordPressフォームのメールアドレス検証ガイドの、Gravity Forms向けの補足です。複数のフォームプラグインを使っている場合はそちらから読み始めてください。Gravity Formsだけを使っているなら、必要な情報はすべて以下にあります。
Gravity Formsのメールアドレス欄だけでは足りない理由#
emailフィールドタイプが検証するのは、入力された内容がアドレスの形をしているかどうかです。@とドメインがあり、余分なスペースがないことを確認します。これは形式のチェックであり、形式は到達性を保証しません。jane@gmial.comは通過します。throwaway@mailinator.comも通過します。6か月前に失効したドメインにある、一見本物らしいメールボックスも通過します。これらは、送信するまで見つかりません。送信した時点では、存在しないアドレスはハードバウンスとなり、バウンス率と送信者レピュテーションを少しずつ損ないます。
本格的な検証では、Gravity Formsにはないレイヤーが加わります。DNS/MXのルックアップ、SMTPによるメールボックスの確認、使い捨て、役割アドレス、フリーメール、キャッチオールの各フラグです。この仕組みに慣れていない場合は、メールアドレス検証の仕組みで、各チェックの内容とその重要性を確認できます。
送信時にGravity Formsのメールアドレスを検証する#
Gravity Formsには、フィールド単位のバリデーションフィルターがあります。このフィルターは、エントリーが保存される前の検証中に実行されます。つまり、メールアドレス欄を無効にして、訪問者に修正を促すエラーメッセージを表示できます。それがgform_field_validationフィルターです。事後のクリーニングではなく、その場で止めたい場合に適したフックです。
コールバックは、フィールドの現在の$result(is_validフラグとmessageを含む)、送信された$value、$form、$fieldを受け取ります。APIを呼び出し、判定が好ましくなければ、is_validをfalseに切り替えてメッセージを設定します。APIキーはwp-config.phpの定数に保存してください。フォームの設定、テーマファイル、フロントエンドのJavaScriptには、決して書かないでください。
// In a code-snippet plugin, or your theme's functions.php.
// In wp-config.php: define( 'QUALISEND_API_KEY', 'YOUR_API_KEY' );
add_filter( 'gform_field_validation', 'qs_gf_verify_email', 10, 4 );
function qs_gf_verify_email( $result, $value, $form, $field ) {
// Only run on email fields that already passed Gravity Forms' own checks.
if ( $field->type !== 'email' || ! $result['is_valid'] ) {
return $result;
}
// An email field with "confirm" enabled hands back an array.
$email = is_array( $value ) ? rgar( $value, 0 ) : $value;
$email = trim( (string) $email );
if ( $email === '' ) {
return $result; // let the field's own required-field check handle empties
}
// Confirm the exact endpoint and request body in /developers.
$response = wp_remote_post( 'https://app.qualisend.com/api/v1/verify', array(
'timeout' => 4, // cap it so a slow probe can't stall the form
'headers' => array(
'Authorization' => 'Bearer ' . QUALISEND_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array( 'email' => $email ) ),
) );
// Fail open: a transient error must never block a real applicant.
if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
return $result;
}
$verdict = json_decode( wp_remote_retrieve_body( $response ), true )['result'] ?? array();
if ( ( $verdict['status'] ?? '' ) === 'undeliverable' ) {
$result['is_valid'] = false;
$result['message'] = "That address doesn't look deliverable — please check it.";
} elseif ( ! empty( $verdict['sub_flags']['disposable'] ) ) {
$result['is_valid'] = false;
$result['message'] = 'Please use a permanent email address.';
}
return $result;
}
このスニペットの要点は3つあり、どの言語でも共通です。キーはサーバー側に置くこと、リクエストに短いタイムアウトを設定すること、そしてフェイルオープンにすることです。呼び出しがエラーになった場合、タイムアウトした場合、200以外が返った場合は、送信をそのまま通します。検証APIは品質を保つためのフィルターであり、認証のゲートではありません。一時的な障害で本物のリードを失うほうが、より大きな損失です。リクエストの仕組み(ヘッダー、エラー処理、resultのレスポンス構造)については、PHPでのメールアドレス検証ガイドで、同じ呼び出しを最初から最後まで説明しています。
適用範囲についての補足です。上のようにフィルターをグローバルにすると、すべてのフォームでメールアドレス欄が検証されます。特定の1つのフォームだけを対象にするには、フォームとフィールドを指定するgform_field_validation_{form_id}_{field_id}を使うか、冒頭にif ( $form['id'] !== 5 ) return $result;というガードを追加します。複数のフィールドにまたがって検証する場合、たとえば別のフィールドが設定されているときだけ検証する場合は、フォーム単位のgform_validationフィルターを使います。$form全体を受け取り、個々のフィールドを失敗としてマークできます。メールアドレス1つだけのゲートであれば、上のフィールドフィルターのほうがシンプルで十分です。
判定結果への対応#
APIはresultオブジェクトを返します。statusはdeliverable、risky、undeliverable、unknownのいずれかで、0~100のscore、reasonコード、disposable、role、free_mail、catch_allのサブフラグが含まれます。スニペットが読み取る$verdictと同じものです。それぞれに、次のようなフォームの動作を割り当てます。
| 判定 | フォームの動作 |
|---|---|
undeliverable | インラインで拒否します(バリデーションフィルター)。または送信前に除外します(webhook)。 |
disposableフラグ | フォームの厳しさに応じて、拒否またはフラグ付けをします。詳しくは役割アドレス、使い捨て、フリーメールをご覧ください。 |
risky / キャッチオール | 受け付けますが、タグを付けます。キャッチオールのセグメントに振り分け、慎重に送信します。 |
unknown | 受け付けます。メールサーバーが応答しなかっただけなので、これを理由に本物の送信を失わないようにします。 |
deliverable | 受け付けます。 |
本番のフォームでは、構文、ドメイン、使い捨て、役割アドレスといった高速なローカルチェックを中心にしてください。すぐに結果が返るため、訪問者を待たせることなく、不要なデータの大部分を排除できます。負荷の大きいSMTPによるメールボックスの確認は、後述の一括検証に向いています。そこでは数秒の遅延は誰にも影響しません。
Webhooks Add-Onを使う方法#
カスタムPHPが使えない場合や、フォームをブロックするのではなく、存在しないアドレスを下流のツールに入れないことだけが目的の場合は、Gravity FormsのWebhooks Add-Onでコードなしに実現できます。これは有料のアドオンです(上位のGravity Formsライセンスに含まれるため、プランを確認してください)。送信のたびに、設定したHTTPリクエストをフィードとして実行します。
フォームの Settings → Webhooks でフィードを追加します。リクエストタイプをPOST、形式をJSONに設定し、管理しているエンドポイントをURLに指定して、メールアドレス欄をリクエストボディにマッピングします。webhook自体のヘッダーにAPIキーを置いて、第三者からQualisendを呼び出すのは安全ではありません。そのため、Webhookの宛先は、自前の小さなサーバーレス関数にするのが確実な方法です。具体的な設定は、サインアップ時に検証するサーバーレスガイドのとおりです。この関数がキーを保持し、Gravity Formsのペイロードを受け取り、メールアドレスを取り出してAPIを呼び出し、判定に応じて処理します。
注意点はタイミングです。Webhooks Add-Onは、エントリーがすでに保存された後に実行されます。そのため非同期で動作し、訪問者に検証エラーを表示できません。この方法では、インラインでの拒否はできないということです。一方で、数秒以内に検証して、結果に応じた処理はできます。CRMにタグを追加する、配信不能なアドレスにはオートレスポンダーを送らない、メール配信プラットフォームに届く前に除外する、といった処理です。訪問者に不正なアドレスを確認して修正してもらいたい場合は、上のバリデーションフィルターを使います。下流のデータ品質だけが目的であれば、webhookで十分です。
Gravity FormsのCSVエクスポートを一括検証する#
すべてのフォームにリアルタイムのゲートが必要なわけではありません。ゲートを追加する前に集めた過去のエントリーも残っています。どちらの場合も、コード不要の方法は、まとめてクリーニングすることです。
- エントリーをCSVにエクスポートします。 Gravity Formsの管理画面で Forms → Import/Export → Export Entries を開き、フォームを選び、メールアドレスの列を含めてファイルをダウンロードします。エントリー1件につき1行で、アドレスは専用の列に入ります。
- CSVを一括検証します。 Qualisendの一括検証にアップロードします。全行に対して、MX、SMTPによる確認、使い捨て、役割アドレス、キャッチオールの各フラグを含む全工程を実行します。結果は、アドレスごとに
statusとreasonが付いたスコア付きのファイルとして返されます。 - 絞り込んで同期します。
deliverableを残し、riskyを確認し、undeliverableを除外してから、残ったアドレスをメール配信プラットフォームにインポートします。
これは、一般的なリストのクリーニングと同じ、エクスポート、検証、再インポートの流れです。元データがGravity Formsのエントリーテーブルであるだけです。詳しくは、メールリストをクリーニングするガイドで説明しています。過去のデータを1回処理し、それ以降は送信時のフックでリストをクリーンに保ちます。
リアルタイム、一括、それとも両方#
この2つは別々の問題を解決するため、多くのサイトでは両方が必要になります。
- リアルタイムは予防です。 送信時に入力ミスが見つかれば、1行の修正でリードを救えます。そこで拒否された存在しないドメインは、ハードバウンスになりません。
- 一括は後始末です。 転職やドメインの失効などで、アドレスは時間とともに無効になっていきます。そのため、送信時の検証を完璧に行っているリストでも、定期的な再検証が必要です。
利用できるリアルタイムの方法は、ライセンスとコードへの慣れで決まります。バリデーションフィルターはPHPのスニペットが必要ですが、インラインでブロックできます。Webhooks Add-Onは有料プランが必要ですが、コードは不要で、非同期のタグ付けに対応します。どちらを選んでも、時々一括検証を組み合わせることが、戦略のすべてです。
よくある質問
01Gravity Formsだけでメールアドレスを検証できますか?
検証できるのは形式だけです。emailフィールドタイプが確認するのは、@とドメインがあるという、アドレスとして整った形かどうかだけです。MXレコードの解決やメールボックスの確認は行わないため、入力ミス、使い捨て、すでに存在しないアドレスでも、一見有効に見えれば通過します。実際の検証には、Qualisendのようなサービスが追加するDNSとSMTPのレイヤーが必要で、バリデーションフィルター、webhook、CSVの一括検証から呼び出します。
02Gravity Formsのwebhookで、不正なアドレスをその場で拒否できますか?
いいえ。Webhooks Add-Onは、エントリーが保存された後に実行されるため、非同期で動作し、訪問者に検証エラーを表示できません。配信不能なアドレスがメール配信ツールに届く前に、タグ付け、振り分け、除外を行うのに最適です。訪問者に見えて修正できるインラインの拒否が必要な場合は、このガイドのPHPスニペットを使ったgform_field_validationフィルターを使ってください。
03送信時に検証するには、どのGravity Formsのフックを使えばよいですか?
メールアドレス欄が1つならgform_field_validationを使います。検証中に実行され、フィールドの値を受け取り、インラインでエラーを返せます。複数のフィールドにまたがって検証したい場合や、フォーム全体を条件にチェックを実行したい場合は、フォーム単位のgform_validationフィルターを使い、個々のフィールドを失敗としてマークします。どちらもエントリーが保存される前にサーバー側で実行されるため、どちらでもブロックできます。
04Gravity Forms向けのQualisendネイティブアドオンはありますか?
現時点ではありません。ネイティブのプラットフォーム連携は作り直しの最中で、Gravity Formsコネクターは今後の予定に入っています。提供されるまでは、このガイドの3つの方法が、サポートされている手段です。バリデーションフィルターからREST APIを呼び出す方法、Webhooks Add-Onの先にあるサーバーレス関数から呼び出す方法、エントリーをCSVにエクスポートして一括検証する方法です。いずれも、ドキュメント化されたAPIを直接使います。
導入の準備はできましたか。無料プランには、すべての方法を試せるクレジットが含まれています。APIリファレンスには、バリデーションフィルターやサーバーレス関数で使う/verifyリクエストの詳細があります。PHPを書き始める前に、無料メールチェッカーで1つのアドレスを試せます。



