週末プログラミング、皆さんやっていますか?
こんにちは。現在、管理人はRuby on RailsでTwitterやFacebook、Instagramといった各種SNSのapiを叩き、oauth認証機能を利用したりタイムラインを引っ張ってきたりするプログラムを書いています。
後々は同じインターフェース内で全てのSNSのタイムラインを表示させるサービスを完成させる予定ですが、それまでの機能的な部分を切り取ってご紹介しています。
【Ruby on Rails】instagram apiを利用してoauth認証・タイムラインを表示する
twitter apiは構造自体は簡単!でもapi利用制限が多く、方法もたくさんあるために意外と難しかった
twitter apiは非常に利用制限が厳しく、15分間に15回までしか叩けない場合もあります。
また、Railsの場合gemを導入して簡単に実装するのが良いのですが、いかんせん多すぎてどれが良いのかよく分かりません。
僕の環境で動いた一例として、以下をお読みください。
Twitter apiを叩くための便利なgemを入れておこう
## twitter api 関連 ## gem 'twitter' gem 'oauth' gem 'omniauth-twitter'
これらは問答無用で入れておきましょう。(環境:Rails 4.2.4, ruby 2.0.0p645 (2015-04-13 revision 50299) [universal.x86_64-darwin15])
Railsの良いところであり悪いところでもあるのですが、これらのgemを導入すると、簡単なコードを書くだけでtwitter apiを叩けます。
しかし、それぞれのメソッドが何をしているのか理解するために導入したgemのソースコードの中身を確認しておくことは必要です。
omniauth.rbを設定しよう(/config/initializers/omniauth.rb)(ファイル名も一致させないと動きません)
Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, Rails.application.secrets.twitter_consumer_key, Rails.application.secrets.twitter_consumer_secret end
omniauth.rbにtwitterのconsumer_keyやconsumer_secretを設定してもいいのですが、それらはsecrets.ymlに格納しておくのがイケてる(らしい)です。
secrets.ymlに自身のconsumer_keyとconsumer_secretを書いておこう(/config/secrets.yml)
default: &default twitter_consumer_key: 'あなたのconsumer_key' twitter_consumer_secret: 'あなたのconsumer_secret' development: <<: *default secret_key_base: ** test: <<: *default secret_key_base: ** # Do not keep production secrets in the repository, # instead read values from the environment. ## 本番環境では下記のように読み込むことで、あなたのconsumer_keyとかを悪用されませんよ、という書き方(らしい) ## production: twitter_consumer_key: <%= ENV["TWITTER_CONSUMER_KEY"] %> twitter_consumer_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %> secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
instagram apiをRuby on Railsで叩くでも紹介しましたが、twitter apiを叩く時に必要なconsumer_keyとconsumer_secretの取得方法を以下に紹介します。
Twitter開発者用ページ(https://dev.twitter.com/)にアクセス!
以下の白枠内をクリックすると、自分のappsページに飛べます。(これマジで分かりにくくて毎度探すのに時間かかるんだけど、Twitterさん何とかして)
次に、自分専用のアプリを登録します。
次はアプリの名前や説明、リダイレクト先等を入力しましょう。(Callback URLを適切に書かないと動作しません。)
最後にconsumer_keyとconsumer_secretを確認しましょう。
上記2項目をsecrets.ymlに書き込みましょう。
ちなみにpermissionは今は気にしなくてOKです。(ユーザーがoauth認証する際に聞かれるもので、基本Read and Writeに設定しておけば良いでしょう。ただし、不要なpermissionは要求しないようにするのがマナーです。)
routes.rbはこんな感じ(/config/routes.rb)(RailsのREST fulなルーティングが分かっていません。参考程度にしてください。)
Rails.application.routes.draw do root 'home#index' get "home/index" # twitter routes get "/tweet" => "tweet#timeline" get "/signout_twitter" => "sessions#destroy" # Oauth routes ←api叩くと/auth/twitter/callbackにリダイレクトされます。session生成しています。 get "/auth/:provider/callback" => "sessions#create" end
一応簡易的なサインインとサインアウト機能作っておきました。
sessions_controller.rbでログインもどきの動き入れました。(/app/controllers/sessions_controller.rb)
class SessionsController < ApplicationController ## session生成 ## def create ## URLがtwitterからのリダイレクトURLの場合、sessionにアクセストークンを格納する。 ## ## ↑これセキュリティー上ダメかな。笑 ## if (request.path_info == "/auth/twitter/callback") auth = request.env["omniauth.auth"] session[:oauth_token] = auth.credentials.token session[:oauth_token_secret] = auth.credentials.secret session[:username] = auth.extra.access_token.params[:screen_name] redirect_to "/tweet", :notice => "サインイン!" else redirect_to root_url end end ## sesion破棄 ## def destroy session[:oauth_token] = nil session[:oauth_token_secret] = nil redirect_to root_url, :notice => "サインアウト!" if (request.path_info == "/signout_twitter") session[:username] = nil end end end
内容としてはシンプルで、上記のコードで簡単にoauth認証を実装できています。gem最高。Rails最高。
これ、ちなみにPHPで書くとアホみたいにコード量増えます。びっくり。(参考:https://syncer.jp/twitter-api-matome)
tweet_controller.rbで実際にタイムラインを表示してみます。(/app/controllers/tweet_controller.rb)
class TweetController < ApplicationController ## viewで使うメソッドはヘルパーメソッドに ## helper_method :timeline ## これ書かないとgemが動きません ## require 'twitter' ## twitter apiを叩いてタイムラインを表示する ## def timeline ## 何でこれ書いてるんだろう...多分無くても動く気はします ## client = Twitter::REST::Client.new do |config| config.consumer_key = Rails.application.secrets.twitter_consumer_key config.consumer_secret = Rails.application.secrets.twitter_consumer_secret config.access_token = session[:oauth_token] config.access_token_secret = session[:oauth_token_secret] end client.home_timeline(:count => 200).each do |tweet| ## 作りかけで恐縮ですが...二重配列にRT数などの要素を格納する予定です ## @array = Array.new @total_array = Array.new text = tweet.full_text fav = tweet.favorite_count rt = tweet.retweet_count @weight = fav + rt * 1.5 @array = [text, fav, rt, @weight] p @array end end end
後はviewを作っておけば、タイムラインを表示できます。
application.html.erbのリンク先だけ気をつけて!(/app/views/layouts/application.html.erb)
<!DOCTYPE html> <html> <head> <title>SocialLog</title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> </head> <body> <div id="container"> <div id="user_nav"> <% if signed_in? %> ようこそ! <%= session[:username] %> <% end %> <%= link_to "twitterにサインイン", "/auth/twitter" %> </div> <%= yield %> </div> </body> </html>
リンク先のpathを/auth/twitterに設定しておけば問題ありません。(必ず登録したURLに一致させましょう。)
いかがですか?
これで自分のタイムラインを表示することができたと思います。
Railsの場合、gemが優秀すぎてtwitter apiを扱うのは本当に手軽です。ぜひやってみてくださいね!
TechAcademyを受講して改めて分かったプログラミングを上達するための3つのコツ