こんばんは
たまにはエンジニアっぽいところを見せようと思い、遅ればせながら、流行りのLINE BOTを試してみました。
今回作ったBOTの返答のロジックはいたってシンプル。
会社名の由来である「タマゴが先か、ニワトリが先か」という言葉にちなみ、「(前の人が話した言葉)が先か、(送ったメッセージ)が先か」という言葉をBOTが返すものを作ってみました。
(会社名の由来はドリルを買う人はドリルが欲しい。を参照)
LINE BOTの仕組みとしてはこんな感じです。
LINE BOTにはSSLが必要なのと固定IPが必要なので、YOUR SYSEMの部分のサーバにはherokuを使います。
herokuは固定IPではないのですが、Fixieというアドオンを使うと、プロキシを経由してくれるのでIPを固定できます。
LINEへの登録
LINE BOT APIのトライアルはhttps://business.line.me から登録できます。
すでにトライアルの配布は上限に達してしまい終わっているのですが、私はこっそり登録してあったものを使います。
デベロッパー登録が終わると、以下の3つが取得できます。
Channel ID
Channel Secret
MID
後でアプリで利用しますのでメモっておきます。
herokuにアプリ作成
herokuにアプリを作成します。
herokuはIPが固定ではないのですが、Fixieというアドオンを追加します。
Fixieを使うとプロキシを経由するようになるので、接続元IPを固定できます。
$ heroku login $ heroku create your_app $ heroku addons:create fixie:tricycle
Server IP Whitelistに固定IPを登録
LINE BOT APIを呼ぶにはLINE BOT APIにFixieで固定した接続元IP(Whitelist)を登録する必要があります。
heroku上で作ったアプリの設定画面から Fixie の画面を開くと次のような画面になるので、
Outbound IPs
の2つの値をメモっておきます。
さらに
Proxy URL
もあとで使うのでメモっておきます。
https://business.line.meから
Channels → Server IP Whitelistを選び、「Server IP Whitelist」にメモったOutbound IPsを登録します。
コールバックURLの登録
コールバックURLをLINE BOT APIに登録します。
今回はhttp://xxx.com:443/callbackというURLで後述のアプリを作成しようとおもいます。(xxx.comの部分はherokuのURL)
https://business.line.meから
Channels → Basic Infomationを選び、下の方にあるEDITボタンより「Callback URL」を登録します。
その際プロトコルはhttps、ポート番号は443を必ず指定します。(指定しないと正しく呼び出せないらしい。)
https://xxxx.com:443/callback
これで事前準備は終わりです。
次からは本題のBOT用アプリ作成です。
Railsアプリの作成
次に、自分のマシンに新しいRailsプロジェクト作成します。
$ rails new your_app
herokuのDBにはPostgreSQL、LINE BOT APIとのHTTP接続にはFaradayを使うので、Gemfileに以下を追加。
gem "pg" gem "faraday" gem "faraday_middleware"
前の人が話した言葉や、ユーザの管理にはherokuで利用できるPostgresqlを使うので、database.ymlに以下を追加。
database、username、passwordに関してはherokuにログインすると確認できます。
production: adapter: postgresql encoding: utf8 database: your_database port: 5432 username: your_username password: your_password
route.rbにLINE BOT APIに登録するコールバックURLのルーティング設定
Rails.application.routes.draw do post '/callback' => 'webhook#callback' end
ユーザを管理するモデルの作成
$ rails generate model users mid:string display_name:string status:integer
前の人が話した言葉を管理するユーザの管理するモデルの作成
$ rails generate model messages user_id:integer text_message:string
次にコントローラ。
class WebhookController < ApplicationController
protect_from_forgery with: :null_session
CHANNEL_ID = ENV['LINE_CHANNEL_ID']
CHANNEL_SECRET = ENV['LINE_CHANNEL_SECRET']
CHANNEL_MID = ENV['LINE_CHANNEL_MID']
OUTBOUND_PROXY = ENV['LINE_OUTBOUND_PROXY']
def callback
unless is_validate_signature
render :nothing => true, status: 470
end
result = params[:result][0]
logger.info({from_line: result})
if result['content']['opType'].present?
mid = result['content']['params'][0]
client = LineClient.new(CHANNEL_ID, CHANNEL_SECRET, CHANNEL_MID, OUTBOUND_PROXY)
res = client.profile(mid)
if res.status == 200
logger.info({success: res})
display_name = res.body['contacts'][0]['displayName']
opType = result['content']['opType']
case opType
when 4 then
user = User.create_with(display_name: display_name, status: 4).find_or_create_by(mid: mid)
user.display_name = display_name
user.status = 4
user.save!
when 8 then
user = User.create_with(display_name: display_name, status: 8).find_or_create_by(mid: mid)
user.display_name = display_name
user.status = 8
user.save!
else
end
else
logger.info({fail: res})
end
else
text_message = result['content']['text']
from_mid = result['content']['from']
last_message = Message.last.text_message
user = User.find_by(mid: from_mid)
Message.create(user_id: user.id, text_message: text_message)
message = last_message + "が先か、" + text_message + "が先か"
client = LineClient.new(CHANNEL_ID, CHANNEL_SECRET, CHANNEL_MID, OUTBOUND_PROXY)
res = client.send([from_mid], message)
if res.status == 200
logger.info({success: res})
else
logger.info({fail: res})
end
end
render :nothing => true, status: :ok
end
private
def is_validate_signature
signature = request.headers["X-LINE-ChannelSignature"]
http_request_body = request.raw_post
hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, CHANNEL_SECRET, http_request_body)
signature_answer = Base64.strict_encode64(hash)
signature == signature_answer
end
end
LINE BOT APIを呼ぶライブラリの作成。
require "faraday"
require "faraday_middleware"
require "json"
require "pp"
class LineClient
module ContentType
TEXT = 1
IMAGE = 2
VIDEO = 3
AUDIO = 4
LOCATION = 7
STICKER = 8
CONTACT = 10
end
module ToType
USER = 1
end
END_POINT = "https://trialbot-api.line.me"
TO_CHANNEL = "1383378250" # Fixed value
EVENT_TYPE = "138311608800106203" # Fixed value
def initialize(channel_id, channel_secret, channel_mid, proxy = nil)
@channel_id = channel_id
@channel_secret = channel_secret
@channel_mid = channel_mid
@proxy = proxy
end
def post(path, data)
client = Faraday.new(:url => END_POINT) do |conn|
conn.request :json
conn.response :json, :content_type => /\bjson$/
conn.adapter Faraday.default_adapter
conn.proxy @proxy
end
res = client.post do |request|
request.url path
request.headers = {
'Content-type' => 'application/json; charset=UTF-8',
'X-Line-ChannelID' => @channel_id,
'X-Line-ChannelSecret' => @channel_secret,
'X-Line-Trusted-User-With-ACL' => @channel_mid
}
request.body = data
end
res
end
def get(path, data)
client = Faraday.new(:url => END_POINT) do |conn|
conn.request :json
conn.response :json, :content_type => /\bjson$/
conn.adapter Faraday.default_adapter
conn.proxy @proxy
end
res = client.get do |request|
request.url path, data
request.headers = {
'Content-type' => 'application/json; charset=UTF-8',
'X-Line-ChannelID' => @channel_id,
'X-Line-ChannelSecret' => @channel_secret,
'X-Line-Trusted-User-With-ACL' => @channel_mid
}
end
res
end
def send(line_ids, message)
post('/v1/events', {
to: line_ids,
content: {
contentType: ContentType::TEXT,
toType: ToType::USER,
text: message
},
toChannel: TO_CHANNEL,
eventType: EVENT_TYPE
})
end
def profile(mids)
get('/v1/profiles', {
mids: mids
})
end
end
heroku ENVの設定
LINE BOT APIの情報
Channel ID
Channel Secret
MID
とFIXIEのアカウント情報にあった
PROXY URL
を設定します。
このENVはRailsプログラムから参照します。
$ heroku config:add LINE_CHANNEL_ID="xxxxxx" $ heroku config:add LINE_CHANNEL_SECRET="xxxxxx" $ heroku config:add LINE_CHANNEL_MID="xxxxxx" $ heroku config:add FIXIE_URL="http://xxxxxx"
herokuへデプロイ
最後にherokuへデプロイします
$ git add . $ git commit -m 'xxxxxx' $ git push heroku master
DBがあるのでマイグレートします。
$ heroku run rake db:migrate
これで準備完了です。
LINEから確認してみましょう。
LINEが入っているスマホから友達追加。
うまく動いてそうです。
まだトライアルなので50人までしか友達増やせないみたいです。
今回はシンプルなロジックのBOTをつくりましたが、工夫次第で面白いものが作れそうです。
















[…] 前回、LINE BOTを無料で試してみました。heroku + RailsでLINE BOTを試してみたのですが、社内でロジックが単純すぎでくだらないという批判が多かったので、ロジックを少し改良しました。 […]
[…] https://www.cotegg.com/blog/?p=436 […]