Nodejs와 공공API를 이용한 버스도착정보 카톡봇입니다.
공부하면서 연습용으로 만든 것이라 조잡합니다.
날씨는 처음에 request연습할 때 넣었던 것이고, 대화창에서 마지막 버튼은 장난으로 ㅎㅎ
showBustArrivalData.js
버스 정보를 알려주는 module
/* NodeJs 샘플 코드 */
//228000710 외대앞 버정 stationId
//228000723 정문 앞 버정 stationId M5107이 들어오는 길
/*
routeName, routeId
5100, 200000115
9, 200000103
1112, 234000016
5500-1, 234000001
7000, 200000112
M5107, 234001243
*/
var request = require('request');
var requestP=require('request-promise');
var cheerio=require('cheerio');
var url = 'http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station';
var serviceKey='=★본인 서비스 키로 바꿔줘야함★';
var stationId='228000710'
var stationIdM='228000723'
//stationId of m5107 : 228000723
var queryParams = '?' + encodeURIComponent('serviceKey') + serviceKey; /* Service Key*/
queryParams += '&' + encodeURIComponent('stationId') + '='; /* 정류소 ID */
var routeIdArr={
id5100:200000115,
id9:200000103,
id1112:234000016,
id5500_1:234000001,
id7000:200000112,
id5107:234001243
}
function routeIdtoName(id){
var name;
switch(id){
//5100
case 200000115:{ name='5100';
break;}
//9
case 200000103:{ name='9';
break;}
//1112
case 234000016:{ name='1112';
break;}
//5500-1
case 234000001:{ name='5500-1';
break;}
//7000
case 200000112:{ name='7000';
break;}
//5107
case 234001243:{ name='M5107';
break;}
}
return name;
}
var resultStr=""
async function showBusArrivalData(){
//_stationId는 M5107과 그 외 버스에 따라 다르다.
var _stationId=stationId;
await requestP({
url: url + queryParams+encodeURIComponent(_stationId),
method: 'GET'
}, function (error, response, body) {
function getData(routeId){
$('routeId').each(function(){
if($(this).text()==routeId){
var busObj=$(this).closest('busArrivalList');
var predictTime=$('predictTime1', busObj).text();
//console.log(routeIdtoName(routeId)+' BUS '+predictTime+'분 전')
resultStr+='['+routeIdtoName(routeId)+' BUS] '+predictTime+'분 전\n';
}
})
}
$=cheerio.load(body);
for(var name in routeIdArr) {
if(name!='id5107') getData(routeIdArr[name])
}
});
//for M5107
_stationId=stationIdM;
await requestP({
url: url + queryParams+encodeURIComponent(_stationId),
method: 'GET'
}, function (error, response, body) {
function getData(routeId){
$('routeId').each(function(){
if($(this).text()==routeId){
var busObj=$(this).closest('busArrivalList');
var predictTime=$('predictTime1', busObj).text();
//console.log(routeIdtoName(routeId)+' BUS '+predictTime+'분 전')
resultStr+='['+routeIdtoName(routeId)+' BUS] '+predictTime+'분 전\n';
}
})
}
$=cheerio.load(body);
getData(routeIdArr['id5107']);
});
return new Promise((resolve, reject)=>{
resolve(resultStr)
})
}
module.exports=showBusArrivalData
ktbot.js
위의 모듈을 이용해 카톡봇을 구현하는 프로그램
//수정 의문 내용
//@@
var express=require('express');
var app=express();
var cheerio=require('cheerio');
var request=require('request');
var requestP=require('request-promise');
var phantom=require('phantom');
var bodyParser=require('body-parser');
var fs=require('fs');
var showBusArrivalData=require('./showBusArrivalData.js')
//var str=await showBusArrivalData());
//console.log(str);
function setRouter(){
//public 내의 파일들 업로드
app.use(express.static('public'));
app.get('/', function(req, res){
res.send('kakaobot Jinsu')
})
}
async function autoWeather(){
var url = 'https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EB%82%A0%EC%94%A8';
var instance=await phantom.create();
var page=await instance.createPage();
var status=await page.open(url);
console.log("page status : "+status);
var clipRect=await page.evaluate(function () {
return document.querySelector('[class="table_info weekly _weeklyWeather"]').getBoundingClientRect();
});
page.property('clipRect', {
top: clipRect.top,
left: clipRect.left,
width: clipRect.width,
height: clipRect.height
});
page.render('./public/weather.png');
console.log('autoWeahter finished in funciton')
}
async function autoSearch(){
var url="https://www.naver.com/";
var rank_str="";
//@@여기를 callback말고 Promise, await으로 구성해보는 게 깔끔할듯?
await requestP(url, function(error, response, html){
if (error) {
console.log('search request err : '+err);
throw error;
}
var $ = cheerio.load(html);
var cnt=0;
$('.ah_item').each(function(){
if(cnt<10){
var str=$(this).text();
cnt++;
rank_str+=cnt+" : "+str.substr(4, str.length-6)+"\n";
}
})
//console.log("autoSearch finished in the function");
});
return new Promise((resolve, reject)=>{
//console.log('rank : '+rank_str)
resolve(rank_str);
});
}
setRouter();
autoWeather();//@@테스트용으로 바로 보려고 그냥 넣은거지 카톡으로 진짜 할 거면 이제 안 해도 됨
autoSearch();
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
const keyboardContents = {
type: 'buttons',
buttons: ["날씨", "네이버 검색 순위", "Bus", "Jinsu--^_^"]
};
//초기 상태 get
app.get('/keyboard', function(req, res){
res.set({
'content-type': 'application/json'
}).send(JSON.stringify(keyboardContents));
console.log("someone GET /keyboard");
});
//카톡 메시지 처리
app.post('/message',async function (req, res) {
const _obj = {
userKey: req.body.userKey,
type: req.body.type,
content: req.body.content
};
//keyboardContents는 항상 들어감
var responseContents={
keyboard:keyboardContents
};
//확인용
console.log('userType : '+_obj.userKey)
console.log('userContents : '+_obj.content)
//네이버 검색 순위
if(_obj.content == '날씨')
{
var rank=await autoSearch();
//console.log('autoSearch finished in message')
//@@message에 keyboard안넣으면 다시 default인 텍스트로 감??
responseContents.message={
"photo": {
//@@내 컴퓨터에 있는 이미지는 불가능한듯..
"url": "http://124.50.93.166:3000/weather.png",
"width": 588,
"height": 228
}
};
}
else if(_obj.content == '네이버 검색 순위')
{
var rank=await autoSearch();
//console.log('autoSearch finished in message')
//@@message에 keyboard안넣으면 다시 default인 텍스트로 감??
responseContents.message={
"text": rank
};
}
else if(_obj.content =='Bus'){
var busDataStr=await showBusArrivalData();
console.log('result'+busDataStr);
setTimeout(function(){console.log('timeout : '+busDataStr)}, 3000)
responseContents.message={
"text": busDataStr
};
}
else if(_obj.content == 'Jinsu--^_^'){
responseContents.message={
"text": '진수는 정말.. 멋져...',
"photo": {
//@@내 컴퓨터에 있는 이미지는 불가능한듯..
"url": "http://124.50.93.166:3000/jinsu.png",
"width": 457,
"height": 133
}
};
}
//카톡으로 전송
res.set({
'content-type': 'application/json'
}).send(JSON.stringify(responseContents));
});
app.listen(3000, function() {
console.log('app is listening to 3000')
});
'Node.js' 카테고리의 다른 글
Socket io, nodejs를 이용한 채팅 사이트 만들기 (0) | 2018.06.10 |
---|---|
node js 웹 크롤링 예제 - request로 사진(웹툰 프리뷰) 수집하기 (0) | 2018.05.22 |
[버스 API] 공공 데이터 api를 이용해 버스 도착 정보 얻는 예제 (0) | 2018.04.26 |
[카톡봇] 카카오톡 API를 이용해 사진 자동 전송하기 (0) | 2018.04.26 |
[카톡봇] 카카오톡API를 이용한 자동 응답기 만들기 (0) | 2018.04.23 |