【LINE Bot】Heroku+PHP+ぐるなびAPIで蕎麦探しBot作ってみた

LINE BotとぐるなびAPIを使って、蕎麦探しBotを作ってみました。

## 概要
- Botに場所を伝える
- Botは伝えられた場所周辺の蕎麦屋を検索し、返信する
- 簡単に蕎麦を探すことができてハッピー

## なぜ蕎麦なのか
蕎麦が好きだからです。

## ぐるなびAPIについて
ぐるなびさんが提供しているAPIです。レストランや口コミを取得することができます。
http://api.gnavi.co.jp/api/

今回はこちらの「レストラン検索API」を使用しました。
http://api.gnavi.co.jp/api/manual/restsearch/

ドキュメントやサンプルコードがとても綺麗に整備されていて、とても使いやすかったです。テストツール（http://api.gnavi.co.jp/api/tools/ ）も用意されていて最の高でした:pray: 

## LINE BotとHerokuの設定
以前同様の環境を構築していたので、そちらを流用しました。
設定など細かい部分については、以下記事をご参照ください。
>【LINE Bot】Heroku+PHP+雑談対話APIで会話Bot作ってみた
http://qiita.com/shanonim/items/f90ee13180ee70a1903d

## ソースコード
phpﾁｮｯﾄﾃﾞｷﾅｲ...ので、お見苦しい部分がありましたらご容赦ください🙇

```php:index.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;

$app = new Silex\Application();
$app->post('/callback', function (Request $request) use ($app) {
    $body = json_decode($request->getContent(), true);
    foreach ($body['result'] as $msg) {
        // get from and message
        $from = $msg['content']['from'];
        $message = $msg['content']['text'];
        // gnavi API
        $restaurant = gnavi($message);
        if (empty($restaurant)) {
            $res_content = $msg['content'];
            $res_content['text'] = "検索結果がなかったわ・・。場所を変えてみて。";
            reply_message($from, $res_content);
        } else {
            $res_content = $msg['content'];
            $reply_msg_header = "おすすめの蕎麦屋さんを" . count($restaurant) . "件探してきたわ。" . "\n\n";
            $res_content['text'] = $reply_msg_header;
            for ($i = 0; $i < count($restaurant); $i++) {
                if ($i != count($restaurant) - 1) {
                    $res_content['text'] = $res_content['text'] . "◆" . $restaurant[$i]->name . " " . $restaurant[$i]->url . "\n\n";
                } else {
                    $res_content['text'] = $res_content['text'] . "◆" . $restaurant[$i]->name . " " . $restaurant[$i]->url;
                }
            }
            reply_message($from, $res_content);
        }
    }
    return 'OK';
});

$app->run();

function gnavi($area_name) {
    $uri = 'http://api.gnavi.co.jp/RestSearchAPI/20150630/';
    $acckey = 'your API key';
    $format = 'json';
    $keyword = '蕎麦';
    $per_page = '5';
    $url  = sprintf("%s%s%s%s%s%s%s%s%s%s%s", $uri, "?format=", $format, "&keyid=", $acckey, "&address=", $area_name, "&freeword=", $keyword, "&hit_per_page=", $per_page);

    $json = file_get_contents($url);
    $obj  = json_decode($json);

    return $obj->rest;
}

function reply_message($from, $res_content) {
    $client = new GuzzleHttp\Client();
    $requestOptions = [
        'body' => json_encode([
            'to' => [$from],
            'toChannel' => 1383378250, #Fixed value
            'eventType' => '138311608800106203', #Fixed value
            "content" => $res_content,
        ]),
        'headers' => [
            'Content-Type' => 'application/json; charset=UTF-8',
            'X-Line-ChannelID' => getenv('LINE_CHANNEL_ID'),
            'X-Line-ChannelSecret' => getenv('LINE_CHANNEL_SECRET'),
            'X-Line-Trusted-User-With-ACL' => getenv('LINE_CHANNEL_MID'),
        ],
        'proxy' => [
            'https' => getenv('FIXIE_URL'),
        ],
    ];
    try {
        $client->request('post', 'https://trialbot-api.line.me/v1/events', $requestOptions);
    } catch (Exception $e) {
        error_log($e->getMessage());
    }
}
```

## 動作結果
最大5件の検索結果を表示します。
<img width="494" alt="スクリーンショット 2016-05-19 19.47.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/66f57b31-7a16-a10c-08d9-6a5583afdb15.png">

初代さんのこれ、めっちゃ美味しいんですよね。（蕎麦じゃないけど。
お蕎麦も美味しいです👼
<img width="252" alt="スクリーンショット 2016-05-19 20.18.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/052e73ae-841b-2564-8326-0904a52b5f17.png">


5件未満の場合は、その数だけ表示します。
<img width="495" alt="スクリーンショット 2016-05-19 19.48.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/a5dd776a-1c5f-d7f9-abdd-c330a1757447.png">

匠さんのへぎそばもおすすめです。
<img width="533" alt="スクリーンショット 2016-05-19 20.20.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/dc4f78a3-f1c2-c82e-3aa2-d2622d48cd38.png">


検索結果がなかったらアドバイスしてくれます。
<img width="382" alt="スクリーンショット 2016-05-19 20.11.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/38442/3f273d9b-ddd9-da02-8d0f-50721a44c39f.png">

## まとめ
- お店の精度が微妙にアレなのは、キーワードのあてが良くないのか、他の検索条件を加えたのほうが良いのか・・・検討中です
- 場所じゃなくて現在地（LINEで現在地を送る）で検索できてもいいかもしれない
- 友達に見せたら蕎麦BotじゃなくてラーメンBotの方が需要あるんじゃない？？と言われました
- Botでは出てこなかったけど、恵比寿は香り家さんがおすすめです。（http://tabelog.com/tokyo/A1303/A130302/13001653/ ）

## 技術のこと
- Herokuで使ってるFixieというプラグインが月100メッセージまでの無料枠なので、自分でサーバ立てたほうが良さそう

## botソンについて
この蕎麦Botは、「botソン」というイベントで作りました。LINE Botに限らず、いろいろなbot技術を使って何かを作るもくもく会です。
>第１回botソンを行いました
http://www.bot-hackathon.info/entry/2016/05/17/102055

興味のある方はぜひご参加ください！