hello-world
webエンジニアのメモ。とりあえずやってみる。

OmniAuthで認証した後に、tweetしたりfollowしたりする

公開日時

昨日、 RailsでOmniauthを使ってTwitterログインする方法をまとめました。

今回はログイン後に定型文をつぶやいたり、特定アカウントをフォローできるようにしたいと思います。

初期設定

  • Gemfile記述

意書き 先日の記事でご紹介したtweetstream gemでStreamingAPIも一緒に使用したい場合、twitter gemの最新バージョン(version 5)だとエラーになってしまうので4.8以上5未満を使用するようにGemfileを修正しました。

tweetstreamを使用しない場合は最新のtwitter gemを使用して問題ないと思います。

今回はtwitter gemバージョン4.8を使用したやり方を書いていますが、バージョン5以降は初期化処理のパラメータ名等が変わっているので注意が必要です。

詳しくは twitter gemのページを参照ください。

# Gemfile

gem 'tweetstream' # streaming api用に使用
gem 'mongoid', git: 'git://github.com/mongoid/mongoid.git' # streaming api用に使用

gem 'omniauth'
gem 'omniauth-twitter'
gem 'settingslogic'
gem 'twitter', "~> 4.8"
  • bundle install
./bin/bundle install
  • twitter initializer設定
#config/initializers/twitter.rb

Twitter.configure do |config|
  config.consumer_key       = Settings.twitter.consumer_key
  config.consumer_secret    = Settings.twitter.consumer_secret
end
  • lib以下をautoloadするようapplication.rbに追記
# config/application.rb

class Application < Rails::Application
  # lib以下をautoloadする
  config.autoload_paths += %W(#{config.root}/lib)
  config.autoload_paths += Dir["#{config.root}/lib/**/"]
end
  • routing追加
# config/routes.rb

root 'home#index'
get "home/index"
get "/tweet", :to => 'home#tweet', :as => 'tweet'
get "/follow", :to => 'home#follow', :as => 'follow'
get "/follow_check", :to => 'home#follow_check', :as => 'follow_check'

controller更新

前回の記事ではUserモデルにユーザ情報を保存するようにしていましたが、今回はモデルは使わずsessionで管理することにします。

  • SessionsController修正
# app/controllers/sessions_controller.rb

class SessionsController < BaseController
  def callback
    auth = request.env['omniauth.auth']

    # sessionに保持するように変更
    session[:user_id] = auth['uid']
    session[:name] = auth['info']['name']
    # 投稿に必要なauth_token, secret_tokenも取得する
    session[:oauth_token] = auth['credentials']['token']
    session[:oauth_token_secret] = auth['credentials']['secret']

    redirect_to root_path
  end

  def destroy
    reset_session
    redirect_to root_path
  end
end
  • BaseController修正
# app/controllers/base_controller.rb

class BaseController < ApplicationController
  protect_from_forgery
  helper_method :current_user

  def login_required
    @current_user = current_user
    unless @current_user
      redirect_to root_path
    end
  end

  private
  def current_user
    # SessionUserクラスからユーザ情報を取得するように
    @current_user ||= SessionUser.new(session) if session[:user_id]
  end
end
  • SessionUserクラス作成
mkdir lib/user
# lib/user/session_user.rb

class SessionUser
  def initialize(session)
    @name = session[:name]
    @uid = session[:user_id]
    @token = session[:oauth_token]
    @secret = session[:oauth_token_secret]
  end

  attr_reader :name, :uid, :token, :secret
end
  • HomeController更新
# app/controllers/home_controller.rb

class HomeController < BaseController
  before_action :login_required, only: [:tweet, :follow, :follow_check]

  def index
  end

  # 定型文をつぶやく
  def tweet
    text = sprintf(Settings.tweet_setting.text, Time.now)
    twitter_client.update(text)
    flash[:notice] = "tweet: #{text}"
    redirect_to root_path
  end

  # 特定ユーザをフォローする
  def follow
    twitter_client.follow(Settings.tweet_setting.follow_target_name)
    flash[:notice] = "follow done"
    redirect_to root_path
  end

  # 特定ユーザをフォローしているかどうかチェックする
  def follow_check
    follow_info = twitter_client.friendships(Settings.tweet_setting.follow_target_name).first
    flash[:notice] = "follow check: #{follow_info['connections'].include?('following')}"
    redirect_to root_path
  end

  private
  def twitter_client
    Twitter::Client.new(
      :oauth_token        => @current_user.token,
      :oauth_token_secret => @current_user.secret
    )
  end

end

view更新

  • layoutにflash[:notice]追加
# app/views/layouts/application.html.erb

<% if current_user %>
  <%= "#{current_user.uid} #{current_user.name}" %> <%= link_to 'ログアウト', logout_path %>
<% else %>
  <%= link_to 'ログイン', '/auth/twitter' %>
<% end %>

<%= flash[:notice] %>

<%= yield %>
  • home/index.html.erb更新
#app/views/home/index.html.erb

<%= link_to 'tweet', tweet_path %>

<%= link_to 'follow', follow_path %>

<%= link_to 'follow check', follow_check_path %>

設定ファイル更新

  • 設定ファイルにつぶやき文言等を設定
# config/settings.yml

defaults: &defaults

development:
  <<: *defaults
  twitter:
    consumer_key: ConsumerKey
    consumer_secret: ConsumerSecret
  tweet_setting:
    text: "ただ今の時間は%sです" # つぶやき文言
    follow_target_name: 'hilotter' # フォローしたいアカウント名

test:
  <<: *defaults

production:
  <<: *defaults

確認

  • rails server起動
./bin/rails s

ブラウザから http://127.0.0.1:3000 にアクセスするとtweetリンクとfollowリンクが表示されます。

ログイン済みの場合は投稿、フォローができます。

API制限に関して

API制限の把握に関しては下記のページを参考にさせていただきました。

1日1アカウント当たりツイート1000件、ダイレクトメッセージ250件といった更新系のAPI、またストリーミングAPIの制限については変更ありません。

参考


Related #OmniAuth

[Rails]Omniauthで戻り先URLを指定する

Ruby2.0, Rails4.1で確認

[ruby]OmniAuth利用時に Authentication failure! timeout: Net::OpenTimeout, execution expired が発生

OmniAuthを使ったTwitter認証機能を試していた際に、

RailsでOmniauthを使ってTwitterログインする

Ruby2.0, Rails4で確認

[rails]omniauth-google-oauth2を使ってGoogleアカウント認証をやってみる

これまでomniauthを使ったtwitter認証やfacebook認証は何度かやったことがあったのですが、Google認証はやってなかったので、「 omniauth-google-oauth2」を使ってGoogleアカウント認証をやってみました。