윤준석

Merge branch 'feature/220525_rich_menu' into 'main'

Feature/220525 rich menu



See merge request !20
1 +const setKeywordsFlexMessage = require("../message/setKeywordsFlexMessage")
2 +
3 +const db = require("../../apis/database");
4 +
5 +const checkKeywords = (client, event) => {
6 + db.getKeywordsByUserId(event.source.userId).then((keywords) => {
7 + flexMessage = setKeywordsFlexMessage(keywords);
8 + client.replyMessage(event.replyToken, flexMessage)
9 + })
10 +};
11 +
12 +module.exports = { checkKeywords };
...\ No newline at end of file ...\ No newline at end of file
...@@ -10,7 +10,7 @@ const db = require("../../apis/database"); ...@@ -10,7 +10,7 @@ const db = require("../../apis/database");
10 // database.getAllUsers = async function() 10 // database.getAllUsers = async function()
11 // database.getAllKeywords = async function() 11 // database.getAllKeywords = async function()
12 12
13 -const checkMamul = (client) => { 13 +const multiCheckMamul = (client) => {
14 db.getAllKeywords().then((keywords) => { 14 db.getAllKeywords().then((keywords) => {
15 for (let i = 0, pending = Promise.resolve(); i < keywords.length; i++) { 15 for (let i = 0, pending = Promise.resolve(); i < keywords.length; i++) {
16 pending = db.getUsersByKeyword(keywords[i]).then((userIds) => { 16 pending = db.getUsersByKeyword(keywords[i]).then((userIds) => {
...@@ -22,4 +22,14 @@ const checkMamul = (client) => { ...@@ -22,4 +22,14 @@ const checkMamul = (client) => {
22 }); 22 });
23 }; 23 };
24 24
25 -module.exports = { checkMamul }; 25 +const checkMamul = (client, userId) => {
26 + db.getKeywordsByUserId(userId).then((keywords) => {
27 + for (let i = 0, pending = Promise.resolve(); i< keywords.length; i++) {
28 + pending = marketMultiSearch(keywords[i]).then((res) => {
29 + client.pushMessage(userId, setCarouselMessage(res));
30 + });
31 + };
32 + });
33 +};
34 +
35 +module.exports = { multiCheckMamul, checkMamul };
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
2 const line = require("@line/bot-sdk"); 2 const line = require("@line/bot-sdk");
3 const setFlexMessage = require("./message/setFlexMessage"); 3 const setFlexMessage = require("./message/setFlexMessage");
4 const setCarouselMessage = require("./message/setCarouselMessage"); 4 const setCarouselMessage = require("./message/setCarouselMessage");
5 +const setKeywordsFlexMessage = require("./message/setKeywordsFlexMessage")
5 6
6 // Market Search 7 // Market Search
7 const { daangnSingleSearch } = require("./search/daangnSearch"); 8 const { daangnSingleSearch } = require("./search/daangnSearch");
...@@ -18,7 +19,7 @@ const fs = require("fs"); ...@@ -18,7 +19,7 @@ const fs = require("fs");
18 // Cron for Mamul Notification 19 // Cron for Mamul Notification
19 const schedule = require("node-schedule"); 20 const schedule = require("node-schedule");
20 const job = schedule.scheduleJob("0 */1 * * *", () => { 21 const job = schedule.scheduleJob("0 */1 * * *", () => {
21 - checkMamul(client); 22 + multiCheckMamul(client);
22 }); 23 });
23 24
24 // Database APIs 25 // Database APIs
...@@ -39,20 +40,23 @@ const config = { ...@@ -39,20 +40,23 @@ const config = {
39 }; 40 };
40 41
41 // Cron for Mamul Notification 42 // Cron for Mamul Notification
42 -const { checkMamul } = require("./checkMamul/checkMamul"); 43 +const { multiCheckMamul, checkMamul } = require("./check/checkMamul");
44 +const { checkKeywords } = require("./check/checkKeywords")
45 +
43 46
44 // Line chat bot client & event 47 // Line chat bot client & event
45 const client = new line.Client(config); 48 const client = new line.Client(config);
46 49
47 let waitNewMamulList = []; // 매물 키워드 입력 기다리는 목록 50 let waitNewMamulList = []; // 매물 키워드 입력 기다리는 목록
51 +let waitDeleteMamulList = []; // 매물 삭제 키워드 입력 기다리는 목록
48 52
49 function handleEvent(event) { 53 function handleEvent(event) {
50 if (event.type !== "message" || event.message.type !== "text") { 54 if (event.type !== "message" || event.message.type !== "text") {
51 console.log(event); 55 console.log(event);
52 if (event.type == "postback") { 56 if (event.type == "postback") {
53 - if (event.postback.data == "new") { 57 + if (event.postback.data == "newKeyword") {
54 - var found = waitNewMamulList.indexOf(event.source.userId); 58 + var foundNew = waitNewMamulList.indexOf(event.source.userId);
55 - if (found == -1) { 59 + if (foundNew == -1) {
56 waitNewMamulList.push(event.source.userId); 60 waitNewMamulList.push(event.source.userId);
57 console.log(`waitNewMamulList Changed : ${waitNewMamulList}`); 61 console.log(`waitNewMamulList Changed : ${waitNewMamulList}`);
58 return Promise.resolve( 62 return Promise.resolve(
...@@ -69,37 +73,36 @@ function handleEvent(event) { ...@@ -69,37 +73,36 @@ function handleEvent(event) {
69 }) 73 })
70 ); 74 );
71 } 75 }
72 - } else if (event.postback.data == "check") { 76 + } else if (event.postback.data == "checkItems") {
73 return Promise.resolve( 77 return Promise.resolve(
74 - client.replyMessage(event.replyToken, { 78 + checkMamul(client, event.source.userId),
75 - type: "flex",
76 - altText: "등록된 매물",
77 - contents: setFlexMessage(
78 - "daangn",
79 - "RTX 3080",
80 - "1000000",
81 - "https://dnvefa72aowie.cloudfront.net/origin/article/202205/94cdd237258671d5806a70f64ab2b3c7dcd790da0384b394ef5809fe10c08ced.webp?q=95&s=1440x1440&t=inside",
82 - "https://www.daangn.com/articles/403755360",
83 - "채굴X, 흡연X, 반려동물X 입니다.\n직거래 희망하며, 쿨거래시 네고 1만원 가능합니다."
84 - ),
85 - })
86 ); 79 );
80 + } else if (event.postback.data == "deleteKeyword") {
81 + var foundDelete = waitDeleteMamulList.indexOf(event.source.userId);
82 + if (foundDelete == -1) {
83 + waitDeleteMamulList.push(event.source.userId);
84 + console.log(`waitDeleteMamulList Changed : ${waitDeleteMamulList}`);
85 + return Promise.resolve(
86 + client.replyMessage(event.replyToken, {
87 + type: "text",
88 + text: "삭제할 매물 키워드를 알려주세요!",
89 + })
90 + );
91 + }
92 + } else if (event.postback.data == "checkKeywords") {
93 + return Promise.resolve(
94 + checkKeywords(client, event)
95 + )
87 } 96 }
88 } 97 }
89 return Promise.resolve(null); 98 return Promise.resolve(null);
90 } else { 99 } else {
91 console.log(event); 100 console.log(event);
92 - var found = waitNewMamulList.indexOf(event.source.userId); 101 + var foundNew = waitNewMamulList.indexOf(event.source.userId);
93 - if (found == -1) { 102 + if (foundNew != -1) {
94 - return Promise.resolve(
95 - marketMultiSearch(event.message.text).then((res) => {
96 - client.pushMessage(event.source.userId, setCarouselMessage(res));
97 - })
98 - );
99 - } else {
100 // TODO: 서버에 키워드 등록하는 api 103 // TODO: 서버에 키워드 등록하는 api
101 - waitNewMamulList.splice(found, 1); 104 + waitNewMamulList.splice(foundNew, 1);
102 - console.log(waitNewMamulList[found]); 105 + console.log(waitNewMamulList[foundNew]);
103 return Promise.resolve( 106 return Promise.resolve(
104 db.addKeyword(event.message.text, event.source.userId), 107 db.addKeyword(event.message.text, event.source.userId),
105 client.replyMessage(event.replyToken, { 108 client.replyMessage(event.replyToken, {
...@@ -111,6 +114,19 @@ function handleEvent(event) { ...@@ -111,6 +114,19 @@ function handleEvent(event) {
111 }) 114 })
112 ); 115 );
113 } 116 }
117 +
118 + var foundDelete = waitDeleteMamulList.indexOf(event.source.userId);
119 + if (foundDelete != -1) {
120 + waitDeleteMamulList.splice(foundDelete, 1);
121 + console.log(waitDeleteMamulList[foundDelete]);
122 + return Promise.resolve(
123 + db.deleteKeyword(event.source.userId, event.message.text),
124 + client.replyMessage(event.replyToken, {
125 + type: "text",
126 + text: `매물이 삭제되었습니다!\n삭제된 매물: ${event.message.text}`,
127 + })
128 + )
129 + }
114 } 130 }
115 } 131 }
116 132
...@@ -165,52 +181,83 @@ module.exports = { handleEvent, config }; ...@@ -165,52 +181,83 @@ module.exports = { handleEvent, config };
165 181
166 /*리치메뉴 설정*/ 182 /*리치메뉴 설정*/
167 // let richMenu = { 183 // let richMenu = {
168 -// size: { 184 +// size: {
169 -// width: 2500, 185 +// width: 2006,
170 -// height: 843, 186 +// height: 827,
171 -// },
172 -// selected: false,
173 -// name: "Nice richmenu",
174 -// chatBarText: "Tap to open",
175 -// areas: [
176 -// {
177 -// bounds: {
178 -// x: 0,
179 -// y: 0,
180 -// width: 1250,
181 -// height: 843,
182 -// },
183 -// action: {
184 -// type: "postback",
185 -// label: "new",
186 -// data: "new",
187 -// displayText: "키워드 등록",
188 -// inputOption: "openKeyboard",
189 -// fillInText: "",
190 -// },
191 // }, 187 // },
192 -// { 188 +// selected: false,
193 -// bounds: { 189 +// name: "Real richMenu",
194 -// x: 1250, 190 +// chatBarText: "메뉴 열기",
195 -// y: 0, 191 +// areas: [
196 -// width: 1250, 192 +// {
197 -// height: 843, 193 +// bounds: {
198 -// }, 194 +// x: 0,
199 -// action: { 195 +// y: 0,
200 -// type: "postback", 196 +// width: 1003,
201 -// label: "check", 197 +// height: 413,
202 -// data: "check", 198 +// },
203 -// displayText: "최신 매물 확인", 199 +// action: {
204 -// inputOption: "openKeyboard", 200 +// type: "postback",
205 -// fillInText: "", 201 +// label: "newKeyword",
206 -// }, 202 +// data: "newKeyword",
207 -// }, 203 +// displayText: "키워드 추가",
208 -// ], 204 +// inputOption: "openKeyboard",
205 +// fillInText: "",
206 +// },
207 +// },
208 +// {
209 +// bounds: {
210 +// x: 1003,
211 +// y: 0,
212 +// width: 1003,
213 +// height: 413,
214 +// },
215 +// action: {
216 +// type: "postback",
217 +// label: "deleteKeyword",
218 +// data: "deleteKeyword",
219 +// displayText: "키워드 삭제",
220 +// inputOption: "openKeyboard",
221 +// fillInText: "",
222 +// },
223 +// },
224 +// {
225 +// bounds: {
226 +// x: 0,
227 +// y: 413,
228 +// width: 1003,
229 +// height: 414,
230 +// },
231 +// action: {
232 +// type: "postback",
233 +// label: "checkKeywords",
234 +// data: "checkKeywords",
235 +// displayText: "키워드 확인",
236 +// },
237 +// },
238 +// {
239 +// bounds: {
240 +// x: 1003,
241 +// y: 413,
242 +// width: 1003,
243 +// height: 414,
244 +// },
245 +// action: {
246 +// type: "postback",
247 +// label: "checkItems",
248 +// data: "checkItems",
249 +// displayText: "매물 즉시 검색",
250 +// },
251 +// },
252 +// ],
209 // }; 253 // };
210 -//// 등록 254 +// 등록
211 -// client.createRichMenu(richMenu).then((richMenuId) => console.log(richMenuId)); 255 +// client.createRichMenu(richMenu).then((richMenuId) => {
256 +// console.log(richMenuId)
257 +// });
212 // client.setRichMenuImage( 258 // client.setRichMenuImage(
213 -// "richmenu-183eff606f059b8244f0a625b54bddf1", 259 +// "richmenu-ab4bba1c3c9235be50e3e8924fabd940",
214 -// fs.createReadStream("./static/img/richMenu.jpg") 260 +// fs.createReadStream("./static/image/richMenu.png")
215 -// ); 261 +// );
216 -// client.setDefaultRichMenu("richmenu-183eff606f059b8244f0a625b54bddf1"); 262 +// client.setDefaultRichMenu("richmenu-ab4bba1c3c9235be50e3e8924fabd940");
263 +//
......
1 +function setKeywordsFlexMessage(keywords) {
2 + let flexMessage = {
3 + type: "bubble",
4 + body: {
5 + type: "box",
6 + layout: "vertical",
7 + contents: [
8 + {
9 + type: "text",
10 + text: "매무리 봇",
11 + weight: "bold",
12 + color: "#1DB446",
13 + size: "sm",
14 + },
15 + {
16 + type: "text",
17 + text: "등록된 키워드",
18 + weight: "bold",
19 + size: "xxl",
20 + margin: "md"
21 + },
22 + {
23 + type: "separator",
24 + margin: "xxl"
25 + },
26 + {
27 + type: "box",
28 + layout: "vertical",
29 + contents: [],
30 + margin: "md"
31 + }
32 + ]
33 + },
34 + };
35 +
36 + for (let i = 0; i < keywords.length; i++) {
37 + const textbox = createKeywordTextBox(keywords[i]);
38 + flexMessage.body.contents[3].contents.push(textbox);
39 + }
40 +
41 + return {
42 + type: "flex",
43 + altText: "키워드 조회 오류",
44 + contents: flexMessage
45 + }
46 +}
47 +
48 +function createKeywordTextBox(keyword) {
49 + return {
50 + type: "text",
51 + text: keyword,
52 + size: "lg",
53 + align: "center",
54 + margin: "md"
55 + }
56 +}
57 +
58 +module.exports = setKeywordsFlexMessage;
...\ No newline at end of file ...\ No newline at end of file