윤준석

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") {
77 + return Promise.resolve(
78 + checkMamul(client, event.source.userId),
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}`);
73 return Promise.resolve( 85 return Promise.resolve(
74 client.replyMessage(event.replyToken, { 86 client.replyMessage(event.replyToken, {
75 - type: "flex", 87 + type: "text",
76 - altText: "등록된 매물", 88 + text: "삭제할 매물 키워드를 알려주세요!",
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 }) 89 })
86 ); 90 );
87 } 91 }
92 + } else if (event.postback.data == "checkKeywords") {
93 + return Promise.resolve(
94 + checkKeywords(client, event)
95 + )
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
...@@ -166,51 +182,82 @@ module.exports = { handleEvent, config }; ...@@ -166,51 +182,82 @@ module.exports = { handleEvent, config };
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 // }, 187 // },
172 // selected: false, 188 // selected: false,
173 -// name: "Nice richmenu", 189 +// name: "Real richMenu",
174 -// chatBarText: "Tap to open", 190 +// chatBarText: "메뉴 열기",
175 // areas: [ 191 // areas: [
176 // { 192 // {
177 // bounds: { 193 // bounds: {
178 // x: 0, 194 // x: 0,
179 // y: 0, 195 // y: 0,
180 -// width: 1250, 196 +// width: 1003,
181 -// height: 843, 197 +// height: 413,
182 // }, 198 // },
183 // action: { 199 // action: {
184 // type: "postback", 200 // type: "postback",
185 -// label: "new", 201 +// label: "newKeyword",
186 -// data: "new", 202 +// data: "newKeyword",
187 -// displayText: "키워드 등록", 203 +// displayText: "키워드 추가",
188 // inputOption: "openKeyboard", 204 // inputOption: "openKeyboard",
189 // fillInText: "", 205 // fillInText: "",
190 // }, 206 // },
191 // }, 207 // },
192 // { 208 // {
193 // bounds: { 209 // bounds: {
194 -// x: 1250, 210 +// x: 1003,
195 // y: 0, 211 // y: 0,
196 -// width: 1250, 212 +// width: 1003,
197 -// height: 843, 213 +// height: 413,
198 // }, 214 // },
199 // action: { 215 // action: {
200 // type: "postback", 216 // type: "postback",
201 -// label: "check", 217 +// label: "deleteKeyword",
202 -// data: "check", 218 +// data: "deleteKeyword",
203 -// displayText: "최신 매물 확인", 219 +// displayText: "키워드 삭제",
204 // inputOption: "openKeyboard", 220 // inputOption: "openKeyboard",
205 // fillInText: "", 221 // fillInText: "",
206 // }, 222 // },
207 // }, 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 +// },
208 // ], 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