割りとしょうもないところではまったのでメモ。
Rails4, Ruby 2.0の環境。
Grackle gem: https://github.com/hayesdavis/grackle
RailsでTwitterを連携させる場合は twitter_oauth gem ( https://github.com/moomerman/twitter_oauth ) が定番みたいだけど、やりたいのは自分のアカウントの最新ツイートの表示だけなので、何となく軽そうに見えたGrackleを使用。
使用するドメインとかサーバーとかが既にあるものとして進める。まずはTwitter側から。
既存のTwitterアカウントを使うか、新規でTwitterアカウントを作成する。新規の場合何がしかテスト投稿しておく。
そのTwitterアカウントで https://dev.twitter.com/ にサインインする。
https://dev.twitter.com/apps を開いて (なぜかリンクが見あたらない)、Create a new applicationをクリック。必要事項を記入してアプリケーションのプロファイルを作成する。
アプリケーションのプロファイルのDetailタブをクリックし、下の方にある Create my access tokenをクリックする。こうしないとトークンが生成されない。トークンがなくても通信はできるような気もするけど、一応作成した。
今度は OAuthタブに移動。以下の4つの項目にキーが長々と入っていれば準備完了。
Consumer key:
Consumer secret:
Access token: *
Access token secret:
ちなみにそのページの下に See OAuth Signature for the requestというボタンがあり、Request Type/Request URI/Request queryを指定してクリックするとクエリが生成される。curlはコマンドラインに貼り付けて実行を確認できる。このクエリの中にはoauth_signature、oauth_signature_method、oauth_timestamp、oauth_token、oauth_versionという必要そうな項目があるのだけど、少なくとも今回の使い方ではこれらの値は不要ということがわかった。
今後はRailsの方。
- 以下をGemfileに追加して、
bundle update
とbundle install
を実行する。
gem 'grackle'
- app/models に tweet.rbファイルを作成し、5.で準備した4つのキーを入力する。コードは以下。
require 'grackle'
class Tweet < ActiveRecord::Base
MY_SCREEN_NAME = '表示名を入力'
def self.get_latest
tweets = client.statuses.user_timeline? screen_name: MY_SCREEN_NAME, trim_user: true
end
private
def self.client
Grackle::Client.new(:auth=>{
type: :oauth,
consumer_key: 'キーを入力',
consumer_secret: 'キーを入力',
token: 'キーを入力',
token_secret: 'キーを入力'
})
end
end
このコードはhttp://www.arctickiwi.com/blog/download-you-twitter-feed-using-ruby-on-rails-with-oauth からのいただきなのだけど、定数がMY_APPLICATION_NAME となっていたために、表示名ではなく自分のアプリケーション名を入れてしまい、それに気が付くのに時間がかかった。
- いよいよ
rails console
を実行し、Tweet.get_latest
を実行。最新ツイートを含む文字列が返されたらOK。後は好きに使う。
もしうまくいかないときは、キーと表示名を再度確認。
なお、コードをGithubなどで公開する場合は、consumer_secretキーとtoken_secretキーをファイルに直に書かないこと。面倒でも ENV['CONSUMER_SECRET']
や ENV['TOKEN_SECRET']
と書き、環境変数に保存するようにすること。詳しくは http://blog.ruedap.com/2011/05/03/ruby-heroku-web-app-development-tips-5 を参照。
今回初めて知ったのだけど、statuses/public_timeline はTwitter API 1.1で廃止されていた。以前はpublic_timelineは認証なしでAPIアクセスできたらしい。
追記: Tweet.get_latest
で取得したデータからtextだけを取り出すのには以下のようにscanメソッドを使った。ストレートだけど何となく行儀が良くないような気がする (気のせいかもしれない)。
@latest_tweet = Tweet.get_latest.to_s.scan(/(?<=text=").*?(?=", source)/)
ところが、以下のコードでパースできることを偶然知った (最初 to_jsonのつもりが間違えた)。
@latest_tweet = Tweet.get_latest.as_json
こうすれば、@latest_tweet[0]['table'][:text]
のような感じでハッシュとしてアクセスできる。ツイートが複数の場合はeachで回して処理する必要がある。上のscanを使った方はeach不要。結局行数が少ないscanの方を採用したけど、後者の行儀の良さも捨てがたいような気がする。
ところで、as_jsonが今ひとつよくわからない。