본문 바로가기

Programming Project/Node로 카톡-페메봇 만들기

Node.js로 카카오톡 플러스 친구 봇 만들기 06 (급식 알리미 기능 추가)


투명한 기부를 하고싶다면 이 링크로 와보세요! 🥰 (클릭!)

바이낸스(₿) 수수료 평생 20% 할인받는 링크로 가입하기! 🔥 (클릭!)

이 글은 


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;