BETA

LINE BotをHerokuへデプロイしたら500エラーに悩まされた

投稿日:2019-02-28
最終更新:2019-02-28

Botとは

Wikipedia

Bot(ボット)は、robot(ロボット)の短縮形・略称。転じて、コンピュータやインターネットの分野においては、作業を自動化するプログラムの総称。

LINE Bot

LINEで動かすBotのこと。
LINE Developersに登録して使用することができる。
登録手順は他に多くの記事が出ているので省略。

手始めにオウム返しのLINE Botを作成

LINE Developersのドキュメントを読むとsinatraでオウム返しbotを作成する場合のサンプルコードを見ることができる。

LINE Developers>ドキュメントトップ>Messaging API>Herokuでサンプルボットを作成する

このサンプルコードをRailsに書き換えていく。

例によってrails newを行い、gemはプロジェクト毎に管理する。

Herokuへデプロイ後、LINE Developersのチャンネル基本設定からWebhook URLの接続確認をしてみたところ、無効なステータスコードが返ってきたとのことで、うまくいかない。

実際にbotへメッセージを送ると既読になるが、何も返答はなく、オウム返しされない。

Herokuのlogをみると、メッセージ送信時や接続確認を実行した際のparameterは取れているようだが、status=500となってしまっている。

チャンネルシークレットやアクセストークンは設定してある。

さっぱり分からず、なぜ解決できないか時々絶望しながら2日ほどあれこれ調べた。
typoを含めて修正、接続確認、メッセージ送信、logの確認を何度も繰り返したが、最終的にstatus=500はHerokuのアプリケーションを作り直したら解決した。
現在、オウム返しは成功するようになったが、Webhook URLの接続確認では相変わらず「無効なステータスコードを返しました」と表示される。
logをみるとstatusが204が返ってきている。200番台なので成功しているということになるはずだが、204が返されている理由と200との違いが気になったので調べた。
204は No Content で、リクエストは成功しているが、返せる内容がないときのステータスコードとのこと。
200を返すように実装できていないようなので、改めて修正することにする。 # TO DO

 

500エラーの原因とは関係ないが、奮闘中に調べたことのメモ。

require 'line/bot'  

class WebhookController < ApplicationController  
  protect_from_forgery :except => [:callback] #①  

  def callback  
    body = request.body.read  
    signature = request.env['HTTP_X_LINE_SIGNATURE'] #②  
    unless client.validate_signature(body, signature)  
      error 400 do 'Bad Request' end  
    end  

    events = client.parse_events_from(body)  

    events.each { |event|  
      case event  
      when Line::Bot::Event::Message  
        case event.type  
        when Line::Bot::Event::MessageType::Text # ③  
          message = {  
              type: 'text',  
              text: event.message['text']  
          }  
          client.reply_message(event['replyToken'], message)  
        when Line::Bot::Event::Follow #④  
          get_line_id = event['source']['userId']  
          User.create(line_id: get_line_id)  
        when Line::Bot::Event::Unfollow #④  
          get_line_id = event['source']['userId']  
          User.find_by(line_id: get_line_id).destroy  
        end  
      end  
    }  

    "ok"  
  end  

  private  

  def client  
    @client ||= Line::Bot::Client.new { |config|  
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]  
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]  
    }  
  end  
end

①のprotect_from_forgery :except => [:callback]Rails5.2.2のリファレンスによると、application.controller.rb内にprotect_from_forgeryが記述されている上で、偽造防止要求の例外を発生させる。

class ApplicationController < ActionController::Base  
  protect_from_forgery  
end  

class FooController < ApplicationController  
  protect_from_forgery except: :index  
end

rails4からapplication_controller.rbにprotect_from_forgeryが記載されているという説明をみかけた。
rails5について自分のローカルにある他のプロジェクトを確認してみたところ、rails5.1.6では記載があった。
今回のbotではrails5.2.2を使用しているが、application_controller.rbにprotect_from_forgeryの記載は無いようだった。
よって、今回はprotect_from_forgery :except => [:callback]が不要かもしれない。(まだ未検証)

 

env['HTTP_X_LINE_SIGNATURE']はAPIリファレンスによると署名検証のために記述が必要とあるので、8-11行目はそのまま記載する。

 

③はアクションによって条件分岐していき、テキストのメッセージを受信したときの処理を書いている。
リファレンスの例によるとテキストオブジェクトは以下のように扱っている。

"message": {  
    "id": "325708",  
    "type": "text",  
    "text": "Hello, world!"  
  }

event.message['text']で送られてきたメッセージを取得。
botからの送信に使用する。

 

④のフォローとフォロー解除イベントについてリファレンスの例は以下のようになっている。。

# フォローイベント  
{  
  "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",  
  "type": "follow",  
  "timestamp": 1462629479859,  
  "source": {  
    "type": "user",  
    "userId": "U4af4980629..."  
  }  
}  

# フォロー解除イベント  
{  
  "type": "unfollow",  
  "timestamp": 1462629479859,  
  "source": {  
    "type": "user",  
    "userId": "U4af4980629..."  
  }  
}

 

events { type:

アクションがユーザからのメッセージか、フォローか、などの種類を判別
(message/follow/leave/unfollow)

replyToken

一時的に割り当てられる応答用のIDで、これを利用して返信などを行う

source => userId

アクションした人のlINE ID

message { type:

メッセージでは文字やスタンプ、画像などを送れるので、オブジェクトの種類を判別
(text/image/sticker/file/video/audeio/location/rich)

message { id:

オブジェクトのID

message { text:

送信されたテキスト

 

2018年5月の記事でPHPだが、受信したアクションの構造はこちらが参考になった。
https://it-engineer-info.com/language/php/1192/

次はこのbotをアレンジしていきたい。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

学んだことの整理と忘備録としてアウトプット始めました。ログは自分用のちょっとしたメモ書き。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!