はじめに
自己学習のためにBluemixでLINE Messaging APIを使用してぐるなびAPIを呼び出すBOTを作成しました。
今回、Bluemix、LINE Message API、ぐるなびAPIの使い方等、多数のQiitaの記事(コードも含めて)を参考にさせていただきました。
この場を借りてお礼申し上げます。
用意するもの
Bluemixのアカウント
LINEビジネスアカウント
ぐるなびWebサービスのアクセスキー
BluemixでBOT用のサーバーを準備する
今回はNode.jsで実装するため、ダッシュボードから「アプリ作成」ボタンをクリックしカタログ画面に遷移し、「SDK for Node.js」を選択する
Cloud Foundryアプリの作成画面にて「アプリ名」を入力して「作成」ボタンをクリックする
LINE BOTを準備する
webhook URLにbluemix側でリクエストを受け付けるURLを指定し、Channel Access Tokenをメモしておく
LINE@MANAGERのBot設定を下記のように変更する。
Webhook送信 → 利用する
自動応答メッセージ → 利用しない
DevOppsServiceにてソースを編集する
概要ページの継続的デリバリーの「hub.jazz.net でプロジェクトをセットアップするために「Git の追加」ボタンをお探しですか? ここをクリックしてください」の「ここを」をクリックする
package.jsonのdependenciesを下記のように書き換える
"dependencies": {
"express": "4.13.x",
"cfenv": "1.0.x",
"body-parser": "1.15.2",
"request": "2.75.0",
"async":"*"
},
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);
});
ソースの修正が完了したらコミット&プッシュする
Delopy Stageが「ステージの成功」となることを確認する
動作確認
下記の組み合わせで送信する
都道府県名+市区町村名
レストランのカテゴリ
例:
東京都中央区
蕎麦