PHPでTwitterのBotを作ってみる - yuyarinの日記
をrhacoで実装しようと思います。使用するrhacoはrev.2594(2008/1/21時点でのtrunk)です。
初期設定
※ 作業中は作業フォルダ以下の全てのフォルダ/ファイルのパーミッションを777(あるいはapacheが読み書きできる属性)にしておいてください。またブラウザ上で作業した際にできたファイルは通常ユーザ権限でアクセスできません。管理者権限で属性を変更する必要があります。(suexecとか windows環境なら気にしなくていいです)
適当な作業フォルダを作り、rhacoフォルダにあるsetup.php(管理画面)をそこにコピーし、それをブラウザから実行します。
最初にrhacoのライブラリのパスを聞かれるので、適当に指定します。
するといろいろ設定画面が出てきますが、とりあえず何も考えずにどこかの「生成」ボタンを押します。
作業フォルダにいろいろ追加されているのがわかると思います。
今回はTwitterにアクセスするので、拙作のTwitterAPIを使用します。
http://rhacolibs.googlecode.com/svn/trunk/network/services/TwitterAPI.php
からダウンロードし(必ず最新のものを使用してください)、作業フォルダのlibrary/network/services/以下に入れてください(library以下は空だと思うのでフォルダは自分で作ってください)。
データベース設定
重複して反応しないように、既読メッセージはデータベースに格納し、それをチェックするようにします。今回はMySQLを使用しますが、SQLiteでも構いません。
管理画面に入り、画面上部に並んでいるメニューから[編集]を選択します。
すると大きめのtextareaに以下のような記述があります。
<project rhacover="1.4.1" version="1.0.0" name="rhacobot" xmlns="http://rhaco.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://rhaco.org http://media.rhaco.org/project.xsd"> </project>
これを以下のように変更し、「更新」を押します。
<project rhacover="1.4.1" version="1.0.0" name="rhacobot" xmlns="http://rhaco.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://rhaco.org http://media.rhaco.org/project.xsd"> <database name="twitterbot"> <table name="deduped"> <column name="id" type="integer" primary="true" /> </table> <table name="keywords" admin="true"> <column name="id" type="serial" primary="true" /> <column name="keyword" type="string" size="255" require="true" /> </table> <table name="replies" admin="true"> <column name="id" type="serial" primary="true" /> <column name="keyword_id" type="integer" reference="keywords.id" require="true" /> <column name="reply" type="string" size="255" require="true" /> </table> </database> </project>
更新されたら、[setting]を選択します。最初と比べると「データベースの設定 [twitterbot]」という項目が追加されています。
ここに各自のデータベース設定を入力し、「生成」を押します。データベースが作成されていない場合は別途作成しておいてください。
さらに[exe]を選択します。「データベースの設定 [twitterbot]」という項目があるので、「テーブル作成」の「作成」を押します。これで上で指定した構造がtwitterbotデータベースに投入されます。
実装
作業フォルダにindex.phpというファイルを作り、以下のように記述します。
<?php include_once("__init__.php"); Rhaco::import("generic.Flow"); Rhaco::import("network.services.TwitterAPI"); Rhaco::import("database.DbUtil"); Rhaco::import("database.model.Criteria"); Rhaco::import("abbr.Q"); Rhaco::import("model.Deduped"); Rhaco::import("model.Keywords"); Rhaco::import("model.Replies"); $login = "nazobot"; // BOTのTwitterのID $password = "pass"; // BOTのTwitterのPassword $flow = new Flow(); $twitter = new TwitterAPI($login, $password); $db = new DbUtil(Deduped::connection()); $timelines = $twitter->status_friends_timeline(); foreach($timelines as $line) { // 重複チェック $c = new Criteria(Q::eq(Deduped::columnId(), $line['id'])); $deduped = $db->get(new Deduped(), $c); if (!$deduped) { // 新規データなので発言を調べる $talk = $line['text']; if (strpos($talk, '@'.$login.' ') === 0) { // 自分に向けられた発言 $len = strlen($talk); $at_len = strlen('@'.$login.' '); $command = substr($talk, $at_len, $len - $at_len); $command = html_entity_decode($command, ENT_QUOTES, 'UTF-8'); // commandが一致するかを調べる $c = new Criteria(Q::eq(Keywords::columnKeyword(), $command)); $keyword = $db->get(new Keywords(), $c); if ($keyword) { // 置換語があるかどうかを調べる $c = new Criteria(Q::eq(Replies::columnKeywordId(), $keyword->getId())); $replies = $db->select(new Replies(), $c); if (count($replies) > 0) { $reply = $replies[rand() % count($replies)]; // ランダムで返答を決定 $twitter->status_update('@'.$line['user']['screen_name'].' '.$reply->getReply()); // 実際に発言する } } } // 重複にする $deduped = new Deduped(); $deduped->setId($line['id']); $deduped->save(); } } $flow->write("index.html");
さらにlibrary/model/Keywords.phpに以下の記述を追加します。
<?php Rhaco::import("model.table.KeywordsTable"); class Keywords extends KeywordsTable{ // ここから追加 function toString() { return $this->getKeyword(); } // ここまで追加 } ?>
resources/templates/index.htmlも作ります。
<html> <head> <meta http-equiv="Refresh" content="120;URL={$rhaco.url('index.php')}"> </head> <body> <p>120秒後に自動リロードされます。</p> </body> </html>
データの登録
発言するデータを登録します。
[db]を選択すると、「Keywords」「Replies」という二つの項目があります。Keywordsに反応する発言を、Repliesに返答を登録していきます。
試しに「Keyword」を選択し、「追加」で、「こんにちは」と入力して「保存」します。
次に「Replies」を選択し、「追加」で、「keyword_id」を「こんにちは」、「reply」を「今日はいい天気ですね!」にして「保存」します。
これで準備は完了です。
実行
ブラウザからindex.phpを開くと実行されます。
誰かが「@あなたの名前 こんにちは」と発言すると自動で「@対象 今日はいい天気ですね!」と返します。
ほっとくと自動リロードします。cronが使えるならそちらのほうがいいと思います。