LoginSignup
9
7

More than 5 years have passed since last update.

BluemixでぐるなびAPIを呼び出すLINE BOTを作成してみた

Last updated at Posted at 2017-05-05

はじめに

自己学習のためにBluemixでLINE Messaging APIを使用してぐるなびAPIを呼び出すBOTを作成しました。
今回、Bluemix、LINE Message API、ぐるなびAPIの使い方等、多数のQiitaの記事(コードも含めて)を参考にさせていただきました。
この場を借りてお礼申し上げます。

用意するもの

Bluemixのアカウント
LINEビジネスアカウント
ぐるなびWebサービスのアクセスキー

BluemixでBOT用のサーバーを準備する

今回はNode.jsで実装するため、ダッシュボードから「アプリ作成」ボタンをクリックしカタログ画面に遷移し、「SDK for Node.js」を選択する
Kobito.flL10s.png

Cloud Foundryアプリの作成画面にて「アプリ名」を入力して「作成」ボタンをクリックする
Kobito.wINH12.png

LINE BOTを準備する

webhook URLにbluemix側でリクエストを受け付けるURLを指定し、Channel Access Tokenをメモしておく
スクリーンショット 2017-05-05 0.16.08.png

LINE@MANAGERのBot設定を下記のように変更する。
 Webhook送信 → 利用する
 自動応答メッセージ → 利用しない
image

DevOppsServiceにてソースを編集する

概要ページの継続的デリバリーの「hub.jazz.net でプロジェクトをセットアップするために「Git の追加」ボタンをお探しですか? ここをクリックしてください」の「ここを」をクリックする
Kobito.bQQX6P.png

「コードの編集」をクリック
Kobito.K8h87P.png

package.jsonのdependenciesを下記のように書き換える

package.json
    "dependencies": {
        "express": "4.13.x",
        "cfenv": "1.0.x",
        "body-parser": "1.15.2",
         "request": "2.75.0",
         "async":"*"
    },

app.jsを下記のように更新する

app.js

// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require("express");

// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require("cfenv");

// create a new express server
var app = express();

// ---- 追加 ここから -------//
var async = require("async");

var bodyParser = require("body-parser");

var request = require("request");

app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());

app.post("/api", function(req, res) {
    // 検索結果をオブジェクト化
    var search_result = {};

    var err = null;             

    async.waterfall([

        function (callback) {            
            var json = req.body;              
            // 受信テキスト
            var search_place = json["events"][0]["message"]["text"];
            var search_place_array = search_place.split("\n");

            //検索キーワード
            var gnavi_keyword = "";
            if(search_place_array.length === 2){
                var keyword_array = search_place_array[1].split("");
                gnavi_keyword = keyword_array.join();
            }

            var gnavi_url = "http://api.gnavi.co.jp/RestSearchAPI/20150630/";

            // ぐるなび リクエストパラメータの設定
            var gnavi_query = {
                "keyid":"<ぐるなびWebサービスのアクセスキー>",
                "format": "json",
                "address": search_place_array[0],
                "hit_per_page": 1,
                "freeword": gnavi_keyword,
                "freeword_condition": 2
            };
            var gnavi_options = {
                url: gnavi_url,
                headers : {"Content-Type" : "application/json; charset=UTF-8"},
                qs: gnavi_query,
                json: true
            };

            request.get(gnavi_options, function (error, response, body) {
                if (!error && response.statusCode === 200) {

                    if("error" in body){
                        err = body.error.message;
                        console.log("検索エラー" + JSON.stringify(body));              
                        callback(err);
                        return;
                    }
                    // 店名
                    if("name" in body.rest){
                        search_result["name"] = body.rest.name;
                    }
                    // 画像
                    if("image_url" in body.rest){
                        search_result["shop_image1"] = body.rest.image_url.shop_image1;
                    }
                    // 住所
                    if("address" in body.rest){
                        search_result["address"] = body.rest.address;
                    }
                    // 緯度
                    if("latitude" in body.rest){
                        search_result["latitude"] = body.rest.latitude;
                    }
                    // 軽度
                    if("longitude" in body.rest){
                        search_result["longitude"] = body.rest.longitude;
                    }
                    // 営業時間
                    if("opentime" in body.rest){
                        search_result["opentime"] = body.rest.opentime;
                    }
                    callback(err,json, search_result );
                } else {
                    console.log("error: "+ response.statusCode);
                }
            });
        }

    ],


    function(err,json,search_result){
    var options = {};

        if (err === null ){     
            options = {
                method: "POST",
                uri: "https://api.line.me/v2/bot/message/reply",
                body: {
                    replyToken: req.body.events[0].replyToken,
                    messageNotified: 0, 
                    messages: [
                        // 基本情報
                        {
                            contentType: 1,
                            type: "text",
                            text: "こちらはいかがですか?\n【お店】" + search_result["name"] + "\n【営業時間】" + search_result["opentime"],
                        }
                        ,
                        // 写真
                        {
                            contentType: 2,
                            type: "image",
                            originalContentUrl: search_result["shop_image1"],
                            previewImageUrl: search_result["shop_image1"]
                        }
                        ,
                        // 位置情報
                        {
                            contentType:7,
                            type: "location",
                            title: search_result["name"],
                            address: search_result["address"],
                            latitude: Number(search_result["latitude"]),
                            longitude: Number(search_result["longitude"])
                        }
                    ]
                },
                auth: {
                    bearer : "<自分のToken>"
                },
                json: true
            };


        }else{
            options = {
                method: "POST",
                uri: "https://api.line.me/v2/bot/message/reply",
                body: {
                    replyToken: req.body.events[0].replyToken,
                    messageNotified: 0, 
                    messages: [
                        // 基本情報
                        {
                            contentType: 1,
                            type: "text",
                            text: "検索エラーです。下記の例の様に入力してください。\n例:\n東京都中央区\n蕎麦",
                        }
                    ]
                },
                auth: {
                    bearer : "<自分のToken>"
                },
                json: true
            };

        }

        request(options, function(err, res, body) {
                console.log(JSON.stringify(res));
        });
        res.send("OK");
    });

});

// ---- 追加 ここまで -------

// serve the files out of ./public as our main files
app.use(express.static(__dirname + "/public"));

// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();

// start server on the specified port and binding host
app.listen(appEnv.port, "0.0.0.0", function() {
  // print a message when the server starts listening
  console.log("server starting on " + appEnv.url);
});

ソースの修正が完了したらコミット&プッシュする

左側のメニューからGitをクリックする
Kobito.juhO30.png

コメントを入力してコミットをクリックする
Kobito.CYuZX1.png

発信の右側のPushボタンを押す
Kobito.wCgA6Q.png

右上のBUILD&DEPLOYボタンを押す
Kobito.meaLYL.png

Delopy Stageが「ステージの成功」となることを確認する
Kobito.WqgxwU.png

動作確認

下記の組み合わせで送信する
都道府県名+市区町村名
レストランのカテゴリ

例:
東京都中央区
蕎麦

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7