2017年2月4日土曜日

Line::Bot::API を使って LINE ボットを作成してみた

概要

噂の LINE BOT API を Ruby で使ってみました
ボットのデプロイ先は Heroku を使っています

環境

  • heroku-toolbelt 3.43.5
  • line-bot-api 0.16
  • sinatra 1.4.7
  • LINE BOT API および Business アカウント (2016/07/08 時点)

Line Business アカウント (ボットアカウント) の取得

これが一番面倒かもしれません

https://business.line.me/ja/products/4/introduction
の一番下に「利用開始」があるので選択します

まず、Business アカウントを取得する前に既存の LINE アカウントで Business Center にログインできるようにする必要があります

スクリーンショットがなくて申し訳ないですが申し込みの流れとしては

  1. メールアドレスの登録
  2. 登録したアドレスに届くメールに記載されている確認用の URL をクリック
  3. 個人情報の登録

で Business Center にログインできるようになります
作成できたら https://business.line.me/ja/ から LINE アカウントでログインしてください

するとようやく Business アカウントを作成できる画面になるので作成します
これが所謂、ボットアカウントになるのでボット用の画像と名前を設定してあげてください
try_line_bot_setting_business_account.png

このあと英語の利用規約が表示されるので同意してアカウントを作成しましょう

Business アカウントを作成したあとでほしい情報は「Channel ID」「Channel Secret」「MID」の 3 つになります
try_line_bot_check_any_keys.png

とりあえずこの 3 つが確認できれば Business アカウントの作成は OK です

ボットアプリの作成

Sinatra + Line::Bot::API を使ってボットアプリを作成していきます
なぜボットを Sinatra で作らなければいけないかと言うと LINE のボットはメッセージの受信を HTTPS で受け取り、メッセージの送信を LINE BOT API の REST API をコールすることで実現しています

流れとしては

  1. LINE アプリで誰かがボットに会話
  2. 会話の情報がデプロイしたボットアプリに HTTPS で POST リクエストとして飛んで来る
  3. ボットがリクエストを受ける
  4. リクエストを処理したあとでレスポンスとして送信するメッセージを送るために LINE BOT API の REST API をコールする

という流れになります (今回は)
なので Sinatra でボットを Web アプリ化する必要があります

でアプリの全容は以下の通りです

  • mkdir -p /path/to/work/line_bot
  • cd /path/to/work/line_bot
  • bundle init
  • vim Gemfile
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"

gem 'sinatra', '1.4.7'
gem 'line-bot-api'
  • vim app.rb
require 'sinatra'
require 'line/bot'

class HTTPProxyClient
  def http(uri)
    proxy_class = Net::HTTP::Proxy(ENV["FIXIE_URL_HOST"], ENV["FIXIE_URL_POST"], ENV["FIXIE_URL_USER"], ENV["FIXIE_URL_PASSWORD"])
    http = proxy_class.new(uri.host, uri.port)
    if uri.scheme == "https"
      http.use_ssl = true
    end

    http
  end

  def get(url, header = {})
    uri = URI(url)
    http(uri).get(uri.request_uri, header)
  end

  def post(url, payload, header = {})
    uri = URI(url)
    http(uri).post(uri.request_uri, payload, header)
  end
end

def client
  @client ||= Line::Bot::Client.new { |config|
    config.httpclient = HTTPProxyClient.new
    config.channel_id = ENV["LINE_CHANNEL_ID"]
    config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
    config.channel_mid = ENV["LINE_CHANNEL_MID"]
  }
end

get '/' do
  "Hello, world"
end

post '/callback' do
  signature = request.env['HTTP_X_LINE_CHANNELSIGNATURE']
  unless client.validate_signature(request.body.read, signature)
    error 400 do 'Bad Request' end
  end

  receive_request = Line::Bot::Receive::Request.new(request.env)

  receive_request.data.each { |message|
    case message.content
    # Line::Bot::Receive::Message
    when Line::Bot::Message::Text
      puts message.content[:text]
      client.send_text(
        to_mid: message.from_mid,
        text: message.content[:text],
      )
    # Line::Bot::Receive::Operation
    when Line::Bot::Operation::AddedAsFriend
      puts 'send_sticker'
      client.send_sticker(
        to_mid: message.from_mid,
        stkpkgid: 2,
        stkid: 144,
        stkver: 100
      )
    end
  }

  "OK"
end
  • vim config.ru
require 'bundler'
Bundler.require

require './app'
run Sinatra::Application
$stdout.sync = true

で必要なファイルを作成したら、とりあえず OK です
ローカルで動作確認するのであれば

  • bundle install && bundle exec rackup config.ru

でエラーがでなければ OK です
実際にアクセスして動作確認するのは Heroku にデプロイしてから行います

Heroku へのデプロイ

ターミナル上でコマンドを実行してデプロイしていきます

  • cd /path/to/work/line_bot
  • git init
  • git add .
  • git commit -m “Initial Commit”
  • heroku create –app your-line-bot
  • heroku git:remote –app your-line-bot
  • git push heroku master
  • heroku config:set LINE_CHANNEL_ID=1111111111 LINE_CHANNEL_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LINE_CHANNEL_MID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx –app your-line-bot

でとりあえずデプロイしましょう
設定している環境変数は Business アカウントを作成した際に取得した 3 つの情報を入力してください

Business アカウントのコールバック URL の設定

Business アカウントの設定画面にコールバック URL を設定する画面があります
このコールバック URL はボットに対して話かけた際にリクエストされるメッセージ受信用の URL になります
なので、ここには先程 Heroku にデプロイしたアプリの URL を設定します

try_line_bot_setting_callback_url.png

こんな感じで Heroku のアプリ名に合わせて設定すれば OK です
今回の場合、/callback でボット用のリクエストを受け取るので上記のように設定してください

Fixie アドオンの追加

Heroku で使う場合にはこの設定が必ず必要です
Fixie は Heroku からリクエストがある場合に送信元の IP を固定化するために使う Heroku のアドオンです

メッセージを送信するためには LINE BOT API をコールするのですが、API は送信元の IP アドレスをホワイトリストで管理して、その IP からしか叩けないようになっています

なので Fixie を挟んで Heroku からのリクエスト IP を固定化することで LINE BOT API をコールできるようにします

Heroku で Fixie アドオンを使うためにはまず Heroku アカウントにクレッジットカードを登録する必要があります
クレッジットカードを登録しますが Fixie 自体は無料で利用することができます

https://dashboard.heroku.com/account/billing

ここからクレッジットカードを登録します
登録できたら

  • cd /path/to/work/line_bot
  • heroku addons:create fixie:tricycle –app your-line-bot

でデプロイしたアプリに Fixie を追加することができます
追加に成功すると

Your IP addresses are xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx

という感じで固定 IP が払い出されるのでこれを Business アカウントのホワイトリストに追加してあげます

その前に Heroku 上にデプロイしたアプリにも Fixie のアクセス情報を渡す必要があるので heroku config:set で渡してあげます

  • cd /path/to/work/line_bot
  • heroku config:set FIXIE_URL_HOST=xxxxxxxxxxxx.usefixie.com FIXIE_URL_PORT=80 FIXIE_URL_USER=fixie FIXIE_URL_PASSWORD=xxxxxxxxxxxxx

おそらく、上記で変更する部分は「FIXIE_URL_HOST」と「FIXIE_URL_PASSWORD」の部分だと思います
これらの設定は「FIXIE_URL」という環境変数の値をバラバラにしただけなので、わからない場合は heroku config で FIXIE_URL の値を確認してください

Business アカウントのホワイトリストの設定

左メニュー上段に「Server IP Whitelist」という項目があるのでここで設定します
Fixie によって払いだされた IP をそのまま Add すれば OK です

try_line_bot_setting_white_list.png

設定は以上で完了です
いよいよ動作確認してみましょう

動作確認

ようやくこれでボットと会話できるようになります
ボットと会話するためにはボットと友達になる必要があります

Business アカウントの情報の一覧に QR コードがあります
これをスマホの LINE アプリで読み込むことでボットと友達になれます

友だち -> 右上追加アイコン -> QR コード

で読み取れば友だちに追加されます
追加されたらトークしてみましょう

以下のような感じでボットから返事が返ってくれば OK です
try_line_bot_result_line_app.png

Heroku のにデプロイした Sinatra アプリのアクセスログにも以下のように出力されていると思います
try_line_bot_result_heroku_logs.png

最後に

紹介は以上です
簡単にできると思ったんですが、Heroku の場合は Fixie を導入しなければいけなかったりと結構ハマりポイントがありました

触ってみた感じだとレスポンスを返す際に、他の API と絡めてうまい感じに返せると結構おもしろいボットが作れるんじゃないかと思いました

あとは cron 等で定期的にメッセージを送信できることができたりするともっといいなと思いました
メッセージ受信 -> 送信の流れではなく、いきなり送信というのができるようにすればできなくはないと思います

まだトライアルなので、今後どうなるかも気になるところです

Tips

その他、気になった点を紹介します

  • Heroku 上のアプリが寝てしまうとレスポンスが遅くなる
  • デバッグする方法

基本は Heroku 上のログを見れば OK です
今回 puts を入れていますが puts の出力も Heroku 上のログに出るので、適当に突っ込みながらデバッグするといいと思います
/callback に POST のリクエストが来て 200 を返していれば受信は OK です
送信に関しては Fixie をちゃんと経由してリクエストしているかを確認する必要があります
https://dashboard.usefixie.com/#/logs で自分の Fixie の利用状況を確認することができるので、ここで「//trialbot-api.line.me:443」にアクセスしているログが出ているか確認するといいと思います
もし出ていない場合は Heroku の環境変数がちゃんと設定されていない必要があるので heroku config で確認してください

参考 URL

0 件のコメント:

コメントを投稿