이 글은
2018/05/26 - [Programming Project/Node로 카톡-페메봇 만들기] - Node.js로 카카오톡 플러스 친구 봇 만들기 01 (플러스친구 계정 생성)
로 부터 읽으면 되고
2018/05/27 - [Programming Project/Node로 카톡-페메봇 만들기] - Node.js로 카카오톡 플러스 친구 봇 만들기 05 (급식 api 사용하기, 급식 봇)
에서 이어진다.
* 급식 API 형식이 조금 바뀌어서 소스에 좀 수정이 있었다.
* 접속하는 주소 , makeText 함수 두 부분을 바꾸면 다시 동작한다
일단 기왕 진요 플러스친구를 만들어놨는데 거기에서 남의 학교 급식이나 추천해주기가 좀 그래서 진요 플친이랑 급식 봇을 분리하기로 했다.
나중에 제대로 노래 추천 봇을 만들거니까 일단은 이대로 노래 추천 해주는 정도로 냅두려고 한다.
우선 routes 폴더에 jinyo.js를 만들고,
app.js에서 /jinyo 하위 링크로 jinyoRouter을 연결해주도록 하자.
그리고 소스 내부에 /keyboard와 /message를 적어줌으로써
~~주소~~/jinyo/keyboard
~~주소~~/jinyo/message
와 같이 url을 구성해서 jinyo.js에서 keyboard와 message를 둘 다 제공해주기로 한다.
이렇게 서버를 구성하고 나면
다음과 같이 뒤에 원래 url에다 /jinyo 를 붙여서 한 서버에서 여러 봇을 운영하는 것이 가능하게 된다.
그리고 급식 봇으로 돌아와서,
난 양재고를 나와서 양재고 급식 봇이나 만들어볼까 했는데 이미 누가 만들어놔서 또 만들기가 그랬다.
그래서 고민하다가 아무 학교나 없는곳에다가 필요하냐고 물어보고 만들기로 결정했따 -
헤헤 그래서 한민고등학교 당첨 룰룰루
이렇게 또 hanminRouter을 추가해줬고, 당연히 hanmin.js도 추가해줬다.
음.. 그리고 const menu 부분을 위로 빼줬다. 어차피 /keyboard랑 /message에서 동시에 같은 답변만 해 줄거라서...
일단
오늘 급식
내일 급식
일주일 급식
세 개를 제공해보려고 한다.
우선 미래의 것을 가져오려면 준비를 단단히 해야한다.
내일이나 일주일 후를 제공해주려다보면 다음달 급식도 필요할 것 같아서
nd2라는 변수가 다음달을 가르키게 한 다음 기존의 코드를 응용해서 다음달의 급식 정보 또한 불러왔다.
더해서, 날짜 정보를 넘기면 해당 날짜의 급식 정보를 return 하는 함수를 만들었다.
1주일치를 모두 노가다해서 쓸 생각을 하니 아득해져서 말이다ㅋ_ㅋ~
한민고는 조식 중식 석식이 모두 있어서 중식을 breakfast에 대입하지 않아도 돼서 행복했따....
이게 학교바이 학교로 조식이 없는 경우 breakfast에 중식정보가 들어가있는 것 같으므로 잘 확인하고 했으면 좋겠다!
그리고 기존의 급식 불러오는 부분이 돌려주는 문자열이 더러워서 조금 정리했다.
aa.replace~~부분인데 일단 , 를 한칸 띄워줬고 . 부분을 없애주었으며 숫자(뭔지 모르겠는데 몇일 몇일 이런식으로 원래는 들어가있는건가보다)를 다 없애주었다.
그리고 마지막으로 ~월~일 급식정보라는 말을 추가해주었다.
이제 이 것들을 이용해서 다음과 같이 코드를 작성했다.
오늘 내일 급식이야 코드가 쉬워서 설명은 생략하고,
일주일 급식 쪽에서는 week 라는 빈 배열을 만든 후에, 1주일어치의 날짜를 넣어줬다.
그리고 return 할 text라는 변수에 1주일치의 급식 정보를 모두 넣고 text라는 변수를 return 하게 만들어 주었다.
자 코딩은 끝났으니까
서버를 디플로이하고 한민고 플친을 만들었다.
그리고 API 채팅을 연동하고나서 보면
/hanmin 붙이는걸 잊지마...!
이케 잘 된다.
소스를 공유할테니까 잘 복붙 ㄱㄱ
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var keyboardRouter = require('./routes/keyboard');
var messageRouter = require('./routes/message');
var jinyoRouter = require('./routes/jinyo');
var hanminRouter = require('./routes/hanmin'); // 1
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/keyboard', keyboardRouter);
app.use('/jinyo', jinyoRouter);
app.use('/hanmin', hanminRouter); //2
app.use('/message', messageRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
//학교코드 찾는 곳 https://www.meatwatch.go.kr/biz/bm/sel/schoolListPopup.do
module.exports = app;
jinyo.js
var express = require('express');
var router = express.Router();
/* 처음 들어왔을 때 */
router.get('/keyboard', function(req, res, next) {
const menu = {
type: 'buttons',
buttons: ["노래 추천해줘.", "네 노래로 추천해줘."]
};
res.set({
'content-type': 'application/json'
}).send(JSON.stringify(menu));
});
/* 사용자의 답장이 들어왔을 때 */
router.post('/message', function(req, res, next) {
const object = {
user_key: req.body.user_key, // 메시지를 발송한 user을 식별할 수 있는 key
type: req.body.type, // user가 보낸 message의 형태. text , photo로 이루어짐
content: req.body.content // user가 보낸 메시지 내용.
};
const menu = {
type: 'buttons',
buttons: ["노래 추천해줘.", "네 노래로 추천해줘."]
};
var res_object;
if(object.type=="text")
{
if(object.content=="노래 추천해줘."){
res_object = {
"message": {
"text": '조지 - boat 어때?'
},
"keyboard": menu
};
}
else if(object.content=="네 노래로 추천해줘."){
res_object = {
"message": {
"text": 'Jinyo - 수면증 어때?'
},
"keyboard": menu
};
}
}
res.set({ //6
'content-type': 'application/json'
}).send(JSON.stringify(res_object));
});
module.exports = router;
hanmin.js
var express = require('express');
const request = require('request');
var router = express.Router();
/* 처음 들어왔을 때 */
const menu = {
type: 'buttons',
buttons: ["오늘 급식", "내일 급식","일주일 급식"]
};
router.get('/keyboard', function(req, res, next) {
res.set({
'content-type': 'application/json'
}).send(JSON.stringify(menu));
});
let now_date = new Date();
let offset = +9;
var utc = now_date.getTime() + (now_date.getTimezoneOffset() * 60000);
var nd = new Date(utc + (3600000*offset));
var nd2 = new Date(utc + (3600000*offset));
nd2.setMonth(nd2.getMonth()+1,1);//1 : 다음 달로 설정
var monthly_food=[0,0];
function refresh_food()
{
let now_date = new Date();
let offset = +9;
utc = now_date.getTime() + (now_date.getTimezoneOffset() * 60000);
nd = new Date(utc + (3600000*offset));
nd2 = new Date(utc + (3600000*offset));
nd2.setMonth(nd2.getMonth()+1,1);//1 : 다음 달로 설정
monthly_food=[0,0];
request('https://schoolmenukr.ml/api/high/J100006763?year='+nd.getFullYear()+'&month='+(nd.getMonth()+1), (err, res, body) => {
monthly_food[0] = JSON.parse(body);
});
request('https://schoolmenukr.ml/api/high/J100006763?year='+nd2.getFullYear()+'&month='+(nd2.getMonth()+1), (err, res, body) => {
monthly_food[1] = JSON.parse(body);
});
console.log("급식 불러옴")
setTimeout(refresh_food, 20*60*1000);
}
refresh_food();
/* 사용자의 답장이 들어왔을 때 */
router.post('/message', function(req, res, next) {
const object = {
user_key: req.body.user_key, // 메시지를 발송한 user을 식별할 수 있는 key
type: req.body.type, // user가 보낸 message의 형태. text , photo로 이루어짐
content: req.body.content // user가 보낸 메시지 내용.
};
var res_object;
if(object.type=="text"){
if(object.content=="오늘 급식"){
res_object = {
"message": {
"text": makeText(nd)
},
"keyboard": menu
};
}
else if(object.content=="내일 급식"){
var temp = new Date(utc + (3600000*offset));
temp.setMonth(nd.getMonth(),nd.getDate()+1);
res_object = {
"message": {
"text": makeText(temp)
},
"keyboard": menu
};
}
else if(object.content=="일주일 급식"){
var week=[],text="";
for(i=0;i<7;i++){
var temp = new Date(utc + (3600000*offset));
temp.setMonth(nd.getMonth(),nd.getDate()+i);
week.push(temp);
}
for(i=0;i<7;i++){
text+=makeText(week[i]);
}
res_object = {
"message": {
"text": text
},
"keyboard": menu
};
}
}
res.set({ //6
'content-type': 'application/json'
}).send(JSON.stringify(res_object));
});
function makeText(day){
console.log(day);
var aa=
"조식 : " + monthly_food[day.getMonth()-nd.getMonth()].menu[day.getDate()-1].breakfast + "\n" +
"중식 : " + monthly_food[day.getMonth()-nd.getMonth()].menu[day.getDate()-1].lunch + "\n" +
"석식 : " + monthly_food[day.getMonth()-nd.getMonth()].menu[day.getDate()-1].dinner + "\n";
aa=aa.replace(/[,]/g,', ').replace(/[.]/g,'').replace(/[0-9]/g,'');
aa="\n"+(day.getMonth()+1)+"월 "+(day.getDate())+"일 급식정보\n"+aa;
return aa;
}
module.exports = router;