以前、私の環境ではスパムコメントを受け付けずに(データベースに登録せずに)削除するプラグインが上手く動作しないと書きましたが、思えばアクションフック使えば自分でそういった類の動作は設定出来るのでした。

という事で、今回はFC2ソーシャルスパム対策等のAPIを使って、スパムサイトへのURLが登録されたコメントは拒否する設定にしてみました。Akismet使っているけどDB圧迫するくらいスパムが飛んでくる方は是非、数式・画像認証プラグイン(これでbotによる投稿はほぼ無くなるので効果絶大)と併用してみてください。

FC2以外のサービスを使ったコードも増やしました。

記事を移転する際にソースコードの一部が自動変換されたみたいです。修正したつもりですがコピペで動かなければご連絡ください。

導入方法

function.phpに以下のコードを追記するだけ。

<?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');

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

【WordPress】コメントが登録される前に処理を入れたい(スパムコメント対策など) at softelメモ

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

ドメイン単位で拒否したい場合

上のAPI&ソースだとURLがFC2のデータベースに登録されているものと完全一致した場合のみ拒否するので、同じサイトの別のページや疑似クエリを付けて投稿された場合はブログのデータベースに登録されてしまいます。

スパムサイトのドメイン単位で拒否したい場合は下のソースをお使いください。

但し、こうするとレンタルサーバーのサイト等でサブディレクトリ型のURLを発行されている閲覧者の方が巻き添えになる可能性があります。(全く別の人が管理していても、一つでもFC2のブラックリストに載っているサイトがあれば、同じドメイン内のサイトは全て拒否される。)

<?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' );

例外ドメインを指定したい場合

FC2のデータベースにはTwitter等のURLも登録されているので、閲覧者の方がTwitterでしか活動していない場合等は不便です。除外しましょう。

除外したいサイトを増やしたり減らしたりしたい場合は4行目を編集。

<?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'){
    $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についても工夫すれば対処可能だと思います。例えば正規表現でURL部分を抜き取ればあとは同じ処理で出来ます。

完成ソース

色々試行錯誤して結局こういう形にしました。例外ドメインとエラーメッセージは各自必要に応じて編集してください。

<?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のスパムリストに登録されています)。');
    }
  }
}
add_action('pre_comment_on_post','simple_custome_spam_filter');

おまけ:Stop Forum Spam のAPIを使って拒否

海外サイトですが Stop Forum Spam というFC2ソーシャルスパムと同様のサービスがあったので、此方のAPIも使ってみました。海外からの迷惑コメントが多い場合は此方の方が効果的かもしれません。

勿論併用もできます。

使い方は、上記のフィルタ関数内の処理部分に、以下を組み込むだけです。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 のスパマーリストに登録されています)。');
}

おまけ2:CleanTalk のAPIを使って拒否

此方も海外サイトです。JSONで返ってきます。詳しくは此方を参照。ドキュメントが無くなったのでもしかするとAPI停止されたかもしれません。

<?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 のスパマーリストに登録されています)。' );
}

これだけやればかなり減らせるのでは。

CleanTalk等はどれだけスパム行為をしているかも判別できるので、あまりに迷惑なIPはPHPを使って自動的にアクセス制限する事も出来そうです。API読むのでちょっと負担がかかるかもしれませんが。

スポンサーリンク