クフでダローバルな日記

タフでもグローバルもない

素人大学生がhatenaAPIをイジって hatenastarのはてブランキングbot作ってみた。

「素人大学生」という甘美な響きですが、残念ながら男です。
趣味でプログラミング(しかも初歩)をやってるだけの大学生で、まだ情報系の学部に所属しているわけでもなんでもないんですが、こんなtwitter botを作ってみました。
毎時0分ごろにはてなのホットエントリを取得し、それらのブコメの中でhatenastarが多く付いているツイートを通知するbotです。









せっかく作ったのでノウハウの伝播や宣伝も兼ねて記事を書いてみようと思います。

動機

数日前こんな記事がはてブでホットエントリ入りしていましたね。
はてブAPIでwebサービスを作りたい全ての人に向けて書きました - Syncer

twitterapiはgemでそれなりに簡単に(理解していなくても)使えたし、丁度はてブapiも使ってみたいと思っていたところだったので、まさに自分のための記事ではないかと。即効ブクマしたわけです。
1000超えという驚異的なブクマ数ですが、おそらく多くの人が「あとで読む」状態になっていることのご多分に漏れず、僕も「ブクマしたはいいけど何作ろう…」と考えこんでしまうことに。

そこで思いついたのは、はてブ、というかはてな村の最大の特徴である大喜利とそれに付いたhatenastar。僕は弱小なので一風堂で食中毒になった時(参考:はてなブックマーク - 朝日新聞デジタル:ラーメンの「一風堂」総本店で食中毒 営業停止1日 - 社会)くらいしか星がたくさんはつかないのですが、多くの人が風刺やダジャレや凍て付く波動によってhatenastarを稼ごうと画策しているのがはてな村ですよね。
ただ、hatenastarは各記事内でのランキングしか見れない。しかも「人気」タブが必ずしもランキングを反映しているわけではない(ソートされているわけではない)、などなどの理由から、いろいろな記事でのhatenastarを比較したら楽しいんじゃないかと思い、hatenastarをランキングにし、それを一時間に一回通知するbotを作ろうと思い至った訳です。

botの概要

言語:Ruby
環境:Heroku
説明:「一時間ごとにはてブのホットエントリ内全てのエントリーで、付けられたはてなスターのランキングtop10を通知するbotです。[黄色、緑、赤、青]がそれぞれ[1,3,6,10]ポイントです。」

作業記録

ソースなどはhttps://github.com/mazamachi/hatenastar_tweetに上がってます。見ていただければわかると思うのですが、オブジェクト指向というものが全く出来ておらず、滅茶苦茶見づらいです。
とりあえずTwitter botは作ったことがあったので、その手順を追いました。
$ heroku create
でheroku appを作り、gitで色々し(よく分かってない)、gem 'twitter'を使うと。

なので肝心なのははてなapi部分なのですが、本当にずぶの初心者なので、そもそもJSONというものがよく分からないレベル。Javascriptに関しても学校で触ってみたときについでにちょっと勉強したレベルなのでいまいち見た目がよく分からない。
でも、そんな人でも大丈夫。そう、rubyならね。
rubyにはもともとmodule JSONがあるので、JSON.parse(url)でJSONを元にハッシュができます。
(主にこの辺のことはこちらのサイトを参考にしました:RubyではてなのブックマークのAPIを利用してみる - yk5656 diary)
JSONを取得するためのurlはエンコードしておかなきゃならないのですが、それもrubyなら require 'uri'をしておけば URL.escape(url)でOK.
ブコメパーマリンクを作成するのも、ブックマーク情報から簡単に出来ました。

ここまで実行してみると403エラー。原因はよくわからないんですが、多分一気に500回もJSONを取得するなんてどう考えてもアクセスしすぎですよね。
そこでurlを&=でつなごうと思ったのですが、今度は逆にURLが長過ぎる414エラー。
結局、パーマリンクを200個ずつ繋げることで解決しました。

つぎにホットエントリの取得ですが、これはRSSRSSも使ったことはあったのですが、どういうものなのかは全く知りませんでした。
でも大丈夫。そう、rubyならね。
JSONの場合と同じくRSSモジュールがあるので、feedのurl(feed_urlとします)が与えられた時、
RSS::Parser.parse(feed_url)
でこれも簡単にハッシュ化できます。

ただ、ブコメパーマリンクからJSONを取得すると、そのブコメがどのページをブックマークしたものなのかわからない。これは最後にツイートするときに困ると思い、["(ブコメのURL)",スコア,"(entry_url)"]という配列を操作するようにすることで解決しています。

そして最後のツイート部分。
エントリーのURLとユーザー名はわかっているので簡単にコメントは取得できて、ツイートも簡単に作成できる…んですが、twitterbotで投稿するときの最大の敵「140文字」及び「重複禁止」。
重複禁止はいつも通り各時間帯をツイートに追加することでどうにかなったんですが、困ったのは140文字。urlはどうしても付加したかったのですがそれはやはり最後に置きたい。本当はTwitterで使用しているt.coの長さを使いたかったのですが、Twitterクラスの使い方がやはりよく分からない。Oauth認証が必要なときのメソッドの使い方ってどうやるんだろう?
と、結局わからないままなのでbit.lyを使うことにしました。これもやはりgemが用意されているので簡単。
参考にしたサイトはこちら:Rails3で、bitly.comを利用した短縮URLを作成する - Qiita

これをつかえばツイートが生成できたので、あとはツイートするだけ。簡単(作業時間多分トータルで10時間くらい)。

これだけでも良かったのですが、せっかくなので高速フォロー機能もつけてみました。これについては前に書いた記事を見てみてください(twitterのStreaming APIを使った高速自動フォロー返し with ruby on Heroku - クフでダローバルな日記)。

感想と心残り

JSONとかRSSをハッシュ化すると超楽!何もできないことはないのではないかと思ってしまうレベルですらありました。やっぱりRubyは楽しい!!
ただ、やはりソースが汚い、オブジェクト指向がわかっていない、gitとかのツールを全く使いこなせない、などなどの反省点は多いです。
ただもう今まで素因数分解するだけの素数時計bot(@)、文字列検索するだけの円周率カレンダーBOT(@)しか作れなかったところから考えれば、まぁそれなりに有用な(?)BOTを作れるように成長できたのかなと思います。

今後はこのランキングに登場した回数をまたランキングにしてみたりするのも楽しいのかなとも考えてます。
あと、星の色に対するポイントをどうすればいいのかとかいまいちわからず、カラースターの扱いが結構軽くなってしまいました。
なんかこうすべきだみたいなのがあれば言ってください。

はてな村の皆さんがmixiをdisったり東京で消耗したり増田文学を批評したりして楽しいhatenastar ライフを送るお手伝いができたら光栄です。
そんじゃーね(小声)

アイコンについて

f:id:SWIMATH2:20140625033446p:plain
アイコンが思い浮かばなかった……13! = 6227020800ですがそんなに星つくことはまぁないでしょうね
なんかイイアイコンあればください(懇願)