###前提・実現したいこと
ここに質問したいことを詳細に書いてください
LINE Messaging APIのサンプルコードをRubyで動かしたい
###発生している問題・エラーメッセージ
サンプルコードを実行すると、「A http status of the response was '400 Bad Request'.」(リクエストに問題があります。リクエストパラメータやJSONのフォーマットを確認してください。)が返ってくる。
LINE Messaging APIドキュメントを読んだところ署名検証が必要らしいが、どのようにコードに起こして実装すればよいのか分からない。
###該当のソースコード
Ruby
1require 'sinatra' 2require 'line/bot' 3 4def client 5 @client ||= Line::Bot::Client.new { |config| 6 config.channel_secret = ENV["LINE_CHANNEL_SECRET"] 7 config.channel_token = ENV["LINE_CHANNEL_TOKEN"] 8 } 9end 10 11post '/callback' do 12 body = request.body.read 13 14 signature = request.env['HTTP_X_LINE_SIGNATURE'] 15 unless client.validate_signature(body, signature) 16 error 400 do 'Bad Request' end 17 end 18 19 events = client.parse_events_from(body) 20 events.each { |event| 21 case event 22 when Line::Bot::Event::Message 23 case event.type 24 when Line::Bot::Event::MessageType::Text 25 message = { 26 type: 'text', 27 text: event.message['text'] 28 } 29 client.reply_message(event['replyToken'], message) 30 when Line::Bot::Event::MessageType::Image, Line::Bot::Event::MessageType::Video 31 response = client.get_message_content(event.message['id']) 32 tf = Tempfile.open("content") 33 tf.write(response.body) 34 end 35 end 36 } 37 38 "OK" 39end
###APIのドキュメント
リクエストの送信元がLINEであることを確認するために署名検証を行わなくてはなりません。
各リクエストには X-Line-Signature ヘッダが付与されています。
X-Line-Signature ヘッダの値と、Request Body と Channel Secret から計算した Signature が同じものであることをリクエストごとに 必ず検証してください。
検証は以下の手順で行います。
Channel Secretを秘密鍵として、HMAC-SHA256アルゴリズムによりRequest Bodyのダイジェスト値を得る。
ダイジェスト値をBASE64エンコードした文字列が、Request Headerに付与されたSignatureと一致することを確認する。
CHANNEL_SECRET
1http_request_body = request.raw_post # Request body string 2hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, CHANNEL_SECRET, http_request_body) 3signature = Base64.strict_encode64(hash) 4# Compare X-Line-Signature request header string and the signature
###補足情報(言語/FW/ツール等のバージョンなど)
ドキュメントURL
https://devdocs.line.me/ja/#webhook
サンプルコードのURL
https://github.com/line/line-bot-sdk-ruby
Herokuをつかっています。