bombtterで爆発させた犯人を推理する迷探偵botを作った

@bombtterでたまに面白いモノが爆発して誰が爆発させてるのか気になったので爆発させた人を探す@meitantei_botを作ってみた。

やってること

  1. bombtterのRSSを取得
  2. 爆発物を抽出
  3. twitter検索に爆発物+"爆発しろ"で検索した結果をRSSで取得
  4. twitter検索の結果から犯人を捜す(@zerrotter@wakatter等、他人の発言を復唱をするようなbotは捜査対象から外す)
  5. 犯人が見つかったものをtwitterにpost(見つからなかった場合はpostしない)

以上の処理をcronで5分おきに回してます。

ソース

基本的に@zerotterのパクりです(hakobe932さんごめんなさい)

#!/usr/bin/perl
# ----------------------------------------------------------------------
use strict;
use warnings;
use utf8;
use XML::Feed;
use URI::Fetch;
use URI;
use Jcode;
use DateTime;
use Net::Twitter;

# twitter アカウント
my $username = 'username';
my $password = 'password';

# 最後に更新した時刻を調べるのにファイルを使う ( via Plagger::Rule::Fresh )
my $FRESH_PATH = "./update_time";
my $now   = time;
my $mtime = (stat($FRESH_PATH))[9];

if ($mtime) {
    utime $now, $now, $FRESH_PATH or die("$FRESH_PATH: $!");
} else {
    open my $fh, ">", $FRESH_PATH or die("$FRESH_PATH: $!");
    close $fh;
    
    $mtime = (stat($FRESH_PATH))[9];
}
my $mtime_dt = DateTime->from_epoch( epoch => $mtime );

# bombtterのRSSを拝借する
my $rss_url = URI->new('http://twitter.com/statuses/user_timeline/14152694.rss');
my $res = URI::Fetch->fetch($rss_url)
    or die URI::Fetch->errstr;
my $rss_content = $res->content;
my $feed = XML::Feed->parse(\$rss_content)
    or die XML::Feed->errstr;

# twitter の準備
my $twit = Net::Twitter->new(username => $username, password => $password);

for my $entry ($feed->entries) {
    my $entry_content = $entry->content->body;
    $entry_content =~ s/^bombtter:\s+//xms;
    $entry_content =~ s/\s*が爆発しました。\s*$//xms;

    # 最後に発言した時間より新しいモノだけ犯人捜索
    if(DateTime->compare($entry->issued, $mtime_dt) == 1) {
	# twitter検索から爆発物と"爆発しろ"の検索結果のRSSを拝借する
	my $search_word = '"' . $entry_content . '" "爆発しろ"';
	$search_word = &url_encode($search_word);
	
	my $search_url2 = 'http://twitter.1x1.jp/rss/search/?keyword=' . $search_word . '&text=1';
	my $rss_url2 = URI->new($search_url2);
	my $res2 = URI::Fetch->fetch($rss_url2)
	    or die URI::Fetch->errstr;
	my $rss_content2 = $res2->content;
	my $feed2 = XML::Feed->parse(\$rss_content2)
	    or die XML::Feed->errstr;
	my $feed3 = $feed2;
	
	$feed2 = $feed3;
	my $hannin_hakken = 0;
	my $entry_title;
	for my $entry2 ($feed2->entries) {
	    $entry_title = $entry2->title;
	    my @hoge;
	    ($entry_title, @hoge) = split(/ /, $entry2->title); 
	    my $entry_messe = $entry2->content->body;
	    # 犯人を捜索
	    my $find =index( $entry_messe, $entry_content);
	    if (($find >= 0) 
		&& (index($entry_title,'@zerotter')<0) 
		&& (index($entry_title,'@wakatter')<0)){
		$hannin_hakken = 1;
		last;
	    }
	    
	}
         # 犯人がわかった場合だけ発言
	if($hannin_hakken == 1){
	    my $status = sprintf("%sを爆発させた犯人は %s です。\n",
				 $entry_content, $entry_title);
	    $twit->update( $status );
	    sleep 5;
	}else{
#	    printf "%sを爆発させた犯人はわかりません。\n",$entry_content;
	}

    } else {
	last;
    }
    
}

# utf8でURLエンコード
sub url_encode($) {
    my $str = shift;
    $str = Encode::encode('utf8',$str);
    $str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;
    $str =~ tr/ /+/;
    $str = Encode::decode('utf8',$str);
    return $str;
}
苦労した点

ubuntu 8.04 Desktop版で開発してたんだけど、色々開発に必要なライブラリが足りなくて困った。
まさかC++標準ライブラリすら入ってないとは…。
しかし、linuxperl初心者の自分でもtwitter用のbotが作れるなんていい時代になったもんです。
apt-getでプログラム等を簡単にインストールできるし、perlのモジュールもcpanでインストールできるし、わからない事はぐぐれば大抵わかるし。
あと、twitter上で色々教えてくれた人ありがとう!


次の機能として、一定時間になったら「じっちゃんの名にかけて!」とか言わせてみようかな。