LINE botをRails6で作ってみた
はじめに
LINEのBOT API(厳密にはMessaging API)をHerokuとRailsを使って実装してみました。
ちなみに、Rails6で作ってみましたが、5と特に変わりはありませんでした。webpackerとか一応叩いてみたけど、あまり関係なかったっぽい。。。
今更〜という記事を見て、更に今更ですが(苦笑)、こんな手軽に使うRailsもあるのか、という感じで作れたので記録に残しておきます。
準備
LINEのアカウントは、BOTのAPIがリリースされた直後に作ったものがありましたが、気づいたらLINE Developerということでサイトも内容も一新されておりました。
今回は参考サイトでも取り上げられているような、話しかけられたら適当に返事をするだけのアプリケーション。
Ruby on Railsの開発
rails new sarabot -d postgresql
が、いきなりポスグレのbundle installがこける!
調べると(よく考えれば当たり前だが)、ローカルサービスを立ち上げる必要があり、macの場合appをインストールするのが手っ取り早いとのことなので、公式HPからappをインストールし、セットアップ。
bundle config build.pg --with-pg-config=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config
bundle
bin/rails db:create
これでRailsアプリが立ち上がるので、あとは実装。
bin/rails g scaffold Post name:string bin/rails db:migrate
まず、返答のデータベースとなるPostモデルを作る。返答は、いくつかの決められたパターンは固定で返答し、それ以外はPostsからランダムで返す単純なもの。
class LinebotController < ApplicationController require 'line/bot' # gem 'line-bot-api' # callbackアクションのCSRFトークン認証を無効 protect_from_forgery :except => [:callback] def client @client ||= Line::Bot::Client.new { |config| config.channel_secret = ENV["LINE_CHANNEL_SECRET"] config.channel_token = ENV["LINE_CHANNEL_TOKEN"] } end def callback # Postモデルの中身をランダムで@postに格納する @post=Post.offset( rand(Post.count) ).first body = request.body.read signature = request.env['HTTP_X_LINE_SIGNATURE'] unless client.validate_signature(body, signature) head :bad_request end events = client.parse_events_from(body) events.each { |event| # event.message['text']でLINEで送られてきた文書を取得 if event.message['text'].include?("好き") response = "いひひ" elsif event.message["text"].include?("行ってきます") response = "はーい" elsif event.message['text'].include?("おはよう") response = "うーーーーーーーん。。。(また寝る)" elsif event.message['text'].include?("さら") response = "さらちゃん!" elsif event.message['text'].include?("ママ") response = "ママたん!" elsif Post.count == 0 response = event.message['text'] else response = @post.name end #if文でresponseに送るメッセージを格納 case event when Line::Bot::Event::Message case event.type when Line::Bot::Event::MessageType::Text message = { type: 'text', text: response } client.reply_message(event['replyToken'], message) end end } head :ok end end
ほとんど参考サイトのコピペ(すみません)。。。 コピペしながら、Messaging APIの仕様をなんとなく理解。
難しいのは、実際にherokuにデプロイしてみないと、APIが叩かれた後の確認やデバッグができないこと。
Rails.application.routes.draw do resources :posts post '/callback' => "linebot#callback" end
ちなみに、routes.rbはこんな感じ。
動くか心配のまま、herokuにデプロイ。(上のコードは修正済みなので動きます)
heroku login heroku create heroku config:set LINE_CHANNEL_SECRET=xxxxx heroku config:set config:set LINE_CHANNEL_TOKEN=xxxxxx #(私のはめっちゃ長かった) git push heroku master heroku run
herokuのURLが決まったら、/callbackを含めてLINE Developer設定のWebHookに追記。
これで呼び出されるはず、だが最初は動かず、heroku上のデバッグどうするんだ!?となったので、
heroku run rails c #consoleを開く heroku run rails tail #ログを確認する
こんな感じでできるよう。ローカルとほぼ同等のことができて素晴らしい(これで今回は十分だったのでこれ以上調べてない)
結局、callbackが呼ばれた後に例外で落ちていたのがログから確認できたので、修正して動きました。
めでたしめでたし。