追記
この記事はトライアル版時代のものになります。すでに正式版が出ているので、ご注意ください。
Railsで今話題のLINE BOTを作ってみました。
とりあえず、送ったメッセージをそのまま返すものです。
LINEへの登録
https://business.line.me から登録できます。
デベロッパー登録が済めば、次のような画面が出てくるので、
- Channel ID
- Channel Secret
- MID
の値を控えておきます。
HerokuにRailsアプリを作成
LINE BOT API の呼び出しには Server IP Whitelist に接続元 IPを登録する必要があるんですが、HerokuのFixieというアドオンを使うと、プロキシを経由してくれるのでIPを固定できます。
参考) LINE BOT をとりあえずタダで Heroku で動かす
とりあえず空のRailsアプリをHerokuにデプロイして、下記コマンドでFixieアドオンを追加してください。
$ heroku addons:create fixie:tricycle
Heroku上で作ったアプリの設定画面から Fixie の画面を開くと次のような画面になるので、
- Proxy URL
- Outbound IPs
を控えます。
そして、LINE DevelopersのServer IP Whitelistに控えたIPが2つあると思うので2つとも登録しておきます。
CallbackURLの設定
BOTに対してメッセージを送るとWebhookでcallback先に情報が飛んでくるのでcallbackURLを設定します。
HTTPSしか許可してくれないんですが、HerokuはもともとHTTPSなのでこの点はクリアです。
自分のサーバでやるときはSSLとかを頑張らないといけないです。
(証明書を使っても、無料のLet's Encryptだとうまく動かないなどの罠があるみたいです。参考)
下記のようにBasic Informationのところに設定します。ポート番号の443も必須みたいです。
自分の場合、CallbackURLを設定してから反映するまで結構時間がかかりました。
1時間以上経ってからコールバックしてきたので、なにか間違ったかといろいろいじり倒してしまいました。
自分を信じて気長に待つ事をオススメします。
Railsアプリ
本題?のRailsアプリです。
まず、Basic Informationに設定したCallbackURLを受け付けるようroute.rbを書きます。
Rails.application.routes.draw do
post '/callback' => 'webhook#callback'
end
次にコントローラです。
WebhookなのでCSRF対策を無効化してます。
is_validate_signatureメソッドはLINE公式ドキュメントのコピペです。
class WebhookController < ApplicationController
protect_from_forgery with: :null_session # CSRF対策無効化
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})
text_message = result['content']['text']
from_mid =result['content']['from']
client = LineClient.new(CHANNEL_ID, CHANNEL_SECRET, CHANNEL_MID, OUTBOUND_PROXY)
res = client.send([from_mid], text_message)
if res.status == 200
logger.info({success: res})
else
logger.info({fail: res})
end
render :nothing => true, status: :ok
end
private
# LINEからのアクセスか確認.
# 認証に成功すればtrueを返す。
# ref) https://developers.line.me/bot-api/getting-started-with-bot-api-trial#signature_validation
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を呼ぶ自作ライブラリです。
Faradayを使うので、Gemfileに
gem "faraday"
gem "faraday_middleware"
を追加しておいてください。
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 # this is fixed value
EVENT_TYPE = "138311608800106203" # this is 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 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
end
環境変数に、
- LINE_CHANNEL_ID
- LINE_CHANNEL_SECRET
- LINE_CHANNEL_MID
- LINE_OUTBOUND_PROXY
を使っているので、控えた値をもとに設定しておいてください。
LINE_OUTBOUND_PROXYの値はポート番号付きで最後の:80を忘れないようにしてください。
Herokuだと、
$ heroku config:add LINE_CHANNEL_ID="XXXXXXXXXXXX"
$ heroku config:add LINE_CHANNEL_SECRET="XXXXXXXXXXXX"
$ heroku config:add LINE_CHANNEL_MID="XXXXXXXXXXXX"
$ heroku config:add LINE_OUTBOUND_PROXY="XXXXXXXXXXXX"
という感じになります。
これで、BOTと友達になって、メッセージを送りつけると、そのまま返してくるはずです。
Basic InformationのところのQRコードを使ったら、友達になれます。
まだトライアルなので50人までしか友達増やせないみたいです。