お天気を教えてくれるbot作ったよ!

cronで何かする練習で、botを書いてみた。
凄くつまらないです。
そこはもう分かってるからツッコまないでいただきたい…。

#!/usr/bin/perl -w

use strict;
use utf8;
use Dumpvalue;
use XML::Simple;
use LWP::UserAgent;
use Net::Twitter;
use MeCab;
use Encode qw/encode/;

my $ua = LWP::UserAgent->new();
my $tw = Net::Twitter->new({ username => 'id', password => 'pass' });
my $mc = MeCab::Tagger->new();
my $wt = prefecture_ids();
my $si = since_id();
my $fi = 1;

# Get follow messages
my $follow_msgs = $tw->search('@botrin1024', { since_id => $si })->{results};
foreach my $msg(@$follow_msgs) {
  my $city;
  my $game;
  my $mode; #= sub { if($msg->{text} =~ /\*([\w_]*)/) { return $1; } }->();
  # get since_id
  if ($fi) {
    $si = $msg->{id};
    $fi = 0;
  }
  # remove follower_id
  $msg->{text} =~ s/\@[\w_]*//;
  # morphological analysis
  for(my $node = $mc->parseToNode($msg->{text});$node;$node = $node->{next} ) {
    next unless defined $node->{surface};
    
    my($speech, $con, $type, $pron) = (split(/,/, $node->{feature}))[0,1,2,7];
    #next if $speech ne encode('utf8', '名詞');
    
    if ($node->{surface} eq encode('utf8', '天気')) {
      $mode = 'weather';
    }
    elsif ($con eq encode('utf8', '固有名詞') && $type eq encode('utf8', 'ゲーム名')) {
      $game = $node->{surface};
    }
    elsif ($con eq encode('utf8', '固有名詞') && $type eq encode('utf8', '地域')) {
      $city = $node->{surface};
    }
    #print $node->{surface}, "\t", $pron, "\t", $speech, "\t", $type, "\n";
  }
  # execute mode
  if ($mode eq 'weather') {
    my $text = '@' . $msg->{from_user} . ' ' . get_weather($city);
    $tw->update({ status => $text });
  }
  else {
    # die('');
  }
  # option mode
  if (length $game) {
    my $text = '@' . $msg->{from_user} . ' '. $game . encode('utf8', 'をやりたいんですね、わかります。');
    $tw->update({ status => $text });
  }
  print "ok.\n";
}
# set since_id
since_id($si);
# rand echo
$tw->update({ status => encode('utf8', '"' . get_keyword() . '"とかで検索してみるとオモロいかも?') });

## Get since_id
sub since_id {
  my $since_id = shift;
  if ($since_id) {
    open my $FILE, '>', '/home/yuki/projects/bot/since_id.txt';
    print $FILE $since_id, "\n";
    close $FILE;
  }
  else {
    open my $FILE, '<', '/home/yuki/projects/bot/since_id.txt';
    $since_id = <$FILE>;
    close $FILE;
  }
  return $since_id;
}

## Get prefecture ids
sub prefecture_ids {
  open my $FILE, '<', '/home/yuki/projects/bot/forecastmap.xml';
  my @ids = <$FILE>;
  close $FILE;
  
  return XMLin(join '', @ids)->{prefectures};
}

## Get weather data
sub get_weather {
  my $city_name = shift;
  my $text = q{};
  my $city_id;
  
  while(my($key,$val) = each(%{$wt->{city}})) {
    if ($val->{title} eq $city_name) {
      $city_id = $key;
      last;
    }
  }
  
  if ($city_id) {
    my $w_url = 'http://weather.livedoor.com/forecast/webservice/rest/v1?city='.$city_id.'&day=tomorrow';
    my $weather = XMLin($ua->simple_request(
       HTTP::Request->new('GET', $w_url)
    )->content);
    
    $text .= $weather->{location}->{pref}.'の天気は、'.$weather->{telop}.'だそうです。'.$/;
    $text .= $weather->{description}.$/;
#    $text .= '詳しくは、'.$weather->{link}.'を見てね'.$/;
  }
  else {
    $text = "ゴメン!ちょっとよくわかんない!!";
  }
  
  return encode('utf8', $text);
}

## Get from sagool api
sub get_keyword {
  my $sagool = XMLin($ua->simple_request(
     HTTP::Request->new('GET', 'http://sagool.jp/wacaalapi?type=xml')
  )->content)->{channel}->{item};
  
  return $sagool->[0]->{title};
}

1;

$ crontab -l
0-59/5 * * * * perl /home/yuki/projects/bot/twitter.pl

・作った経緯
http://www.team-lab.com/news/index.php?itemid=469
こんなのやってたから。


・使い方
http://twitter.com/botrin1024
こいつに県名と「天気教えてー」って見たいな事言うと教えてくれる。
5分おき位に返事くれるよ。
エロゲのタイトルが本文にあると何か言うよ。
独り言ではさぐーるの最近検索されたワードの紹介するよ。


・反省点
encode一杯使わないで、XMLファイルの方をdecodeした方が絶対楽そう。
普通すぎて正直つまんない。
each文が何か良い子じゃないからdumpvalueで1回表示してやり直してる(これ可笑しい)。
→途中でreturnとかやってたからアカンかった。ちゃんと代入してlast使えばok。


・ホントにやりたかったこと
ツンデレbot.
エロゲのタイトル書くとツンツンしながら色々調べてくれるの。
辞書までは作った(Wiki使って) → http://sorauta.net/files/EroDic.csv


・ふとよく考えてみると
独自アルゴリズムなんて部分これっぽっちもないよね。
\(^o^)/

市町村ID取得用XML(livedoor天気使用)
http://sorauta.net/files/forecastmap.xml


・8/29追記
utf8フラグonにしてたらエラー出てたので今更だけど,修正した.
参考:http://floralcompany.jp/archives/2009/08/workaround_for.html