しふみんのブログ

しふみんのブログです。

Heroku+RailsでLine botを作る 第8回 LINE botの雛形の作成

前回までのあらすじ

第1回: http://shifumin.hatenablog.com/entry/2018/04/20/000500
第2回: http://shifumin.hatenablog.com/entry/2018/04/22/002000
第3回: http://shifumin.hatenablog.com/entry/2018/04/23/000500
第4回: http://shifumin.hatenablog.com/entry/2018/04/24/000500
第5回: http://shifumin.hatenablog.com/entry/2018/04/25/000500
第6回: http://shifumin.hatenablog.com/entry/2018/04/26/000500
第7回: shifumin.hatenablog.com

LINEデベロッパー登録を終え、必要なAPIキーである「Channel Secret」と「アクセストークン」を手に入れました。
また、Railsアプリを作成し、動作することを確認しました。
そして、記念すべき(?)はじめてのgit commitを行いました。
今回はLINE botの雛形を作成していきたいと思います。

line-bot-sdk-ruby

github.com

上記がLINE bot開発に使うRuby用のLINE Messaging APISDK(Software Development Kit)となります。

このリポジトリのREADMEのSynopsisにサンプルコードが載せられています。
Railsと同じくRubyのWAF(Web Application Framework)であるSinatraのコードです。
オウム返しを行う実装となっているようですね。

GitHub - line/line-bot-sdk-ruby: Line: :API - SDK of the LINE Messaging API for Ruby.

このサンプルコードをRailsで動くように移植します。
Railsへの移植では下記も大いに参考させていただきました。

qiita.com

Railsへの移植

追加修正・新規作成したファイルは下記の2つです。

  • config/routes.rb (変更)
  • app/controllers/webhook_controller.rb (新規作成)

概要としては、LINE Messaging APIから受け取ったリクエストについてのルーティングを設定して(config/routes.rb)、その際に行うアクションを追加しています(app/controllers/webhook_controller.rb)。

Railsへ移植したコードと一言解説を下記に載せます。

config/routes.rb

Rails.application.routes.draw do
  post '/callback' => 'webhook#callback'
end

<HerokuアプリのURL>/callback にPOSTメソッドのリクエストを受け取った場合にWebbookコントローラのcallbackアクションに割り当てるようにしています。

app/controllers/webhook_controller.rb

require 'line/bot'

class WebhookController < ApplicationController
  protect_from_forgery except: :callback

  def callback
    body = request.body.read

    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
      error 400 do 'Bad Request' end
    end

    events = client.parse_events_from(body)
    events.each { |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message = {
            type: 'text',
            text: event.message['text']
          }
          client.reply_message(event['replyToken'], message)
        end
      end
    }

    head :ok
  end

  private

  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
  end
end

APIトークンを使って認証するため、下記のコードでCSRF対策を無効にしています。
callbackメソッドを除く -> callbackメソッドでは無効。
というか、無効にしないとローカル開発環境で動作確認する時にエラーが出る気がします。

  protect_from_forgery except: :callback

参考:
qiita.com

それ以外はほぼコピペですね。
一応clientメソッドをprivateメソッドに移した以外は。

  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
  end

このclientメソッドの中で「Channel Secret」と「アクセストークン」を設定しています(ようやく第1回の伏線(?)を回収できました)
ですので、Herokuで動かす場合はHerokuに、ローカルで動かす場合はローカルに下記の環境変数を設定する必要があります。

  • LINE_CHANNEL_SECRET
  • LINE_CHANNEL_TOKEN

環境変数の設定は必要になった際にやっていきましょう。

終わりに

今回はLINE botの雛形として公式サンプルコードのオウム返しbotRailsへと移植しました。
動き的には下記画像のようにオウム返しを行うbotとなっています。

f:id:shifumin:20180428230824p:plain

次回は作成したこのbotをHerokuにデプロイしていきましょう。

参考

line/line-bot-sdk-ruby: Line: :API - SDK of the LINE Messaging API for Ruby.
https://github.com/line/line-bot-sdk-ruby

今更ながらRails5+line-bot-sdk-ruby+HerokuでLineBot作成してみたら、色々詰まったのでまとめました。 - Qiita
https://qiita.com/y428_b/items/d2b1a376f5900aea30dc

Rails4のCSRF対策で「Can't verify CSRF token authenticity」エラー - Qiita
https://qiita.com/chobi9999/items/2b59fdaf3dd8f2ed9268