2011/03/07 (Mon) 22:21
第6回というか、第2部というか。
ひさびさにperlと格闘しました。
先日公開された、公式リズムシbot(@rhythmushi_bot)のプログラムを担当しました。
リズムシ作者さんの公式HPはこちら:オトノアソビバ
機能は、
・定時ツイート
・リプライへの返事
・フォローされたらリフォロー&リプライ送信
おおまかにこの3つ。
今回はお見せできない部分もあるのですが、以下ソースコードです。
@4/19 追記
コードを大幅にいじりました。
比較のためにこちらのコードも残しておきますが、よりよい(と思われる)最新版はこちら。
Tweet
ひさびさにperlと格闘しました。
先日公開された、公式リズムシbot(@rhythmushi_bot)のプログラムを担当しました。
リズムシ作者さんの公式HPはこちら:オトノアソビバ
機能は、
・定時ツイート
・リプライへの返事
・フォローされたらリフォロー&リプライ送信
おおまかにこの3つ。
今回はお見せできない部分もあるのですが、以下ソースコードです。
@4/19 追記
コードを大幅にいじりました。
比較のためにこちらのコードも残しておきますが、よりよい(と思われる)最新版はこちら。
Tweet
#!/usr/bin/perl use warnings; use strict; use CGI::Carp qw(fatalsToBrowser); # モジュールのパスを追加 use lib qw(/パス); # Net::Twitter::Lite、Data::Dumperモジュールを使用 use Net::Twitter::Lite; use Data::Dumper; # utf8エンコードを使用 use utf8; use Encode; use JSON 'decode_json'; binmode(STDOUT, ":utf8"); # HTML出力 print "Content-Type: text/html\n\n"; # twitter認証 my %RAP_CONSUMER_TOKENS = ( consumer_key => 'コンシューマトークンのキー', consumer_secret => 'コンシューマトークンのパスワード'); my $RAP_ACCESS_TOKEN = 'アクセストークンのキー'; my $RAP_ACCESS_TOKEN_SECRET = 'アクセストークンのパスワード'; # 呼び出し、トークンセット my $rapTweet = Net::Twitter::Lite->new(%RAP_CONSUMER_TOKENS); $rapTweet->access_token($RAP_ACCESS_TOKEN); $rapTweet->access_token_secret($RAP_ACCESS_TOKEN_SECRET); ###################### ## 定時ツイート ## # localtime()関数は、秒、分、時、日にち、月、年、曜日の配列になっている # ※年は1900をプラス、月は1をプラスして使う (my $sec, my $min, my $hour, my $mday, my $mon, my $year, my $wday) = localtime(); # $min=分が10分未満のとき=毎時間実行 if($min < 10){ my $rnd = int(rand(2)); if($rnd == 0){ my $kotobaResult; # サブルーチン"pattGenarate"を実行 $kotobaResult = pattGenerate(); $rapTweet->update($kotobaResult); } } sub pattGenerate{ # 非公開です!ごめんなさい。 return $result; } ###################### ## リプライ返し ## # 自分へのリプライを取得 my $rapParam = $rapTweet->mentions(); # 結果を書き出すテキストファイル my $rapFile = '.txt'; # 書き出しに使用 my @rapFlags; my @rapStatus; my @rapIds; # リプライの内容の配列 my @replyStatus = ("リプライの内容"); foreach my $str (@$rapParam){ # 投稿する文章を格納 my $s; # パターンをランダムで選択 # rand(整数) -> 0から指定した整数までの数をランダムで出力(小数) # int() -> 数値の整数部を取り出し(=切り捨て) my $kRand = int(rand(整数)); # $kRand番目にあたる文字列を取得 $s = $replyStatus[$kRand]; # @ユーザ名 発言の形に $s = join('', "@",$str->{'user'}{'screen_name'}, " ", $s); # 配列に格納 push @rapStatus, $s; push @rapIds, $str->{'id'}; } # ログファイルを共用読み取りでオープン open (my $fh, '+<', $rapFile) or die "Can't open file : $!"; for(my $i=0; $i<@rapIds; $i++){ while( my $line = <$fh> ){ # ファイルの中にidがあるかチェック if($line =~ /$rapIds[$i]/){ $rapFlags[$i] = 0; last; } else{ $rapFlags[$i] = 1; } } } for(my $j=0; $j<@rapIds; $j++){ # フラグが1=新しい場合のみ、発言を投稿、IDをログに書きこむ if($rapFlags[$j] == 1){ $rapTweet->update($rapStatus[$j]); print $fh $rapIds[$k]; print $fh "\n"; } } # ファイルクローズ close $fh; ###################### ## フォロー返し ## #followers(フォローされている)、friends(フォローしている)を取得 my $rapFollowers = $rapTweet->followers(); my $rapFriends = $rapTweet->friends(); my @followName; my @friendsName; my @protect; foreach my $desc (@$rapFollowers){ # ユーザ名とプロテクト(鍵つきアカウント)かどうかを配列にプッシュ my $follow = $desc->{'screen_name'}; push @followName, $follow; my $bProt = $desc->{'protected'}; push @protect, $bProt; } foreach my $desc (@$rapFriends){ # フォロワーのユーザ名をプッシュ my $friend = $desc->{'screen_name'}; push @friendsName, $friend; } my $mutchFlag = 0; for (my $i = 0; $i < @followName; $i++) { for (my $j = 0; $j < @friendsName; $j++) { if($friendsName[$j] =~ /$followName[$i]/){ # マッチした=既にフォローしているので、内側のループを抜ける $mutchFlag = 1; last; } } # flagを0にして、次へ if($mutchFlag == 1){ $mutchFlag = 0; } else { # 鍵付きアカウントでない場合 if($protect[$i] =~ /false/){ # フォローに失敗するとエラーが吐かれるので、 # それをキャッチ/プログラムを終了させないために、evalを使用 eval{ $rapTweet->create_friend($followName[$i]) }; if($@){ # "$@"にエラー内容が格納される print $@, "\n "; } else { # エラーが出なかったので、新しいフォロワーにリプライ my $s; # @ユーザ名 発言 の形に $s = join('', "@", $followName[$i], " リプライ内容"); #ツイート $rapTweet->update($s); } } } } exit; __END__
以上です。
いろいろ削ったりしていますが、だいたいこんなかんじ。
ご質問ご意見お待ちしてます。
Net::Twitter::Liteでどんな値が取れるのかは、
Net-Twitter-Lite - search.cpan.org
こちらで確認ができます。
->{'user'}{'screen_name'}なんていうように、パラメータが入れ子になっていたりいなかったりするので、一番大きい枠を(たとえばmentions())取ったら、
このようにダンプすれば、中の各パラメータが表示されるので、そこから当たりをつけるというのもあり。my $tweet = Net::Twitter::Lite->new(%_CONSUMER_TOKENS); my $param = $tweet->mentions(); print Dumper $param;
以下ぼやき。
フォロー返しのしくみは、たぶんこのやり方でいいんだと思います。
最初は鍵つきさんのことをまったく考えてなくって、数人にリプライを送り続けるという失敗をかましました。申し訳ありません。
あとはリムーブされたらこちらもリムーブ、をやろうと思っているんですが、まあ、もうちょっと後でもいいかな。
フォロー>>>フォロワーくらいになったらやります。
相変わらずelse ifって書いちゃうくせが抜けません。
for文の書き方もas3、C、perlでちょっとずつ違ってこんがらがります。
あ、あと、perlではif($val == true)とかができないんですね。
undifinedは偽、それ以外が真。
なので、ここでも
if($protect[$i] =~ /false/){
このように取ってます。
PR
Comment
カテゴリー
最新記事
(12/07)
(12/06)
(10/17)
(08/09)
(07/18)
最新トラックバック
プロフィール
follow me!
@ar_tama
ar_tama / Makoto Arata
東京のはしっこでプログラミング、ときどきコンピュータ音楽。
音大生。
にゃんこともちもちが好き。
詳細
contact:arata.makoto(at)gmail.com
(at)->@
ブログ内検索
__
リンク