HerokuとPython3.6で近場の居酒屋を検索してくれるLineBotを作成した。

##背景
社会人になると同期たちがよく飲みに行っていたので2次会の店を決定するために作成しました。
飲み屋に迷ったときなどに使ってもらえると嬉しいです。

##QRコード

![M.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316759/0b87e31f-d1d6-195a-ab07-fb7b9e2f40be.png)
##環境
Python3.6
Flask
Heroku

食べログAPI
LineBot_SDK

※本記事ではLineBotそのものの作り方や、Herokuへのデプロイの仕方は割愛させていただきます。
　また、Herokuの無料枠を使用しているのでレスポンスが悪い場合がありますがご了承ください。

##位置情報から居酒屋を検索する

適宜ぐるナビAPIからアクセスキーを取得します。
その後、緯度と軽度から居酒屋を検索できるようにします。

latとlon以外のパラメータで日本国内の居酒屋を検索するようにしています。
また、defaultでは5件までの検索ですがhit_per_pageの値を変更することで変更することができます。

また、取得したデータをリストに格納しています。

```python

"""
緯度(latitude),軽度(longitude)を引数に取ります
"""
def rest_search(lat,lon):
    URL = "https://api.gnavi.co.jp/RestSearchAPI/v3/"

    api_params = {
                "keyid":"ACCESS_KEY",
                "category_s":"RSFST09004",
                "latitude":lat,
                "longitude":lon,
                "range":3,
                "hit_per_page":5
                }

    rest = requests.get(URL,params = api_params).json()["rest"]
    json_datas = [data for data in rest]
    return json_datas

```

##LineBotの設定
基本的にはLineBotSDKのサンプルプログラムを少し弄っただけです。

```python:app.py
import os
import sys
from flask import Flask, request, abort
import requests
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import *
from carousel import create_carousel,rest_search

app = Flask(__name__)

channel_secret = os.environ['YOUR_CHANNEL_SECRET']
channel_access_token = os.environ['YOUR_CHANNEL_ACCESS_TOKEN']

if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)



@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text="住所をおくってね！")
        )

@handler.add(MessageEvent, message=LocationMessage)
def handle_location(event):
    lat = event.message.latitude
    lon = event.message.longitude

    rest_datas = rest_search(lat,lon)
    
    template_message = TemplateSendMessage(alt_text='周辺の居酒屋だよ!', template=create_carousel(rest_datas))
    line_bot_api.reply_message(event.reply_token, template_message)

if __name__ == "__main__":
    app.run()
```

carousel　の中身はこんな感じです。

```python:carousel.py
from linebot.models import (
    CarouselTemplate, CarouselColumn,URITemplateAction)
import requests

def create_carousel(rest_colum):
    carousel_template = CarouselTemplate(
        columns=[
            CarouselColumn(
                text=rest["name"],
                actions=[
                    URITemplateAction(
                        label="開く",
                        uri=rest["url_mobile"]
                        )]
                    )
                for rest in rest_colum
                ])
    return carousel_template
    
def rest_search(lat,lon):
    URL = "https://api.gnavi.co.jp/RestSearchAPI/v3/"
    api_params = {
                "keyid":"ACCESS_KEY",
                "category_s":"RSFST09004",
                "latitude":lat,
                "longitude":lon,
                "range":3,
                "hit_per_page":5
                }

    rest = requests.get(URL,params = api_params).json()["rest"]
    json_datas = [data for data in rest]
    return json_datas

```

##結果
作成したLineBotをHerokuにデプロイし実際に使用してみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316759/a2a25822-83d9-8b73-dcdb-428263db91c6.jpeg" width=50%>

写真が無いので少しリッチ感にかけますがうまく表示することができました!

ぐるナビAPIが返してくるデータの中に写真用のURLがあるのですが登録していないお店のほうが多いのでどうやって写真を添付するか悩み中です。