Twitter ボットの作り方 Perl 編 (2)

Twitter ボットの作り方解説第 2 弾。あらかじめ用意された定型文の中からランダムでつぶやくボットを作ってみます。
以下は、第 1 弾までの状態を前提としています。

状態ファイルの準備

完全なランダムでつぶやいてもいいのですが、それだと同じつぶやきが連続したり、なかなか出てこないつぶやきがあったりしてしまいますね。
ですので、どこまでつぶやき終わったかを保持して、一通りつぶやき終わるまでは重複しないように制御したいと思います。
そのために、現在の状態を保持するファイルを用意します。ここでは名前を status.yml にしましょう。
ファイルのフォーマットは、config.yml と同様です。
1 回つぶやくたびに状態を保存するため、ファイルには書き込み属性をつけておいて下さい。

lastIndex: 9999

lastIndex には、最後につぶやいた文のインデックスを保持するようにします。
初期データとしては、用意しようとしている定型文の数よりも十分に大きな数値を設定しておいて下さい。

データの準備

ボットがつぶやく定型文をあらかじめ準備しておきます。
設定ファイルと同様に、yml ファイルで作ります。ここでは名前を list.yml にしましょう。
下記のような感じです。日本語を含む場合は UTF-8 で保存して下さい。

このファイルはランダムでつぶやくようにするため、後ほどプログラムでシャッフルします。
シャッフルしたあと、このファイルに上書きするようにするので、書き込み属性をつけておいて下さい。

- つぶやきA
- つぶやきB
- つぶやきC
- つぶやきD
- つぶやきE

なお、行頭にある半角ハイフンは、YAML の文法における配列の表現になります。

実際のスクリプト

#!/usr/bin/perl

# 使用するモジュールの読み込み
use strict;
use warnings;
use FindBin;
use List::Util;
use Encode;
use YAML::Tiny;
use Net::Twitter;

# yml ファイルの読み込みと、Twitter モジュールの初期化
my $config = (YAML::Tiny->read($FindBin::Bin . '/config.yml'))->[0];
my $status = (YAML::Tiny->read($FindBin::Bin . '/status.yml'))->[0];
my @list = @{(YAML::Tiny->read($FindBin::Bin . '/list.yml'))->[0]};
my $twit = Net::Twitter->new(username => $config->{'username'}, password => $config->{'password'});

# 最後につぶやいたインデックスと、定型文リストのサイズ
my $lastIndex = $status->{lastIndex};
my $listSize = @list;

# つぶやきが一周していたら、定型文をシャッフルしてファイルに保存
if ($lastIndex >= ($listSize - 1)) {
        @list = List::Util::shuffle(@list);
        YAML::Tiny::DumpFile($FindBin::Bin . '/list.yml', [@list]);
        $lastIndex = -1;
}

# 実際のつぶやき
my $update = $list[++$lastIndex];
$update = Encode::encode('utf8', $update);
$twit->update($update);
YAML::Tiny::DumpFile($FindBin::Bin . '/status.yml', {lastIndex => $lastIndex});

大体の動作に関しては、スクリプト内のコメントに書いたとおりですが、いくつか補足します。

FindBin は、スクリプトの絶対パスを取得するために使用しています。
第 1 弾のスクリプトでは、設定ファイルなどを相対パスで指定していましたが、ボットとして cron に登録する際は、絶対パスでの動作が求められます。
スクリプトの位置を変えるたびに、設定ファイルのパスを書き換えなくて済むように、スクリプト自体の絶対パスを取得して、同ディレクトリにある設定ファイルを読み書きするようにしています。

List::Util は、配列をランダムにシャッフルするために使用しています。
必要時のみ、List::Util::shuffle で配列をシャッフルしてその内容をファイルに保存しています。

Encode は、yml ファイルから読み取った日本語文字列を適切に扱うために使用しています。
*.yml ファイル自体を UTF-8 で記述していても、YAML::Tiny での UTF-8 の扱いが微妙なため、この変換が必要になっています。
※”use utf8; use encoding ‘utf-8’;” 等があるとかえってうまくいきませんでした。

YAML::Tiny::DumpFile は、各種データを *.yml ファイルに書き込むために使用しています。
渡すデータの形式に少しクセがあるので、このように使うもの、と覚えてしまった方が良いでしょう。

cron への登録

上記のスクリプトの動作が確認出来たら、後は自動的につぶやくように設定するだけです。
つぶやきの自動化には、cron を使います。

例えば以下のように設定すると、5 分おきにつぶやきます。

*/5 * * * * /home/username/twitbot/twitbot.pl

Twitter API は 1 分あたり 100回まで (2009-06-29 現在) しか実行出来ないという制限があるので、あまり頻度を上げすぎない方が良いでしょう。
もちろん、ボットの属性によって色々と変更した方が良いのは、言うまでもありません。

cron の設定に関して分からない点があれば、このあたりを参照して下さい。

さあ、ごく簡単なボットですがこれで自動的につぶやき続けるボットを作る事が出来ました。
第 3 弾以降では、より高度なボットの作成を行っていきます。

2 thoughts on “Twitter ボットの作り方 Perl 編 (2)

  1. 質問失礼します。

    同じコードで実行しても、”Can’t use an undefined value as an ARRAY reference”
    と出てしまいます。

    何か方法はありますか?

  2. OTCHY.NET の環境では、同じようなエラーが発生しなかったので、何らか環境の違いか、ソースや設定ファイルのどこかが誤っているのだと思います。

    Data::Dumper モジュールを追加した上で、エラーの対象となっている参照に対して、Dumper した情報を見るなどの方法で、デバッグしてみて下さい。

コメントを残す

メールアドレスが公開されることはありません。