Heroku Mongolab + RubyでTwitter Stream APIのJSONを保存【EventMachine】


TwitterのStreaming APIをいろいろといじっています。今回はMongoLabがJSONをそのまま保存できるというのを最近おしえてもらったので、勉強がてらMongoLabを触ってみました。

また、この機会にRubyのEventMachineについても多少勉強したり、資料を探してみたので合わせて
紹介いたしやす!


😸 Mongoの基本を学ぶ

MongoDBの基本は、安定のドットインストールで!

あとは英語ですが、MongoDB Ruby Driver Tutorialを読めば最低限の操作は理解できそう。

🎳 EventMachineの基本を学ぶ

RubyのEventMachineですが、海外の入門PDFをナイスに翻訳してくれているこちらが一番オススメ。

こちらはEventMachineを使ったアプリケーションの一例。なかなか悪くない!

🤔 サンプルソース

Gemfile

まずは今回使ったGemfile。

ruby '2.1.0'

source 'https://rubygems.org'

gem 'tweetstream'
gem 'eventmachine'
gem 'mongo'
gem 'bson'
gem 'bson_ext'
gem 'foreman'
gem 'dotenv'

🐝 Twitter Stream API => MongoDBのソース

Twitter Stream APIから取得したJSONをそのままMongoDBに保存するまでのRubyのソースコードです。

大まかなプログラムの流れはこちら。

(1) MongoDBからFollowersの一覧を取得
(2) Twitter Stream APIでFollowersを監視
(3) Tweetが流れてきたらMongoDBにJSONをそのまま保存
(4) Followersが増えたらworkerをエラー終了(herokuでworkerとして起動した場合は、エラー終了しても再起動してくれる)
require 'rubygems'
require 'bundler'

Bundler.require
Dotenv.load unless ENV['MONGODB_URL']

# MONGODBへの接続
connection = Mongo::Connection.from_uri(ENV['MONGODB_URL'])
@db = connection.db(ENV['DB_NAME'])
@db.authenticate(ENV['USER_NAME'], ENV['PASSWORD'])
@tweets = @db.collection('tweet')

# (1) MongoDBからFollowersの一覧を取得
def get_followers_id
@followers = @db.collection('follower')
@followers.find().map{|f| f['id'].to_i }
end
@followers_id_list = get_followers_id

TweetStream.configure do |config|
config.consumer_key = ENV['TWITTER_CONSUMER_KEY']
config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
config.oauth_token = ENV['TWITTER_OAUTH_TOKEN']
config.oauth_token_secret = ENV['TWITTER_OAUTH_TOKEN_SECRET']
config.auth_method = :oauth
end

@count = 0
EM.run do
client = TweetStream::Client.new

# (3) Tweetが流れてきたらMongoDBにJSONをそのまま保存
def write_to_mongodb(status)
EM.defer do
$stdout.print "status: #{status}\n"
$stdout.flush

# tweetを保存
@tweets.insert({status: status})
end
end

# (2) Twitter Stream APIでFollowersを監視
client.follow(@followers_id_list) do |status|
write_to_mongodb(status)
end

# (4) Followersが増えたらworkerをエラー終了
EM::PeriodicTimer.new(ENV['FOLLOWER_CHECK_INTERVAL']) do
new_followers_id_list = get_followers_id
EM.stop if new_followers_id_list and new_followers_id_list != @followers_id_list
end
end

今回は、Twitter-Stream-API用Gemに『tweetstream/tweetstream』を使いました。アップデートの頻度が高いことと、説明が充実していたからです。

.envの読み込みをしてくれる『dotenv』をはじめて知って使いました。pryでデバッグするのを助けてくれます。

あとログを残したいのでAddonを検討中。Pure Rubyでログを残すときにお勧めの方法とかあればぜひ教えてください。

Procfile

今回のProcfileはこちら。

worker: bundle exec ruby tweet_stream_to_mongodb.rb

今回はプロセス名をワーカにしました。ワーカの場合は異常終了した場合に、再起動をしてくれるそう。はじめて知りましたが、これはTwitter stream APIのように通信の失敗などでこけることがあるプロセスにはほんとうにうれしい仕様。

参考リンク

Elämä on — 実質無料!Rubyで作りMongoDBで保存しHerokuで運用するコスパ最強のTweet収集方法

.env: 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: MongoDBの接続設定

まずはMongoDBでDBとユーザーを作成。

mongo
use db_name
db.addUser("user_name","password");

db.auth('user_name','password')
#> 1 # <= となっていれば成功< span>

次に、localhostでのMongoDBの接続設定。DB_NAME, USER_NAME, PASSWORDを入力して登録。

MONGODB_URL=mongodb://localhost
DB_NAME=xxxx
USER_NAME=xxxx
PASSWORD=xxxx

参考リンク

mongodbユーザ認証有効化 - Studio3104::BLOG.new

🐮 Herokuへのデプロイ

では、Herokuにソースコードをデプロイ。

(このまえにソースはローカルでGitにコミットしておいてください)

heroku create APP --stack cedar
git push heroku master

続いてMongoLabのAddonを追加。

heroku addons:add mongolab

次のコマンドで接続情報をブラウザで見れるので、その情報をHerokuの環境変数に登録。

heroku addons:open mongolab

Twitterのキー情報やDBへの接続情報もHerokuの環境変数に登録。

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 scale worker=1

ということでHerokuの無料枠の中で、ツイートをそのままJSONとして保存できるようになりました!

🏀 Special

mongodb-driver-examples/ruby/ruby_simple_example.rb at master · mongolab/mongodb-driver-examples

rubyでmongodbを使ってみる by mongolab - shoprevのブログ

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍