조아혜

modify chatbot.js

Showing 1 changed file with 217 additions and 88 deletions
...@@ -2,95 +2,88 @@ var express = require('express'); ...@@ -2,95 +2,88 @@ var express = require('express');
2 const request = require('request'); 2 const request = require('request');
3 const TARGET_URL = 'https://api.line.me/v2/bot/message/reply' 3 const TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
4 const TOKEN = 'w5i8sURqF5bof6DWeB87n+oCeWrYaFf7a5YZzfzN1jeITIlZ3PcOmZRcdGCo/djTuHhNxybfJ69y7Jex+7tipBNRynngfyWX9CK1L3EupuhnX8rubeCmJda7HvsQWXVo8ZDcwl2aLwXsE3kiYF2qEwdB04t89/1O/w1cDnyilFU=' 4 const TOKEN = 'w5i8sURqF5bof6DWeB87n+oCeWrYaFf7a5YZzfzN1jeITIlZ3PcOmZRcdGCo/djTuHhNxybfJ69y7Jex+7tipBNRynngfyWX9CK1L3EupuhnX8rubeCmJda7HvsQWXVo8ZDcwl2aLwXsE3kiYF2qEwdB04t89/1O/w1cDnyilFU='
5 +const SECRET = 'b0b4501ebc2813a2b0e586293a35b466'
5 const fs = require('fs'); 6 const fs = require('fs');
6 const path = require('path'); 7 const path = require('path');
7 const HTTPS = require('https'); 8 const HTTPS = require('https');
8 const domain = "www.osstest237.ml" 9 const domain = "www.osstest237.ml"
9 const sslport = 23023; 10 const sslport = 23023;
11 +const line = require('@line/bot-sdk');
10 12
11 const bodyParser = require('body-parser'); 13 const bodyParser = require('body-parser');
14 +const { assert } = require('console');
12 var app = express(); 15 var app = express();
13 app.use(bodyParser.json()); 16 app.use(bodyParser.json());
14 17
15 var usingMessage = '' 18 var usingMessage = ''
16 - 19 +var content_id = ''
17 app.post('/hook', function (req, res) { 20 app.post('/hook', function (req, res) {
18 21
19 var eventObj = req.body.events[0]; 22 var eventObj = req.body.events[0];
20 - // var source = eventObj.source;
21 - // var message = eventObj.message;
22 var text = eventObj.message.text; 23 var text = eventObj.message.text;
23 24
24 // request log 25 // request log
26 + if (!(eventObj.message.type == 'image')) {
25 console.log('======================', new Date() ,'======================'); 27 console.log('======================', new Date() ,'======================');
26 console.log('[request]', req.body); 28 console.log('[request]', req.body);
27 console.log('[request source] ', eventObj.source); 29 console.log('[request source] ', eventObj.source);
28 console.log('[request message]', eventObj.message); 30 console.log('[request message]', eventObj.message);
31 + }
32 +
33 + if (eventObj.message.type == 'location') {
34 +
35 + //위치 받아서 맛집 추천해주는 함수
29 36
30 - if (text == 'Cfr:Yes') { 37 + RecommendationResult(eventObj.replyToken);
38 + res.sendStatus(200);
39 + } else if (text == 'Cfr:Yes') {
31 QuickReplyCfrYes(eventObj.replyToken); 40 QuickReplyCfrYes(eventObj.replyToken);
32 res.sendStatus(200); 41 res.sendStatus(200);
33 } else if (text == 'Cfr:No') { 42 } else if (text == 'Cfr:No') {
34 QuickReplyCfrNo(eventObj.replyToken); 43 QuickReplyCfrNo(eventObj.replyToken);
35 res.sendStatus(200); 44 res.sendStatus(200);
45 + } else if (text == '랜덤 추천' || text == '위치 기반 추천') {
46 + if (text == '랜덤 추천') {
47 +
48 + //랜덤으로 맛집 추천해주는 함수
49 +
50 + RecommendationResult(eventObj.replyToken);
51 + res.sendStatus(200);
52 + }
53 + else {
54 + SendingLocation(eventObj.replyToken);
55 + res.sendStatus(200);
56 + }
36 } else if (eventObj.message.type == 'image') { 57 } else if (eventObj.message.type == 'image') {
37 - console.log('image url: ', eventObj.message.contentProvider); 58 + content_id = eventObj.message.id;
38 - console.log('image url: ', eventObj.message.originalContentUrl); 59 + const downloadPath = path.join(__dirname, `${content_id}.jpg`);
39 - console.log('image url: ', eventObj.message.previewImageUrl); 60 + downloadContent(content_id, downloadPath);
40 - console.log('id:', eventObj.message.id); 61 +
62 + //사진으로 얼굴 인식해주는 함수
63 +
64 + SendingLocation(eventObj.replyToken);
41 res.sendStatus(200); 65 res.sendStatus(200);
42 - } 66 + } else {
43 - else {
44 usingMessage = text; 67 usingMessage = text;
45 - request.post( 68 + initReply(eventObj.replyToken);
46 - {
47 - url: TARGET_URL,
48 - headers: {
49 - 'Authorization': `Bearer ${TOKEN}`
50 - },
51 - json: {
52 - "replyToken":eventObj.replyToken,
53 - "messages":[
54 - {
55 - "type": "sticker",
56 - "packageId": "11537",
57 - "stickerId": "52002738"
58 - },
59 - {
60 - "type": "text",
61 - "text": "안녕하세요.\nCFR을 이용한 경기도 맛집 추천봇입니다."
62 - },
63 - {
64 - "type": "template",
65 - "altText": "얼굴 인식을 위해 사진을 가져오시겠습니까?",
66 - "template": {
67 - "type": "confirm",
68 - "text": "얼굴 인식을 위해 사진을 가져오시겠습니까?",
69 - "actions": [
70 - {
71 - "type": "message",
72 - "label": "Cfr:Yes",
73 - "text": "Cfr:Yes"
74 - },
75 - {
76 - "type": "message",
77 - "label": "Cfr:No",
78 - "text": "Cfr:No"
79 - }
80 - ]
81 - }
82 - },
83 - ]
84 - }
85 - },(error, response, body) => {
86 - console.log(body)
87 - });
88 res.sendStatus(200); 69 res.sendStatus(200);
89 } 70 }
90 71
91 }); 72 });
92 73
93 -const quickReplyYes = { 74 +const quickReplyLocation = {
75 + "items": [
76 + {
77 + "type": "action",
78 + "action": {
79 + "type": "location",
80 + "label": "위치 입력"
81 + }
82 + }
83 + ]
84 +};
85 +
86 +const quickReplyCfrYes = {
94 "items": [ 87 "items": [
95 { 88 {
96 "type": "action", 89 "type": "action",
...@@ -106,40 +99,12 @@ const quickReplyYes = { ...@@ -106,40 +99,12 @@ const quickReplyYes = {
106 "label": "사진 찍기" 99 "label": "사진 찍기"
107 } 100 }
108 }, 101 },
109 - {
110 - "type": "action",
111 - "action": {
112 - "type": "location",
113 - "label": "위치"
114 - }
115 - }
116 ] 102 ]
117 }; 103 };
118 104
119 -function QuickReplyCfrYes(replyToken) { 105 +const quickReplyCfrNo = {
120 - request.post(
121 - {
122 - url: TARGET_URL,
123 - headers: {
124 - 'Authorization': `Bearer ${TOKEN}`
125 - },
126 - json: {
127 - "replyToken": replyToken,
128 - "messages": [
129 - {
130 - "type": "text",
131 - "text": "사진 입력",
132 - "quickReply": quickReplyYes
133 - }
134 - ]
135 - }
136 - },(error, response, body) => {
137 - console.log(body)
138 - });
139 -}
140 -
141 -const quickReplyNo = {
142 items: [ 106 items: [
107 + /*
143 { 108 {
144 "type": "action", 109 "type": "action",
145 "action": { 110 "action": {
...@@ -156,17 +121,120 @@ const quickReplyNo = { ...@@ -156,17 +121,120 @@ const quickReplyNo = {
156 "text": "메뉴" 121 "text": "메뉴"
157 } 122 }
158 }, 123 },
124 + */
159 { 125 {
160 "type": "action", 126 "type": "action",
161 "action": { 127 "action": {
162 "type": "message", 128 "type": "message",
163 "label": "random", 129 "label": "random",
164 - "text": "랜덤" 130 + "text": "랜덤 추천"
131 + }
132 + },
133 + {
134 + "type": "action",
135 + "action": {
136 + "type": "message",
137 + "label": "location",
138 + "text": "위치 기반 추천"
165 } 139 }
166 } 140 }
167 ] 141 ]
168 }; 142 };
169 143
144 +//기본 reply
145 +function initReply (replyToken) {
146 + request.post(
147 + {
148 + url: TARGET_URL,
149 + headers: {
150 + 'Authorization': `Bearer ${TOKEN}`
151 + },
152 + json: {
153 + "replyToken":replyToken,
154 + "messages":[
155 + {
156 + "type": "sticker",
157 + "packageId": "11537",
158 + "stickerId": "52002738"
159 + },
160 + {
161 + "type": "text",
162 + "text": "안녕하세요.\nCFR을 이용한 경기도 맛집 추천봇입니다."
163 + },
164 + {
165 + "type": "template",
166 + "altText": "얼굴 인식을 위해 사진을 가져오시겠습니까?",
167 + "template": {
168 + "type": "confirm",
169 + "text": "얼굴 인식을 위해 사진을 가져오시겠습니까?",
170 + "actions": [
171 + {
172 + "type": "message",
173 + "label": "Cfr:Yes",
174 + "text": "Cfr:Yes"
175 + },
176 + {
177 + "type": "message",
178 + "label": "Cfr:No",
179 + "text": "Cfr:No"
180 + }
181 + ]
182 + }
183 + }
184 + ]
185 + }
186 + },(error, response, body) => {
187 + console.log(body)
188 + });
189 +}
190 +
191 +//위치 입력 reply
192 +function SendingLocation(replyToken) {
193 + request.post(
194 + {
195 + url: TARGET_URL,
196 + headers: {
197 + 'Authorization': `Bearer ${TOKEN}`
198 + },
199 + json: {
200 + "replyToken": replyToken,
201 + "messages": [
202 + {
203 + "type": "text",
204 + "text": "위치를 입력해주세요.",
205 + "quickReply": quickReplyLocation
206 + }
207 + ]
208 + }
209 + },(error, response, body) => {
210 + console.log(body)
211 + });
212 +}
213 +
214 +//cfr 이용할 때 reply
215 +function QuickReplyCfrYes(replyToken) {
216 + request.post(
217 + {
218 + url: TARGET_URL,
219 + headers: {
220 + 'Authorization': `Bearer ${TOKEN}`
221 + },
222 + json: {
223 + "replyToken": replyToken,
224 + "messages": [
225 + {
226 + "type": "text",
227 + "text": "사진을 입력해주세요.",
228 + "quickReply": quickReplyCfrYes
229 + }
230 + ]
231 + }
232 + },(error, response, body) => {
233 + console.log(body)
234 + });
235 +}
236 +
237 +//cfr 이용하지 않을 때 reply
170 function QuickReplyCfrNo (replyToken) { 238 function QuickReplyCfrNo (replyToken) {
171 request.post( 239 request.post(
172 { 240 {
...@@ -179,8 +247,8 @@ function QuickReplyCfrNo (replyToken) { ...@@ -179,8 +247,8 @@ function QuickReplyCfrNo (replyToken) {
179 "messages": [ 247 "messages": [
180 { 248 {
181 "type": "text", 249 "type": "text",
182 - "text": "맛집 추천 옵션 선택", 250 + "text": "랜덤 추천 옵션을 선택해주세요.",
183 - "quickReply": quickReplyNo 251 + "quickReply": quickReplyCfrNo
184 } 252 }
185 ] 253 ]
186 } 254 }
...@@ -189,6 +257,67 @@ function QuickReplyCfrNo (replyToken) { ...@@ -189,6 +257,67 @@ function QuickReplyCfrNo (replyToken) {
189 }); 257 });
190 } 258 }
191 259
260 +function RecommendationResult(replyToken) {
261 + request.post(
262 + {
263 + url: TARGET_URL,
264 + headers: {
265 + 'Authorization': `Bearer ${TOKEN}`
266 + },
267 + json: {
268 + "replyToken": replyToken,
269 + "messages": [
270 + {
271 + "type": "imagemap",
272 + // 이미지 불러올 수 없습니다 뜸
273 + "baseUrl": "https://www.flaticon.com/free-icon/food-store_2934069?term=restaurant&page=1&position=7&related_item_id=2934069",
274 + "altText": "이미지를 누르시면 해당 가게로 이동합니다.",
275 + "baseSize": {
276 + "width": 1040,
277 + "height": 1040
278 + },
279 + "actions": [
280 + {
281 + "type": "uri",
282 + "linkUri": `${link}`, // 가게 링크
283 + "area": {
284 + "x":0,
285 + "y":0,
286 + "width":1040,
287 + "height":1040
288 + }
289 + }
290 + ]
291 + },
292 + {
293 + "type": "text",
294 + "text": "기타 결과 출력" // 정보 수정
295 + }
296 + ]
297 + }
298 + },(error, response, body) => {
299 + console.log(body)
300 + });
301 +}
302 +
303 +//사용자가 보낸 사진 저장
304 +const config = ({
305 + channelAccessToken: `${TOKEN}`,
306 + channelSecret: `${SECRET}`,
307 +});
308 +
309 +const client = new line.Client(config);
310 +function downloadContent(messageId, downloadPath) {
311 + return client.getMessageContent(messageId)
312 + .then((stream) => new Promise((resolve, reject) => {
313 + const writable = fs.createWriteStream(downloadPath);
314 + stream.pipe(writable);
315 + stream.on('end', () => resolve(downloadPath));
316 + stream.on('error', reject);
317 + }));
318 +}
319 +
320 +
192 try { 321 try {
193 const option = { 322 const option = {
194 ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'), 323 ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'),
...@@ -203,4 +332,4 @@ try { ...@@ -203,4 +332,4 @@ try {
203 } catch (error) { 332 } catch (error) {
204 console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.'); 333 console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
205 console.log(error); 334 console.log(error);
206 - }
...\ No newline at end of file ...\ No newline at end of file
335 +}
...\ No newline at end of file ...\ No newline at end of file
......