Herokuでリクエストを受けとり、VPSで処理をするLINE BOTをつくってみた


対象

LINE BOT をとりあえずタダで Heroku で動かす を参考にタダで Heroku で動かせたひと。
SSL証明書はないけど、固定IPの割り当てられてる VPS (など)を持ってるひと。

なんとかしたい

Fixie プラグインの毎月500リクエストで制限がかかってしまうのをなんとかしたい。

対策

Heroku で LINE サーバからリクエストを受け取ってキューイングし、VPS で取り出して LINE API にリクエストを投げる。
Fixie に頼らなくてよくなる。
キューイングの仕組みは、heroku-redissidekiq を使うと簡単。
(ただし heroku-redis はまれに接続情報が変わるので、VPS で redis の運用をした方がより良さそう)

やってみる

参考文献のプログラムを元に改造していく。
まず app.rb にあったオウム返し処理を echoback.rb に切り出す。(sidekiq の設定もついでにかく)

app.rb
require 'bundler/setup'
require 'sinatra'
require 'json'
require './echoback'

post '/linebot/callback' do
  params = JSON.parse(request.body.read)

  params['result'].each do |msg|
    Echoback.perform_async(msg)
  end

  "OK"
end
echoback.rb
require 'sidekiq'
require 'httpclient'

Sidekiq.configure_client do |config|
  config.redis = { url: ENV.fetch('REDIS_URL'), namespace: ENV.fetch('RACK_ENV') }
end

Sidekiq.configure_server do |config|
  config.redis = { url: ENV.fetch('REDIS_URL'), namespace: ENV.fetch('RACK_ENV') }
end

class Echoback
  include Sidekiq::Worker

  def perform(msg)
    request_content = {
      to: [msg['content']['from']],
      toChannel: 1383378250, # Fixed  value
      eventType: "138311608800106203", # Fixed value
      content: msg['content']
    }

    http_client = HTTPClient.new
    endpoint_uri = 'https://trialbot-api.line.me/v1/events'
    content_json = request_content.to_json
    http_client.post_content(endpoint_uri, content_json,
        'Content-Type' => 'application/json; charset=UTF-8',
        'X-Line-ChannelID' => ENV["LINE_CHANNEL_ID"],
        'X-Line-ChannelSecret' => ENV["LINE_CHANNEL_SECRET"],
        'X-Line-Trusted-User-With-ACL' => ENV["LINE_CHANNEL_MID"]
      )
  end
end
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'sinatra'
gem 'httpclient'

# gemも3つ追加
gem 'sidekiq'
gem 'redis-namespace'
gem 'dotenv'
# Procfile
web: bundle exec ruby app.rb -p $PORT

続いて、Heroku と VPS それぞれの環境を整える。
あと LINE の Whitelist に VPS の IP を登録する。

Heroku

heroku-redis をよしなにインストール。
ちなみに heroku-redis はメモリ25MBまで無料枠。

VPS

ソースコードをもってきて bundle する。
.env をつくる。

$ git clone https://github.com/user/sample
$ cd sample
$ bundle
$ vi .env
LINE_CHANNEL_ID='XXXXXXXXXXX'
LINE_CHANNEL_SECRET='XXXXXXXXXXX'
LINE_CHANNEL_MID='XXXXXXXXXXX'
REDIS_URL='XXXXXXXXXXX'

REDIS_URLheroku config | grep REDIS で確認できる。

最後に sidekiq を動かす。 heroku-redis の最大コネクション数が20なので、それに収まるように調整する。

$ bundle exec sidekiq ./echoback.rb -c 5
or
$ bundle exec sidekiq ./echoback.rb -c 5 -d -L /path/to/logfile

以上で、LINE BOT に話しかけると Heroku と VPS が連携してオウム返し処理をしてくれる。