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)->@
ブログ内検索
__
リンク
