TwitterのStreaming APIを使うと、流れてくるツイートを常時監視できます。
監視する対象は特定のキーワードだったり、特定のユーザーだったり、特定のサイトを指定したりできます。ユーザーの場合はユーザーのツイートに対するリプライも取得できるので、使って見るとかなり夢が広がるAPIです。
今回はこのTwitter Stream APIをHerokuで無料で監視しつつ、DBに蓄積するPGを書いたのでその紹介をしていきます。
🐮 ソースコード
今回作成したソースコードはこちら。
詳細の説明は省きますが、基本的には環境変数に「TwitterのAPIのキー情報」と「DBへの接続情報」を書いて、後はAPIをEventMachineで監視 => ツイートが取得できたらDBに書き込むようになっています。
今回はこのソースをツイートscan.rb
とします。
require 'rubygems' require 'bundler' require 'mysql2' require 'json'
Bundler.require
require 'twitter/json_stream'
# TwitterのAPIキー情報を環境変数から取得 TWITTER_CONSUMER_KEY ||= ENV['TWITTER_CONSUMER_KEY'] TWITTER_CONSUMER_SECRET ||= ENV['TWITTER_CONSUMER_SECRET'] TWITTER_OAUTH_TOKEN ||= ENV['TWITTER_OAUTH_TOKEN'] TWITTER_OAUTH_TOKEN_SECRET ||= ENV['TWITTER_OAUTH_TOKEN_SECRET'] FOLLOWS ||= ENV['FOLLOWS']
# DBへの接続情報を環境変数から取得 DB_HOSTNAME ||= ENV['DB_HOSTNAME'] DB_USER_NAME ||= ENV['DB_USER_NAME'] DB_PASSWORD ||= ENV['DB_PASSWORD'] DB_NAME ||= ENV['DB_NAME']
EventMachine::run { stream = Twitter::JSONStream.connect( :path => "/1.1/statuses/filter.json?follow=#{FOLLOWS}", :oauth => { :consumer_key => TWITTER_CONSUMER_KEY, :consumer_secret => TWITTER_CONSUMER_SECRET, :access_key => TWITTER_OAUTH_TOKEN, :access_secret => TWITTER_OAUTH_TOKEN_SECRET }, :ssl => true )
stream.each_item do |item| $stdout.print "item: #{item}\n" $stdout.flush
# MySQLへ接続(Postgresなどを使う場合は適宜変更) client = Mysql2::Client.new(:host => DB_HOSTNAME, :username => DB_USER_NAME, :password => DB_PASSWORD || '', :database => DB_NAME)
# Tweetのjsonをパース tw_json = JSON.parse(item)
# DBに格納するためにエンコーディング user_id = client.escape(tw_json['user']['id_str']) user_name = client.escape(tw_json['user']['name']) user_screen_name = client.escape(tw_json['user']['screen_name']) user_image = client.escape(tw_json['user']['profile_image_url']) user_description = client.escape(tw_json['user']['description']) rescue nil text = client.escape(tw_json['text']) post_media_url = client.escape(tw_json['entities']['media'].first['media_url']) rescue nil twitter_status_id = client.escape(tw_json['id_str']) twitter_reply_status_id = client.escape(tw_json['in_reply_to_status_id_str']) rescue nil twitter_reply_user_id = client.escape(tw_json['in_reply_to_user_id_str']) rescue nil twitter_reply_user_screen_name = client.escape(tw_json['in_reply_to_screen_name']) rescue nil
# tweetsテーブルに書き込み client.query("INSERT INTO tweets (user_id, user_name, user_screen_name, text, post_media_url, user_image, user_description, twitter_status_id, twitter_reply_status_id, twitter_reply_user_id, twitter_reply_user_screen_name, updated_at, created_at) VALUES ('#{user_id}', '#{user_name}', '#{user_screen_name}', '#{text}', '#{post_media_url}', '#{user_image}', '#{user_description}', '#{twitter_status_id}', '#{twitter_reply_status_id}', '#{twitter_reply_user_id}', '#{twitter_reply_user_screen_name}', '#{Time.now}', '#{Time.now}')")
# MySQLとの接続を解除 client.close end
stream.on_error do |message| $stdout.print "error: #{message}\n" $stdout.flush end
# 再接続は書いていないです。書いて教えてくださいw stream.on_reconnect do |timeout, retries| $stdout.print "reconnecting in: #{timeout} seconds\n" $stdout.flush end stream.on_max_reconnects do |timeout, retries| $stdout.print "Failed after #{retries} failed reconnects\n" $stdout.flush end }
|
🎳 foremanをつかったプロセス管理
今回のソースはforemanを使っています。Gemfile
に次のコードを追加してbundle install
を実行。
次にforeman用の設定ファイルProcfile
を作成。
tweetscan: bundle exec ruby tweetscan.rb
|
これで設定は完了です。次のコードを実行するとプロセスがスタートして、Twitter Streamの監視を始めます。
ただし現時点では、Twitterのキー情報やDBへの接続情報が登録されていないので失敗します。
🐠 Twitterのキー情報の取得と環境変数への登録
まずは次のサイトでTwitterアプリケーションを登録してください。
(Sign in => アプリケーションの登録)
Twitter Developers
登録したら環境変数にTwitterキーを登録します。まずはローカルへのキー情報の登録です。foremanで管理しているプロセスでは、.env
ファイルに環境変数にしたい情報を書き込むと勝手に読み込んでくれます。
TWITTER_CONSUMER_KEY=xxx TWITTER_CONSUMER_SECRET=xxx TWITTER_OAUTH_TOKEN=xxx TWITTER_OAUTH_TOKEN_SECRET=xxx
|
こういった面倒な手順をふむ理由は、キー情報が第三者に使われると悪いことをされる可能性があるからです。(.env
はgitignore☆)
同じ流れで、DBの情報やAPIの引数なども環境変数に登録してください。
🗻 Herokuへのデプロイ
では、Herokuにソースコードをデプロイ。
(このまえにソースはローカルでGitにコミットしておいてください)
heroku create heroku-twitterscan --stack cedar git push heroku master
|
続いて、環境変数にTwitterのキー情報やDBへの接続情報、APIの引数などを登録。
heroku config:set TWITTER_CONSUMER_KEY=xxx heroku config:set TWITTER_CONSUMER_SECRET=xxx heroku config:set TWITTER_OAUTH_TOKEN=xxx heroku config:set TWITTER_OAUTH_TOKEN_SECRET=xxx
|
ちなみに、HerokuのDBの作成手順などは拙著の次の記事などがオススメです。
Heroku/Posgresqlでよく使うコマンド一覧
Rails4でheroku Pushまでの最短手順 [haml/bootstrap 3.0/postgresql or MySQL]
ということでtwitterscan.rb
のプロセスを起動!
heroku scale twitterscan=1
|
次のコマンドでプロセスが起動しているか、確認できます。
ツイート結果はログからも確認できます!
ということでHerokuの無料枠でツイートをチェックして、DBに格納までする手順でした。
こちらはGitHubでもソースコードを公開しておきます。
morizyun/ツイートscan GitHub
エンジニア経験浅いので、是非いろいろとツッコミをいただければ幸いです。よろしくお願いします!
😎 参考リンク
voloko/twitter-stream
HerokuでStreaming APIを使うTwitter Botを作る | monoの開発ブログ
RubyでMySQLに繋ぐためのruby-mysqlとmysql2 - tagomorisのメモ置き場
Convert datetime to mysql format on Ruby on Rails - Stack Overflow
🖥 VULTRおすすめ
「VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。
最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!