박권수

feat. FCM start

...@@ -8,6 +8,7 @@ const Mongoose = require('mongoose'); ...@@ -8,6 +8,7 @@ const Mongoose = require('mongoose');
8 const api = require('./src/api'); 8 const api = require('./src/api');
9 const MqttServer = require('./src/util/MqttServer'); 9 const MqttServer = require('./src/util/MqttServer');
10 const BatchSystem = require('./src/util/Batch'); 10 const BatchSystem = require('./src/util/Batch');
11 +const FCM = require('./src/util/FCM');
11 12
12 require('dotenv').config(); 13 require('dotenv').config();
13 // eslint-disable-next-line no-undef 14 // eslint-disable-next-line no-undef
...@@ -37,5 +38,7 @@ app.use(router.routes()).use(router.allowedMethods()); ...@@ -37,5 +38,7 @@ app.use(router.routes()).use(router.allowedMethods());
37 app.listen(SERVER_PORT, () => { 38 app.listen(SERVER_PORT, () => {
38 console.log('\x1b[1;36mPORT : ', SERVER_PORT, 'is connected\x1b[0m'); 39 console.log('\x1b[1;36mPORT : ', SERVER_PORT, 'is connected\x1b[0m');
39 MqttServer.on(); 40 MqttServer.on();
40 - BatchSystem.PushNotifyByDosage(); 41 + FCM.initializeFCM();
42 + BatchSystem.removeQrCode();
43 + BatchSystem.pushNotifyByDosage();
41 }); 44 });
...\ No newline at end of file ...\ No newline at end of file
......
This diff could not be displayed because it is too large.
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
19 "dependencies": { 19 "dependencies": {
20 "@google-cloud/storage": "^5.14.2", 20 "@google-cloud/storage": "^5.14.2",
21 "@koa/cors": "^3.1.0", 21 "@koa/cors": "^3.1.0",
22 + "firebase-admin": "^9.11.1",
22 "koa-body": "^4.2.0", 23 "koa-body": "^4.2.0",
23 "moment": "^2.29.1", 24 "moment": "^2.29.1",
24 "moment-timezone": "^0.5.33", 25 "moment-timezone": "^0.5.33",
......
...@@ -17,6 +17,7 @@ exports.register = async(ctx) => { ...@@ -17,6 +17,7 @@ exports.register = async(ctx) => {
17 userNm, 17 userNm,
18 birth, 18 birth,
19 contact, 19 contact,
20 + deviceToken,
20 } = ctx.request.body; 21 } = ctx.request.body;
21 22
22 const schema = Joi.object().keys({ 23 const schema = Joi.object().keys({
...@@ -58,7 +59,8 @@ exports.register = async(ctx) => { ...@@ -58,7 +59,8 @@ exports.register = async(ctx) => {
58 userId, 59 userId,
59 userNm, 60 userNm,
60 birth, 61 birth,
61 - contact, 62 + contact,
63 + deviceToken,
62 }); 64 });
63 65
64 await user.save(); 66 await user.save();
...@@ -192,7 +194,7 @@ exports.doctorRegister = async ctx => { ...@@ -192,7 +194,7 @@ exports.doctorRegister = async ctx => {
192 } 194 }
193 195
194 exports.login = async(ctx) => { 196 exports.login = async(ctx) => {
195 - const { userId, password } = ctx.request.body; 197 + const { userId, password, deviceToken } = ctx.request.body;
196 198
197 const schema = Joi.object().keys({ 199 const schema = Joi.object().keys({
198 userId : Joi.string().email().max(50).required(), 200 userId : Joi.string().email().max(50).required(),
...@@ -225,7 +227,6 @@ exports.login = async(ctx) => { ...@@ -225,7 +227,6 @@ exports.login = async(ctx) => {
225 }; 227 };
226 return; 228 return;
227 } 229 }
228 -
229 if(user.useYn !== 'Y') { 230 if(user.useYn !== 'Y') {
230 ctx.status = 403; 231 ctx.status = 403;
231 ctx.body = { 232 ctx.body = {
...@@ -234,6 +235,16 @@ exports.login = async(ctx) => { ...@@ -234,6 +235,16 @@ exports.login = async(ctx) => {
234 return; 235 return;
235 } 236 }
236 237
238 + //일반 유저의 deviceToken값이 바뀌면 업데이트한다 = 기기가 바뀌면
239 + if(user.userTypeCd === 'NORMAL') {
240 + const profile = await Profile.findByUserId(user.userId);
241 + if(deviceToken && profile.deviceToken !== deviceToken) {
242 + profile.updateDeviceToken(deviceToken);
243 + await profile.save();
244 + }
245 + }
246 +
247 +
237 const token = await user.generateToken(); 248 const token = await user.generateToken();
238 ctx.cookies.set('access_token', token, { 249 ctx.cookies.set('access_token', token, {
239 httpOnly : true, 250 httpOnly : true,
...@@ -243,7 +254,7 @@ exports.login = async(ctx) => { ...@@ -243,7 +254,7 @@ exports.login = async(ctx) => {
243 ctx.status = 200; 254 ctx.status = 200;
244 ctx.body = { 255 ctx.body = {
245 userTypeCd : user.userTypeCd, 256 userTypeCd : user.userTypeCd,
246 - token 257 + token,
247 }; 258 };
248 259
249 }; 260 };
......
...@@ -6,17 +6,20 @@ ...@@ -6,17 +6,20 @@
6 * 1) Dosage에 따라, Push Notification 발송 6 * 1) Dosage에 따라, Push Notification 발송
7 */ 7 */
8 8
9 - const cron = require('node-cron'); 9 +const cron = require('node-cron');
10 +const fs = require('fs');
10 11
11 - const Profile = require('../models/profile'); 12 +const Profile = require('../models/profile');
12 - const User = require('../models/user'); 13 +const User = require('../models/user');
13 - const Hub = require('../models/hub'); 14 +const Hub = require('../models/hub');
14 - const Bottle = require('../models/bottle'); 15 +const Bottle = require('../models/bottle');
15 - const BottleMedicine = require('../models/bottleMedicine'); 16 +const BottleMedicine = require('../models/bottleMedicine');
17 +const Medicine = require('../models/medicine');
16 18
17 const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); 19 const updateMedicineInfo = require('../lib/UpdatingMedicineInfo');
18 - 20 +const { sendPushMessage } = require('./FCM');
19 - 21 +
22 +
20 // //매년 1월 1일 00시 00분에 1살씩 추가 23 // //매년 1월 1일 00시 00분에 1살씩 추가
21 // exports.CheckNewYear = () => { 24 // exports.CheckNewYear = () => {
22 // cron.schedule('0 0 0 1 1 *', async () => { 25 // cron.schedule('0 0 0 1 1 *', async () => {
...@@ -25,7 +28,7 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); ...@@ -25,7 +28,7 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo');
25 // await profile.updateUserAge(); 28 // await profile.updateUserAge();
26 // profile.save(); 29 // profile.save();
27 // }); 30 // });
28 - 31 +
29 // }, { 32 // }, {
30 // timezone : 'Asia/Tokyo', 33 // timezone : 'Asia/Tokyo',
31 // }); 34 // });
...@@ -35,78 +38,111 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); ...@@ -35,78 +38,111 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo');
35 exports.updateMedicineData = async () => { 38 exports.updateMedicineData = async () => {
36 cron.schedule('0 0 0 1 * *', () => { 39 cron.schedule('0 0 0 1 * *', () => {
37 updateMedicineInfo.updateMedicineInfo(); 40 updateMedicineInfo.updateMedicineInfo();
41 + }, {
42 + timezone : 'Asia/Tokyo',
38 }); 43 });
39 }; 44 };
40 - 45 +
46 +//매주 일요일마다 불필요한 qrcode 제거
47 +exports.removeQrCode = () => {
48 + cron.schedule('0 0 0 * * 0', () => {
49 + // eslint-disable-next-line no-undef
50 + const qrDir = process.env.QR_DIR;
51 + fs.rm(qrDir, { recursive : true, force : true, }, () => {
52 + fs.mkdir(qrDir, (err) => { if(err) console.log(err) });
53 + });
54 + }, {
55 + timezone : 'Asia/Tokyo',
56 + });
57 +};
58 +
41 //dosage에 따라, Push Notification을 발송한다. 59 //dosage에 따라, Push Notification을 발송한다.
42 //아침 8시, 점심 12시, 저녁 6시에 한번씩 발송 60 //아침 8시, 점심 12시, 저녁 6시에 한번씩 발송
43 - exports.PushNotifyByDosage = async() => { 61 +exports.pushNotifyByDosage = async() => {
44 - 62 +
45 - //매일 아침 8시 : 복용량 상관 없이 보냄 63 + //매일 아침 8시 : 복용량 상관 없이 보냄
46 - cron.schedule('0 0 8 * * *', async () => { 64 + cron.schedule('0 0 8 * * *', async () => {
47 - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 1 } }); 65 + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 1 } });
48 - bottleMedicineList.forEach(async bottleMedicine => { 66 + bottleMedicineList.forEach(async bottleMedicine => {
49 - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); 67 + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId });
50 - const hub = await Hub.findOne({ hubId : bottle.hubId }); 68 + const hub = await Hub.findOne({ hubId : bottle.hubId });
51 - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); 69 + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' });
52 - 70 +
53 - if(user) { 71 + if(user) {
54 - const profile = await Profile.findOne({ userId : user.userId }); 72 + const profile = await Profile.findOne({ userId : user.userId });
55 - 73 + const { deviceToken } = profile;
56 - const { deviceToken } = profile; 74 +
57 - PushNotify(deviceToken); 75 + if(deviceToken) {
58 - } 76 + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
59 - }); 77 + pushNotify({
60 - }, { 78 + deviceToken,
61 - timezone : 'Asia/Tokyo', 79 + message : medicine.name + '을 복용하셔야 합니다.',
62 - }); 80 + });
63 - 81 + }
64 - 82 + }
65 - //매일 점심 12시 : 복용량이 3인 환자들만 83 + });
66 - cron.schedule('0 0 12 * * *', async () => { 84 + }, {
67 - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 3 } }); 85 + timezone : 'Asia/Tokyo',
68 - bottleMedicineList.forEach(async bottleMedicine => { 86 + });
69 - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); 87 +
70 - const hub = await Hub.findOne({ hubId : bottle.hubId }); 88 +
71 - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); 89 + //매일 점심 12시 : 복용량이 3인 환자들만
72 - 90 + cron.schedule('0 0 12 * * *', async () => {
73 - if(user) { 91 + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 3 } });
74 - const profile = await Profile.findOne({ userId : user.userId }); 92 + bottleMedicineList.forEach(async bottleMedicine => {
75 - 93 + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId });
76 - const { deviceToken } = profile; 94 + const hub = await Hub.findOne({ hubId : bottle.hubId });
77 - PushNotify(deviceToken); 95 + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' });
78 - } 96 +
79 - }); 97 + if(user) {
80 - }, { 98 + const profile = await Profile.findOne({ userId : user.userId });
81 - timezone : 'Asia/Tokyo', 99 + const { deviceToken } = profile;
82 - }); 100 +
83 - 101 + if(deviceToken) {
84 - 102 + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
85 - //매일 저녁 6시 103 + pushNotify({
86 - cron.schedule('0 0 18 * * *', async () => { 104 + deviceToken,
87 - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 2 } }); 105 + message : medicine.name + '을 복용하셔야 합니다.',
88 - bottleMedicineList.forEach(async bottleMedicine => { 106 + });
89 - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); 107 + }
90 - const hub = await Hub.findOne({ hubId : bottle.hubId }); 108 + }
91 - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); 109 + });
92 - 110 + }, {
93 - if(user) { 111 + timezone : 'Asia/Tokyo',
94 - const profile = await Profile.findOne({ userId : user.userId }); 112 + });
95 - 113 +
96 - const { deviceToken } = profile; 114 +
97 - PushNotify(deviceToken); 115 + //매일 저녁 6시
98 - } 116 + cron.schedule('0 0 18 * * *', async () => {
99 - }); 117 + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 2 } });
100 - }, { 118 + bottleMedicineList.forEach(async bottleMedicine => {
101 - timezone : 'Asia/Tokyo', 119 + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId });
102 - }); 120 + const hub = await Hub.findOne({ hubId : bottle.hubId });
103 - 121 + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' });
104 - }; 122 +
105 - 123 + if(user) {
106 - const PushNotify = async(deviceToken) => { 124 + const profile = await Profile.findOne({ userId : user.userId });
125 + const { deviceToken } = profile;
126 +
127 + if(deviceToken) {
128 + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
129 + pushNotify({
130 + deviceToken,
131 + message : medicine.name + '을 복용하셔야 합니다.',
132 + });
133 + }
134 + }
135 + });
136 + }, {
137 + timezone : 'Asia/Tokyo',
138 + });
139 +
140 +};
141 +
142 +const pushNotify = ({ deviceToken, message }) => {
107 //toDo : deviceToken을 받아서 push notification을 발송하는 함수 143 //toDo : deviceToken을 받아서 push notification을 발송하는 함수
108 - if(deviceToken) {
109 - console.log(deviceToken);
110 - }
111 - };
112 -
...\ No newline at end of file ...\ No newline at end of file
144 + sendPushMessage({
145 + deviceToken,
146 + message,
147 + });
148 +};
......
1 +const fcm = require('firebase-admin');
2 +
3 +
4 +exports.initializeFCM = () => {
5 + fcm.initializeApp({
6 + credential : fcm.credential.applicationDefault(),
7 + });
8 +};
9 +
10 +exports.sendPushMessage = async ({ deviceToken, message }) => {
11 + const notifyMessage = {
12 + notification : {
13 + title : '약 먹을 시간입니다',
14 + body : message,
15 + },
16 + token : deviceToken,
17 + };
18 + fcm.messaging().send(notifyMessage);
19 +};
...\ No newline at end of file ...\ No newline at end of file
...@@ -3,14 +3,15 @@ const moment = require('moment'); ...@@ -3,14 +3,15 @@ const moment = require('moment');
3 3
4 4
5 exports.generateQrCode_prescribe = async ({ medicine, dosage, patientId, doctorId }) => { 5 exports.generateQrCode_prescribe = async ({ medicine, dosage, patientId, doctorId }) => {
6 - const directory = "/Users/parkkwonsoo/Desktop/Project/Capstone_Design_1/server/data/"; 6 + // eslint-disable-next-line no-undef
7 + const directory = process.env.QR_DIR;
7 8
8 const now = moment().format('YYYY-MM-DD_HH:mm'); 9 const now = moment().format('YYYY-MM-DD_HH:mm');
9 const qrCodeFileName = `${now}_${doctorId}_${patientId}_${medicine.medicineId}_${dosage}.png`; 10 const qrCodeFileName = `${now}_${doctorId}_${patientId}_${medicine.medicineId}_${dosage}.png`;
10 11
11 try { 12 try {
12 await QrCode.toFile( 13 await QrCode.toFile(
13 - directory + qrCodeFileName, 14 + directory + '/' + qrCodeFileName,
14 `${medicine.name}/${medicine.medicineId}/${dosage}/${patientId}/${doctorId}`, 15 `${medicine.name}/${medicine.medicineId}/${dosage}/${patientId}/${doctorId}`,
15 { 16 {
16 color : { 17 color : {
......
This diff could not be displayed because it is too large.