Showing
1 changed file
with
335 additions
and
0 deletions
app.js
0 → 100644
1 | +const express = require('express'); | ||
2 | +const request = require('request'); | ||
3 | +const convert = require('xml-js'); | ||
4 | + | ||
5 | +const TARGET_URL = 'https://api.line.me/v2/bot/message/reply' | ||
6 | +const TOKEN = 'z5iy5sMU1W4xZAlwvn0/5x4U+4ZsqI0hKO1ZZNFxUGlNzGBjFg2D1u6/Ij5C/Sbkncx3hyYg7Nfz5JnMD8BG/9Z3TEEHPvy1A2XhkPKs04v0/n6TjH1A3e9X23zYdYmNSGyPn2hDGglgm2p3YmtLSwdB04t89/1O/w1cDnyilFU=' | ||
7 | + | ||
8 | +var ProductCategoryName ; | ||
9 | +var first_url = 'http://apis.data.go.kr/1470000/FoodAdtvInfoService/getFoodAdtvInfoList'; | ||
10 | +var first_key ='ofY2ppOq5kBqT5jYPaGsW%2BEy7OR5a1bf5Z9PHvqNKvwO5DSCaU2x2qCj%2FoXnuB1YVbMTlErkHWSMEsR5b7isrw%3D%3D'; | ||
11 | + | ||
12 | +var second_url ='http://openapi.foodsafetykorea.go.kr/api'; | ||
13 | +var second_key ='f8ce3271a2dc4decb83b'; | ||
14 | +var filetype ='json'; | ||
15 | +var startIndex = 1; | ||
16 | +var endIndex = 5; | ||
17 | +var simpleResult = true; | ||
18 | + | ||
19 | + | ||
20 | +const fs = require('fs'); | ||
21 | +const path = require('path'); | ||
22 | +const HTTPS = require('https'); | ||
23 | +const domain = "www.foodbot2020.ml" | ||
24 | +const sslport = 23023; | ||
25 | +const bodyParser = require('body-parser'); | ||
26 | +var app = express(); | ||
27 | +app.use(bodyParser.json()); | ||
28 | + | ||
29 | + | ||
30 | +function sendOneLineMessage(eventObj, line) | ||
31 | +{ | ||
32 | + request.post({ | ||
33 | + url: TARGET_URL, | ||
34 | + headers:{ | ||
35 | + 'Authorization': `Bearer ${TOKEN}` | ||
36 | + }, | ||
37 | + json:{ | ||
38 | + "replyToken":eventObj.replyToken, | ||
39 | + "messages" :[ | ||
40 | + { | ||
41 | + "type":"text", | ||
42 | + "text": line | ||
43 | + } | ||
44 | + ] | ||
45 | + } | ||
46 | + },(error,response,body)=>{ | ||
47 | + console.log(body) | ||
48 | + }); | ||
49 | +} | ||
50 | + | ||
51 | +function helloAndErrorMsg(eventObj){ | ||
52 | + request.post({ | ||
53 | + url: TARGET_URL, | ||
54 | + headers:{ | ||
55 | + 'Authorization': `Bearer ${TOKEN}` | ||
56 | + }, | ||
57 | + json:{ | ||
58 | + "replyToken":eventObj.replyToken, | ||
59 | + "messages" :[ | ||
60 | + { | ||
61 | + "type":"text", | ||
62 | + "text": "안녕하세요, 식품첨가물 정보를 알려드립니다." | ||
63 | + }, | ||
64 | + { | ||
65 | + "type":"text", | ||
66 | + "text": "정확한 식품명을 기입해주세요.\n안내가 필요하신 경우 '안내'라고 입력해주세요." | ||
67 | + } | ||
68 | + | ||
69 | + ] | ||
70 | + } | ||
71 | + },(error,response,body)=>{ | ||
72 | + console.log(body) | ||
73 | + }); | ||
74 | +} | ||
75 | + | ||
76 | +function prdNameNotFound(eventObj){ | ||
77 | + request.post({ | ||
78 | + url: TARGET_URL, | ||
79 | + headers:{ | ||
80 | + 'Authorization': `Bearer ${TOKEN}` | ||
81 | + }, | ||
82 | + json:{ | ||
83 | + "replyToken":eventObj.replyToken, | ||
84 | + "messages" :[ | ||
85 | + { | ||
86 | + "type":"text", | ||
87 | + "text": "죄송합니다. \n해당 식품의 정보를 찾을 수 없습니다.\n" | ||
88 | + +"정확한 식품명을 기입해주세요.\n" | ||
89 | + +"사용 안내가 필요하신 경우 '안내'라고 입력해주세요." | ||
90 | + }, | ||
91 | + { | ||
92 | + "type": "sticker", | ||
93 | + "packageId": "11537", | ||
94 | + "stickerId": "52002770" | ||
95 | + } | ||
96 | + ] | ||
97 | + } | ||
98 | + },(error,response,body)=>{ | ||
99 | + console.log(body) | ||
100 | + }); | ||
101 | +} | ||
102 | + | ||
103 | +function instruction(eventObj){ | ||
104 | + request.post({ | ||
105 | + url: TARGET_URL, | ||
106 | + headers:{ | ||
107 | + 'Authorization': `Bearer ${TOKEN}` | ||
108 | + }, | ||
109 | + json:{ | ||
110 | + "replyToken":eventObj.replyToken, | ||
111 | + "messages" :[ | ||
112 | + { | ||
113 | + "type":"text", | ||
114 | + "text": "식품첨가물 정보 알리미 사용 안내입니다." | ||
115 | + }, | ||
116 | + { | ||
117 | + "type":"text", | ||
118 | + "text": "사용방법\n" | ||
119 | + +"1. 식품명을 '정확하게' 입력해주세요.\n" | ||
120 | + +"2. 입력하신 식품명이 식약처 데이터베이스에 존재하는 경우,\n" | ||
121 | + +"식품 유형과 첨가물, 첨가물 안전정보에 대해 받아보실 수 있습니다.\n" | ||
122 | + +"3. '모드' 명령어를 통해 결과 간단히 보기/자세히 보기 모드를 전환할 수 있습니다.\n" | ||
123 | + +"4. 결과 간단히 보기 모드에서는 첨가물과 식품유형을 확인하실 수 있습니다.\n" | ||
124 | + +"5. 자세한 결과 보기 모드에서는 위 정보 및 첨가물 안전정보를 확인하실 수 있습니다." | ||
125 | + }, | ||
126 | + { | ||
127 | + "type":"text", | ||
128 | + "text": "식품첨가물 정보 알리미가 제공하는 식품첨가물 정보는 식품의약품안전처의 공신력 있는 자료를 바탕으로 만들어졌습니다." | ||
129 | + }, | ||
130 | + | ||
131 | + ] | ||
132 | + } | ||
133 | + },(error,response,body)=>{ | ||
134 | + console.log(body) | ||
135 | + }); | ||
136 | +} | ||
137 | + | ||
138 | + | ||
139 | +app.post('/hook', function (req, res) { | ||
140 | + | ||
141 | + var eventObj = req.body.events[0]; | ||
142 | + var source = eventObj.source; | ||
143 | + var message = eventObj.message; | ||
144 | + var message_text = message.text; | ||
145 | + | ||
146 | + // request log | ||
147 | + console.log('======================', new Date() ,'======================'); | ||
148 | + console.log('[request]', req.body); | ||
149 | + console.log('[request source] ', eventObj.source); | ||
150 | + console.log('[request message]', eventObj.message); | ||
151 | + | ||
152 | + if(message_text =='안내'){ | ||
153 | + console.log('[안내 출력]'); | ||
154 | + instruction(eventObj); | ||
155 | + } | ||
156 | + else if(message_text == '모드') | ||
157 | + { | ||
158 | + console.log("모드를 변경합니다") | ||
159 | + simpleResult = !simpleResult; | ||
160 | + if(simpleResult) | ||
161 | + { | ||
162 | + var msg = "결과 간단히 보기 모드 입니다."; | ||
163 | + } | ||
164 | + else | ||
165 | + { | ||
166 | + var msg = "자세한 결과 보기 모드입니다. 첨가물의 정보를 확인하실 수 있습니다." | ||
167 | + } | ||
168 | + | ||
169 | + sendOneLineMessage(eventObj, msg); | ||
170 | + } | ||
171 | + else{ | ||
172 | + getfoodinfoByPdtName(eventObj, message_text); | ||
173 | + } | ||
174 | + | ||
175 | + res.sendStatus(200); | ||
176 | +}); | ||
177 | + | ||
178 | +function getfoodinfoByPdtName(eventObj, prdName) | ||
179 | +{ | ||
180 | + var queryParams = '/' + encodeURIComponent(second_key); | ||
181 | + queryParams += '/' + encodeURIComponent('C002'); | ||
182 | + queryParams += '/' + encodeURIComponent(filetype); | ||
183 | + queryParams += '/' + encodeURIComponent(startIndex); | ||
184 | + queryParams += '/' + encodeURIComponent(endIndex); | ||
185 | + queryParams += '/' + encodeURIComponent('PRDLST_NM') + '=' + encodeURIComponent(prdName); | ||
186 | + | ||
187 | + request({ | ||
188 | + url: second_url + queryParams, | ||
189 | + method: 'GET' | ||
190 | + }, function (error, response, body) { | ||
191 | + if(error){ | ||
192 | + helloAndErrorMsg(oventObj); | ||
193 | + console.log('에러입니다.') | ||
194 | + } | ||
195 | + else{ | ||
196 | + var result2 =body; | ||
197 | + var resObj2 = eval("("+result2+")"); | ||
198 | + var resultCode2 = resObj2.C002.RESULT.CODE; | ||
199 | + | ||
200 | + console.log("[입력] : ", prdName); | ||
201 | + console.log("식품명으로 식품유형과 첨가물 정보를 받아옵니다..."); | ||
202 | + | ||
203 | + if(resultCode2 == "INFO-200")//'유효하지 않은 입력' | ||
204 | + { | ||
205 | + console.log("존재하지 않는 식품명입니다."); | ||
206 | + prdNameNotFound(eventObj); | ||
207 | + } | ||
208 | + else if(response.statusCode ==200) | ||
209 | + { // 유효한 입력 | ||
210 | + var ProductCategory = resObj2.C002.row[0].PRDLST_DCNM; | ||
211 | + // 첨가물정보 API가 입력으로 받을 parameter | ||
212 | + | ||
213 | + //console.log(result); | ||
214 | + console.log("성공적으로 정보를 받았습니다.") | ||
215 | + console.log("[처리결과] ",resObj2.C002.RESULT.MSG); | ||
216 | + console.log("[유형] ", ProductCategory); | ||
217 | + console.log("[첨가물] ",resObj2.C002.row[0].RAWMTRL_NM ) | ||
218 | + | ||
219 | + | ||
220 | + | ||
221 | + // 다음 API호출 | ||
222 | + var queryParams = '?' + encodeURIComponent('ServiceKey') + '=' +first_key; | ||
223 | + queryParams += '&' + encodeURIComponent('pc_kor_nm') + '=' + encodeURIComponent(ProductCategory); | ||
224 | + | ||
225 | + request({ | ||
226 | + url: first_url + queryParams, | ||
227 | + method: 'GET' | ||
228 | + }, function (error, response, body) { | ||
229 | + if(error){ | ||
230 | + console.log('에러입니다.') | ||
231 | + } | ||
232 | + else if(response.statusCode ==200) | ||
233 | + { | ||
234 | + var result1 =body; | ||
235 | + var xmltojson = convert.xml2json(result1,{compact:true,spaces:4}); | ||
236 | + var resObj1 = eval("("+xmltojson+")"); | ||
237 | + var resultItems = resObj1.response.body.items; | ||
238 | + | ||
239 | + if(Object.keys(resultItems).length != 0) | ||
240 | + { | ||
241 | + console.log("valid input : 식품 첨가물 정보를 받아옵니다."); | ||
242 | + | ||
243 | + var responseMessage ='[ ' + resultItems.item[0].PC_KOR_NM._text + ' ]\n'; | ||
244 | + //하나의 카테고리에 대한 정보만 받는다고 가정해 반복문 밖으로 뺐습니다. | ||
245 | + | ||
246 | + for(var i=0 ; i < resultItems.item.length; i ++) | ||
247 | + { | ||
248 | + //var responseMessage ='[ ' + resultItems.item[i].PC_KOR_NM._text + ' ]\n'; | ||
249 | + var addictive = resultItems.item[i].T_KOR_NM._text; | ||
250 | + var specVal = resultItems.item[i].SPEC_VAL_SUMUP._text; | ||
251 | + var yn = resultItems.item[i].INJRY_YN._text; | ||
252 | + responseMessage += addictive + ' : ' + specVal + '['+yn+']'+ '\n'; | ||
253 | + } | ||
254 | + | ||
255 | + | ||
256 | + var replyment = | ||
257 | + { | ||
258 | + "replyToken":eventObj.replyToken, | ||
259 | + "messages":[ | ||
260 | + { | ||
261 | + "type":"text", | ||
262 | + "text":prdName +"에 대해 알아볼까요?" | ||
263 | + }, | ||
264 | + { | ||
265 | + "type":"text", | ||
266 | + "text":"[유형]\n" + ProductCategory | ||
267 | + }, | ||
268 | + { | ||
269 | + "type":"text", | ||
270 | + "text":"[첨가물]\n" + resObj2.C002.row[0].RAWMTRL_NM | ||
271 | + } | ||
272 | + ] | ||
273 | + } | ||
274 | + | ||
275 | + if(! simpleResult) | ||
276 | + { | ||
277 | + var moreInfo = | ||
278 | + { | ||
279 | + "type":"text", | ||
280 | + "text":"더 자세한 첨가물 안전 정보\n" +responseMessage | ||
281 | + }; | ||
282 | + replyment.messages.push(moreInfo); | ||
283 | + } | ||
284 | + | ||
285 | + //메시지 전송 | ||
286 | + request.post( | ||
287 | + { | ||
288 | + url: TARGET_URL, | ||
289 | + headers: { | ||
290 | + 'Authorization': `Bearer ${TOKEN}` | ||
291 | + }, | ||
292 | + json: replyment | ||
293 | + },(error, response, body) => { | ||
294 | + console.log(body) | ||
295 | + }); | ||
296 | + } | ||
297 | + else | ||
298 | + { | ||
299 | + console.log("Invalid Input : 에러 메시지 전송"); | ||
300 | + var responseMessage = "잘못 된 입력입니다. 라벨의 식품유형을 확인하고 다시 입력해주세요."; | ||
301 | + } | ||
302 | + console.log('[responese message]',responseMessage); | ||
303 | + | ||
304 | + } | ||
305 | + | ||
306 | + }); | ||
307 | + } | ||
308 | + else | ||
309 | + { | ||
310 | + console.log("입력 이외의 오류가 발생하였습니다."); | ||
311 | + } | ||
312 | + } | ||
313 | + | ||
314 | + }); | ||
315 | + | ||
316 | +} | ||
317 | + | ||
318 | + | ||
319 | + | ||
320 | + | ||
321 | +try { | ||
322 | + const option = { | ||
323 | + ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'), | ||
324 | + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/privkey.pem'), 'utf8').toString(), | ||
325 | + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/cert.pem'), 'utf8').toString(), | ||
326 | + }; | ||
327 | + | ||
328 | + HTTPS.createServer(option, app).listen(sslport, () => { | ||
329 | + console.log(`[HTTPS] Server is started on port ${sslport}`); | ||
330 | + }); | ||
331 | + } catch (error) { | ||
332 | + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.'); | ||
333 | + console.log(error); | ||
334 | + } | ||
335 | + | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment