RSSをツイートするbotを作ってみた
SATOXがTwitterを始めた頃。
……2008年の4月ですよ。
この頃のTwitterは「1日回ツイートしないとメール通知が来る」というえらい仕様がありました。
この設定はオフにできたと思いますが、そうしてはなんだか負けた感じがしたんですよね。
それだったら、当時からブログはほぼ毎日更新していた事を利用して、RSSを元に自動でTwitter投稿してくれればメール通知を抑止できると思いました。はい、おかしな理論です(笑)。
で、それが実現できたTwitterFeedを使い始めたんです。
でもTwitterFeedは日本語にいまいち弱かったり、好きなようにカスタマイズできないという問題がありました。
一方でレンタルサーバを月500円で借りていて、このサーバーを使い倒さないと損だよなぁという貧乏心と、「作ってみたい」という衝動から自作のRSSツイートサービスを作ろうと思い立ったわけです。
前置きが長かったですけど、結論から言うと、オリジナルのTwitterへツイートするRSS投稿サービスが稼働中です。
以下、肝心なところは割愛しますが、要点だけ書いてみます。
PHPでツイート!
こちらのPHPライブラリを使わさせて頂きました。https://github.com/abraham/twitteroauth
もちろん Twitter REST API v1.1に対応しています。
恐ろしいことですが、これだけでツイートできます。
// OAuthオブジェクト生成 $twitter = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret); // ツイート! $twitter->OAuthRequest("https://api.twitter.com/1.1/statuses/update.json", "POST", array("status"=>"ほげほげ"));
かんったん!これだけで「ほげほげ」がツイートされます。
もちろん、Twitter開発サイトで該当アカウントにアプリケーションを登録し、各キーを入力しておく必要があります。
RSSを取得
このツイート処理を書いたphpを叩いたときに、この日記のRSS(XML)を取得して、ツイートすればいいわけです。PHPでXMLを取得するにはこれだけ。
// RSSの取得 $rawxml = simplexml_load_file('http://d.hatena.ne.jp/satox/rss');
さらにパースしてあげれば記事タイトルをゲットできます。
$xml = get_object_vars($rawxml); $postitem = get_object_vars($xml['item'][0]); $title = $postitem['title'];
Tiny URLを使う
これもTwitterにお任せすれば良い話ですが、簡単に短縮URLを利用できたのでご紹介。$tinyurl = file_get_contents("http://tinyurl.com/api-create.php?url=" . $original_url);
URL($original_url)をこれだけで短縮できます。
Tiny URLのサービスが停止したらいろいろ終わりです(笑)。
cronの設定
さくらインターネットのレンタルサーバでのコマンドですが、以下のようにします。要するに、PHPを実行するコマンドです。
これで例えば1時間に一回呼ばれるように指定することで、その間隔でRSSを調べてツイートしてくれるといったあんばい。
さらに「同じ文言のツイートはTwitterサーバ側に蹴られる」という仕様を利用すれば、1日1回更新された記事タイトルがツイートできる……と思ったのですが、問題発生。
同じ文言をツイートできるのは1日1回。つまり、翌日になるとまたツイートされてしまうんです。
これはうざい。
データベースを使う
こうなったら自棄です。自棄はやけと読みます。一度ツイートした内容をDB(MySQL)に保存し、ツイートの度に2回目以降、同じツイートは投稿しないように抑止すればいいわけです。
そこまでする意味があるかどうかは、もはやどうでも良いのです。
やりきります。
これではDBのレコードが貯まる一方だ
まぁ容量的には無視しても一生大丈夫なものですが、日々記事タイトルのレコードがDBに増えていくのは気持ちの悪いもの。また、同タイトルを調べるという仕様の場合、たまたままた同じタイトルの記事を過去に書いた場合、2回目はツイートされないことになります。
そこで、10日以上経ったレコードを消すSQLクエリを書いてみました。
timestampというレコードのタイムスタンプフィールドがあるのが前提です。
$syntax = "DELETE FROM ". SQL_TABLE_NAME . " WHERE timestamp<=sysdate() - interval 10 day"; $result = mysql_query($syntax);
SELECTなんか要りません。これだけで10日以上経ったレコードが消えます。
記事を書いたらすぐにツイートされてしまうのは如何なものか
「記事を書いたら自動でツイートした。」「でも、四六時中ツイートするのはちょっと目障りになりそう。」
……じゃあ深夜にツイートしようと思い立ったわけです。
つまり、cronにより1時間に1回PHPはキックされますが、深夜以外は処理をキャンセルしてツイートしないようにしたいわけです。
こんな関数を使って3時〜6時だけツイートするようにしました。
function isNight() { $hour = intval(date("H")); if ($hour >= 3 && $hour <= 6) { return TRUE; } return FALSE; } if (isNight() === TRUE) { // RSS取得とDBチェックとツイート; }
cronがホントに動いてるのか
心配になるのがcronがホントに動いてるのかということ。アクセスログに文字を書き出すPHPのコード。
$now = date("Y-m-d H:i:s"); error_log($now . " tweet canceled\r\n", 3, 'access.log');
access.logと言うファイルに1番目の引数が書き足されます。
かんたーん。
でも、こんなログ貯めてたら、DBの容量を気にしている意味ないじゃん……というのがオチです。