こんにちは、sovaのはき猫です。
とあるメンバーから「Twitterでハッシュタグ検索って簡単に出来ない?RTの多い順で並べられたらいいなー」的なことを言われたので、作ってみました。
TwitterAPIをちゃんと触るのが初めてだったので、いい機会だと思い、Railsを使ってさくっとできる範囲で実装してみました。
結果的には初めてTwitter APIを触ったのですが、調査から完成まで2時間程度で出来ました。さすが天下のTwitter、APIもよく出来ていますね。
完成物
完成物はherokuにアップしていますので、以下から画面を見ることができます。
デザイン部分は素のBootstrapで作っています。
https://sova-twitter-sample.herokuapp.com/
また、ソースコードはgithubで公開しているので、興味のある方は見ていただければと思います。
https://github.com/sova-lab/twitter-rails-sample
RubyでTwitter APIを使う方法
rubyからTwitter APIを使うにはtwitterというgemが一番よさそうです。
https://github.com/sferik/twitter
Twitter APIには大きく2種類のAPIがあります。
- REST API
- Streaming API
REST APIはその名の通り、一度APIを叩くとリクエストに対応したレスポンスが返ってくる、いわゆるREST APIです。
それに対してStreaming APIはリアルタイムにtwitterでつぶやかれている情報を取得することができるAPIです。
今回はハッシュタグの検索なので、REST APIの方を使いたいと思います。
Twitter APIの各種キー情報の取得
各種キー情報については以下のページからTwitter APIの利用の登録をしたのちに確認することができます。
ググるといろいろな情報がヒットしますので、詳細についてはここでは割愛します。
twitter gemを使ってハッシュタグの情報を取得してみる
まずは素のRubyを使ってハッシュタグの情報を取得してみます。
コマンドラインからの実行時引数にハッシュタグを与えると、最新のツイートを10件取得する、というサンプルを実装します。
実際のコードは以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
require 'twitter' client ||= Twitter::REST::Client.new do |config| config.consumer_key = 'your consumer key' config.consumer_secret = 'your consumer secret key' end if ARGV[0].nil? puts 'Error occurred. Please specify tag id.' puts 'Usage: ruby twitter_hashtag.rb tag_id' exit 1 end tag = ARGV[0][0] == '#' ? ARGV[0][1..-1] : ARGV[0] client.search("##{tag}", lang: 'ja', result_type: 'recent', count: 1).map do |tweet| puts "#{tweet.user.name}: #{tweet.text}" end |
まず、1行目でtwitter gemを読み込みます。
次に3〜6行目でtwitter gemのRest Clientを利用するためのキー情報を設定します。このキー情報はTwitterから発行されたキーを設定してください。
8〜12行目は引数がなかった場合の例外処理です。
14行目で引数のタグ情報を抽出しています。引数に 「#hoge」 or 「hoge」 のどちらを入力しても問題ないように処理を入れています。
16〜18行目でタグがついたツイート情報を取得しています。実際の処理部分はここだけになります。
とても簡単にできましたね。これだけで特定タグのついたツイート情報が取得出来ました。
twitter gemについてはドキュメントに詳細に書かれているので、気になった方は見てみてください。
http://www.rubydoc.info/gems/twitter
Railsに組み込んでみる
今回試したのはこれがほぼ全てなのですが、最後にRailsに組み込んでブラウザからハッシュタグを入力するとRT順に表示するように実装してみます。
Model
サンプルということで、TwitterのREST APIクライアントの生成はmodelのメソッドで実装してしまいます。
(本来はinitializerで実施出来るようにした方がよいかと思います)
modelはDBとの接続は持たないのですが、validation機能を使いたかったので、継承ではなくincludeにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class MyTwitter include ActiveModel::Model attr_accessor :tag, :limit, :tweet validates :tag, presence: true def client @client ||= Twitter::REST::Client.new do |config| config.consumer_key = "your consumer_key" config.consumer_secret = "your consumer_secret" config.access_token = 'your access_token' config.access_token_secret = 'your access_token_secret' end end end |
Controller
基本的には素のRubyで作った際のロジックをそのままControllerに実装しています。
ほぼ同じなので、説明は省略します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class TwitterController < ApplicationController def index @twitter ||= MyTwitter.new end def tweet @twitter ||= MyTwitter.new if @twitter && params[:tag] @twitter.tag = params[:tag] tag = @twitter.tag.slice(0) == '#' ? @twitter.tag.slice(1, 999) : @twitter.tag @twitter.tweet = @twitter.client.search("##{tag}", lang: "ja", result_type: 'recent', count: params[:limit]).map do |tweet| { icon: tweet.user.profile_image_url, name: tweet.user.name, text: tweet.text, rt: tweet.retweet_count } end.sort do |a, b| b[:rt] <=> a[:rt] end end render action: 'index' rescue => e logger.error e.message flash[:error] = "エラーが起きました[#{e.message}]" render action: 'index' end end |
冒頭でも書きましたが、ソースの全容と動作サンプルはリンクを貼っていますので、興味あれば見てみてください。
動作サンプル: https://sova-twitter-sample.herokuapp.com/
コード: https://github.com/sova-lab/twitter-rails-sample
最後に
RTされたツイートが連続で出てしまってまだ格好悪い部分はありますが、簡単に動くものが出来てしまいました。今回twitter gemを初めて使って実装してみましたが、初期調査から画面を作るまで、大体2時間程度で出来てしまいました。Rubyをお使いの方でTwitterAPIを使ってごにょごにょやろうと思っている人は是非twitter gemを使ってすてきなTwitterライフを送ってみてはいかがでしょうか。
So, what do you think ?