Commit eb28d472dfdd78993b47618c9e5bd8ab0920d8ac

Authored by Surasit Yerpui
1 parent a8dde2dd
Exists in master

update Service

index copy.js 0 → 100644
... ... @@ -0,0 +1,317 @@
  1 +"use strict";
  2 +
  3 +const line = require("@line/bot-sdk");
  4 +const express = require("express");
  5 +const config = require("./config.json");
  6 +const bodyParser = require("body-parser");
  7 +const axios = require("axios");
  8 +const fs = require("fs");
  9 +const request = require("request");
  10 +const moment = require("moment");
  11 +const flexMsg = require("./flexMsg");
  12 +
  13 +// create LINE SDK client
  14 +const client = new line.Client(config);
  15 +
  16 +const app = express();
  17 +
  18 +// webhook callback
  19 +app.use("/webhook", line.middleware(config));
  20 +app.post("/webhook", (req, res) => {
  21 + // req.body.events should be an array of events
  22 + if (!Array.isArray(req.body.events)) {
  23 + return res.status(500).end();
  24 + }
  25 + // handle events separately
  26 + Promise.all(
  27 + req.body.events.map((event) => {
  28 + console.log("event", event);
  29 + // check verify webhook event
  30 + if (
  31 + event.replyToken === "00000000000000000000000000000000" ||
  32 + event.replyToken === "ffffffffffffffffffffffffffffffff"
  33 + ) {
  34 + return;
  35 + }
  36 + return handleEvent(event);
  37 + })
  38 + )
  39 + .then(() => res.end())
  40 + .catch((err) => {
  41 + console.error(err);
  42 + res.status(500).end();
  43 + });
  44 +});
  45 +
  46 +// simple reply function
  47 +const replyText = (token, texts) => {
  48 + texts = Array.isArray(texts) ? texts : [texts];
  49 + return client.replyMessage(
  50 + token,
  51 + texts.map((text) => ({ type: "text", text }))
  52 + );
  53 +};
  54 +
  55 +const tolow = (str) => {
  56 + return str.toLowerCase();
  57 +};
  58 +const handleEvent = (event) => {
  59 + let payload = {
  60 + type: "text",
  61 + text: "Hello From PUI",
  62 + };
  63 +
  64 + if (event.message.type == "text") {
  65 + let selecttext = tolow(event.message.text);
  66 + let get_text = mockText()[selecttext];
  67 + if (get_text) {
  68 + payload = get_text;
  69 + }
  70 + } else {
  71 + payload.text = "Other Message =>>>" + JSON.stringify(event);
  72 + }
  73 +
  74 + return client.replyMessage(event.replyToken, payload);
  75 +};
  76 +app.use(bodyParser.json());
  77 +
  78 +app.get("/", (req, res) => {
  79 + res.json({ line: "ok" });
  80 +});
  81 +
  82 +app.get("/push", bodyParser.json(), (req, res) => {
  83 + let message = {
  84 + type: "text",
  85 + text: `use Push Message! to `,
  86 + };
  87 + client.pushMessage("Uaac2ca5a02feab67a18d5521b572b5aa", message);
  88 + res.json(message);
  89 +});
  90 +
  91 +app.post("/save", bodyParser.json(), async (req, res) => {
  92 + console.log("saveFile!");
  93 + try {
  94 + const downloadFile = function (uri, filename, callback) {
  95 + request.head(uri, function (err, res, body) {
  96 + console.log("content-type:", res.headers["content-type"]);
  97 + console.log("content-length:", res.headers["content-length"]);
  98 + console.log("Content-Type:", res.headers["Content-Type"]);
  99 + console.log("res.headers ::", res.headers);
  100 +
  101 + request(uri, {
  102 + headers: {
  103 + Authorization:
  104 + "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  105 + },
  106 + })
  107 + .pipe(fs.createWriteStream(filename))
  108 + .on("close", callback);
  109 + });
  110 + };
  111 +
  112 + let unquie_file = moment().format("YYYY-MM-DD_HHmmssss");
  113 + let file_name = `filesave_${unquie_file}`;
  114 + let message_id = req.body.message_id;
  115 + let URI = `https://api-data.line.me/v2/bot/message/${message_id}/content`;
  116 + console.log("message_id ::", message_id);
  117 + console.log("file_name ::", file_name);
  118 +
  119 + axios
  120 + .get(URI, {
  121 + headers: {
  122 + Authorization:
  123 + "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  124 + },
  125 + })
  126 + .then(function (response) {
  127 + // handle success
  128 + console.log("axios =>>", response.headers["content-type"]);
  129 + let sp = response.headers["content-type"].split("/");
  130 + let type = sp[sp.length - 1];
  131 + let full_file_name = file_name + "." + type;
  132 + console.log("full_file_name =", full_file_name);
  133 + downloadFile(URI, full_file_name, function () {
  134 + console.log("done!");
  135 + res.json({ LoadFlieName: "Success" });
  136 + });
  137 + })
  138 + .catch(function (error) {
  139 + // handle error
  140 + console.log(error);
  141 + console.error("errorxx ::", error);
  142 + res.json({ error: "error" });
  143 + });
  144 + } catch (error) {
  145 + console.error("errorxx ::", error);
  146 + }
  147 +});
  148 +
  149 +app.post("/saveNew", bodyParser.json(), async (req, res) => {
  150 + console.log("saveFile!");
  151 + try {
  152 + let stream = await client.getMessageContent("14955535936627");
  153 + console.log("stream!", stream);
  154 + } catch (error) {
  155 + console.error(error);
  156 + }
  157 + res.json({ OK: "OK" });
  158 +});
  159 +
  160 +app.post("/push", (req, res) => {
  161 + let body = req.body;
  162 + let { user_id } = body;
  163 + console.log("body ::", body);
  164 + let message = {
  165 + type: "text",
  166 + text: `use Push Message! to ${user_id}`,
  167 + };
  168 + client.pushMessage(user_id, message);
  169 + res.json(message);
  170 +});
  171 +
  172 +app.post("/multicast", (req, res) => {
  173 + let body = req.body;
  174 + let { user_ids } = body;
  175 + console.log("body ::", body);
  176 + let message = [
  177 + {
  178 + type: "text",
  179 + text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
  180 + },
  181 + {
  182 + type: "text",
  183 + text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
  184 + },
  185 + ];
  186 + client.multicast(user_ids, message);
  187 + res.json(message);
  188 +});
  189 +
  190 +const port = config.port;
  191 +app.listen(port, () => {
  192 + console.log(`listening on ${port}`);
  193 +});
  194 +
  195 +const GenContentFlex = (content) => {
  196 + return {
  197 + flex1: {
  198 + type: "flex",
  199 + altText: "GenContentFlex!",
  200 + contents: content,
  201 + },
  202 + };
  203 +};
  204 +
  205 +const genMsgContent = flexMsg.GenContentFlex;
  206 +const flexs = flexMsg.flexs;
  207 +// console.log(genMsgContent());
  208 +
  209 +const mockText = () => {
  210 + return {
  211 + flex0: flexs.flex0,
  212 + flex1: flexs.flex1,
  213 +
  214 + bub1: flexs.bub1,
  215 + bub2: flexs.bub2,
  216 + bub3: flexs.bub3,
  217 + bub4: flexs.bub4,
  218 + bub5: flexs.bub5,
  219 + bub6: flexs.bub6,
  220 +
  221 + confirm:{
  222 + "type": "template",
  223 + "altText": "this is a confirm template",
  224 + "template": {
  225 + "type": "confirm",
  226 + "text": "Are you sure?",
  227 + "actions": [
  228 + {
  229 + "type": "message",
  230 + "label": "Yes",
  231 + "text": "yes"
  232 + },
  233 + {
  234 + "type": "message",
  235 + "label": "No",
  236 + "text": "no"
  237 + }
  238 + ]
  239 + }
  240 + },
  241 +
  242 +
  243 + location: {
  244 + type: "text", // ①
  245 + text: "Select your favorite food category or send me your location!",
  246 + quickReply: {
  247 + // ②
  248 + items: [
  249 + {
  250 + type: "action", // ③
  251 + imageUrl: "https://example.com/sushi.png",
  252 + action: {
  253 + type: "message",
  254 + label: "Sushi",
  255 + text: "Sushi",
  256 + },
  257 + },
  258 + {
  259 + type: "action",
  260 + imageUrl: "https://example.com/tempura.png",
  261 + action: {
  262 + type: "message",
  263 + label: "Tempura",
  264 + text: "Tempura",
  265 + },
  266 + },
  267 + {
  268 + type: "action", // ④
  269 + action: {
  270 + type: "location",
  271 + label: "Send location",
  272 + },
  273 + },
  274 + ],
  275 + },
  276 + },
  277 +
  278 +
  279 +
  280 +
  281 + //
  282 + image_carousel: {
  283 + "type": "template",
  284 + "altText": "this is a image carousel template",
  285 + "template": {
  286 + "type": "image_carousel",
  287 + "columns": [
  288 + {
  289 + "imageUrl": "https://example.com/bot/images/item1.jpg",
  290 + "action": {
  291 + "type": "postback",
  292 + "label": "Buy",
  293 + "data": "action=buy&itemid=111"
  294 + }
  295 + },
  296 + {
  297 + "imageUrl": "https://example.com/bot/images/item2.jpg",
  298 + "action": {
  299 + "type": "message",
  300 + "label": "Yes",
  301 + "text": "yes"
  302 + }
  303 + },
  304 + {
  305 + "imageUrl": "https://example.com/bot/images/item3.jpg",
  306 + "action": {
  307 + "type": "uri",
  308 + "label": "View detail",
  309 + "uri": "http://example.com/page/222"
  310 + }
  311 + }
  312 + ]
  313 + }
  314 + }
  315 +
  316 + };
  317 +};
... ...
index.js
... ... @@ -9,6 +9,8 @@ const fs = require("fs");
9 9 const request = require("request");
10 10 const moment = require("moment");
11 11 const flexMsg = require("./flexMsg");
  12 +const ContentService = require("./services/ContentService");
  13 +const LineService = require("./services/LineService");
12 14  
13 15 // create LINE SDK client
14 16 const client = new line.Client(config);
... ... @@ -43,18 +45,6 @@ app.post("/webhook", (req, res) => {
43 45 });
44 46 });
45 47  
46   -// simple reply function
47   -const replyText = (token, texts) => {
48   - texts = Array.isArray(texts) ? texts : [texts];
49   - return client.replyMessage(
50   - token,
51   - texts.map((text) => ({ type: "text", text }))
52   - );
53   -};
54   -
55   -const tolow = (str) => {
56   - return str.toLowerCase();
57   -};
58 48 const handleEvent = (event) => {
59 49 let payload = {
60 50 type: "text",
... ... @@ -62,8 +52,8 @@ const handleEvent = (event) => {
62 52 };
63 53  
64 54 if (event.message.type == "text") {
65   - let selecttext = tolow(event.message.text);
66   - let get_text = mockText()[selecttext];
  55 + let selecttext = String(event.message.text).toLowerCase();
  56 + let get_text = ContentService.mockText()[selecttext];
67 57 if (get_text) {
68 58 payload = get_text;
69 59 }
... ... @@ -73,21 +63,73 @@ const handleEvent = (event) => {
73 63  
74 64 return client.replyMessage(event.replyToken, payload);
75 65 };
76   -app.use(bodyParser.json());
77 66  
  67 +app.use(bodyParser.json());
78 68 app.get("/", (req, res) => {
79 69 res.json({ line: "ok" });
80 70 });
81 71  
82   -app.get("/push", bodyParser.json(), (req, res) => {
  72 +app.post("/push", (req, res) => {
  73 + let body = req.body;
  74 + let { user_id } = body;
  75 + console.log("push =>> body ::", body);
83 76 let message = {
84 77 type: "text",
85   - text: `use Push Message! to `,
  78 + text: `Push Message! to ${user_id}`,
86 79 };
87   - client.pushMessage("Uaac2ca5a02feab67a18d5521b572b5aa", message);
  80 + client.pushMessage(user_id, message);
  81 + res.json(message);
  82 +});
  83 +
  84 +app.post("/multicast", (req, res) => {
  85 + let body = req.body;
  86 + let { user_ids } = body;
  87 + console.log("body ::", body);
  88 + let message = [
  89 + {
  90 + type: "text",
  91 + text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
  92 + },
  93 + {
  94 + type: "text",
  95 + text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
  96 + },
  97 + ];
  98 +
  99 + client.multicast(user_ids, message);
88 100 res.json(message);
89 101 });
90 102  
  103 +app.post("/multicast", (req, res) => {
  104 + let body = req.body;
  105 + let { user_ids } = body;
  106 + console.log("body ::", body);
  107 + let message = [
  108 + {
  109 + type: "text",
  110 + text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
  111 + },
  112 + {
  113 + type: "text",
  114 + text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
  115 + },
  116 + ];
  117 +
  118 + client.multicast(user_ids, message);
  119 + res.json(message);
  120 +});
  121 +
  122 +app.post("/broadcast", async (req, res) => {
  123 + let body = req.body;
  124 + let { messages } = body;
  125 + console.log("body ::", body);
  126 +
  127 + let resx = await LineService.Broadcast(messages);
  128 + console.log("resx", resx);
  129 +
  130 + res.json({ message: "OK" });
  131 +});
  132 +
91 133 app.post("/save", bodyParser.json(), async (req, res) => {
92 134 console.log("saveFile!");
93 135 try {
... ... @@ -146,172 +188,7 @@ app.post("/save", bodyParser.json(), async (req, res) => {
146 188 }
147 189 });
148 190  
149   -app.post("/saveNew", bodyParser.json(), async (req, res) => {
150   - console.log("saveFile!");
151   - try {
152   - let stream = await client.getMessageContent("14955535936627");
153   - console.log("stream!", stream);
154   - } catch (error) {
155   - console.error(error);
156   - }
157   - res.json({ OK: "OK" });
158   -});
159   -
160   -app.post("/push", (req, res) => {
161   - let body = req.body;
162   - let { user_id } = body;
163   - console.log("body ::", body);
164   - let message = {
165   - type: "text",
166   - text: `use Push Message! to ${user_id}`,
167   - };
168   - client.pushMessage(user_id, message);
169   - res.json(message);
170   -});
171   -
172   -app.post("/multicast", (req, res) => {
173   - let body = req.body;
174   - let { user_ids } = body;
175   - console.log("body ::", body);
176   - let message = [
177   - {
178   - type: "text",
179   - text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
180   - },
181   - {
182   - type: "text",
183   - text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
184   - },
185   - ];
186   - client.multicast(user_ids, message);
187   - res.json(message);
188   -});
189   -
190 191 const port = config.port;
191 192 app.listen(port, () => {
192 193 console.log(`listening on ${port}`);
193 194 });
194   -
195   -const GenContentFlex = (content) => {
196   - return {
197   - flex1: {
198   - type: "flex",
199   - altText: "GenContentFlex!",
200   - contents: content,
201   - },
202   - };
203   -};
204   -
205   -const genMsgContent = flexMsg.GenContentFlex;
206   -const flexs = flexMsg.flexs;
207   -// console.log(genMsgContent());
208   -
209   -const mockText = () => {
210   - return {
211   - flex0: flexs.flex0,
212   - flex1: flexs.flex1,
213   -
214   - bub1: flexs.bub1,
215   - bub2: flexs.bub2,
216   - bub3: flexs.bub3,
217   - bub4: flexs.bub4,
218   - bub5: flexs.bub5,
219   - bub6: flexs.bub6,
220   -
221   - confirm:{
222   - "type": "template",
223   - "altText": "this is a confirm template",
224   - "template": {
225   - "type": "confirm",
226   - "text": "Are you sure?",
227   - "actions": [
228   - {
229   - "type": "message",
230   - "label": "Yes",
231   - "text": "yes"
232   - },
233   - {
234   - "type": "message",
235   - "label": "No",
236   - "text": "no"
237   - }
238   - ]
239   - }
240   - },
241   -
242   -
243   - location: {
244   - type: "text", // ①
245   - text: "Select your favorite food category or send me your location!",
246   - quickReply: {
247   - // ②
248   - items: [
249   - {
250   - type: "action", // ③
251   - imageUrl: "https://example.com/sushi.png",
252   - action: {
253   - type: "message",
254   - label: "Sushi",
255   - text: "Sushi",
256   - },
257   - },
258   - {
259   - type: "action",
260   - imageUrl: "https://example.com/tempura.png",
261   - action: {
262   - type: "message",
263   - label: "Tempura",
264   - text: "Tempura",
265   - },
266   - },
267   - {
268   - type: "action", // ④
269   - action: {
270   - type: "location",
271   - label: "Send location",
272   - },
273   - },
274   - ],
275   - },
276   - },
277   -
278   -
279   -
280   -
281   - //
282   - image_carousel: {
283   - "type": "template",
284   - "altText": "this is a image carousel template",
285   - "template": {
286   - "type": "image_carousel",
287   - "columns": [
288   - {
289   - "imageUrl": "https://example.com/bot/images/item1.jpg",
290   - "action": {
291   - "type": "postback",
292   - "label": "Buy",
293   - "data": "action=buy&itemid=111"
294   - }
295   - },
296   - {
297   - "imageUrl": "https://example.com/bot/images/item2.jpg",
298   - "action": {
299   - "type": "message",
300   - "label": "Yes",
301   - "text": "yes"
302   - }
303   - },
304   - {
305   - "imageUrl": "https://example.com/bot/images/item3.jpg",
306   - "action": {
307   - "type": "uri",
308   - "label": "View detail",
309   - "uri": "http://example.com/page/222"
310   - }
311   - }
312   - ]
313   - }
314   - }
315   -
316   - };
317   -};
... ...
indexbk.js
... ... @@ -1,166 +0,0 @@
1   -"use strict";
2   -
3   -const line = require("@line/bot-sdk");
4   -const express = require("express");
5   -const config = require("./config.json");
6   -
7   -// create LINE SDK client
8   -const client = new line.Client(config);
9   -
10   -const app = express();
11   -
12   -// webhook callback
13   -app.post("/webhook", line.middleware(config), (req, res) => {
14   - // req.body.events should be an array of events
15   - if (!Array.isArray(req.body.events)) {
16   - return res.status(500).end();
17   - }
18   - // handle events separately
19   - Promise.all(
20   - req.body.events.map((event) => {
21   - console.log("event", event);
22   - // check verify webhook event
23   - if (
24   - event.replyToken === "00000000000000000000000000000000" ||
25   - event.replyToken === "ffffffffffffffffffffffffffffffff"
26   - ) {
27   - return;
28   - }
29   - return handleEvent2(event);
30   - })
31   - )
32   - .then(() => res.end())
33   - .catch((err) => {
34   - console.error(err);
35   - res.status(500).end();
36   - });
37   -});
38   -
39   -// simple reply function
40   -const replyText = (token, texts) => {
41   - texts = Array.isArray(texts) ? texts : [texts];
42   - return client.replyMessage(
43   - token,
44   - texts.map((text) => ({ type: "text", text }))
45   - );
46   -};
47   -
48   -const handleEvent = (event) => {
49   - // const payload = {
50   - // type: "text",
51   - // text: "Hello From PUI",
52   - // };
53   -
54   -
55   - const payload = {
56   - "type": "text", // ①
57   - "text": "Select your favorite food category or send me your location!",
58   - "quickReply": { // ②
59   - "items": [
60   - {
61   - "type": "action", // ③
62   - "imageUrl": "https://example.com/sushi.png",
63   - "action": {
64   - "type": "message",
65   - "label": "Sushi",
66   - "text": "Sushi"
67   - }
68   - },
69   - {
70   - "type": "action",
71   - "imageUrl": "https://example.com/tempura.png",
72   - "action": {
73   - "type": "message",
74   - "label": "Tempura",
75   - "text": "Tempura"
76   - }
77   - },
78   - {
79   - "type": "action", // ④
80   - "action": {
81   - "type": "location",
82   - "label": "Send location"
83   - }
84   - }
85   - ]
86   - }
87   - }
88   -
89   - return client.replyMessage(event.replyToken, payload);
90   -};
91   -
92   -// callback function to handle a single event
93   -function handleEvent2(event) {
94   - switch (event.type) {
95   - case 'message':
96   - const message = event.message;
97   - switch (message.type) {
98   - case 'text':
99   - return handleText(message, event.replyToken);
100   - case 'image':
101   - return handleImage(message, event.replyToken);
102   - case 'video':
103   - return handleVideo(message, event.replyToken);
104   - case 'audio':
105   - return handleAudio(message, event.replyToken);
106   - case 'location':
107   - return handleLocation(message, event.replyToken);
108   - case 'sticker':
109   - return handleSticker(message, event.replyToken);
110   - default:
111   - throw new Error(`Unknown message: ${JSON.stringify(message)}`);
112   - }
113   -
114   - case 'follow':
115   - return replyText(event.replyToken, 'Got followed event');
116   -
117   - case 'unfollow':
118   - return console.log(`Unfollowed this bot: ${JSON.stringify(event)}`);
119   -
120   - case 'join':
121   - return replyText(event.replyToken, `Joined ${event.source.type}`);
122   -
123   - case 'leave':
124   - return console.log(`Left: ${JSON.stringify(event)}`);
125   -
126   - case 'postback':
127   - let data = event.postback.data;
128   - return replyText(event.replyToken, `Got postback: ${data}`);
129   -
130   - case 'beacon':
131   - const dm = `${Buffer.from(event.beacon.dm || '', 'hex').toString('utf8')}`;
132   - return replyText(event.replyToken, `${event.beacon.type} beacon hwid : ${event.beacon.hwid} with device message = ${dm}`);
133   -
134   - default:
135   - throw new Error(`Unknown event: ${JSON.stringify(event)}`);
136   - }
137   -}
138   -
139   -function handleText(message, replyToken) {
140   - return replyText(replyToken, message.text);
141   -}
142   -
143   -function handleImage(message, replyToken) {
144   - return replyText(replyToken, "Got Image");
145   -}
146   -
147   -function handleVideo(message, replyToken) {
148   - return replyText(replyToken, "Got Video");
149   -}
150   -
151   -function handleAudio(message, replyToken) {
152   - return replyText(replyToken, "Got Audio");
153   -}
154   -
155   -function handleLocation(message, replyToken) {
156   - return replyText(replyToken, "Got Location");
157   -}
158   -
159   -function handleSticker(message, replyToken) {
160   - return replyText(replyToken, "Got Sticker");
161   -}
162   -
163   -const port = config.port;
164   -app.listen(port, () => {
165   - console.log(`listening on ${port}`);
166   -});
indexv1.js
... ... @@ -1,553 +0,0 @@
1   -"use strict";
2   -
3   -const line = require("@line/bot-sdk");
4   -const express = require("express");
5   -const config = require("./config.json");
6   -const bodyParser = require("body-parser");
7   -const axios = require("axios");
8   -const fs = require("fs");
9   -const request = require("request");
10   -const moment = require("moment");
11   -const { type } = require("os");
12   -
13   -// create LINE SDK client
14   -const client = new line.Client(config);
15   -
16   -const app = express();
17   -
18   -// webhook callback
19   -app.use("/webhook", line.middleware(config));
20   -app.post("/webhook", (req, res) => {
21   - // req.body.events should be an array of events
22   - if (!Array.isArray(req.body.events)) {
23   - return res.status(500).end();
24   - }
25   - // handle events separately
26   - Promise.all(
27   - req.body.events.map((event) => {
28   - console.log("event", event);
29   - // check verify webhook event
30   - if (
31   - event.replyToken === "00000000000000000000000000000000" ||
32   - event.replyToken === "ffffffffffffffffffffffffffffffff"
33   - ) {
34   - return;
35   - }
36   - return handleEvent(event);
37   - })
38   - )
39   - .then(() => res.end())
40   - .catch((err) => {
41   - console.error(err);
42   - res.status(500).end();
43   - });
44   -});
45   -
46   -// simple reply function
47   -const replyText = (token, texts) => {
48   - texts = Array.isArray(texts) ? texts : [texts];
49   - return client.replyMessage(
50   - token,
51   - texts.map((text) => ({ type: "text", text }))
52   - );
53   -};
54   -
55   -const tolow = (str) => {
56   - return str.toLowerCase();
57   -};
58   -const handleEvent = (event) => {
59   - let payload = {
60   - type: "text",
61   - text: "Hello From PUI",
62   - };
63   -
64   - if (event.message.type == "text") {
65   - let selecttext = tolow(event.message.text);
66   - let get_text = mockText()[selecttext];
67   - if (get_text) {
68   - payload = get_text;
69   - }
70   - } else {
71   - payload.text = "Other Message =>>>" + JSON.stringify(event);
72   - }
73   -
74   - return client.replyMessage(event.replyToken, payload);
75   -};
76   -app.use(bodyParser.json());
77   -
78   -app.get("/", (req, res) => {
79   - res.json({ line: "ok" });
80   -});
81   -
82   -app.get("/push", bodyParser.json(), (req, res) => {
83   - let message = {
84   - type: "text",
85   - text: `use Push Message! to `,
86   - };
87   - client.pushMessage("Uaac2ca5a02feab67a18d5521b572b5aa", message);
88   - res.json(message);
89   -});
90   -
91   -app.post("/save", bodyParser.json(), async (req, res) => {
92   - console.log("saveFile!");
93   - try {
94   - const downloadFile = function (uri, filename, callback) {
95   - request.head(uri, function (err, res, body) {
96   - console.log("content-type:", res.headers["content-type"]);
97   - console.log("content-length:", res.headers["content-length"]);
98   - console.log("Content-Type:", res.headers["Content-Type"]);
99   - console.log("res.headers ::", res.headers);
100   -
101   - request(uri, {
102   - headers: {
103   - Authorization:
104   - "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
105   - },
106   - })
107   - .pipe(fs.createWriteStream(filename))
108   - .on("close", callback);
109   - });
110   - };
111   -
112   - let unquie_file = moment().format("YYYY-MM-DD_HHmmssss");
113   - let file_name = `filesave_${unquie_file}`;
114   - let message_id = req.body.message_id;
115   - let URI = `https://api-data.line.me/v2/bot/message/${message_id}/content`;
116   - console.log("message_id ::", message_id);
117   - console.log("file_name ::", file_name);
118   -
119   - axios
120   - .get(URI, {
121   - headers: {
122   - Authorization:
123   - "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
124   - },
125   - })
126   - .then(function (response) {
127   - // handle success
128   - console.log("axios =>>", response.headers["content-type"]);
129   - let sp = response.headers["content-type"].split("/");
130   - let type = sp[sp.length - 1];
131   - let full_file_name = file_name + "." + type;
132   - console.log("full_file_name =", full_file_name);
133   - downloadFile(URI, full_file_name, function () {
134   - console.log("done!");
135   - res.json({ LoadFlieName: "Success" });
136   - });
137   - })
138   - .catch(function (error) {
139   - // handle error
140   - console.log(error);
141   - console.error("errorxx ::", error);
142   - res.json({ error: "error" });
143   - });
144   - } catch (error) {
145   - console.error("errorxx ::", error);
146   - }
147   -});
148   -
149   -app.post("/saveNew", bodyParser.json(), async (req, res) => {
150   - console.log("saveFile!");
151   - try {
152   - let stream = await client.getMessageContent("14955535936627");
153   - console.log("stream!", stream);
154   - } catch (error) {
155   - console.error(error);
156   - }
157   - res.json({ OK: "OK" });
158   -});
159   -
160   -app.post("/push", (req, res) => {
161   - let body = req.body;
162   - let { user_id } = body;
163   - console.log("body ::", body);
164   - let message = {
165   - type: "text",
166   - text: `use Push Message! to ${user_id}`,
167   - };
168   - client.pushMessage(user_id, message);
169   - res.json(message);
170   -});
171   -
172   -app.post("/multicast", (req, res) => {
173   - let body = req.body;
174   - let { user_ids } = body;
175   - console.log("body ::", body);
176   - let message = [
177   - {
178   - type: "text",
179   - text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
180   - },
181   - {
182   - type: "text",
183   - text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
184   - },
185   - ];
186   - client.multicast(user_ids, message);
187   - res.json(message);
188   -});
189   -
190   -const port = config.port;
191   -app.listen(port, () => {
192   - console.log(`listening on ${port}`);
193   -});
194   -
195   -const GenContentFlex = (content) => {
196   - return {
197   - flex1: {
198   - type: "flex",
199   - altText: "GenContentFlex!",
200   - contents: content,
201   - },
202   - };
203   -};
204   -
205   -const mockText = () => {
206   - return {
207   - flex1: {
208   - type: "flex",
209   - altText: "this is a flex message",
210   - contents: {
211   - type: "bubble",
212   - body: {
213   - type: "box",
214   - layout: "vertical",
215   - contents: [
216   - {
217   - type: "text",
218   - text: "hello",
219   - },
220   - {
221   - type: "text",
222   - text: "world",
223   - },
224   - ],
225   - },
226   - },
227   - },
228   -
229   - flex2: {
230   - type: "flex",
231   - altText: "this is a flex message",
232   - contents: {
233   - type: "bubble",
234   - direction: "ltr",
235   - header: {
236   - type: "box",
237   - layout: "vertical",
238   - contents: [
239   - {
240   - type: "text",
241   - text: "แมว",
242   - align: "center",
243   - contents: [],
244   - },
245   - ],
246   - },
247   - hero: {
248   - type: "image",
249   - url: "https://static.trueplookpanya.com/tppy/member/m_545000_547500/545994/cms/images/2019-Q3/แมว9ชีวิต.jpg",
250   - size: "full",
251   - aspectRatio: "1.51:1",
252   - aspectMode: "fit",
253   - },
254   - body: {
255   - type: "box",
256   - layout: "vertical",
257   - contents: [
258   - {
259   - type: "text",
260   - text: "คำอธิบาย",
261   - align: "center",
262   - contents: [],
263   - },
264   - ],
265   - },
266   - footer: {
267   - type: "box",
268   - layout: "horizontal",
269   - contents: [
270   - {
271   - type: "button",
272   - action: {
273   - type: "uri",
274   - label: "ดูรูปแมวชัดๆ",
275   - uri: "https://static.trueplookpanya.com/tppy/member/m_545000_547500/545994/cms/images/2019-Q3/แมว9ชีวิต.jpg",
276   - },
277   - },
278   - ],
279   - },
280   - },
281   - },
282   -
283   - flex3: {
284   - type: "flex",
285   - altText: "this is a flex message",
286   - contents: {
287   - type: "bubble",
288   - direction: "ltr",
289   - hero: {
290   - type: "image",
291   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_3_movie.png",
292   - size: "full",
293   - aspectRatio: "20:13",
294   - aspectMode: "cover",
295   - action: {
296   - type: "uri",
297   - label: "Action",
298   - uri: "https://linecorp.com/",
299   - },
300   - },
301   - body: {
302   - type: "box",
303   - layout: "vertical",
304   - spacing: "md",
305   - contents: [
306   - {
307   - type: "text",
308   - text: "BROWN'S ADVENTURE\nIN MOVIE",
309   - weight: "bold",
310   - size: "xl",
311   - gravity: "center",
312   - wrap: true,
313   - contents: [],
314   - },
315   - {
316   - type: "box",
317   - layout: "baseline",
318   - margin: "md",
319   - contents: [
320   - {
321   - type: "icon",
322   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
323   - size: "sm",
324   - },
325   - {
326   - type: "icon",
327   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
328   - size: "sm",
329   - },
330   - {
331   - type: "icon",
332   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
333   - size: "sm",
334   - },
335   - {
336   - type: "icon",
337   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
338   - size: "sm",
339   - },
340   - {
341   - type: "icon",
342   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png",
343   - size: "sm",
344   - },
345   - {
346   - type: "text",
347   - text: "4.0",
348   - size: "sm",
349   - color: "#999999",
350   - flex: 0,
351   - margin: "md",
352   - contents: [],
353   - },
354   - ],
355   - },
356   - {
357   - type: "box",
358   - layout: "vertical",
359   - spacing: "sm",
360   - margin: "lg",
361   - contents: [
362   - {
363   - type: "box",
364   - layout: "baseline",
365   - spacing: "sm",
366   - contents: [
367   - {
368   - type: "text",
369   - text: "Date",
370   - size: "sm",
371   - color: "#AAAAAA",
372   - flex: 1,
373   - contents: [],
374   - },
375   - {
376   - type: "text",
377   - text: "Monday 25, 9:00PM",
378   - size: "sm",
379   - color: "#666666",
380   - flex: 4,
381   - wrap: true,
382   - contents: [],
383   - },
384   - ],
385   - },
386   - {
387   - type: "box",
388   - layout: "baseline",
389   - spacing: "sm",
390   - contents: [
391   - {
392   - type: "text",
393   - text: "Place",
394   - size: "sm",
395   - color: "#AAAAAA",
396   - flex: 1,
397   - contents: [],
398   - },
399   - {
400   - type: "text",
401   - text: "7 Floor, No.3",
402   - size: "sm",
403   - color: "#666666",
404   - flex: 4,
405   - wrap: true,
406   - contents: [],
407   - },
408   - ],
409   - },
410   - {
411   - type: "box",
412   - layout: "baseline",
413   - spacing: "sm",
414   - contents: [
415   - {
416   - type: "text",
417   - text: "Seats",
418   - size: "sm",
419   - color: "#AAAAAA",
420   - flex: 1,
421   - contents: [],
422   - },
423   - {
424   - type: "text",
425   - text: "C Row, 18 Seat",
426   - size: "sm",
427   - color: "#666666",
428   - flex: 4,
429   - wrap: true,
430   - contents: [],
431   - },
432   - ],
433   - },
434   - ],
435   - },
436   - {
437   - type: "box",
438   - layout: "vertical",
439   - margin: "xxl",
440   - contents: [
441   - {
442   - type: "spacer",
443   - },
444   - {
445   - type: "image",
446   - url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/linecorp_code_withborder.png",
447   - size: "xl",
448   - aspectMode: "cover",
449   - },
450   - {
451   - type: "text",
452   - text: "You can enter the theater by using this code instead of a ticket",
453   - size: "xs",
454   - color: "#AAAAAA",
455   - margin: "xxl",
456   - wrap: true,
457   - contents: [],
458   - },
459   - ],
460   - },
461   - ],
462   - },
463   - },
464   - },
465   -
466   -
467   -
468   - cat: {
469   - type: "bubble",
470   - direction: "ltr",
471   - header: {
472   - type: "box",
473   - layout: "vertical",
474   - contents: [
475   - {
476   - type: "text",
477   - text: "แมว",
478   - align: "center",
479   - contents: [],
480   - },
481   - ],
482   - },
483   - hero: {
484   - type: "image",
485   - url: "https://static.trueplookpanya.com/tppy/member/m_545000_547500/545994/cms/images/2019-Q3/แมว9ชีวิต.jpg",
486   - size: "full",
487   - aspectRatio: "1.51:1",
488   - aspectMode: "fit",
489   - },
490   - body: {
491   - type: "box",
492   - layout: "vertical",
493   - contents: [
494   - {
495   - type: "text",
496   - text: "คำอธิบาย",
497   - align: "center",
498   - contents: [],
499   - },
500   - ],
501   - },
502   - footer: {
503   - type: "box",
504   - layout: "horizontal",
505   - contents: [
506   - {
507   - type: "button",
508   - action: {
509   - type: "uri",
510   - label: "ดูรูปแมวชัดๆ",
511   - uri: "https://static.trueplookpanya.com/tppy/member/m_545000_547500/545994/cms/images/2019-Q3/แมว9ชีวิต.jpg",
512   - },
513   - },
514   - ],
515   - },
516   - },
517   -
518   - location: {
519   - type: "text", // ①
520   - text: "Select your favorite food category or send me your location!",
521   - quickReply: {
522   - // ②
523   - items: [
524   - {
525   - type: "action", // ③
526   - imageUrl: "https://example.com/sushi.png",
527   - action: {
528   - type: "message",
529   - label: "Sushi",
530   - text: "Sushi",
531   - },
532   - },
533   - {
534   - type: "action",
535   - imageUrl: "https://example.com/tempura.png",
536   - action: {
537   - type: "message",
538   - label: "Tempura",
539   - text: "Tempura",
540   - },
541   - },
542   - {
543   - type: "action", // ④
544   - action: {
545   - type: "location",
546   - label: "Send location",
547   - },
548   - },
549   - ],
550   - },
551   - },
552   - };
553   -};
services/ContentService.js 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +
  2 +const flexMsg = require("./flexMsg");
  3 +const genMsgContent = flexMsg.GenContentFlex;
  4 +const flexs = flexMsg.flexs;
  5 +
  6 +
  7 +const ContentService = {
  8 + mockText: () => {
  9 + return {
  10 + flex0: flexs.flex0,
  11 + flex1: flexs.flex1,
  12 +
  13 + bub1: flexs.bub1,
  14 + bub2: flexs.bub2,
  15 + bub3: flexs.bub3,
  16 + bub4: flexs.bub4,
  17 + bub5: flexs.bub5,
  18 + bub6: flexs.bub6,
  19 + };
  20 + },
  21 +};
  22 +
  23 +module.exports = ContentService;
... ...
services/LineService.js 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +const axios = require("axios").default;
  2 +const headers = {
  3 + Authorization:
  4 + "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  5 + "Content-Type": "application/json",
  6 +};
  7 +
  8 +const LineService = {
  9 + Broadcast: async (messages) => {
  10 + console.log("");
  11 + return new Promise(async (resolve, reject) => {
  12 + let URL = "https://api.line.me/v2/bot/message/broadcast";
  13 + let payload = { messages: messages };
  14 + try {
  15 + let res = await axios.post(URL, payload, {
  16 + headers: headers,
  17 + });
  18 + // console.log("res ::", res);
  19 + resolve(res);
  20 + } catch (e) {
  21 + console.log("bbb!");
  22 + console.log("Error ::", e);
  23 + reject(null);
  24 + }
  25 + });
  26 + },
  27 +};
  28 +
  29 +module.exports = LineService;
... ...
services/flexMsg.js 0 → 100644
... ... @@ -0,0 +1,749 @@
  1 +const GenContentFlex = (content, text = "0") => {
  2 + return {
  3 + type: "flex",
  4 + altText: "GenContentFlex!" + text,
  5 + contents: content,
  6 + };
  7 +};
  8 +
  9 +const flexs = {
  10 + flex0: {
  11 + type: "flex",
  12 + altText: "this is a flex message",
  13 + contents: {
  14 + type: "bubble",
  15 + body: {
  16 + type: "box",
  17 + layout: "vertical",
  18 + contents: [
  19 + {
  20 + type: "text",
  21 + text: "hello",
  22 + },
  23 + {
  24 + type: "text",
  25 + text: "world",
  26 + },
  27 + ],
  28 + },
  29 + },
  30 + },
  31 + flex1: GenContentFlex({
  32 + type: "bubble",
  33 + body: {
  34 + type: "box",
  35 + layout: "vertical",
  36 + contents: [
  37 + {
  38 + type: "text",
  39 + text: "hello",
  40 + },
  41 + {
  42 + type: "text",
  43 + text: "world",
  44 + },
  45 + ],
  46 + },
  47 + }),
  48 +
  49 + bub1: GenContentFlex({
  50 + type: "bubble",
  51 + direction: "ltr",
  52 + header: {
  53 + type: "box",
  54 + layout: "vertical",
  55 + contents: [
  56 + {
  57 + type: "text",
  58 + text: "Header",
  59 + align: "center",
  60 + contents: [],
  61 + },
  62 + ],
  63 + },
  64 + hero: {
  65 + type: "image",
  66 + url: "https://vos.line-scdn.net/bot-designer-template-images/bot-designer-icon.png",
  67 + size: "full",
  68 + aspectRatio: "1.51:1",
  69 + aspectMode: "fit",
  70 + },
  71 + body: {
  72 + type: "box",
  73 + layout: "vertical",
  74 + contents: [
  75 + {
  76 + type: "text",
  77 + text: "Body",
  78 + align: "center",
  79 + contents: [],
  80 + },
  81 + ],
  82 + },
  83 + footer: {
  84 + type: "box",
  85 + layout: "horizontal",
  86 + contents: [
  87 + {
  88 + type: "button",
  89 + action: {
  90 + type: "uri",
  91 + label: "Button",
  92 + uri: "https://linecorp.com",
  93 + },
  94 + },
  95 + ],
  96 + },
  97 + }),
  98 +
  99 + bub2: GenContentFlex({
  100 + type: "bubble",
  101 + hero: {
  102 + type: "image",
  103 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_1_cafe.png",
  104 + size: "full",
  105 + aspectRatio: "20:13",
  106 + aspectMode: "cover",
  107 + action: {
  108 + type: "uri",
  109 + label: "Line",
  110 + uri: "https://linecorp.com/",
  111 + },
  112 + },
  113 + body: {
  114 + type: "box",
  115 + layout: "vertical",
  116 + contents: [
  117 + {
  118 + type: "text",
  119 + text: "Brown Cafe",
  120 + weight: "bold",
  121 + size: "xl",
  122 + contents: [],
  123 + },
  124 + {
  125 + type: "box",
  126 + layout: "baseline",
  127 + margin: "md",
  128 + contents: [
  129 + {
  130 + type: "icon",
  131 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  132 + size: "sm",
  133 + },
  134 + {
  135 + type: "icon",
  136 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  137 + size: "sm",
  138 + },
  139 + {
  140 + type: "icon",
  141 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  142 + size: "sm",
  143 + },
  144 + {
  145 + type: "icon",
  146 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  147 + size: "sm",
  148 + },
  149 + {
  150 + type: "icon",
  151 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png",
  152 + size: "sm",
  153 + },
  154 + {
  155 + type: "text",
  156 + text: "4.0",
  157 + size: "sm",
  158 + color: "#999999",
  159 + flex: 0,
  160 + margin: "md",
  161 + contents: [],
  162 + },
  163 + ],
  164 + },
  165 + {
  166 + type: "box",
  167 + layout: "vertical",
  168 + spacing: "sm",
  169 + margin: "lg",
  170 + contents: [
  171 + {
  172 + type: "box",
  173 + layout: "baseline",
  174 + spacing: "sm",
  175 + contents: [
  176 + {
  177 + type: "text",
  178 + text: "Place",
  179 + size: "sm",
  180 + color: "#AAAAAA",
  181 + flex: 1,
  182 + contents: [],
  183 + },
  184 + {
  185 + type: "text",
  186 + text: "Miraina Tower, 4-1-6 Shinjuku, Tokyo",
  187 + size: "sm",
  188 + color: "#666666",
  189 + flex: 5,
  190 + wrap: true,
  191 + contents: [],
  192 + },
  193 + ],
  194 + },
  195 + {
  196 + type: "box",
  197 + layout: "baseline",
  198 + spacing: "sm",
  199 + contents: [
  200 + {
  201 + type: "text",
  202 + text: "Time",
  203 + size: "sm",
  204 + color: "#AAAAAA",
  205 + flex: 1,
  206 + contents: [],
  207 + },
  208 + {
  209 + type: "text",
  210 + text: "10:00 - 23:00",
  211 + size: "sm",
  212 + color: "#666666",
  213 + flex: 5,
  214 + wrap: true,
  215 + contents: [],
  216 + },
  217 + ],
  218 + },
  219 + ],
  220 + },
  221 + ],
  222 + },
  223 + footer: {
  224 + type: "box",
  225 + layout: "vertical",
  226 + flex: 0,
  227 + spacing: "sm",
  228 + contents: [
  229 + {
  230 + type: "button",
  231 + action: {
  232 + type: "uri",
  233 + label: "CALL",
  234 + uri: "https://linecorp.com",
  235 + },
  236 + height: "sm",
  237 + style: "link",
  238 + },
  239 + {
  240 + type: "button",
  241 + action: {
  242 + type: "uri",
  243 + label: "WEBSITE",
  244 + uri: "https://linecorp.com",
  245 + },
  246 + height: "sm",
  247 + style: "link",
  248 + },
  249 + {
  250 + type: "spacer",
  251 + size: "sm",
  252 + },
  253 + ],
  254 + },
  255 + }),
  256 + bub3: GenContentFlex({
  257 + type: "bubble",
  258 + header: {
  259 + type: "box",
  260 + layout: "horizontal",
  261 + contents: [
  262 + {
  263 + type: "text",
  264 + text: "NEWS DIGEST",
  265 + weight: "bold",
  266 + size: "sm",
  267 + color: "#AAAAAA",
  268 + contents: [],
  269 + },
  270 + ],
  271 + },
  272 + hero: {
  273 + type: "image",
  274 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_4_news.png",
  275 + size: "full",
  276 + aspectRatio: "20:13",
  277 + aspectMode: "cover",
  278 + action: {
  279 + type: "uri",
  280 + label: "Action",
  281 + uri: "https://linecorp.com/",
  282 + },
  283 + },
  284 + body: {
  285 + type: "box",
  286 + layout: "horizontal",
  287 + spacing: "md",
  288 + contents: [
  289 + {
  290 + type: "box",
  291 + layout: "vertical",
  292 + flex: 1,
  293 + contents: [
  294 + {
  295 + type: "image",
  296 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/02_1_news_thumbnail_1.png",
  297 + gravity: "bottom",
  298 + size: "sm",
  299 + aspectRatio: "4:3",
  300 + aspectMode: "cover",
  301 + },
  302 + {
  303 + type: "image",
  304 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/02_1_news_thumbnail_2.png",
  305 + margin: "md",
  306 + size: "sm",
  307 + aspectRatio: "4:3",
  308 + aspectMode: "cover",
  309 + },
  310 + ],
  311 + },
  312 + {
  313 + type: "box",
  314 + layout: "vertical",
  315 + flex: 2,
  316 + contents: [
  317 + {
  318 + type: "text",
  319 + text: "7 Things to Know for Today",
  320 + size: "xs",
  321 + flex: 1,
  322 + gravity: "top",
  323 + contents: [],
  324 + },
  325 + {
  326 + type: "separator",
  327 + },
  328 + {
  329 + type: "text",
  330 + text: "Hay fever goes wild",
  331 + size: "xs",
  332 + flex: 2,
  333 + gravity: "center",
  334 + contents: [],
  335 + },
  336 + {
  337 + type: "separator",
  338 + },
  339 + {
  340 + type: "text",
  341 + text: "LINE Pay Begins Barcode Payment Service",
  342 + size: "xs",
  343 + flex: 2,
  344 + gravity: "center",
  345 + contents: [],
  346 + },
  347 + {
  348 + type: "separator",
  349 + },
  350 + {
  351 + type: "text",
  352 + text: "LINE Adds LINE Wallet",
  353 + size: "xs",
  354 + flex: 1,
  355 + gravity: "bottom",
  356 + contents: [],
  357 + },
  358 + ],
  359 + },
  360 + ],
  361 + },
  362 + footer: {
  363 + type: "box",
  364 + layout: "horizontal",
  365 + contents: [
  366 + {
  367 + type: "button",
  368 + action: {
  369 + type: "uri",
  370 + label: "More",
  371 + uri: "https://linecorp.com",
  372 + },
  373 + },
  374 + ],
  375 + },
  376 + }),
  377 + bub4: GenContentFlex({
  378 + type: "bubble",
  379 + hero: {
  380 + type: "image",
  381 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_2_restaurant.png",
  382 + size: "full",
  383 + aspectRatio: "20:13",
  384 + aspectMode: "cover",
  385 + action: {
  386 + type: "uri",
  387 + label: "Action",
  388 + uri: "https://linecorp.com",
  389 + },
  390 + },
  391 + body: {
  392 + type: "box",
  393 + layout: "vertical",
  394 + spacing: "md",
  395 + action: {
  396 + type: "uri",
  397 + label: "Action",
  398 + uri: "https://linecorp.com",
  399 + },
  400 + contents: [
  401 + {
  402 + type: "text",
  403 + text: "Brown's Burger",
  404 + weight: "bold",
  405 + size: "xl",
  406 + contents: [],
  407 + },
  408 + {
  409 + type: "box",
  410 + layout: "vertical",
  411 + spacing: "sm",
  412 + contents: [
  413 + {
  414 + type: "box",
  415 + layout: "baseline",
  416 + contents: [
  417 + {
  418 + type: "icon",
  419 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/restaurant_regular_32.png",
  420 + },
  421 + {
  422 + type: "text",
  423 + text: "$10.5",
  424 + weight: "bold",
  425 + margin: "sm",
  426 + contents: [],
  427 + },
  428 + {
  429 + type: "text",
  430 + text: "400kcl",
  431 + size: "sm",
  432 + color: "#AAAAAA",
  433 + align: "end",
  434 + contents: [],
  435 + },
  436 + ],
  437 + },
  438 + {
  439 + type: "box",
  440 + layout: "baseline",
  441 + contents: [
  442 + {
  443 + type: "icon",
  444 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/restaurant_large_32.png",
  445 + },
  446 + {
  447 + type: "text",
  448 + text: "$15.5",
  449 + weight: "bold",
  450 + flex: 0,
  451 + margin: "sm",
  452 + contents: [],
  453 + },
  454 + {
  455 + type: "text",
  456 + text: "550kcl",
  457 + size: "sm",
  458 + color: "#AAAAAA",
  459 + align: "end",
  460 + contents: [],
  461 + },
  462 + ],
  463 + },
  464 + ],
  465 + },
  466 + {
  467 + type: "text",
  468 + text: "Sauce, Onions, Pickles, Lettuce & Cheese",
  469 + size: "xxs",
  470 + color: "#AAAAAA",
  471 + wrap: true,
  472 + contents: [],
  473 + },
  474 + ],
  475 + },
  476 + footer: {
  477 + type: "box",
  478 + layout: "vertical",
  479 + contents: [
  480 + {
  481 + type: "spacer",
  482 + size: "xxl",
  483 + },
  484 + {
  485 + type: "button",
  486 + action: {
  487 + type: "uri",
  488 + label: "Add to Cart",
  489 + uri: "https://linecorp.com",
  490 + },
  491 + color: "#905C44",
  492 + style: "primary",
  493 + },
  494 + ],
  495 + },
  496 + }),
  497 + bub5: GenContentFlex({
  498 + type: "bubble",
  499 + hero: {
  500 + type: "image",
  501 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_3_movie.png",
  502 + size: "full",
  503 + aspectRatio: "20:13",
  504 + aspectMode: "cover",
  505 + action: {
  506 + type: "uri",
  507 + label: "Action",
  508 + uri: "https://linecorp.com/",
  509 + },
  510 + },
  511 + body: {
  512 + type: "box",
  513 + layout: "vertical",
  514 + spacing: "md",
  515 + contents: [
  516 + {
  517 + type: "text",
  518 + text: "BROWN'S ADVENTURE\nIN MOVIE",
  519 + weight: "bold",
  520 + size: "xl",
  521 + gravity: "center",
  522 + wrap: true,
  523 + contents: [],
  524 + },
  525 + {
  526 + type: "box",
  527 + layout: "baseline",
  528 + margin: "md",
  529 + contents: [
  530 + {
  531 + type: "icon",
  532 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  533 + size: "sm",
  534 + },
  535 + {
  536 + type: "icon",
  537 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  538 + size: "sm",
  539 + },
  540 + {
  541 + type: "icon",
  542 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  543 + size: "sm",
  544 + },
  545 + {
  546 + type: "icon",
  547 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
  548 + size: "sm",
  549 + },
  550 + {
  551 + type: "icon",
  552 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png",
  553 + size: "sm",
  554 + },
  555 + {
  556 + type: "text",
  557 + text: "4.0",
  558 + size: "sm",
  559 + color: "#999999",
  560 + flex: 0,
  561 + margin: "md",
  562 + contents: [],
  563 + },
  564 + ],
  565 + },
  566 + {
  567 + type: "box",
  568 + layout: "vertical",
  569 + spacing: "sm",
  570 + margin: "lg",
  571 + contents: [
  572 + {
  573 + type: "box",
  574 + layout: "baseline",
  575 + spacing: "sm",
  576 + contents: [
  577 + {
  578 + type: "text",
  579 + text: "Date",
  580 + size: "sm",
  581 + color: "#AAAAAA",
  582 + flex: 1,
  583 + contents: [],
  584 + },
  585 + {
  586 + type: "text",
  587 + text: "Monday 25, 9:00PM",
  588 + size: "sm",
  589 + color: "#666666",
  590 + flex: 4,
  591 + wrap: true,
  592 + contents: [],
  593 + },
  594 + ],
  595 + },
  596 + {
  597 + type: "box",
  598 + layout: "baseline",
  599 + spacing: "sm",
  600 + contents: [
  601 + {
  602 + type: "text",
  603 + text: "Place",
  604 + size: "sm",
  605 + color: "#AAAAAA",
  606 + flex: 1,
  607 + contents: [],
  608 + },
  609 + {
  610 + type: "text",
  611 + text: "7 Floor, No.3",
  612 + size: "sm",
  613 + color: "#666666",
  614 + flex: 4,
  615 + wrap: true,
  616 + contents: [],
  617 + },
  618 + ],
  619 + },
  620 + {
  621 + type: "box",
  622 + layout: "baseline",
  623 + spacing: "sm",
  624 + contents: [
  625 + {
  626 + type: "text",
  627 + text: "Seats",
  628 + size: "sm",
  629 + color: "#AAAAAA",
  630 + flex: 1,
  631 + contents: [],
  632 + },
  633 + {
  634 + type: "text",
  635 + text: "C Row, 18 Seat",
  636 + size: "sm",
  637 + color: "#666666",
  638 + flex: 4,
  639 + wrap: true,
  640 + contents: [],
  641 + },
  642 + ],
  643 + },
  644 + ],
  645 + },
  646 + {
  647 + type: "box",
  648 + layout: "vertical",
  649 + margin: "xxl",
  650 + contents: [
  651 + {
  652 + type: "spacer",
  653 + },
  654 + {
  655 + type: "image",
  656 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/linecorp_code_withborder.png",
  657 + size: "xl",
  658 + aspectMode: "cover",
  659 + },
  660 + {
  661 + type: "text",
  662 + text: "You can enter the theater by using this code instead of a ticket",
  663 + size: "xs",
  664 + color: "#AAAAAA",
  665 + margin: "xxl",
  666 + wrap: true,
  667 + contents: [],
  668 + },
  669 + ],
  670 + },
  671 + ],
  672 + },
  673 + }),
  674 + bub6: GenContentFlex({
  675 + type: "bubble",
  676 + hero: {
  677 + type: "image",
  678 + url: "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_5_carousel.png",
  679 + size: "full",
  680 + aspectRatio: "20:13",
  681 + aspectMode: "cover",
  682 + },
  683 + body: {
  684 + type: "box",
  685 + layout: "vertical",
  686 + spacing: "sm",
  687 + contents: [
  688 + {
  689 + type: "text",
  690 + text: "Arm Chair, White",
  691 + weight: "bold",
  692 + size: "xl",
  693 + wrap: true,
  694 + contents: [],
  695 + },
  696 + {
  697 + type: "box",
  698 + layout: "baseline",
  699 + contents: [
  700 + {
  701 + type: "text",
  702 + text: "$49",
  703 + weight: "bold",
  704 + size: "xl",
  705 + flex: 0,
  706 + wrap: true,
  707 + contents: [],
  708 + },
  709 + {
  710 + type: "text",
  711 + text: ".99",
  712 + weight: "bold",
  713 + size: "sm",
  714 + flex: 0,
  715 + wrap: true,
  716 + contents: [],
  717 + },
  718 + ],
  719 + },
  720 + ],
  721 + },
  722 + footer: {
  723 + type: "box",
  724 + layout: "vertical",
  725 + spacing: "sm",
  726 + contents: [
  727 + {
  728 + type: "button",
  729 + action: {
  730 + type: "uri",
  731 + label: "Add to Cart",
  732 + uri: "https://linecorp.com",
  733 + },
  734 + style: "primary",
  735 + },
  736 + {
  737 + type: "button",
  738 + action: {
  739 + type: "uri",
  740 + label: "Add to wishlist",
  741 + uri: "https://linecorp.com",
  742 + },
  743 + },
  744 + ],
  745 + },
  746 + }),
  747 +};
  748 +
  749 +module.exports = { GenContentFlex, flexs };
... ...