유명현

Merge branch 'feature/line_bot' into 'main'

Line bot 기본 기능 구현



See merge request !16
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 }
......