Merge branch 'feature/line_bot' into 'main'
Line bot 기본 기능 구현 See merge request !16
Showing
5 changed files
with
316 additions
and
5 deletions
server/apis/setFlexMessage.js
0 → 100644
1 | +function priceToString(price) { | ||
2 | + return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | ||
3 | +} | ||
4 | + | ||
5 | +function setFlexMessage(platform, name, price, thumbnailUrl, itemUrl) { | ||
6 | + let koreanPlatformName = ""; | ||
7 | + if (platform === "daangn") { | ||
8 | + koreanPlatformName = "당근"; | ||
9 | + } else if (platform === "joongna") { | ||
10 | + koreanPlatformName = "중고나라"; | ||
11 | + } else if (platform === "bunjang") { | ||
12 | + koreanPlatformName = "번개나라"; | ||
13 | + } else { | ||
14 | + koreanPlatformName = "Unknown"; | ||
15 | + } | ||
16 | + | ||
17 | + let flexMessage = { | ||
18 | + type: "bubble", | ||
19 | + hero: { | ||
20 | + type: "image", | ||
21 | + url: thumbnailUrl, | ||
22 | + size: "full", | ||
23 | + aspectRatio: "20:13", | ||
24 | + aspectMode: "cover", | ||
25 | + action: { | ||
26 | + type: "uri", | ||
27 | + uri: itemUrl, | ||
28 | + }, | ||
29 | + }, | ||
30 | + body: { | ||
31 | + type: "box", | ||
32 | + layout: "vertical", | ||
33 | + contents: [ | ||
34 | + { | ||
35 | + type: "text", | ||
36 | + text: name, | ||
37 | + weight: "bold", | ||
38 | + size: "xl", | ||
39 | + }, | ||
40 | + // { | ||
41 | + // type: "box", | ||
42 | + // layout: "baseline", | ||
43 | + // margin: "md", | ||
44 | + // contents: [ | ||
45 | + // { | ||
46 | + // type: "icon", | ||
47 | + // size: "sm", | ||
48 | + // url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png", | ||
49 | + // }, | ||
50 | + // { | ||
51 | + // type: "icon", | ||
52 | + // size: "sm", | ||
53 | + // url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png", | ||
54 | + // }, | ||
55 | + // { | ||
56 | + // type: "icon", | ||
57 | + // size: "sm", | ||
58 | + // url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png", | ||
59 | + // }, | ||
60 | + // { | ||
61 | + // type: "icon", | ||
62 | + // size: "sm", | ||
63 | + // url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png", | ||
64 | + // }, | ||
65 | + // { | ||
66 | + // type: "icon", | ||
67 | + // size: "sm", | ||
68 | + // url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png", | ||
69 | + // }, | ||
70 | + // { | ||
71 | + // type: "text", | ||
72 | + // text: "4.0", | ||
73 | + // size: "sm", | ||
74 | + // color: "#999999", | ||
75 | + // margin: "md", | ||
76 | + // flex: 0, | ||
77 | + // }, | ||
78 | + // ], | ||
79 | + // }, | ||
80 | + { | ||
81 | + type: "box", | ||
82 | + layout: "vertical", | ||
83 | + margin: "lg", | ||
84 | + spacing: "sm", | ||
85 | + contents: [ | ||
86 | + { | ||
87 | + type: "box", | ||
88 | + layout: "baseline", | ||
89 | + spacing: "sm", | ||
90 | + contents: [ | ||
91 | + { | ||
92 | + type: "text", | ||
93 | + text: "플랫폼", | ||
94 | + color: "#aaaaaa", | ||
95 | + size: "sm", | ||
96 | + flex: 1, | ||
97 | + }, | ||
98 | + { | ||
99 | + type: "text", | ||
100 | + text: koreanPlatformName, | ||
101 | + wrap: true, | ||
102 | + color: "#666666", | ||
103 | + size: "sm", | ||
104 | + flex: 5, | ||
105 | + }, | ||
106 | + ], | ||
107 | + }, | ||
108 | + { | ||
109 | + type: "box", | ||
110 | + layout: "baseline", | ||
111 | + spacing: "sm", | ||
112 | + contents: [ | ||
113 | + { | ||
114 | + type: "text", | ||
115 | + text: "가격", | ||
116 | + color: "#aaaaaa", | ||
117 | + size: "sm", | ||
118 | + flex: 1, | ||
119 | + }, | ||
120 | + { | ||
121 | + type: "text", | ||
122 | + text: priceToString(price * 1) + "원", | ||
123 | + wrap: true, | ||
124 | + color: "#666666", | ||
125 | + size: "sm", | ||
126 | + flex: 5, | ||
127 | + }, | ||
128 | + ], | ||
129 | + }, | ||
130 | + ], | ||
131 | + }, | ||
132 | + ], | ||
133 | + }, | ||
134 | + footer: { | ||
135 | + type: "box", | ||
136 | + layout: "vertical", | ||
137 | + spacing: "sm", | ||
138 | + contents: [ | ||
139 | + { | ||
140 | + type: "button", | ||
141 | + style: "link", | ||
142 | + height: "sm", | ||
143 | + action: { | ||
144 | + type: "uri", | ||
145 | + label: "매물 확인", | ||
146 | + uri: itemUrl, | ||
147 | + }, | ||
148 | + }, | ||
149 | + { | ||
150 | + type: "box", | ||
151 | + layout: "vertical", | ||
152 | + contents: [], | ||
153 | + margin: "sm", | ||
154 | + }, | ||
155 | + ], | ||
156 | + flex: 0, | ||
157 | + }, | ||
158 | + }; | ||
159 | + return flexMessage; | ||
160 | + //return JSON.stringify(flexMessage); | ||
161 | +} | ||
162 | + | ||
163 | +module.exports = setFlexMessage; |
1 | -var express = require("express"); | 1 | +const express = require("express"); |
2 | -var app = express(); | 2 | +const line = require("@line/bot-sdk"); |
3 | +const setFlexMessage = require("./apis/setFlexMessage"); | ||
4 | +const fs = require("fs"); | ||
3 | 5 | ||
4 | -app.get("/", function (req, res) { | 6 | +require("dotenv").config(); |
5 | - res.send("<h1>hello express!</h1>"); | 7 | +const config = { |
8 | + channelAccessToken: process.env.channelAccessToken, | ||
9 | + channelSecret: process.env.channelSecret, | ||
10 | +}; | ||
11 | + | ||
12 | +const app = express(); | ||
13 | +app.post("/webhook", line.middleware(config), (req, res) => { | ||
14 | + Promise.all(req.body.events.map(handleEvent)).then((result) => | ||
15 | + res.json(result) | ||
16 | + ); | ||
6 | }); | 17 | }); |
7 | 18 | ||
8 | -app.listen(3000); | 19 | +const client = new line.Client(config); |
20 | + | ||
21 | +let waitNewMamulList = []; // 매물 키워드 입력 기다리는 목록 | ||
22 | + | ||
23 | +function handleEvent(event) { | ||
24 | + if (event.type !== "message" || event.message.type !== "text") { | ||
25 | + console.log(event); | ||
26 | + if (event.type == "postback") { | ||
27 | + if (event.postback.data == "new") { | ||
28 | + var found = waitNewMamulList.indexOf(event.source.userId); | ||
29 | + if (found == -1) { | ||
30 | + waitNewMamulList.push(event.source.userId); | ||
31 | + console.log(waitNewMamulList); | ||
32 | + return Promise.resolve( | ||
33 | + client.replyMessage(event.replyToken, { | ||
34 | + type: "text", | ||
35 | + text: "등록할 매물 키워드를 알려주세요!", | ||
36 | + }) | ||
37 | + ); | ||
38 | + } else { | ||
39 | + return Promise.resolve( | ||
40 | + client.replyMessage(event.replyToken, { | ||
41 | + type: "text", | ||
42 | + text: "등록할 매물 키워드를 알려주세요!", | ||
43 | + }) | ||
44 | + ); | ||
45 | + } | ||
46 | + } else if (event.postback.data == "check") { | ||
47 | + return Promise.resolve( | ||
48 | + client.replyMessage(event.replyToken, { | ||
49 | + type: "flex", | ||
50 | + altText: "등록된 매물", | ||
51 | + contents: setFlexMessage( | ||
52 | + "daangn", | ||
53 | + "RTX 3080", | ||
54 | + "1000000", | ||
55 | + "https://dnvefa72aowie.cloudfront.net/origin/article/202205/94cdd237258671d5806a70f64ab2b3c7dcd790da0384b394ef5809fe10c08ced.webp?q=95&s=1440x1440&t=inside", | ||
56 | + "https://www.daangn.com/articles/403755360" | ||
57 | + ), | ||
58 | + }) | ||
59 | + ); | ||
60 | + } | ||
61 | + } | ||
62 | + return Promise.resolve(null); | ||
63 | + } else { | ||
64 | + console.log(event); | ||
65 | + var found = waitNewMamulList.indexOf(event.source.userId); | ||
66 | + if (found == -1) { | ||
67 | + return Promise.resolve( | ||
68 | + client.replyMessage(event.replyToken, { | ||
69 | + type: "text", | ||
70 | + text: "왼쪽 하단 메뉴버튼(☰)을 클릭해 상호작용 해주세요!", | ||
71 | + }) | ||
72 | + ); | ||
73 | + } else { | ||
74 | + // TODO: 서버에 키워드 등록하는 api | ||
75 | + waitNewMamulList.splice(found, 1); | ||
76 | + console.log(waitNewMamulList[found]); | ||
77 | + return Promise.resolve( | ||
78 | + client.replyMessage(event.replyToken, { | ||
79 | + type: "text", | ||
80 | + text: "매물이 등록되었습니다!\n등록된 매물: " + event.message.text, | ||
81 | + }) | ||
82 | + ); | ||
83 | + } | ||
84 | + } | ||
85 | +} | ||
86 | + | ||
87 | +const port = 1231; | ||
88 | +app.listen(port); | ||
89 | +console.log(`listening...\nport : ${port}`); | ||
90 | + | ||
91 | +/*Push Message*/ | ||
92 | +// client.pushMessage(event.source.userId, { | ||
93 | +// type: "flex", | ||
94 | +// altText: "새로운 매물이 왔어요!", | ||
95 | +// contents: setFlexMessage( | ||
96 | +// "daangn", | ||
97 | +// "RTX 3080", | ||
98 | +// "1000000", | ||
99 | +// "https://dnvefa72aowie.cloudfront.net/origin/article/202205/94cdd237258671d5806a70f64ab2b3c7dcd790da0384b394ef5809fe10c08ced.webp?q=95&s=1440x1440&t=inside", | ||
100 | +// "https://www.daangn.com/articles/403755360" | ||
101 | +// ), | ||
102 | +// }) | ||
103 | + | ||
104 | +/*리치메뉴 설정*/ | ||
105 | +// let richMenu = { | ||
106 | +// size: { | ||
107 | +// width: 2500, | ||
108 | +// height: 843, | ||
109 | +// }, | ||
110 | +// selected: false, | ||
111 | +// name: "Nice richmenu", | ||
112 | +// chatBarText: "Tap to open", | ||
113 | +// areas: [ | ||
114 | +// { | ||
115 | +// bounds: { | ||
116 | +// x: 0, | ||
117 | +// y: 0, | ||
118 | +// width: 1250, | ||
119 | +// height: 843, | ||
120 | +// }, | ||
121 | +// action: { | ||
122 | +// type: "postback", | ||
123 | +// label: "new", | ||
124 | +// data: "new", | ||
125 | +// displayText: "키워드 등록", | ||
126 | +// inputOption: "openKeyboard", | ||
127 | +// fillInText: "", | ||
128 | +// }, | ||
129 | +// }, | ||
130 | +// { | ||
131 | +// bounds: { | ||
132 | +// x: 1250, | ||
133 | +// y: 0, | ||
134 | +// width: 1250, | ||
135 | +// height: 843, | ||
136 | +// }, | ||
137 | +// action: { | ||
138 | +// type: "postback", | ||
139 | +// label: "check", | ||
140 | +// data: "check", | ||
141 | +// displayText: "최신 매물 확인", | ||
142 | +// inputOption: "openKeyboard", | ||
143 | +// fillInText: "", | ||
144 | +// }, | ||
145 | +// }, | ||
146 | +// ], | ||
147 | +// }; | ||
148 | +//// 등록 | ||
149 | +// client.createRichMenu(richMenu).then((richMenuId) => console.log(richMenuId)); | ||
150 | +// client.setRichMenuImage( | ||
151 | +// "richmenu-183eff606f059b8244f0a625b54bddf1", | ||
152 | +// fs.createReadStream("./static/img/richMenu.jpg") | ||
153 | +// ); | ||
154 | +// client.setDefaultRichMenu("richmenu-183eff606f059b8244f0a625b54bddf1"); | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | "author": "", | 15 | "author": "", |
16 | "license": "MIT", | 16 | "license": "MIT", |
17 | "dependencies": { | 17 | "dependencies": { |
18 | + "@line/bot-sdk": "^7.5.0", | ||
19 | + "dotenv": "^16.0.1", | ||
18 | "express": "^4.18.1", | 20 | "express": "^4.18.1", |
19 | "nodemon": "^2.0.16" | 21 | "nodemon": "^2.0.16" |
20 | } | 22 | } | ... | ... |
server/static/img/richMenu.jpg
0 → 100644
114 KB
-
Please register or login to post a comment