3
2009
よく見かけるサイト風なtwitterのbotを作ってみる
きっかけ
海外のblogのタイトルを日本語に訳して、その記事を紹介してるだけのサイトをよく見かける(例えば、phpspot開発日誌やコリス)。もちろん、それ自体を否定する気はさらさら無いのだが、そういうのって、実はある程度自動化でできたりするんじゃないかと思う。そんなわけで、そういう仕組みを作りたいのだが、ちょうどtwitterでbotを作りたいと思っていたので、twitterを土台にしてやってみることにする。
処理の流れ
- Web開発者向け記事のまとめサイトの元の記事のフィードを寄せ集めて、取得する。
- それをtwitterに流す
以上が簡単な処理の流れ。では、以下にコード(使用するのは、PHP)ありの紹介をする。
ちなみに、めんどくさいので、できるだけシンプルな実装で進めていく。なお、元の記事のタイトルを翻訳するという考えもあったが、BingのTranslator APIがうまくいかなかったのと、Googleじゃ翻訳精度悪すぎだろとかで現段階では不採用とする。
1. フィードを集める
はじめに、なぜもうすでに日本語訳してくれたまとめサイトの方を紹介しないのかというと、それじゃあつまらないとか、元記事も紹介したいので、かぶったときにめんどくさいとか、そういう理由なのである。
とりあえず、人気なサイトが分からないので、適当に挙げてみた候補が以下。
とりあえずなところ、この辺。現段階では。
2. 複数のフィードをいい感じに処理する
サーバーの負荷の軽減や処理をシンプルにするため、できるだけアウトソーシングしたいので、フィードを集めて時間順に並べるのはPipesに委ねることにする。Pipeを作るには、Yahoo.comのアカウントが必要である。たぶん、Yahoo! JAPANのアカウントじゃだめなはず。
Yahoo.comのアカウント登録などは、ここを見てる猛者なら簡単に自分でできるはずなので割愛する。ここでは、Pipeの作り方を紹介する。しかし、何となくそれらしきものをつなぎ合わせてるだけなので以下が本当に正確かどうかはわからない。でも、何も知らなくてもインタラクティブに作れるPipesは本当にすごい。米Yahoo万歳!
というわけで、ここでは一切コードを書かない。
2.1 まず、Create a pipeをクリックする。
2.2 Fetch Feedを右にドラッグし、フィードのURLを入力する。
2.3 Unionをクリックして、それらをPipeでつないでいき、完成
Unionはようするにそれらをまとめるものである。
以上で、複数のフィードをひとつにまとめることができる。
え?もう終わり?という感じだが、終わりなのである。
ここでは説明しなかったが、そのほかにも日付順でソートしたり、もっとたくさんのフィードをまとめたり、いろいろフィルターしたりフィード以外の機能等、様々なことがPipesでできる。
3. フィードから情報を抜き出す
simplexml_load_fileを使うと一瞬でできる。ものすごく手続き型で設定もソースの中に書いてるなど、色々突っ込みどころはあるだろうが、シンプルを極める実装なので以下で良いのである。
function getData() {
$xml = simplexml_load_file('あなたのフィードのURL');
$time = time() - 60 * 15;
$data = array();
foreach ($xml->channel->item as $key => $item) {
if (strtotime($item->pubdate) > $time) {
continue;
}
$data[] = array(
'url' => $item->link,
'title' => $item->titl
);
}
return $data;
}
cronで15分置きにこのPHPを読むと見越して、15分前から今の間に更新されたリンクのみのデータを返す。
4. tweetする
Twitterでつぶやくことは、tweetであってる…よね?参考リンク1のとおりにやったら驚く程すんなり行った。
function tweet($message = '') {
$url = 'http://twitter.com/statuses/update.xml?';
$username = 'あなたのユーザー名';
$password = 'あなたのパスワード';
$params = "status=". rawurlencode($message);
$result = file_get_contents($url.$params , false, stream_context_create(array(
"http" => array(
"method" => "POST",
"header" => "Authorization: Basic ". base64_encode($username. ":". $password)
)
)));
}
5. full source code
<?php
$startTime = microtime(true);
require_once('SOAP/Client.php');
function getData() {
$xml = simplexml_load_file('あなたのフィードのURL');
$time = time() - 60 * 15;
$data = array();
foreach ($xml->channel->item as $key => $item) {
if (strtotime($item->pubdate) > $time) {
continue;
}
$data[] = array(
'url' => $item->link,
'title' => $item->title
);
}
return $data;
}
function tweet($message = '') {
$url = 'http://twitter.com/statuses/update.xml?';
$username = 'あなたのユーザー名';
$password = 'あなたのパスワード';
$params = "status=". rawurlencode($message);
$result = file_get_contents($url.$params , false, stream_context_create(array(
"http" => array(
"method" => "POST",
"header" => "Authorization: Basic ". base64_encode($username. ":". $password)
)
)));
}
function endProcess($message, $startTime) {
die($message.':'.microtime(true) - $startTime);
}
// データを取得
$data = getData();
// データがなければ終了
if (!count($data)) {
endProcess("Warning: No data!!", $startTime);
}
// tweetする
foreach ($data as $key => $value) {
tweet($value['title'].' -> '.$value['url']);
}
endProcess("Success: OK!!", $startTime);
?>
このPHPをcron設定したら自動botの完成である。やったー。パチパチ。
できあがったものはこちら→web_devel (web_devel) on Twitter
※ ちなみに今はレンタルサーバーの性質上、cronの間隔を60分に設定しているため、ウルトラできそこないbotとなっている。
6. 今後の拡張
- OOP化するなどして、再利用性、拡張性、自己満足性を高めてみる。
- フォロー周り
- Feedの追加の効率化
- @やDirect messageなど
- 翻訳して投稿





An article by yuyak