Application Programming Interface(API),字面上的意思是應用程式介面,白話一點就是可以取用其他服務而不用了解其內部程式運作的邏輯或演算法,你只要提供API要的資料,他就會把你想知道的結果回傳給你。
在本篇分享中,我會就之前所做結合google API 或 Imgur所提供的API來做查詢附近地點的機器人,跟上傳圖片的小幫手。
利用Google API建立附近地點查詢LINE BOT
我們這邊要利用Google Map Platform提供的地圖、路徑、地方資訊等三種產品來分類,我們要使用谷哥地圖產品的API就需要先申請API key授權金鑰,我們的LINE BOT才可以用來呼叫Google Map API所提供的服務。
申請Google Map API金鑰
Google Map Platform提供了地圖介面集、路徑介面集、與地點介面集等三種產品分類,Google Map Platform是Google Cloud Platform(GCP)中的一個服務,新使用者在註冊GCP時可以用免費300美元的試用額度,試用期為90天(這點務必注意,以前試用期為12個月,故網路很多教學文章都會說試用期為一年),另外需要信用卡或VISA金融卡才可以註冊GCP,這點也需要特別留意。
註冊完後啟用Place API,並且建立一個API 憑證,如下圖所示。
使用HeroKu建立查詢地點LINE BOT後端server
接著我們在VSCode開一個新的Terminal,並創建一個新的Heroku app,如下圖所示。
接著初始化Git,並且設定remote端的Heroku專案
然後就可以來寫我們機器人程式本體了,首先先設定一些套件
'use strict';
const line = require('@line/bot-sdk');
const express = require('express');
const request = require('request');
接著設定設定LINE BOT的access token跟secret
const config = {
channelAccessToken:<your channel access token>,
channelSecret:<your channel secret>,
};
然後設定剛剛拿到的Google Map API key
const googleMapAPI = {
key: <google api key>
};
然後就是我們主要的LINE BOT 事件處理handler function了
let userLocation = {};function handleEvent(event) {//LINE會發出連續32個0或f來測試webhook,所以我們這裡要避免用到這組replytoken
if (event.replyToken === "00000000000000000000000000000000" ||
event.replyToken === "ffffffffffffffffffffffffffffffff") {
return Promise.resolve(null);
} if (event.type === 'message' && event.message.type === 'location') {
userLocation[event.source.userId] = event.message;
const replyMsg = {
type: 'text',
text: '輸入要查詢的地點類型與半徑範圍(公尺)\n例如:\n300公尺內的餐廳\r\n1000 加油站\r\n提款機3000\r\n'
};
return client.replyMessage(event.replyToken, replyMsg);
}
else if (event.type === 'message' &&
event.message.type === 'text' &&
userLocation[event.source.userId] !== undefined) {
const lat = userLocation[event.source.userId].latitude;
const lng = userLocation[event.source.userId].longitude;
let radius = event.message.text.match(/\d/g);
if (radius === null) {
radius = 1500
}
else {
radius = radius.join('');
radius = radius < 5 ? 100 : radius;
}
//用正規表達式找出搜尋種類. ex.餐廳, 機場
let searchType;
let searchTypeEng;
if(event.message.text.match(/[\u9910\u5ef3]+/g) !== null){
searchTypeEng = 'restaurant';
searchType = '餐廳';
}
else if(event.message.text.match(/[\u5716\u66f8\u9928]+/g) !== null){
searchTypeEng == 'library';
searchType = '圖書館';
}
else if(event.message.text.match(/[\u5716\u66f8\u9928]+/g) !== null){
searchTypeEng == 'atm';
searchType = '提款機';
}
else if(event.message.text.match(/[\u9eb5\u5305]+/g) !== null ||
event.message.text.match(/[\u86cb\u7cd5]+/g) !== null ||
event.message.text.match(/[\u70d8\u7119]+/g) !== null ){
searchTypeEng == 'bakery';
searchType = '蛋糕店';
}
else if(event.message.text.match(/[\u52a0\u6cb9\u7ad9]+/g) !== null){
searchTypeEng == 'gas_station';
searchType = '加油站';
}
else{
searchTypeEng == null;
searchType = '餐廳';
}searchTypeEng = searchTypeEng === null ? 'restaruant' : searchTypeEng;
const searchUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?
location=${lat},${lng}&
radius=${radius}&
type=${searchTypeEng}&
language=zh-TW&
key=${googleMapAPI.key}`.replace(/\n/g, '').replace(/\s/g, '');
request.get(searchUrl, (err, httpResponse, body) => {
let msgReply = { type: 'text', text: 'Searching' };
if (httpResponse.statusCode === 200) {
const resBody = JSON.parse(body);
let places = resBody.results.map((p) => {
return `${p.name}\r\nhttps://www.google.com/maps/place/?q=place_id:${p.place_id}`
});
places.unshift(`${radius}公尺內的${searchType}:`);
msgReply.text = places.join('\r\n');
} else {
msgReply.text = `${radius}公尺內沒有找到${searchType}。`;
}
return client.replyMessage(event.replyToken, msgReply);
})
delete userLocation[event.source.userId];
} else {
const searchReply = { type: 'text', text: '請輸入位置資訊!' };
return client.replyMessage(event.replyToken, searchReply);
}
return Promise.resolve(null);
}
首先我們會先用一個 userLocation
來存使用者傳給我們的位置資訊,接著讓使用者輸入想要查找的地圖類型與範圍,例如500公尺內餐廳、1000公尺加油站等,然後中間用正規表達式來找出使用者想要搜尋的類型還有範圍,這邊可以注意的是正規表達式內用的是中文的unicode來做搜尋。
擷取出使用者所輸入的類型跟範圍之後,就可以利用google search url來進行搜尋,並透過返回的的response body來進行解析,並將解析完的結果回傳給使用者,這邊我有用一些JavaScript ES6的寫法,想說順便練習一下。
最後結果就會像這樣~
完整的程式碼會放在github上面,有需要的人可以自行上去看,接下來在下一篇文章中我會介紹LINE BOT其他Template Message應用跟Quick Reply。
還有很多東西像是Rich menu、Flex Message、LIFF、LINE Notify、還有LINE Login等等,在未來的文章中我會陸續的跟各位分享實作心得。