RailsでDeviseと用いてTwitter認証してみる
はじめに
Railsでブログをつくっているのですが、コメント欄とTwitterを連携させたら面白そうと思いたちTwitter認証をやってみることにしました。Twitter認証については多くの記事がありますので、詳しくはそちらを参考にしてください。
この記事は半ば自分へのメモ用です。。。
ぼくが参考にさせていただいた記事はこの記事の一番下にまとめてあります。
Twitter Developerへの登録
まず認証に必要なAPIキーを取得するためにTwitter Developer Platformに登録します。Twitter Developer Platform — Twitter Developers
以前は下のApplication Managementにて登録する流れでしたが、現在Developerに登録する必要があります。
apps.twitter.com
アプリを追加後注意するべきは以下です。
- URIをhttp://127.0.0.1:3000/にする。
- Redirect URIをhttp://127.0.0.1:3000/users/auth/twitter/callbackにする。(のちのDeviseで作成するモデルの名前に依存する。)
- PermissionをRead, Write and Access direct messagesにする。
おそらくほかの項目は適当でも大丈夫です。
登録が終わると、Keys and Access Tokensの欄にConsumer KeyとConsumer Secretがあります。今回は、このキーを使います。
Gemの編集
今回使用するGemを入れます。ログイン処理用にDevise、Twitter認証用にOmniauthを使用します。
Deviseはログイン機能を簡単に実装できるGemです。
dotenvはAPIキーを保持するためのGemです。
gem 'devise' gem 'omniauth' gem 'omniauth-twitter' gem 'dotenv'
Gem fileを編集後installします。
$ bundle install --path vendor/bundle
Deviseの設定
Deviseでのログイン機能を実装していきます。下のコマンドを実行していきます。
$ bundle exec rails g devise:install $ bundle exec rails g devise:views $ bundle exec rails g devise User $ bundle exec rails g migration add_columns_to_users provider uid username $ bundle exec rails db:migrate
これでログイン機能の実装は終わりです。(簡単!!!
はじめの方は実行して試してみましょう!
$ bundle exec rails s
.envにAPIキーを保存
アプリの直下に.envファイルを作成します。$ emacs .env
ここにAPIキーを書いていきます。
TWITTER_CONSUMER_KEY="あなたのAPIキー" TWITTER_CONSUMER_SECRET="あなたのAPIシークレット"
これは、
ENV["TWITTER_CONSUMER_KEY"]
などとすると取り出すことができます。
Consoleなどで試してみるといいでしょう。
Twitter認証の設定
いよいよ本題です。ログイン後に表示するページを作ります。
$ bundle exec rails g controller Pages index show
ルーティングの設定をします。
config/routes.rb
root 'pages#index' get 'pages/show' devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
UserモデルをTwitter用に編集します。
emailはダミーを登録しないとエラーになるそうです。
models/user.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable def self.find_for_oauth(auth) user = User.where(uid: auth.uid, provider: auth.provider).first unless user user = User.create( uid: auth.uid, provider: auth.provider, email: User.dummy_email(auth), username: auth.info.nickname, password: Devise.friendly_token[0, 20] ) end user end private def self.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end
表示するViewを編集します。
views/layouts/application.html.erb
<header> <nav> <% if user_signed_in? %> <strong><%= link_to current_user.username, pages_show_path %></strong> <%= link_to 'プロフィール変更', edit_user_registration_path %> <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %> <% else %> <%= link_to 'サインアップ', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %> <% end %> </nav> </header> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p>
views/pages/index.html.erb
<% if user_signed_in? %> <h1>こんにちは、<%= current_user.username %>さん</h1> <p>ユーザー用ページです。</p> <% else %> <p>ログインしてください</p> <% end %>
ログインしているかの確認
controllers/application_controller.rb
protect_from_forgery with: :exception before_action :authenticate_user!
Deviseのinitializersに次を追加します。
config/initializers/devise.rb
config.omniauth :twitter, ENV["TWITTER_CONSUMER_KEY"], ENV["TWITTER_CONSUMER_SECRET"]
Callback用のControllerを作成し、編集します。
$ bundle exec rails g controller users/omniauth_callbacks
controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def twitter callback_from :twitter end private def callback_from(provider) provider = provider.to_s @user = User.find_for_oauth(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize) sign_in_and_redirect @user, event: :authentication else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end end
実行
ここまでで完成です。$ bundle exec rails s
Sign in with twitterにてTwitter認証のサイトにいき認証後rootに戻る...はずです。
お疲れ様でした!!!
次回予告
よし、次はこれを使ってツイートしたい!というわけで
参考サイト
qiita.comfreesworder.net
freesworder.net
Ruby on Railsでブログを作成しました!
こんにちは!
今回Ruby on Railsでブログを作成し、デプロイまでできたので紹介します。
題して『Mt.Log』です。
まだまだコメント機能などつけていきたい機能があるので随時アップデートしていきます!
適当なところで安定してきたら独自ドメインもとりたいな・・・とか考えてます。
では、Mt.Logで会いましょうノシ
RubyをつかってTwitterの翻訳Botを作ってみる
はじめに
TwitterのBotに興味があったので調べてみました。それでRailsにも使いたいなという感じでRubyでやりました。
どんなBotを作ろうかというもんでまあ前使った翻訳Botでも使って英語→日本語への翻訳をするBotでもあればおもしろいなってことでやってみました。
Twitter Developersからキーを取得
まず、下記サイトからAPIキーを取得します。apps.twitter.com
Twitterアカウントを持っていない人は作ってからの取得になります。
BotからのTweetはこのアカウントからのTweetになるのでメインでアカウントを持っていてもBot用に作ったほうが良いかと思います。
・Create New Appから新規Appの作成
・各プロパティを埋める(WebsiteとCallbackはなんでもいいけどなんでもいい人は下のローカルでも書いとけばおk)
Website : http://127.0.0.1:3000
Callback URI's : http://127.0.0.1:3000/auth/twitter
・Keys and Access TokensからAccess Tokenを取得しメモっておく
みんなの自動翻訳APIからキーを取得
続いて、翻訳APIです。今回は、みんなの自動翻訳TexTraというものを使用します。商用では使用できませんが、簡単に使用できるのでお手軽です。
みんなの自動翻訳@TexTra®
ここのサイトから英語→日本語のキーを取得します。
Gemをインストールする
必要なGemをインストールします。gem 'twitter' gem 'oauth' gem 'json'
使うGemは3つです。Twitter用にTwitterと翻訳APIの認証用にoauthとレスポンスのパース用にjsonをインストールします。
$ bundle install
ここからコードを書いていきます。
Configを書く
キーとトークンをconfig.rbを作成して書いていきます。config.rb
require 'twitter' require 'oauth' config = { consumer_key: "TwitterのAPIキー", consumer_secret: "Twitterのシークレットキー", access_token: "Twitterのアクセストークン", access_token_secret: "Twitterのシークレットトークン", } @restClient = Twitter::REST::Client.new(config) @streamingClient=Twitter::Streaming::Client.new(config) translate_key="翻訳APIのAPIキー" translate_secret="翻訳APIのシークレットキー" url="https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/generalN_en_ja/" name="翻訳APIのユーザー名" consumer = OAuth::Consumer.new(translate_key, translate_secret) endpoint = OAuth::AccessToken.new(consumer)
これでそれぞれのキー、トークンを書いて、各APIで使用するインスタンスを作成しました。
本文を書く
さて、本文を書きます。translate.rb
require 'twitter' require 'oauth' require 'json' require './config' #タイムゾーンの指定 ENV['TZ']='JST-9' #今回は説明のためにmtryoさんとする username="送信したいユーザー名(@抜きで書いてます)" #mtryoさんのTweetを見張る @streamingClient.user do |tweet| #もしmtryoさんの「Translate:」を含むTweetを見つけたら if tweet.class==Twitter::Tweet && tweet.text.include?("Translate:") && !tweet.in_reply_to_status_id puts "Found tweet: #{tweet}" #Tweetの本文を翻訳APIにかける response = endpoint.post(url,{key: consumer_key, type: 'json', name: name, text: tweet.text}) #レスポンスをパースする result = JSON.parse(response.body) #username宛にリプライする。 @restClient.update("@#{username} #{result['resultset']['result']['text']}", in_reply_to_status_id: tweet.id) end end
今回は「Translate:」を含むTweetをしたときに翻訳してリプライすることにしました。
include?の部分を変えればキーワードは変更できます。
実行する
最後に実行すれば終わりです。$ ruby translate.rb
お疲れ様でーす!
参考サイト
NICT の自動翻訳 API を Rails で使うTwitterボット(Twitter Bot)の作り方(Ruby編) - サーバ設定不要のPaizaCloud上でTwitterボットをRubyで作る - paiza開発日誌
RailsのOmniAuthでSpotifyの認証をする
はじめに
OmniAuthでTwitter、FaceBookにログインすることができますが今回Spotifyを使うことになったので調べてみました。OmniAuthを使ったログイン機能の実装に関する記事はTwitterは多くありますが、Spotifyはなかったのでメモっておきます。
とはいえ、ほとんどTwitter認証と同じです。
どうやらSpotifyにもOmniAuthのGemがあるようなので使ってみます。
Spotify for DeveloperでAppの作成
まず、SpotifyでAppを作成します。下記サイトにとんで、DashboardからAppの作成をしてください。
developer.spotify.com
作成後、EDIT SETTINGSから
Website : http://127.0.0.1:3000
Redirect URI'S : http://127.0.0.1:3000/auth/spotify/callback
を追加します。
Twitterの場合はlocalhostで作成できなかったので上のURIで作成します。
[Client ID]と[Client Secret]が作成されるのでメモっておきましょう。
KEYの保存
では、アプリを作成してKEYを保存します。先ほど作成したIDやSecretはコントローラーやモデル内に書くべきではないのでcredentialsに書き込んでいきます。
Rails5.2からsecret.ymlがなくなってcredentialsになったみたいです。このサイトを参考にしました。
Rails5.2から追加された credentials.yml.enc のキホン
エディターはEmacsに設定します。(Atomはなぜかうまく表示されないのでViかEmacsを推奨)
$ echo 'export EDITOR="emacs"' >> ~/.bash_profile $ source ~/.bash_profile $ echo $EDITOR #=> emacs
これで毎回エディタを選択する必要がなくなります。
$ bin/rails credentials:edit
これにKEYを追加していきます。
# aws: # access_key_id: 123 # secret_access_key: 345 client_key: [Your ID] client_secret: [Your Secret ID] # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. secret_key_base: 8be8e637d755f79c799048bed8be0c...
これには
Rails.application.credentials.[hogehoge]
で値を取れます。
OmniAuthの設定
config/initializer/omniauth.rbを作成し、先程のKEYをOmniAuthに登録します。Rails.application.config.middleware.use OmniAuth::Builder do provider :spotify, Rails.application.credentials.client_id, Rails.application.credentials.client_secret, scope: 'playlist-read-private user-read-private user-read-email' end
ログイン機能の作成
まず、ユーザーモデルを作成します。$ rails g model user provider:string uid:string nickname:string image_url:string $ rails db:migrate
ログイン機能のためのビューを書きます。
app/view/layout/application.html.erb
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right"> <li><%= link_to 'Spotifyでログイン', '/auth/spotify/' %></li> </ul> </div> <div class="container"> <% if flash[:notice] %> <div class="alert alert-success"> <%= flash[:notice] %> </div> <% end %> <%= yield %> </div>
コントローラーを作成します。
$ rails g controller sessions top
コントローラーに書いていきます。
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController def top end def create user = Spotifyuser.find_or_create_from_auth_hash(request.env['omniauth.auth']) session[:user_id] = user.id redirect_to root_path, notice: 'ログインしました' end end
続いて、user.rbです。
app/models/user.rb
class User < ApplicationRecord def self.find_or_create_from_auth_hash(auth) provider = auth[:provider] uid = auth[:uid] user_name = auth[:info][:user_name] image_url = auth[:info][:image] self.find_or_create_by(provider: provider, uid: uid) do |user| user.user_name = user_name user.image_url = image_url end end end
最後にルーティングを設定します。
Rails.application.routes.draw do get '/'=>'sessions#top' get '/auth/:provider/callback' => 'sessions#create' end
これでできました。
お疲れ様でした!
追記:
Credentialでキーの管理は普通にできるのですが、なぜがその後のエラーが多い気がします。
僕は現在キーの管理をdotenvというgemでやっています。
参考
OmniAuthを利用して、Twitterログイン機能を作る【初心者向け】RailsでOmniauthを使ってTwitterログインする
参考にした、したいサイトのメモ
完全に自分用にRailsに関して参考にした、したいサイトをメモります。
Rails全般
・インストール
・シークレットキーの保存(Rails5.2.0以上)
Rails5.2から追加された credentials.yml.enc のキホン
・dotenv-railsを使ったキーの保存
API key等をgithubで公開しない方法(rails,heroku)
・link_toとurl_for
【Rails】link_to / url_forなどリンク関連のビューヘルパーまとめ
・form_tagとform_for
【Rails】form_for/form_tagの違い・使い分けをまとめた
・ページごとにタイトルを変える
Railsでページごとにページタイトルを変える方法 - A Little Each Day
Railsのいろいろ
・部分テンプレート
・link_to,url_for
【Rails】link_to / url_forなどリンク関連のビューヘルパーまとめ
・Twitter認証
OmniAuthを利用して、Twitterログイン機能を作る【初心者向け】
・Google Calender
HOWTO integrate Google Calendar with Rails · ReadySteadyCode
・コメント返信機能
Gem
・clockwork
GitHub -
clockwork について - 君の瞳はまるでルビー - Ruby 関連まとめサイト
・みんなの自動翻訳@TexTra
・Microsoft Translator Text API
Microsoft Translator テキスト APIで日本語を翻訳してみる - しめ鯖日記
RubyからMicrosoft Translator APIを呼び出す - それはBooks
OmniAuthで認証した後に、tweetしたりfollowしたりする
Twitterボット(Twitter Bot)の作り方(Ruby編) - サーバ設定不要のPaizaCloud上でTwitterボットをRubyで作る - paiza開発日誌
Active Record
・メソッド一覧
Active Record クエリインターフェイス | Rails ガイド
・ランダムに要素を取り出す
ActiveRecord でランダムに2件以上取得したいケース
・HTTPクライアント
jQeury
・jQueryを使って、Ajaxを利用してHelloWorld
「Ruby on Railsで簡単で素早くWebアプリを開発する」 最終回 Rails + jQuery でAjaxを使ってみよう
・ループなどで個々に違う動作をさせる
jQueryの基礎:独自HTML属性を使って汎用的なトグルボタンを作る | CloudAdvisor
その他
・React入門
30分間React入門「いいねボタン」作成チュートリアル | | Craftsman Software Inc.
・IFTTT
IFTTT helps your apps and devices work together
ViewでHTMLを適用させつつ表示する
ブログというか自分のサイトを勉強がてら作っています。
困ったところメモです。
ブログの内容をモデルにタイトルとコンテンツなどを保存していて、コンテンツは画像とか太字を適用させたいのでHTML形式で書きました。
ところがこれをそのままViewで表示するとタグがそのまま出力されてしまいました。
結論から言うと、simple_formatを使うと解決しました。
これを入力とすると
@content=<h1>大きな文字で表示してほしい</h1><p>なってくれええええ</p>
普通にViewで表示するとこうです。
<%=@content%>
出力:
<h1>大きな文字で表示してほしい</h1><p>なってくれええええ</p>
このようにタグがこのまま出力されます。
simple_formatを使うとこうなります。
<%=simple_format @content%>
出力:
大きな文字で表示してほしい
なってくれええええ
はてな記法に慣れていないので出力が少し変です。
ですが、これで解決です。
ブログの作成を続けましょう!
Bundleをなしでアプリ作成後に別途インストール
最近はじめてMacユーザーになっていろいろ勝手の違いに苦労しております...
それでMacにRailsをインストールしました。
インストールは以下を参考にしました。
qiita.com
それで$rails newするのにbundleを別途インストールしないとなぜかうまくいかないので呪文をメモしておきます。
bundleなしでアプリを作成
$ bundle exec rails new (アプリ名) --skip-bundle
cdでアプリ内に入ってからbundleをinstallします
$ bundle install --path vendor/bundle
これでlocalhostを立ち上げ
$ bundle exec rails s
これで実行できました。
$ bundle exec
これRailsプロジェクトのGemfileで指定された環境で実行する事ができるようになるらしい...(よくわかってない
追記:
バンドルskipは省略できるようです。簡単!
$ rails new --skip-bundle $ rails new -B