reCAPTCHA導入済みContact Form 7で送信できない時の対処法<スパムエラー>

Contact Form 7のreCAPTCHA v3を導入してから、とんとメールが届かない時期がありました。
フォームをテストしてみると、オレンジ色の枠で「メッセージの送信に失敗しました。後でまたお試しください。」というメッセージが。

調べて原因候補をひとつひとつ検証してみたところ、自身でテーマに記述したJavaScriptの非同期読み込みが悪さしていたことが分かり、無事修正できました。

今回の記事ではreCAPTCHA v3導入済みContact Form 7で本メッセージの送信エラー対処法について、よく見かける解決策と今回の原因・解決策についてまとめたいと思います。

事象と状況の詳細

Contact Form 7で作成した問い合わせフォームから送信しようとすると、何回やってもオレンジ枠で送信失敗メッセージが表示されてしまいました。
送信が一切できないという訳ではなく、10回前後送信ボタンクリックを繰り返すと送信成功することも。
ちょっと挙動に不安定な部分が見られます。

メッセージの送信に失敗しました。後でまたお試しください。
図は”送信がスパムと見なされた”際のデフォルトメッセージ

重要なのは枠色で、オレンジ色はスパムのサインとのこと。
今回送信失敗したのは全てスパムと見なされていたためのようでした。

オレンジのボーダーラインはスパムのサインです。対スパムモジュールのひとつがフォーム送信に疑わしい動きを検知したことを示しています。

オレンジのボーダーラインのエラーが出るのはなぜですか?

それではreCAPTCHAで弾かれてしまったか?
と思いきや、reCAPTCHAの管理コンソールを見てみると以下の通り。
全くフォームから送信できていないに関わらず不審なリクエストとしてカウントされている数は少なく、不正トラフィックもさほどなさそう。

  • 不審なリクエスト数→全体の5.6%
  • スコア分布→おおよそ0.9


reCAPTCHA管理コンソール画面
スコア分布の範囲は 0.0(不正なトラフィック)~1.0(安全なトラフィック)

こうなるとreCAPTCHAの判定の問題ではなく、フォームの送信処理に何らかのトラブルがあってスパムメッセージがでてしまっている予感がしてきます。

スパムメッセージ表示の解決策

メッセージの内容と枠色から調べたところ、解決方法として以下のような事例や情報が見当たりました。

① reCAPTCHAの再設定をする

最初にreCAPTCHAを設定した時と同様の手順で再設定を行う。

公式設定ガイド

  1. reCAPTCHA管理コンソールから、登録しているサイトを一旦削除(設定ボタンからゴミ箱マーククリック)
  2. 改めてサイトの登録を行い、サイトキー とシークレットキーを取得
  3. WP管理画面>お問い合わせ > インテグレーションでreCAPTCHAの[インテグレーションのセットアップ]→[キーを削除]
  4. 先ほど取得したサイトキーとシークレットキーを改めて設定

② reCAPTCHAの管理を他のプラグインに任せる

Contact Form 7でのreCAPTCHAの情報を削除した上で、「Invisible reCAPTCHA for WordPress」などのプラグインをインストールして管理をそちらで行う。

③ Contact Form 7 とreCAPTCHAのバージョンがあっていない場合アップデート等を行う

例えば以下など

・reCAPTCHAのバージョンがv2の場合、v3を設定する
・Contact Form 7 v5.1 & reCAPTCHA v3 の組み合わせの場合、Contact Form 7を5.1.1 にアップグレードする(”状況が緩和される可能性がある”とのこと)

④ 使用するテーマの各ページのフッター領域で適切にJavaScriptをロードできているか確認し、問題があれば修正する

例えば、テーマでwp_footer() 呼び出しを省略している場合は記述する など

いくつか可能性を潰していき、ふと気になったのが④テーマに関する指摘。
このテーマは数年前に勉強がてら自作したもので、ちょこちょこ機能追加することはあっても制作当初の記述を見返すことはあまり無かったので、記述が不適切な部分がある自覚がありました。
wp_footer()こそあるものの、そのせいで不具合が起きたというのはありそう。

ということでファイル圧縮・結合プラグインを解除しつつ、wp_enqueue_scriptsアクションフックあたりを中心に読み込み周りをひとまず整理してみました。

今回の場合:適切ではないJavaScript非同期読み込みが原因だった

整理して検証したことで、プラグインやreCAPTCHA等からエラーがランダム・不定期にあがっていることが判明。
エラーの内容と発生条件にあまり規則性が見られず、エラーが出ない時も結局送信失敗するような状態です。

// エラーメッセージ例
Uncaught ReferenceError: grecaptcha is not defined

これはJS関係でなにかやらかしてるぞと思い、さらにテーマを漁っていくと以下の記述を発見しました。

以前サイトの表示高速化のために行った施策のひとつ(だったと思う)で、内容はdeferが付与されていないすべてのスクリプトに対してasyncを付与するというもの。

/*JSの非同期読み込み*/
function replace_scripttag($tag, $handle){
    if(!preg_match('/defer/',$tag)){
        return str_replace("type='text/javascript'",'async',$tag);
    }
    return $tag;
}
add_filter('script_loader_tag','replace_scripttag', 10, 2);

こちらをコメントアウトしたところ、無事フォームの送信が成功!

導入当時はこれでも問題なかったと思うんですが、その後改修をしていった環境ではasync強制付与によってスクリプトの依存関係が正しく整理されず、JSエラーが発生してしまったようでした。


送信成功

asyncとdeferの違い

どちらも非同期でブラウザに読み込ませるための属性で、ページの読み込み速度の改善につながることも。実行タイミングや順番の違いがあるため、スクリプトに応じて適切に付与する必要がある。

async:実行タイミングはリソース読み込み直後。実行順が不明なので単独で動くファイル等で使う
defer:実行タイミングはHTML解析終了後。依存関係があるスクリプト同士や、DOM操作を行うスクリプトを非同期読み込みしたい場合に使う

おわりに

自身で(もしくは他の方に依頼して)テーマをカスタマイズしたり様々なプラグインを入れている人は、JSの読み込みに関してテーマで何かいじってないか、またフォームページで何かエラーが発生していないかを確認してみると何か見つかるかもしれません。
他の要因に当てはまらない場合もぜひ一度確認してみてください。

以上、reCAPTCHA導入済みのContact Form 7でスパム判定で送信できない時の対処法についてでした!

下記もスパムエラー関連の記事ですのでよければ併せてご覧ください。