Showing
1 changed file
with
0 additions
and
545 deletions
chatbotPlus.js
deleted
100644 → 0
1 | -var express = require('express'); | ||
2 | -var client_id = 'v3M4wjolGLkrvNA3GUIW'; | ||
3 | -var client_secret = 'fKF6vjkWhE'; | ||
4 | -const request = require('request'); | ||
5 | -const TARGET_URL = 'https://api.line.me/v2/bot/message/reply' | ||
6 | -const TOKEN = 'hMnfhBQc8nadyn5Ow6aejAVDUoUEp9N8YxOFxfOB2V83TOf0vjquT4cC8ll4Ccq4hkWJ8xHij53FzjMteqLLuUL6bZs+ZONI+f5aawIulRg4Y4FFBGp1O03awvgxGn503iyI7+5iQCEi80Kus6cRZQdB04t89/1O/w1cDnyilFU=' | ||
7 | -const SECRET = '270103fd4cbd81695ceb6d0ed7f85f4b' | ||
8 | -const fs = require('fs'); | ||
9 | -const path = require('path'); | ||
10 | -const HTTPS = require('https'); | ||
11 | -const domain = "www.osschatbot.tk" | ||
12 | -const sslport = 23023; | ||
13 | -const line = require('@line/bot-sdk'); | ||
14 | - | ||
15 | -const bodyParser = require('body-parser'); | ||
16 | -const { assert } = require('console'); | ||
17 | -var app = express(); | ||
18 | -app.use(bodyParser.json()); | ||
19 | - | ||
20 | -var usingMessage = '' | ||
21 | -var content_id = '' | ||
22 | -var imgDownloaded = false; | ||
23 | -var downloadedImg = '' | ||
24 | - | ||
25 | -//search | ||
26 | -var search_client_id = 'cnS9zzj0OZ3xPgHqtaLJ'; | ||
27 | -var search_client_secret = 'oQGaxdr7aq'; | ||
28 | - | ||
29 | -//data parsing | ||
30 | -var data=''; | ||
31 | -var title=''; | ||
32 | -var link=''; | ||
33 | -var category=''; | ||
34 | -var address=''; | ||
35 | -var roadAddress=''; | ||
36 | - | ||
37 | - | ||
38 | -app.post('/hook', function (req, res) { | ||
39 | - | ||
40 | - var eventObj = req.body.events[0]; | ||
41 | - var text = eventObj.message.text; | ||
42 | - | ||
43 | - // request log | ||
44 | - if (!(eventObj.message.type == 'image')) { | ||
45 | - console.log('======================', new Date() ,'======================'); | ||
46 | - console.log('[request]', req.body); | ||
47 | - console.log('[request source] ', eventObj.source); | ||
48 | - console.log('[request message]', eventObj.message); | ||
49 | - } | ||
50 | - | ||
51 | - if (eventObj.message.type == 'location') { | ||
52 | - | ||
53 | - //위치 받아서 맛집 추천해주는 함수 | ||
54 | - var chatbotaddress=eventObj.message; | ||
55 | - var chatbotdata1=chatbotaddress.address; | ||
56 | - var chatbotdata2=chatbotdata1.split(' '); | ||
57 | - var place=chatbotdata2[0]; | ||
58 | - | ||
59 | - console.log(place); | ||
60 | - var menu=''; | ||
61 | - var query= place + ' ' + menu + ' 맛집'; //검색 원하는 문자열 | ||
62 | - RecommendationResult(eventObj.replyToken, query); | ||
63 | - | ||
64 | - res.sendStatus(200); | ||
65 | - } else if (text == 'Cfr:Yes') { | ||
66 | - QuickReplyCfrYes(eventObj.replyToken); | ||
67 | - res.sendStatus(200); | ||
68 | - } else if (text == 'Cfr:No') { | ||
69 | - QuickReplyCfrNo(eventObj.replyToken); | ||
70 | - res.sendStatus(200); | ||
71 | - } else if (text == '랜덤 추천' || text == '위치 기반 추천') { | ||
72 | - if (text == '랜덤 추천') { | ||
73 | - | ||
74 | - //랜덤으로 맛집 추천해주는 함수 | ||
75 | - var query = '맛집'; | ||
76 | - RecommendationResult(eventObj.replyToken, query); | ||
77 | - | ||
78 | - res.sendStatus(200); | ||
79 | - } | ||
80 | - else { | ||
81 | - SendingLocation(eventObj.replyToken); | ||
82 | - res.sendStatus(200); | ||
83 | - } | ||
84 | - } else if (eventObj.message.type == 'image') { | ||
85 | - content_id = eventObj.message.id; | ||
86 | - const downloadPath = path.join(__dirname, 'sample.jpg'); | ||
87 | - downloadContent(content_id, downloadPath); | ||
88 | - //downloadedImg = content_id; | ||
89 | - //imgDownloaded = true; | ||
90 | - Checking(eventObj.replyToken); | ||
91 | - res.sendStatus(200); | ||
92 | - } else if (text == '계속 진행') { | ||
93 | - //사진으로 얼굴 인식해주는 함수 | ||
94 | - imgtodata('sample.jpg'); | ||
95 | - SendingLocation(eventObj.replyToken); | ||
96 | - res.sendStatus(200); | ||
97 | - } | ||
98 | - else { | ||
99 | - usingMessage = text; | ||
100 | - initReply(eventObj.replyToken); | ||
101 | - res.sendStatus(200); | ||
102 | - } | ||
103 | - | ||
104 | -}); | ||
105 | - | ||
106 | -const quickReplyLocation = { | ||
107 | - "items": [ | ||
108 | - { | ||
109 | - "type": "action", | ||
110 | - "action": { | ||
111 | - "type": "location", | ||
112 | - "label": "위치 입력" | ||
113 | - } | ||
114 | - } | ||
115 | - ] | ||
116 | -}; | ||
117 | - | ||
118 | -const quickReplyCfrYes = { | ||
119 | - "items": [ | ||
120 | - { | ||
121 | - "type": "action", | ||
122 | - "action": { | ||
123 | - "type": "cameraRoll", | ||
124 | - "label": "사진 가져오기" | ||
125 | - } | ||
126 | - }, | ||
127 | - { | ||
128 | - "type": "action", | ||
129 | - "action": { | ||
130 | - "type": "camera", | ||
131 | - "label": "사진 찍기" | ||
132 | - } | ||
133 | - }, | ||
134 | - ] | ||
135 | - }; | ||
136 | - | ||
137 | -const quickReplyCfrNo = { | ||
138 | - items: [ | ||
139 | - /* | ||
140 | - { | ||
141 | - "type": "action", | ||
142 | - "action": { | ||
143 | - "type": "message", | ||
144 | - "label": "weather", | ||
145 | - "text": "날씨" | ||
146 | - } | ||
147 | - }, | ||
148 | - { | ||
149 | - "type": "action", | ||
150 | - "action": { | ||
151 | - "type": "message", | ||
152 | - "label": "menu", | ||
153 | - "text": "메뉴" | ||
154 | - } | ||
155 | - }, | ||
156 | - */ | ||
157 | - { | ||
158 | - "type": "action", | ||
159 | - "action": { | ||
160 | - "type": "message", | ||
161 | - "label": "random", | ||
162 | - "text": "랜덤 추천" | ||
163 | - } | ||
164 | - }, | ||
165 | - { | ||
166 | - "type": "action", | ||
167 | - "action": { | ||
168 | - "type": "message", | ||
169 | - "label": "location", | ||
170 | - "text": "위치 기반 추천" | ||
171 | - } | ||
172 | - } | ||
173 | - ] | ||
174 | - }; | ||
175 | - | ||
176 | -//기본 reply | ||
177 | -function initReply (replyToken) { | ||
178 | - request.post( | ||
179 | - { | ||
180 | - url: TARGET_URL, | ||
181 | - headers: { | ||
182 | - 'Authorization': `Bearer ${TOKEN}` | ||
183 | - }, | ||
184 | - json: { | ||
185 | - "replyToken":replyToken, | ||
186 | - "messages":[ | ||
187 | - { | ||
188 | - "type": "sticker", | ||
189 | - "packageId": "11537", | ||
190 | - "stickerId": "52002738" | ||
191 | - }, | ||
192 | - { | ||
193 | - "type": "text", | ||
194 | - "text": "안녕하세요.\nCFR을 이용한 얼굴인식 맛집 추천봇입니다." | ||
195 | - }, | ||
196 | - { | ||
197 | - "type": "template", | ||
198 | - "altText": "얼굴 인식을 위해 사진을 가져오시겠습니까?", | ||
199 | - "template": { | ||
200 | - "type": "confirm", | ||
201 | - "text": "얼굴 인식을 위해 사진을 가져오시겠습니까?", | ||
202 | - "actions": [ | ||
203 | - { | ||
204 | - "type": "message", | ||
205 | - "label": "Cfr:Yes", | ||
206 | - "text": "Cfr:Yes" | ||
207 | - }, | ||
208 | - { | ||
209 | - "type": "message", | ||
210 | - "label": "Cfr:No", | ||
211 | - "text": "Cfr:No" | ||
212 | - } | ||
213 | - ] | ||
214 | - } | ||
215 | - } | ||
216 | - ] | ||
217 | - } | ||
218 | - },(error, response, body) => { | ||
219 | - console.log(body) | ||
220 | - }); | ||
221 | -} | ||
222 | - | ||
223 | -//위치 입력 reply | ||
224 | -function SendingLocation(replyToken) { | ||
225 | - request.post( | ||
226 | - { | ||
227 | - url: TARGET_URL, | ||
228 | - headers: { | ||
229 | - 'Authorization': `Bearer ${TOKEN}` | ||
230 | - }, | ||
231 | - json: { | ||
232 | - "replyToken": replyToken, | ||
233 | - "messages": [ | ||
234 | - { | ||
235 | - "type": "text", | ||
236 | - "text": "위치를 입력해주세요.", | ||
237 | - "quickReply": quickReplyLocation | ||
238 | - } | ||
239 | - ] | ||
240 | - }, | ||
241 | - body: request | ||
242 | - },(error, response, body) => { | ||
243 | - console.log(body) | ||
244 | - }); | ||
245 | -} | ||
246 | - | ||
247 | -//cfr 이용할 때 reply | ||
248 | -function QuickReplyCfrYes(replyToken) { | ||
249 | - request.post( | ||
250 | - { | ||
251 | - url: TARGET_URL, | ||
252 | - headers: { | ||
253 | - 'Authorization': `Bearer ${TOKEN}` | ||
254 | - }, | ||
255 | - json: { | ||
256 | - "replyToken": replyToken, | ||
257 | - "messages": [ | ||
258 | - { | ||
259 | - "type": "text", | ||
260 | - "text": "사진을 입력해주세요.", | ||
261 | - "quickReply": quickReplyCfrYes | ||
262 | - } | ||
263 | - ] | ||
264 | - } | ||
265 | - },(error, response, body) => { | ||
266 | - console.log(body) | ||
267 | - }); | ||
268 | -} | ||
269 | - | ||
270 | -//cfr 이용하지 않을 때 reply | ||
271 | -function QuickReplyCfrNo (replyToken) { | ||
272 | - request.post( | ||
273 | - { | ||
274 | - url: TARGET_URL, | ||
275 | - headers: { | ||
276 | - 'Authorization': `Bearer ${TOKEN}` | ||
277 | - }, | ||
278 | - json: { | ||
279 | - "replyToken": replyToken, | ||
280 | - "messages": [ | ||
281 | - { | ||
282 | - "type": "text", | ||
283 | - "text": "랜덤 추천 옵션을 선택해주세요.", | ||
284 | - "quickReply": quickReplyCfrNo | ||
285 | - } | ||
286 | - ] | ||
287 | - } | ||
288 | - },(error, response, body) => { | ||
289 | - console.log(body) | ||
290 | - }); | ||
291 | -} | ||
292 | - | ||
293 | -function Checking (replyToken) { | ||
294 | - request.post( | ||
295 | - { | ||
296 | - url: TARGET_URL, | ||
297 | - headers: { | ||
298 | - 'Authorization': `Bearer ${TOKEN}` | ||
299 | - }, | ||
300 | - json: { | ||
301 | - "replyToken": replyToken, | ||
302 | - "messages": [ | ||
303 | - { | ||
304 | - "type": "text", | ||
305 | - "label": "계속 진행", | ||
306 | - "text": "계속 진행하시려면 '계속 진행'을 입력해주세요." | ||
307 | - }, | ||
308 | - ], | ||
309 | - } | ||
310 | - },(error, response, body) => { | ||
311 | - console.log(body) | ||
312 | - }); | ||
313 | -} | ||
314 | - | ||
315 | - | ||
316 | -//추천 결과 + Search | ||
317 | -function RecommendationResult(replyToken, query) { | ||
318 | - | ||
319 | - console.log(query); | ||
320 | - var display = '1'; //검색 결과 출력 건수. 최대 5개 | ||
321 | - var start = '1'; //검색 시작 위치. 1만 가능 | ||
322 | - var sort = 'comment'; //정렬 옵션 (random : 유사도순, comment : 카페/블로그 리뷰 개수 순) | ||
323 | - | ||
324 | - var api_url = 'https://openapi.naver.com/v1/search/local?query=' + encodeURI(query) + '&display=' + encodeURI(display) + '&start=' + encodeURI(start) + '&sort=' + encodeURI(sort); | ||
325 | - var options = { | ||
326 | - url: api_url, | ||
327 | - headers: { 'X-Naver-Client-Id': search_client_id, 'X-Naver-Client-Secret': search_client_secret } | ||
328 | - }; | ||
329 | - request.get(options, function (error, response, body) { | ||
330 | - if (!error && response.statusCode == 200) { | ||
331 | - //response.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'}); | ||
332 | - console.log(body); | ||
333 | - | ||
334 | - //데이터 parsing | ||
335 | - data = JSON.parse(body); | ||
336 | - title = data.items[0].title; | ||
337 | - console.log(title); | ||
338 | - | ||
339 | - link = data.items[0].link; | ||
340 | - console.log(link); | ||
341 | - | ||
342 | - category = data.items[0].category; | ||
343 | - console.log(category); | ||
344 | - | ||
345 | - address = data.items[0].address; | ||
346 | - console.log(address); | ||
347 | - | ||
348 | - roadAddress = data.items[0].roadAddress; | ||
349 | - console.log(roadAddress); | ||
350 | - | ||
351 | - request.post( | ||
352 | - { | ||
353 | - url: TARGET_URL, | ||
354 | - headers: { | ||
355 | - 'Authorization': `Bearer ${TOKEN}` | ||
356 | - }, | ||
357 | - json: { | ||
358 | - "replyToken": replyToken, | ||
359 | - "messages": [ | ||
360 | - /*{ | ||
361 | - "type": "imagemap", | ||
362 | - // 이미지 불러올 수 없습니다 뜸 | ||
363 | - "baseUrl": "https://www.flaticon.com/free-icon/food-store_2934069?term=restaurant&page=1&position=7&related_item_id=2934069", | ||
364 | - "altText": "이미지를 누르시면 해당 가게로 이동합니다.", | ||
365 | - "baseSize": { | ||
366 | - "width": 1040, | ||
367 | - "height": 1040 | ||
368 | - }, | ||
369 | - "actions": [ | ||
370 | - { | ||
371 | - "type": "uri", | ||
372 | - "linkUri": link, // 가게 링크 | ||
373 | - "area": { | ||
374 | - "x": 0, | ||
375 | - "y": 0, | ||
376 | - "width": 1040, | ||
377 | - "height": 1040 | ||
378 | - } | ||
379 | - } | ||
380 | - ] | ||
381 | - },*/ | ||
382 | - { | ||
383 | - "type": "text", | ||
384 | - "text": "맛집 이름: " + title | ||
385 | - }, | ||
386 | - { | ||
387 | - "type":"text", | ||
388 | - "text": "맛집 주소: " + address | ||
389 | - } | ||
390 | - /*{ | ||
391 | - "type":"location", | ||
392 | - "title":"맛집 주소", | ||
393 | - "address":address | ||
394 | - }*/ | ||
395 | - ] | ||
396 | - } | ||
397 | - }, (error, response, body) => { | ||
398 | - console.log(body) | ||
399 | - }); | ||
400 | - | ||
401 | - } else { | ||
402 | - res.status(response.statusCode).end(); | ||
403 | - console.log('error = ' + response.statusCode); | ||
404 | - } | ||
405 | - }) | ||
406 | - | ||
407 | -} | ||
408 | - | ||
409 | -imgtodata = function(dir){ | ||
410 | - var api_url = 'https://openapi.naver.com/v1/vision/face'; // 얼굴 감지 | ||
411 | - | ||
412 | - var _formData = { | ||
413 | - image:'image', | ||
414 | - image: fs.createReadStream(path.join(__dirname, dir)) // FILE 이름 | ||
415 | - }; | ||
416 | - | ||
417 | - request.post( | ||
418 | - { url:api_url, | ||
419 | - formData:_formData, | ||
420 | - headers: {'X-Naver-Client-Id':client_id, | ||
421 | - 'X-Naver-Client-Secret': client_secret} | ||
422 | - }, (err,response,body) =>{ | ||
423 | - console.log(response.statusCode); // 200 | ||
424 | - //console.log(response.headers['content-type']) | ||
425 | - console.log(body); | ||
426 | - var cfrdata=JSON.parse(body); | ||
427 | - | ||
428 | - var cfrgender=cfrdata.faces[0].gender.value; //CFR의 성별 데이터 (json) | ||
429 | - var cfremotion=cfrdata.faces[0].emotion.value; //CFR의 감정 데이터 (json) | ||
430 | - | ||
431 | - var gender = cfrgender; //사용자 성별 | ||
432 | - var emotion = cfremotion; //사용자 감정 | ||
433 | - | ||
434 | - | ||
435 | - console.log(gender); | ||
436 | - console.log(emotion); | ||
437 | - | ||
438 | - if(gender=='male'){ | ||
439 | - if(emotion=='angry'){ | ||
440 | - menu='술'; | ||
441 | - } | ||
442 | - else if(emotion=='disgust'){ | ||
443 | - menu='야식'; | ||
444 | - } | ||
445 | - else if(emotion=='fear'){ | ||
446 | - menu='한식'; | ||
447 | - } | ||
448 | - else if(emotion=='laugh'){ | ||
449 | - menu='치킨'; | ||
450 | - } | ||
451 | - else if(emotion=='neutral'){ | ||
452 | - menu='양식'; | ||
453 | - } | ||
454 | - else if(emotion=='sad'){ | ||
455 | - menu='중식'; | ||
456 | - } | ||
457 | - else if(emotion=='surprise'){ | ||
458 | - menu='일식'; | ||
459 | - } | ||
460 | - else if(emotion=='smile'){ | ||
461 | - menu='고기'; | ||
462 | - } | ||
463 | - else if(emotion=='talking'){ | ||
464 | - menu='술'; | ||
465 | - } | ||
466 | - else{ | ||
467 | - menu=''; | ||
468 | - } | ||
469 | - } | ||
470 | - else if(gender=='female'){ | ||
471 | - if(emotion=='angry'){ | ||
472 | - menu='고기'; | ||
473 | - } | ||
474 | - else if(emotion=='disgust'){ | ||
475 | - menu='디저트'; | ||
476 | - } | ||
477 | - else if(emotion=='fear'){ | ||
478 | - menu='한식'; | ||
479 | - } | ||
480 | - else if(emotion=='laugh'){ | ||
481 | - menu='일식'; | ||
482 | - } | ||
483 | - else if(emotion=='neutral'){ | ||
484 | - menu='중식'; | ||
485 | - } | ||
486 | - else if(emotion=='sad'){ | ||
487 | - menu='야식'; | ||
488 | - } | ||
489 | - else if(emotion=='surprise'){ | ||
490 | - menu='중식'; | ||
491 | - } | ||
492 | - else if(emotion=='smile'){ | ||
493 | - menu='치킨'; | ||
494 | - } | ||
495 | - else if(emotion=='talking'){ | ||
496 | - menu='카페'; | ||
497 | - } | ||
498 | - else{ | ||
499 | - menu=''; | ||
500 | - } | ||
501 | - } | ||
502 | - else{ | ||
503 | - menu=''; | ||
504 | - } | ||
505 | - | ||
506 | - console.log(menu); | ||
507 | - | ||
508 | - | ||
509 | - //return {gender:gender,emotion:emotion}; | ||
510 | - }); | ||
511 | - } | ||
512 | - | ||
513 | -//사용자가 보낸 사진 저장 | ||
514 | -const config = ({ | ||
515 | - channelAccessToken: `${TOKEN}`, | ||
516 | - channelSecret: `${SECRET}`, | ||
517 | -}); | ||
518 | - | ||
519 | -const client = new line.Client(config); | ||
520 | -function downloadContent(messageId, downloadPath) { | ||
521 | - return client.getMessageContent(messageId) | ||
522 | - .then((stream) => new Promise((resolve, reject) => { | ||
523 | - const writable = fs.createWriteStream(downloadPath); | ||
524 | - stream.pipe(writable); | ||
525 | - stream.on('end', () => resolve(downloadPath)); | ||
526 | - stream.on('error', reject); | ||
527 | - })); | ||
528 | -} | ||
529 | - | ||
530 | - | ||
531 | -try { | ||
532 | - const option = { | ||
533 | - ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'), | ||
534 | - key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/privkey.pem'), 'utf8').toString(), | ||
535 | - cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/cert.pem'), 'utf8').toString(), | ||
536 | - }; | ||
537 | - if (usingMessage == '') { | ||
538 | - HTTPS.createServer(option, app).listen(sslport, () => { | ||
539 | - console.log(`[HTTPS] Server is started on port ${sslport}`); | ||
540 | - }); | ||
541 | - } | ||
542 | - } catch (error) { | ||
543 | - console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.'); | ||
544 | - console.log(error); | ||
545 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment