Posted at

APIを利用してWordPressへのスパムコメントを拒否

※ブログ記事整理の為に移転させてきました。

APIが今も生きているかくらいは確認しましたが古くなっている部分があるかも(初出2014年の記事)。


私の環境ではスパムコメントを受け付けずに(データベースに登録せずに)削除するプラグインが上手く動作しなかったので、アクションフックを使って自分でやってみた。

Akismet使っているけどDB圧迫するくらいスパムが飛んでくる方は、数式・画像認証プラグイン(これでbotによる投稿はほぼ無くなるので効果絶大)と併用してみてください。


やったこと

APIを使って、スパムサイトへのURLが登録されたコメントは拒否する。

(データベースにも登録しない)

以下では、URLについてはコメントフォームのURL欄のみチェックしていますが、本文内に書き込まれたURLについても工夫すれば対処可能だと思います。

例えば正規表現でURL部分を抜き取ればあとは同じ処理で出来ます。


使ったAPI

前回記事を移転する際にソースコードの一部が自動変換されたようです。

修正したつもりですがコピペで動かなければご連絡ください。


ウェブページ単位で拒否する

URLがFC2のデータベースに登録されているものと完全一致した場合のみ拒否する。


function.php

function simple_custome_spam_filter($comment_post_ID){ //URL欄に入力されたデータを取得

$url = (isset($_POST['url']) ? trim($_POST['url']) : null); //FC2のAPIを呼びだすURL
$data = 'http://seo.fc2.com/spam/spamapi.php?url='.$url; //データベースに登録されていたらエラーメッセージ
if(file_get_contents($data) == 'False'){
wp_die('スパム投稿はお断りしています。');
}
}
add_action('pre_comment_on_post','simple_custome_spam_filter');

アクションフックの使い方に関しては以下を参考にさせていただきました。

https://www.softel.co.jp/blogs/tech/archives/2106


ドメイン単位で拒否する

上のAPIだと、疑似クエリを付けて投稿された場合等はブログのデータベースに登録されてしまいます。

スパムサイトのドメイン単位で拒否したい場合は以下。


function.php

function simple_custome_spam_filter($comment_post_ID){

$url = (isset($POST['url']) ? trim($_POST['url']) : null);
$url = parse_url($url);
$data = 'http://seo.fc2.com/spam/spamapi.php?m=dl&dm='.$url['host'];
if($url['host'] && !strstr(file_get_contents($data),'No Data List.')){
wp_die('スパム投稿はお断りしています。');
}
}
add_action( 'pre_comment_on_post' , 'simple_custome_spam_filter' );

但し、こうするとレンタルサーバーのサイト等でサブディレクトリ型のURLを発行されているサイトが巻き添えになる可能性があります。

(全く別の人が管理していても、一つでもFC2のブラックリストに載っているサイトがあれば、同じドメイン内のサイトは全て拒否される。)


例外ドメインを指定する

FC2のデータベースにはTwitter等のURLも登録されています。

Twitterのドメインを丸ごとブロックするのは現実的ではないので除外しましょう。


function.php

function simple_custome_spam_filter( $comment_post_ID ){

$url = (isset( $_POST [ 'url' ]) ? trim( $_POST [ 'url' ]) : null);
$url = parse_url ( $url );
if($url['host'] != 'twitter.com' && $url['host'] != 'www.youtube.com'){ // 多くなるようならarrayとかでやった方が良い
$data = 'http://seo.fc2.com/spam/spamapi.php?m=dl&dm='.$url['host'];
if ( $url['host'] && ! strstr (file_get_contents($data),'No Data List.')){
wp_die('スパム投稿はお断りしています。');
}
}
}
add_action( 'pre_comment_on_post' , 'simple_custome_spam_filter' );


メールアドレスで拒否する

コメント投稿者が記入したメールアドレスで拒否する場合はこちら。


function.php

$email = (isset($POST [ 'email' ]) ? trim($POST [ 'email' ]) : null);

$stopspam = simplexml_load_file( 'http://api.stopforumspam.org/api?email[]=' . $email . '&ip[]=' . $commentdata [ 'comment_author_IP' ]);
if ( $stopspam->email->appears == 1 || $stopspam->ip->appears == 1){
wp_die('スパム投稿はお断りしています(貴方は Stop Forum Spam のスパマーリストに登録されています)。');
}


完成ソース

色々試行錯誤して結局こういう形にしました。

例外ドメインとエラーメッセージは各自必要に応じて編集してください。


function.php

function simple_custome_spam_filter( $comment_post_ID ){

$url = (isset($_POST['url']) ? trim($_POST['url']) : null);
$purl = parse_url($url);
if (!strstr($purl['host'],'twitter.com') && !strstr($purl['host'],'google.com') && !strstr($purl['host'],'youtube.com')){
$data = 'http://seo.fc2.com/spam/spamapi.php?m=dl&dm='.$purl['host'];
if ($purl['host'] && !strstr(file_get_contents($data),'No Data List.')){
wp_die('スパム投稿はお断りしています(貴方のドメインはFC2のスパムリストに登録されています)。');
}
}
else{
$data = 'http://seo.fc2.com/spam/spamapi.php?url='.$url;
if(file_get_contents($data) == 'False'){
wp_die('スパム投稿はお断りしています(貴方のサイトはFC2のスパムリストに登録されています)。');
}
}

$email = (isset($POST [ 'email' ]) ? trim($POST [ 'email' ]) : null);
$stopspam = simplexml_load_file( 'http://api.stopforumspam.org/api?email[]=' . $email . '&ip[]=' .
$commentdata [ 'comment_author_IP' ]);
if ( $stopspam->email->appears == 1 || $stopspam->ip->appears == 1){
wp_die('スパム投稿はお断りしています(貴方は Stop Forum Spam のスパマーリストに登録されています)。');
}
}
add_action('pre_comment_on_post','simple_custome_spam_filter');



CleanTalkなら1つのAPIで全部できそう


function.php

$email = (isset( $POST [ 'email' ]) ? trim( $POST [ 'email' ]) : null);

$url = (isset( $POST [ 'url' ]) ? trim( $POST [ 'url' ]) : null);
$purl = parse_url ( $url );
$cleantalk = json_decode( file_get_contents ( 'http://cleantalk.org/blacklists?format=json&email=' . $email . '&ip=' . $commentdata [ 'comment_author_IP' ]. '&domain=' . $purl [ 'host' ]));
if ( $cleantalk->domain->appears == 1 || $cleantalk->email->appears == 1 || $cleantalk->ip->appears == 1){
wp_die( 'スパム投稿はお断りしています(貴方は CleanTalk のスパマーリストに登録されています)。' );
}