LINE bot API・グルナビAPIを使って、近くの飲食店を探すLINE botを作成

###1. 概要
<img width="300px" src = "https://qiita-image-store.s3.amazonaws.com/0/256060/e87f310a-3d36-acbe-dac3-0a63ba9b8dac.jpeg">

ここでは、LINEで自分の位置情報を送ることにより、自分がいる場所の近くにある飲食店を一つランダムに返しています。また地名やカテゴリーを送ることもできるようになっています。

###２. Web APIとは
APIとは__「Application Programming Interface」__の略です。
<img width="645" alt="スクリーンショット 2018-12-05 17.29.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/256060/3fd9bc1a-de7a-1798-e29b-a6e91fdd513d.png">

インターフェースとは日本語に直訳すると境界面や接点という意味があります。つまり、両方とも、何かと何かの境界面のことだと分かればざっくりとしたイメージがつかめると思います。

そして、__Web API__とはHTTPという通信方式を用いてネットワーク越しに呼び出すAPIです。

###３. アプリの構造
自分が作成したアプリの仕組みを簡単に図に表したのが以下の図です。
<img width="848" alt="スクリーンショット 2018-12-01 19.14.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/256060/fba323de-fbbc-b1f0-f169-06826db4ddbf.png">

①．ユーザーが位置情報もしくは地名をLINEbotに送信する
②．LINEサーバが①のイベントを検知して、botで指定されているRailsアプリのURLにリクエストを送る
③．RailsアプリがLINEから送られてきた情報を元に、グルナビAPIにリクエストを送る。
④．グルナビAPIからのレスポンス（店舗の情報）をRailsアプリが受け取る。
⑤．受け取った情報をもとに、処理した内容をLINEサーバに送る
⑥．LINEサーバがスマホのLINEに通知を送信する

これでこのアプリの概要が分かっていただけましたか？

###４. 作成のために必要な知識
ここでは自分が作成したものと同じものを作るために必要な知識をあげてみます。

１.APIに関して
２.Rubyに関して
３.Railsに関して
４.Herokuを使ったデプロイの仕方に関して
５.gitに関して

これらについての簡単な知識があれば作成ができます。

###５. 作成の仕方の概要

####手順
Step１　LINE bot APIの部分を設定する
Step２　グルナビAPIの部分を設定する
Step３　Railsの部分を実装する
Step４　アプリケーションをデプロイする

注意点としては、lien_botはhttpsのアドレスが必要なためローカル環境では特別な設定をしない限り、実行することができません。ここではHerokuにデプロイすることにします。自分は修正するたびにherokuにデプロイをして、実行結果を確認しながら作業を進めました。

###６. 実装の仕方
ここでは簡単に説明していきます。
実際に作ってみたい方は、他の詳細な説明が書いてあるサイトも参考にしながらやってみてください。

####Step１　LINE bot APIの部分を設定する
ここではLINE bot APIの設定を行います。まず、LINE Developersに登録し、新規チャンネルを作成します。ここで特に注意すべき点は以下の２点です。以下のサイトから行なってください。

１、Messaging APIを選択し、Channel Secretとアクセストークンが得られていることを確認する。
２、webhookを有効にする（webhook URLはherokuにデプロイした際にhttpsのURL
が与えられるのでそれを登録します。）

####Step２　グルナビAPIの部分を設定する
以下のサイトからレストラン検索APIを使います。
登録するとアクセスキーが取得できます。
https://api.gnavi.co.jp/api/

ここまでで自分のアプリを作成する準備は完璧です。

####Step３　Railsの部分を実装する
まず次のgemを入れます

```ruby:Gemfile
gem 'line-bot-api'
```

ルーティングやコントローラーは以下の通りです。

```ruby:linebot_controller
class LinebotController < ApplicationController
   require 'line/bot'  # gem 'line-bot-api'
   # callbackアクションのCSRFトークン認証を無効
   protect_from_forgery :except => [:callback] 
   def client
     @client ||= Line::Bot::Client.new { |config| 
       config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
       config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
     } 
   end

   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)
 
     #ここでlineに送られたイベントを検出している
     # messageのtext: に指定すると、返信する文字を決定することができる
     #event.message['text']で送られたメッセージを取得することができる
     events.each { |event|
       if event.message['text'] != nil
         place = event.message['text'] #ここでLINEで送った文章を取得
         result = `curl -X GET http://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid='&'format=json'&'address=#{place}`#ここでぐるなびAPIを叩く
       else
         latitude = event.message['latitude']
         longitude = event.message['longitude']

         result = `curl -X GET http://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid='&'format=json'&'latitude=#{latitude}'&'longitude=#{longitude}`#ここでぐるなびAPIを叩く
       end
       
       hash_result = JSON.parse result #レスポンスが文字列なのでhashにパースする
       shops = hash_result["rest"] #ここでお店情報が入った配列となる
       shop = shops.sample #任意のものを一個選ぶ

       #店の情報
       url = shop["url_mobile"] #サイトのURLを送る
       shop_name = shop["name"] #店の名前
       category = shop["category"] #カテゴリー
       open_time = shop["opentime"] #空いている時間
       holiday = shop["holiday"] #定休日

       if open_time.class != String #空いている時間と定休日の二つは空白の時にHashで返ってくるので、文字列に直そうとするとエラーになる。そのため、クラスによる場合分け。
         open_time = ""
      end
      if holiday.class != String
         holiday = ""
       end
 
       response = "【店名】" + shop_name + "\n" + "【カテゴリー】" + category + "\n" + "【営業時間と定休日】" + open_time + "\n" + holiday + "\n" + url
        case event #case文　caseの値がwhenと一致する時にwhenの中の文章が実行される(switch文みたいなもの)
       when Line::Bot::Event::Message
         case event.type
         when Line::Bot::Event::MessageType::Text,Line::Bot::Event::MessageType::Location
           message = {
             type: 'text',
             text: response
           }
           client.reply_message(event['replyToken'], message)
         end
 
       end
     } 

     head :ok
   end
 end
```

```ruby:routes.rb
post '/callback' => 'linebot#callback'
```

####Step４　アプリケーションをデプロイする
railsアプリケーションをherokuにデプロイします。この時にhttpsのURLが与えられるのでLINE bot APIのWebhook URLに追加します。
ポイントとしては、```heroku logs -t```でlogを見ながらデプロイやデバッグをすると何が起こっているか分かりやすいです。

##終わりに
どうだったでしょうか？APIが何かわかりましたか？
以下のようなサイトにWeb APIが様々な種類載っています。面白そうなのがあれば実際に使ってみてください!
http://smsurf.app-rox.com/api/

##参考
LINE bot API
https://qiita.com/y428_b/items/d2b1a376f5900aea30dc

heroku
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39