読者です 読者をやめる 読者になる 読者になる

codes / cipher

文章置き場(移転作業中)

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

WordPress

 記事を移転する際にソースコードの一部が自動変換されたみたいなのでコピペだと動かないかもしれません。改行も取れてしまったので修正中。

 以前、私の環境ではスパムコメントを受け付けずに(データベースに登録せずに)削除するプラグインが上手く動作しないと書きましたが、思えばアクションフック使えば自分でそういった類の動作は設定出来るのでした。
 という事で、今回はFC2ソーシャルスパム対策等のAPIを使って、スパムサイトへのURLが登録されたコメントは拒否する設定にしてみました。Akismet使っているけどDB圧迫するくらいスパムが飛んでくる方は是非、数式・画像認証プラグイン(これでbotによる投稿はほぼ無くなるので効果絶大)と併用してみてください。

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

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

www.softel.co.jp

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

 上のAPI&ソースだとURLがFC2のデータベースに登録されているものと完全一致した場合のみ拒否するので、同じサイトの別のページや疑似クエリを付けて投稿された場合はブログのデータベースに登録されてしまいます。
 スパムサイトのドメイン単位で拒否したい場合は下のソースをお使いください。
 但し、こうするとレンタルサーバーのサイト等でサブディレクトリ型のURLを発行されている閲覧者の方が巻き添えになる可能性があります。(全く別の人が管理していても、一つでもFC2のブラックリストに載っているサイトがあれば、同じドメイン内のサイトは全て拒否される。)

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行目を編集。

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部分を抜き取ればあとは同じ処理で出来ます。

完成ソース

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

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 SpamAPIを使って拒否

 海外サイトですが 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:CleanTalkAPIを使って拒否

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

$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読むのでちょっと負担がかかるかもしれませんが。