WordPressのContact Form 7はメール送信をするためにはとても便利なプラグインだ。
多くのサイトで利用されているからこそ、スパムの対象になり多くのメールが届くことがある。
今回は、スパム対策の紹介と、実際に対策した内容を書いていく。
スパム対策一覧
スパム対策はいくつかあるので紹介する。
もちろん、これ以外にも多様な選択肢があるので参考程度に見ていただければと思う。
[プラグイン] reCAPTCHAv3の導入
「フォームの不正利用やスパム対策の認証システム」で、データの送信者が「人間なのかロボットなのか」を判定してくれるので、スパムはほぼ届かなくなる。
Googleに紐づくアカウントが必要で、設定が少し複雑。
料金は基本無料。ただし100万/月以上のアクセスからは有料にする必要があります。コーポレートサイトなら導入の価値はありそうです。
![](https://ps.w.org/google-captcha/assets/banner-772x250.jpg?rev=2202679)
[プラグイン] Akismet Anti-Spamの導入
世界中のスパムに関するブラックリストをもち、フィルタしてくれます。
商用サイトで利用は有料 ( $10 /月 )
![](https://ps.w.org/akismet/assets/banner-772x250.png?rev=2900731)
Contact Form 7 を改修
項目に日本語が含まれている時だけ送信するように改修します。
スパムに関してはおおよそ海外からの送信が多いです。Webサイトをクロールしてお問い合わせ画面に自動入力、送信といった流れです。そのため、日本語フィルタを入れるだけでスパムはかなり減ります。
Contact Form 7で日本語フィルターを追加する
手軽にそして管理が簡単な方法を選択して、「Contact Form 7を改修して、日本語フィルター」を追加することにした。
Contact Form 7 の Custom validation を実装する
Contact Form 7 は、ユーザー入力のバリデーションはフィルター関数として実装されています。
バリデーションに使われるフィルターフックは、wpcf7_validate_ + {フォームタグの種類}
で設定できます。
例えば、テキストフォームタグにはwpcf7_validate_textフィルターフックが使われます。同様に、email*フォームタグにはwpcf7_validate_email*が使われます。(*は入力必須オプション)
今回は、textareaに対して、日本語フィルターを作成しています。
WordPressなので、functions.phpに追加します。
add_filter('wpcf7_validate_textarea', 'wpcf7_validate_lang_jpn', 11, 2);
add_filter('wpcf7_validate_textarea*', 'wpcf7_validate_lang_jpn', 11, 2);
function wpcf7_validate_lang_jpn($result,$tag){
$tag = new WPCF7_Shortcode($tag);
$name = $tag->name;
$value = isset($_POST[$name]) ? trim(wp_unslash(strtr((string) $_POST[$name], "\n", " "))) : "";
if (!preg_match("/[\p{Hiragana}\p{Katakana}\p{Han}]/u", $value)) {
$result->invalidate($tag, "日本語でご記入ください");
}
return $result;
}
やっていることはシンプルで、wpcf7_validate_textareaフィルターフックでwpcf7_validate_lang_jpn関数を呼び出し、日本語(ひらがな・カタカナ・漢字) が1文字もない場合は、invalidateを呼び出し、アラートを表示します。
大切なのは正規表現の部分で、Unicodeの規格制定団体である UTC https://home.unicode.org/ がUnicode文字のブロック範囲を定義しています。
ここで、Hiragana(ひらがな)、Katakana ( カタカナ )、Han ( 漢字 ) が定義されているので利用しています。
Summary
スパム対策の効果としては reCAPTCHAv3が最も高そうですが、設定期間・長い目を見たコスト管理・スパムの程度を考慮すると、Contact Form 7でCustom validationを使ってあげたほうが良さそうです。