Mt.Log

編入、編入後の勉強

RailsでDeviseと用いてTwitter認証してみる

はじめに

Railsでブログをつくっているのですが、コメント欄とTwitterを連携させたら面白そうと思いたちTwitter認証をやってみることにしました。
Twitter認証については多くの記事がありますので、詳しくはそちらを参考にしてください。
この記事は半ば自分へのメモ用です。。。
ぼくが参考にさせていただいた記事はこの記事の一番下にまとめてあります。

Twitter Developerへの登録

まず認証に必要なAPIキーを取得するためにTwitter Developer Platformに登録します。
Twitter Developer Platform — Twitter Developers
以前は下のApplication Managementにて登録する流れでしたが、現在Developerに登録する必要があります。
apps.twitter.com
アプリを追加後注意するべきは以下です。

おそらくほかの項目は適当でも大丈夫です。
登録が終わると、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に戻る...はずです。
お疲れ様でした!!!

次回予告

よし、次はこれを使ってツイートしたい!
というわけでやります。やりました。

mtryo1021.hatenablog.com



参考サイト

qiita.com
freesworder.net
freesworder.net

Ruby on Railsでブログを作成しました!

こんにちは!

 

今回Ruby on Railsでブログを作成し、デプロイまでできたので紹介します。

題して『Mt.Log』です。

 

mtloglog.herokuapp.com

 

まだまだコメント機能などつけていきたい機能があるので随時アップデートしていきます!

 

適当なところで安定してきたら独自ドメインもとりたいな・・・とか考えてます。

では、Mt.Logで会いましょうノシ

 

RubyをつかってTwitterの翻訳Botを作ってみる

はじめに

TwitterBotに興味があったので調べてみました。
それで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を取得しメモっておく

これでTwitter APIを使う準備ができました。

みんなの自動翻訳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でTwitterFaceBookにログインすることができますが今回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全般

・インストール

最速!MacでRuby on Rails環境構築

Rails開発用のAtomパッケージ

Atomで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のいろいろ

・部分テンプレート

Rails 部分テンプレートの使い方

・link_to,url_for

【Rails】link_to / url_forなどリンク関連のビューヘルパーまとめ

Twitter認証

OmniAuthを利用して、Twitterログイン機能を作る【初心者向け】

RailsでのTwitter認証。

Google Calender

HOWTO integrate Google Calendar with Rails · ReadySteadyCode

・コメント返信機能

Railsでコメントに対する返信機能を実装した!

 

Gem

 ・clockwork

GitHub - adamwiggins/clockwork: A scheduler process to replace cron

clockwork について - 君の瞳はまるでルビー - Ruby 関連まとめサイト

 

API

・みんなの自動翻訳@TexTra

みんなの自動翻訳@TexTra®

NICT の自動翻訳 API を Rails で使う

 

Microsoft Translator Text API

Microsoft Translator テキスト APIで日本語を翻訳してみる - しめ鯖日記

RubyからMicrosoft Translator APIを呼び出す - それはBooks

 

Twitter API

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

【Rails】Twitterでサンタコスbotを作る

twitterのapiを使ってrailsからtweet

Twitterボット(Twitter Bot)の作り方(Ruby編) - サーバ設定不要のPaizaCloud上でTwitterボットをRubyで作る - paiza開発日誌

 

Active Record

・メソッド一覧

Active Record クエリインターフェイス | Rails ガイド

・ランダムに要素を取り出す

ActiveRecord でランダムに2件以上取得したいケース

 

Ruby

・HTTPクライアント

Ruby 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ユーザーになっていろいろ勝手の違いに苦労しております...
それでMacRailsをインストールしました。
インストールは以下を参考にしました。
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