JabberでBotを作る
JabberでBotを作ってみた.まず,最小限の設定をDJabberdにしてみる.
<VHost jabber.foo.co.jp> S2S false RequireSSL no <Plugin DJabberd::Authen::AllowedUsers> Policy accept AllowedUsers mac win </Plugin> <Plugin DJabberd::Authen::StaticPassword> Password password </Plugin> <Plugin DJabberd::RosterStorage::SQLite> Database roster.sqlite </Plugin> </VHost>
Psiを使ってmacアカウントでログオンできることを確認.次にBotを作り始める.最初に作ったのはこんな感じ.
#!/usr/local/bin/perl use Bot::JabberBot; use strict; Bot::JabberBot->new( server => 'jabber.foo.co.jp', port => 5222, nick => 'win', password => 'password', resource => 'bot' )->run();
Psiでmacアカウントからwinをコンタクトリストに載せることができたので,ちゃんとwinアカウントでログオンできたらしい.でも,他には何も動かないつまらないスクリプト.というわけで,言われたことを繰り返すスクリプトにすると…,
#!/usr/local/bin/perl use Bot::JabberBot; use Bot::JabberBot::Plugin::Mine; use strict; Bot::JabberBot->new( server => 'jabber.foo.co.jp', port => 5222, nick => 'win', password => 'password', resource => 'bot' )->run();
Bot::JabberBot::saidを再定義することでBotを作ることになっていたので,Bot::JabberBot::Plugin::Mineというモジュールを作って,その中で定義することにした.参考にしたのは宮川さんの書いたプラグインの薦め記事.中身はこんな感じになる.
package Bot::JabberBot::Plugin::Mine; use strict; sub import { my $class = shift; *Bot::JabberBot::said = sub { my ( $self, $said ) = @_; return $said->{body}; } } 1;
これで,alphabetなメッセージなら返事を返すようになった.でも日本語メッセージを送るとBotスクリプトが異常終了してしまう.これはutf-8フラグが立ったままの文字列をsocketで送信しようとしたために起こっているらしい.そこでsocketに書き出す前にフラグを落とすモジュールを新たに作成した.
package Jabber::Connection::Plugin::Mine; use Encode qw(_utf8_off); use strict; sub import { my $class = shift; *Jabber::Connection::_write = sub { my ( $self, $data ) = @_; _utf8_off($data); $self->_log("SEND: ".$data); $self->{socket}->send($data); } } 1;
このモジュールを読み込むようにしたBotスクリプトはこんな感じになった
#!/usr/local/bin/perl use Bot::JabberBot; use Bot::JabberBot::Plugin::Mine; use Jabber::Connection::Plugin::Mine; use strict; Bot::JabberBot->new( server => 'jabber.foo.nttr.co.jp', port => 5222, nick => 'win', password => 'password', resource => 'bot' )->run();
日本語でも異常終了しなくなった.めでたしめでたし.