Commit eb28d472dfdd78993b47618c9e5bd8ab0920d8ac
1 parent
a8dde2dd
Exists in
master
update Service
Showing
7 changed files
with
1178 additions
and
902 deletions
Show diff stats
| @@ -0,0 +1,317 @@ | @@ -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,6 +9,8 @@ const fs = require("fs"); | ||
| 9 | const request = require("request"); | 9 | const request = require("request"); |
| 10 | const moment = require("moment"); | 10 | const moment = require("moment"); |
| 11 | const flexMsg = require("./flexMsg"); | 11 | const flexMsg = require("./flexMsg"); |
| 12 | +const ContentService = require("./services/ContentService"); | ||
| 13 | +const LineService = require("./services/LineService"); | ||
| 12 | 14 | ||
| 13 | // create LINE SDK client | 15 | // create LINE SDK client |
| 14 | const client = new line.Client(config); | 16 | const client = new line.Client(config); |
| @@ -43,18 +45,6 @@ app.post("/webhook", (req, res) => { | @@ -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 | const handleEvent = (event) => { | 48 | const handleEvent = (event) => { |
| 59 | let payload = { | 49 | let payload = { |
| 60 | type: "text", | 50 | type: "text", |
| @@ -62,8 +52,8 @@ const handleEvent = (event) => { | @@ -62,8 +52,8 @@ const handleEvent = (event) => { | ||
| 62 | }; | 52 | }; |
| 63 | 53 | ||
| 64 | if (event.message.type == "text") { | 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 | if (get_text) { | 57 | if (get_text) { |
| 68 | payload = get_text; | 58 | payload = get_text; |
| 69 | } | 59 | } |
| @@ -73,21 +63,73 @@ const handleEvent = (event) => { | @@ -73,21 +63,73 @@ const handleEvent = (event) => { | ||
| 73 | 63 | ||
| 74 | return client.replyMessage(event.replyToken, payload); | 64 | return client.replyMessage(event.replyToken, payload); |
| 75 | }; | 65 | }; |
| 76 | -app.use(bodyParser.json()); | ||
| 77 | 66 | ||
| 67 | +app.use(bodyParser.json()); | ||
| 78 | app.get("/", (req, res) => { | 68 | app.get("/", (req, res) => { |
| 79 | res.json({ line: "ok" }); | 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 | let message = { | 76 | let message = { |
| 84 | type: "text", | 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 | res.json(message); | 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 | app.post("/save", bodyParser.json(), async (req, res) => { | 133 | app.post("/save", bodyParser.json(), async (req, res) => { |
| 92 | console.log("saveFile!"); | 134 | console.log("saveFile!"); |
| 93 | try { | 135 | try { |
| @@ -146,172 +188,7 @@ app.post("/save", bodyParser.json(), async (req, res) => { | @@ -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 | const port = config.port; | 191 | const port = config.port; |
| 191 | app.listen(port, () => { | 192 | app.listen(port, () => { |
| 192 | console.log(`listening on ${port}`); | 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,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,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 | -}; |
| @@ -0,0 +1,23 @@ | @@ -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; |
| @@ -0,0 +1,29 @@ | @@ -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; |
| @@ -0,0 +1,749 @@ | @@ -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 }; |