イベント再現botのコードを書いてみた

過去にあった事例を、twitterの現在のタイムラインに持ってくると面白いと思って、昨日そのアイデアについて書いた。


twitter bot のアイデア的なもの


定型の内容をポストしていくだけのbotで、簡単そうなのでたたき台となるコードを書いてみた。


例のスクリプト
天才ゲームクリエイター・飯田和雄氏インタビュー「どうかしてるんです」-ガジェット通信
から、一部を引用しました。
記者と飯田さん用の2つのアカウントがリプライを飛ばしながらインタビューを再現するという内容です。


データ用のテキストファイルを読みながら一行づつポストしていきます。
データのフォーマットは

  • # ではじまる
    • 別名,アカウント名,パスワード
  • # ではじまらない
    • 送信するアカウントの別名,リプライ先のアカウント名の別名,待機時間,メッセージ

となっています。


リプライ先は省略OK。
リプライは相手の直近の発言のみという制約がありますが、たぶん問題ないでしょう。


待機時間は秒単位で指定できるのでCRONを使うよりも細かく、やりとりの間隔を作る事ができるし、ほぼ同時にポストして声がそろう見たいな状況も再現できそうです。ただし、ほとんどの twitter クライアントは定期的にタイムラインを取得して、ドバッと表示しているようなので、あんまり細かいやり取りの間隔は意味がなさそうです。

#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use Encode qw(decode);
use FindBin;
use Net::Twitter;

my $filename = 'script.txt';
my $filepath = "$FindBin::RealBin/$filename";

exit unless -f $filepath;
open my $fh, '<', $filepath or warn "Cannot open $filename";

my ($twit, $recent_status_id);
while (<$fh>) {
    chomp;
    if (/^#(.*)$/) {
        my ($alias, $username, $password) = split(/,/, $1);
        print "CREAT: [$alias] => ($username, $password)\n";
        $twit->{$alias} = Net::Twitter->new(username=>$username, password=>$password);
        $recent_status_id->{$alias} = 0;
    } else {
        my ($from, $to, $dly_tim, $msg) = split(/,/, $_);
        sleep($dly_tim);
        
        $from = trim($from);
        $to   = trim($to);
        $msg  = trim($msg);
        
        if ( ! exists $twit->{$from} ) {
            print "ERROR: '$from' not defined!\n";
            next;
        }
        
        if ( $to && ! exists $twit->{$to} ) {
            print "ERROR: '$to' not defined!\n";
            next;
        }
        
        my $from_user = $twit->{$from}->{username};
        my $to_user   = $to ? $twit->{$to}->{username} : '<anyone>';
        
        my $params;
        my $in_reply_to_status_id = 0;
        if ($to) {
            $in_reply_to_status_id = $params->{in_reply_to_status_id} = $recent_status_id->{$to};
            $msg = ".\@$to_user $msg";
        }
        $params->{status} = decode('utf8', $msg);
        
        my $status = $twit->{$from}->update($params);
        ${recent_status_id}->{$from} = $status->{id};
        
        print "$status->{id}: $from_user > $to_user (reply_to_status_id:$in_reply_to_status_id)\n";
        print "    [msg:$msg]\n";
    }
}

close $fh;


sub trim
{
    my $val = shift;
    $val =~ s/^\s*//;
    $val =~ s/\s*$//;
    return $val;
}


script.txt

#A,<ユーザ名>,<パスワード>
#B,<ユーザ名>,<パスワード>
A,B,  0, 『ディシプリン』の開発で苦労した点はありますか?
B,A, 90, 6月19日だったかな。かなり厳しかったです。
A,B, 90, 何かあったんですか? バグ?
B,A, 90, かしゆかがデートしてるとこ撮影されたんですよ。またフライデーに!
B,A, 30, 今思い出しても......、厳しいですよ。
A,B, 90, ......?『パフューム』の樫野有香さんのことですか?
B,A, 90, ええ。のっちのショックを頑張って乗り越えようとしたら、またフライデーですよ。これどういうことなんですか......。
A,B, 90, ......。
B,A, 0, ............。