PukiWiki/1.4/ちょっと便利に
Akismetによるspam(スパム)防止機能†
WordPress用スパム対策プラグインとして開発されており、多数のWordPress利用者から「最強」との呼び声が高いプラグイン「Akismet」
を PukiWiki で利用します。
投稿内容をチェックし、Spamを防止することができます。
事前準備†
- WordPress API Key の取得
- Akismet は元々 WordPress 用プラグインとして作られたもので WordPress のユーザ登録をする必要があります。
- 以下のページからユーザ登録をおこない、APIキーを取得してください。(基本的に無料ですが、商用に利用する場合は有料となります。)
- http://wordpress.com/api-keys/
- PHP4 Akismet Class のダウンロード
ファイルの書き換え†
lib/pukiwiki.php を変更します。
// Spam filtering
if ($spam && $method != 'GET') {
.
.
.
}
のような箇所があります。そこを以下に置き換えます。<API Key> を取得した API Key に変更します。
// Spam filtering
if (isset($vars['msg']) && $vars['msg'] != '' && $method != 'GET') {
// SPAM chek by akismet
require_once(LIB_DIR . 'akismet.class.php');
// load array with comment data
$comment = array(
'author' => isset($vars['name']) ? $vars['name'] : '',
'email' => '',
'website' => '',
'body' => $vars['msg'],
'permalink' => '',
'user_ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
);
// instantiate an instance of the class
$akismet = new Akismet(get_script_uri(), '<API Key>', $comment);
// test for errors
if($akismet->errorsExist()) { // returns true if any errors exist
if($akismet->isError('AKISMET_INVALID_KEY')) {
die_message('akismet : APIキーが不正です.');
} elseif($akismet->isError('AKISMET_RESPONSE_FAILED')) {
//die_message('akismet : レスポンスの取得に失敗しました');
} elseif($akismet->isError('AKISMET_SERVER_NOT_FOUND')) {
//die_message('akismet : サーバへの接続に失敗しました.');
}
} elseif ($akismet->isSpam()) { // returns true if Akismet thinks the comment is spam
die_message('投稿はスパムと判断されました.');
}
}
相談所†
問題
- AkismetのAPIでは、以下の情報を元にスパム判定をおこなう
- 投稿者(author)
- E-mail
- WebSite(投稿者のURL)
- 本文
- 基本的に「本文」だけを設定すればスパム判定はおこなわれる。
- が、Pukiwikiのほうではプラグインによって、本文が設定される変数名が異なる。
- 例えばコメントプラグインなどの場合は「msg」に本文が設定されるが、トラッカープラグインの場合は変数名は、ユーザーの設定によって異なる。
- ようするに、AkismetAPIの本文に対して、Pukiwiki上で投稿された変数のうちどれをマッピングさせるかという問題が存在する。
解決策
- 案1:$vars['msg'] を使用(現状)
- comment, article プラグインや edit プラグイン(通常編集)には対応できる
- tracker の場合設定 :config ページで msg にしなければならない
- article の subject などがスルー
- 案2:$vars 全体を使用(オリジナル小沼版)
- 全フィールドに対応。
- しかし、ゴミが付く(自動生成される、メッセージダイジェスト値など)。それらのせいで普通の投稿もスパムに間違われはしないか懸念がある。
- また edit の場合元の文章全体を $vars['original'] に保存しているので Akismet に送信する情報量が2倍。重い(original はスパムではありえないはずなので送る必要がない)。
- などなど送信しない値をこつこつと1つずつ対応していくか、無視して全体送信か。
- 案3:送信する値をこつこつと1つずつ対応
- 案2とは逆に送信する値をこつこつと1つずつきっちり対応。
- 大変。また、PukiwikiやAkismetの仕様変更が行われるたびに修正しなければならず、サポートも大変。
- tracker の場合 :config 設定による
- 案4:page_write 関数の文章書き込みの直前にチェック
- Wikiページに書き込まれる文章だけを確実に取得できる
- しかし、たとえ comment プラグインでもそのページ本文全てを Akismet.com に送信することになり重い
- 書き込む前の内容と差分を取って送ればよい。
- それによって、確実に新規内容だけをチェックできる。
- ただ、合体→分離と無駄なことをしている感は否めない。
- page_write を使用しない、つまりwikiページへの書き込みをしないプラグイン(bbs.inc.phpやメール送信プラグイン)には対応できない。
コメント†
- 感想などお待ちしています。 -- 小沼
- http://www.ark-web.jp/blog/archives/2006/12/pukiwikiakismet.html?rss10 --
- お疲れ様です。Akismetに関する概要説明がこの上のblogエントリにしかありませんから、初めての方は手を出し辛いかもしれません (^^; -- henoheno
- ありがとうございます。確かに手を出しにくいかもしれないですね(^^; -- 小沼
- GIGAZINEによる紹介*1 http://gigazine.net/index.php?/news/comments/20070127_akismet/ --
- 1.4.7にて導入してみようとしたのですが、動きませんでした。lib/pulgin.php を書き換えて適用した時点で全てwikiが固まります --
- 2007/1/27のAkismetの仕様変更で動作しなくなっていたと思われます。 -- 小沼
- 私もAkismetはBlogで使用していますが、非常に強力で重宝しています。導入して2ヶ月、一度もSPAMを突破された事がありません。PukiWikiで公式に利用できるようになると非常に嬉しいです。 -- AntiSpam
- こうした外部のシステムを(一つじゃなく、管理者の任意の種類と数)呼べるように、anti-spam機構の下地を作ればいいんだろうなあと思っています。 -- henoheno
- クラスの仕様が変わって既に小沼さんのakismet_filter.phpの内容は古くなっているようです。以下にcommentプラグインを直接改造する例を挙げておきます。(comment.inc.php 30行目付近。<PukiWikiのURI>と<API Key>は各サイトに合わせて変更) --
if (! isset($vars['msg'])) return array('msg'=>'', 'body'=>''); // Do nothing
+//////////////////////////////////////////////
+// SPAM chek by akismet
+require_once(LIB_DIR.'akismet.class.php');
+
+// load array with comment data
+$comment = array(
+ 'author' => $vars['name'],
+ 'email' => '',
+ 'website' => '',
+ 'body' => $vars['msg'],
+ 'permalink' => ''
+);
+
+// instantiate an instance of the class
+$akismet = new Akismet('<PukiWikiのURI>', '<API Key>', $comment);
+
+// test for errors
+if($akismet->errorsExist()) { // returns true if any errors exist
+ $akismet_msg = '';
+ if($akismet->isError('AKISMET_INVALID_KEY')) {
+ $akismet_msg = 'akismet : APIキーが不正です.';
+ } elseif($akismet->isError('AKISMET_RESPONSE_FAILED')) {
+ $akismet_msg = 'akisumet : レスポンスの取得に失敗しました';
+ } elseif($akismet->isError('AKISMET_SERVER_NOT_FOUND')) {
+ $akismet_msg = 'akismet : サーバへの接続に失敗しました.';
+ }
+ return array('msg'=>'投稿内容の確認中にエラーが発生しました.', 'body'=>$akismet_msg);
+} else {
+ if ($akismet->isSpam()) { // returns true if Akismet thinks the comment is spam
+ return array('msg'=>'投稿内容の確認中にエラーが発生しました.', 'body'=>'投稿はスパムと判断されました.');
+ }
+}
+//////////////////////////////////////////////
$vars['msg'] = str_replace("\n", '', $vars['msg']); // Cut LFs
- コメント以外にも全ての編集にAkismetのチェックをしたいのですがどのように改造すればいいのでしょうか? --
- 今のCVS版(1.4.8_alpha) の cvs:lib/pukiwiki.php にはまさにそんな感じの処理があるかもしれません。GET以外の処理について、プラグインの判定と下処理をした上で、その内容を全部関数に渡すようなものが。ここをもう少し拡張して、こうした外部サービスを呼べるようにすればいいんではないかなと思っています。 -- henoheno
- オリジナルの小沼さん版が動作しないとのことなので今現在のまとめ的なものに内容を整頓しました。 --
- 小沼です。しばらく目を離している間にいろいろあったみたいですね。すいません。これから状況を確認します。それとメンテしていただいている方々、本当にありがとうございます。 -- 小沼
- オリジナル版を更新しました。akismet_filter.phpを新しいものに差し替えていただければ動作するようになると思います。 -- 小沼
http://www.ark-web.jp/sandbox/wiki/190.html
- コメントがtimeoutになってしまい、今になって仕様変更を知りました。気が付いたこと2点。1)うちではakismet.class.phpを以前と同じように大文字(Akismet.class.php)にしないと固まってしまいました*2 2)if ( is_spam_message($_POST, $name) == "1" ) die_message("Spam check faild. Plugin:$name");の「faild」はミススペルですか? -- peg
- 補則:私んとこは導入が1.9.07で、コメントは最初に動作確認した程度で日頃は使ってなかったので更新に気づくのが遅れた次第です。PukiWikiは1.4.7。今んとこ一切SPAMの被害を受けておりません。大変重宝しています。 -- peg
- pegさんへの返答です。 -- 小沼
- 1)すいません。akimet_fileterの中での呼び出しが大文字で呼び出していたためです。修正しておきました。(Akismet.class.php→akismet.class.php)
- 2)スペルミスです。^^;
- 上記2点につきましてはこちらで修正しておきました。
- official:自作プラグイン/akismet.inc.php スパム取り消し報告、スパムログ参照ができる。 --