Commit b9184255546f0bae16d23bc98494c70e1d210276

Authored by Surasit Yerpui
1 parent f4bbcb63
Exists in master

update Code Rewebhook

config.json
1 1 {
2   - "port" : "3000",
  2 + "port" : "4000",
3 3 "channelAccessToken": "be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
4 4 "channelSecret": "df6ab26f85f5130ebf5b546f3a5a4b7f"
5 5 }
6 6 \ No newline at end of file
... ...
index dynamic.js 0 → 100644
... ... @@ -0,0 +1,326 @@
  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 +const ContentService = require("./services/ContentService");
  13 +const LineService = require("./services/LineService");
  14 +
  15 +// create LINE SDK client
  16 +const client = new line.Client(config);
  17 +
  18 +const app = express();
  19 +
  20 +const configLine = [
  21 + {
  22 + lineOA_name: "น้องปุ้ย OA",
  23 + webhook: "/webhook1",
  24 + lineOA: {
  25 + channelAccessToken:
  26 + "be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  27 + channelSecret: "df6ab26f85f5130ebf5b546f3a5a4b7f",
  28 + },
  29 + },
  30 + {
  31 + lineOA_name: "ปุ้ย OA2",
  32 + webhook: "/webhook2",
  33 + lineOA: {
  34 + channelAccessToken:
  35 + "NYy1k9OM7e/T7PgabnjafdqcxbRc58m7/K4A3kuNCVkoPxhBoZ/Jvg9gaarsqySG2BtvsoQcVgE4yulPaT1WJ7qTUyBaqegae+r8uh0oWrZO93zXIUILn3bOGUFtLmVFcTuBfRKgFHCaJhi1+wFQ6QdB04t89/1O/w1cDnyilFU=",
  36 + channelSecret: "58690bf9c646cb2535894e07c387c0aa",
  37 + },
  38 + },
  39 + {
  40 + lineOA_name: "น้องปุ้ย OA3",
  41 + lineOA: {
  42 + channelAccessToken:
  43 + "4GuNsc3jKQuohzyD81dWtHu2CB3Lay1WJjfS8ZRvODbTmnK0W9U5Elra2JEFbHeHp+X58qfXlEAMbHLlI9ACklppS06qp3Kd8/y6SyYrQVsyIozyG8Taj/OZtvPrlz9I1NoSnTxRh+4iuntIB9792QdB04t89/1O/w1cDnyilFU=",
  44 + channelSecret: "44332b03dee7c5631c7954b2e5e64f84",
  45 + },
  46 + webhook: "/webhook3",
  47 + },
  48 +];
  49 +
  50 +for (let cl of configLine) {
  51 + app.post(cl.webhook,line.middleware(cl.lineOA), (req, res) => {
  52 + const clientx = new line.Client(cl.lineOA);
  53 + if (!Array.isArray(req.body.events)) {
  54 + return res.status(500).end();
  55 + }
  56 + console.log('to lineOA :',cl.lineOA_name);
  57 + console.log('-------------------------------')
  58 + console.log("req.body.events !", req.body.events);
  59 +
  60 + Promise.all(
  61 + req.body.events.map((event) => {
  62 + console.log("event", event);
  63 + // check verify webhook event
  64 + if (
  65 + event.replyToken === "00000000000000000000000000000000" ||
  66 + event.replyToken === "ffffffffffffffffffffffffffffffff"
  67 + ) {
  68 + return;
  69 + }
  70 + return replyHookBasic(event,clientx);
  71 + })
  72 + )
  73 + .then(() => res.end())
  74 + .catch((err) => {
  75 + console.error(err);
  76 + res.status(500).end();
  77 + });
  78 +
  79 + });
  80 +}
  81 +
  82 +// webhook callback
  83 +let debugMode = false;
  84 +app.use("/webhook", line.middleware(config));
  85 +app.post("/webhook", (req, res) => {
  86 + // req.body.events should be an array of events
  87 + if (!Array.isArray(req.body.events)) {
  88 + return res.status(500).end();
  89 + }
  90 + console.log("req.body.events !", req.body.events);
  91 + // handle events separately
  92 + Promise.all(
  93 + req.body.events.map((event) => {
  94 + console.log("event", event);
  95 + // check verify webhook event
  96 + if (
  97 + event.replyToken === "00000000000000000000000000000000" ||
  98 + event.replyToken === "ffffffffffffffffffffffffffffffff"
  99 + ) {
  100 + return;
  101 + }
  102 + return handleEvent(event);
  103 + })
  104 + )
  105 + .then(() => res.end())
  106 + .catch((err) => {
  107 + console.error(err);
  108 + res.status(500).end();
  109 + });
  110 +});
  111 +
  112 +const handleEvent = (event) => {
  113 + let payload = {
  114 + type: "text",
  115 + text: "Hello From PUI",
  116 + };
  117 +
  118 + if (event.type == "message" && event.message.type == "text") {
  119 + let selecttext = String(event.message.text).toLowerCase();
  120 +
  121 + let get_text = ContentService.mockText()[selecttext];
  122 + if (get_text) {
  123 + payload = get_text;
  124 + }
  125 + console.log("event.message.text ::", event.message.text);
  126 + if (event.message.text == "แจ้งซ่อม") {
  127 + const user_id = event.source.userId;
  128 + let sendNotiData = {
  129 + body: `ทำรายการแจ้งซ่อม`,
  130 + title: "SmartRMS For Condo",
  131 + };
  132 + let messx = {
  133 + type: "flex",
  134 + altText: "GenContentFlex!0",
  135 + contents: {
  136 + type: "bubble",
  137 + body: {
  138 + type: "box",
  139 + layout: "vertical",
  140 + spacing: "sm",
  141 + contents: [
  142 + {
  143 + type: "text",
  144 + text: sendNotiData.body,
  145 + weight: "bold",
  146 + size: "xl",
  147 + wrap: true,
  148 + contents: [],
  149 + },
  150 + {
  151 + type: "box",
  152 + layout: "baseline",
  153 + contents: [
  154 + {
  155 + type: "text",
  156 + text: sendNotiData.title,
  157 + weight: "bold",
  158 + size: "xl",
  159 + flex: 0,
  160 + wrap: true,
  161 + contents: [],
  162 + },
  163 + ],
  164 + },
  165 + ],
  166 + },
  167 + footer: {
  168 + type: "box",
  169 + layout: "vertical",
  170 + spacing: "sm",
  171 + contents: [
  172 + {
  173 + type: "button",
  174 + action: {
  175 + type: "uri",
  176 + label: "ไปแจ้งซ่อมได้ที่นี่",
  177 + uri: `http://localhost:4200/fix-alert/${user_id}`,
  178 + },
  179 + style: "primary",
  180 + },
  181 + ],
  182 + },
  183 + },
  184 + };
  185 +
  186 + payload = messx;
  187 + }
  188 + } else {
  189 + payload.text = "Other Message =>>>" + JSON.stringify(event);
  190 + }
  191 +
  192 + console.log("SEND TO ==> " + JSON.stringify(payload));
  193 +
  194 + return client.replyMessage(event.replyToken, payload);
  195 +};
  196 +
  197 +app.use(bodyParser.json());
  198 +app.get("/", (req, res) => {
  199 + res.json({ line: "ok" });
  200 +});
  201 +
  202 +app.post("/push", (req, res) => {
  203 + let body = req.body;
  204 + let { user_id, message } = body;
  205 + console.log("push =>> body ::", body);
  206 + if (!message) {
  207 + message = {
  208 + type: "text",
  209 + text: `Push Message! to ${user_id}`,
  210 + };
  211 + }
  212 + client.pushMessage(user_id, message);
  213 + res.json(message);
  214 +});
  215 +
  216 +app.post("/multicast", (req, res) => {
  217 + let body = req.body;
  218 + let { user_ids } = body;
  219 + console.log("body ::", body);
  220 + let message = [
  221 + {
  222 + type: "text",
  223 + text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
  224 + },
  225 + {
  226 + type: "text",
  227 + text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
  228 + },
  229 + ];
  230 +
  231 + client.multicast(user_ids, message);
  232 + res.json(message);
  233 +});
  234 +
  235 +app.post("/multicast", (req, res) => {
  236 + let body = req.body;
  237 + let { user_ids } = body;
  238 + console.log("body ::", body);
  239 + let message = [
  240 + {
  241 + type: "text",
  242 + text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
  243 + },
  244 + {
  245 + type: "text",
  246 + text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
  247 + },
  248 + ];
  249 +
  250 + client.multicast(user_ids, message);
  251 + res.json(message);
  252 +});
  253 +
  254 +app.post("/broadcast", async (req, res) => {
  255 + let body = req.body;
  256 + let { messages } = body;
  257 + console.log("body ::", body);
  258 +
  259 + let resx = await LineService.Message.Broadcast(messages);
  260 + console.log("resx.data", resx.data);
  261 +
  262 + res.json({ message: "OK" });
  263 +});
  264 +
  265 +app.post("/save", bodyParser.json(), async (req, res) => {
  266 + console.log("saveFile!");
  267 + try {
  268 + const downloadFile = function (uri, filename, callback) {
  269 + request.head(uri, function (err, res, body) {
  270 + console.log("content-type:", res.headers["content-type"]);
  271 + console.log("content-length:", res.headers["content-length"]);
  272 + console.log("Content-Type:", res.headers["Content-Type"]);
  273 + console.log("res.headers ::", res.headers);
  274 +
  275 + request(uri, {
  276 + headers: {
  277 + Authorization:
  278 + "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  279 + },
  280 + })
  281 + .pipe(fs.createWriteStream(filename))
  282 + .on("close", callback);
  283 + });
  284 + };
  285 +
  286 + let unquie_file = moment().format("YYYY-MM-DD_HHmmssss");
  287 + let file_name = `filesave_${unquie_file}`;
  288 + let message_id = req.body.message_id;
  289 + let URI = `https://api-data.line.me/v2/bot/message/${message_id}/content`;
  290 + console.log("message_id ::", message_id);
  291 + console.log("file_name ::", file_name);
  292 +
  293 + axios
  294 + .get(URI, {
  295 + headers: {
  296 + Authorization:
  297 + "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  298 + },
  299 + })
  300 + .then(function (response) {
  301 + // handle success
  302 + console.log("axios =>>", response.headers["content-type"]);
  303 + let sp = response.headers["content-type"].split("/");
  304 + let type = sp[sp.length - 1];
  305 + let full_file_name = file_name + "." + type;
  306 + console.log("full_file_name =", full_file_name);
  307 + downloadFile(URI, full_file_name, function () {
  308 + console.log("done!");
  309 + res.json({ LoadFlieName: "Success" });
  310 + });
  311 + })
  312 + .catch(function (error) {
  313 + // handle error
  314 + console.log(error);
  315 + console.error("errorxx ::", error);
  316 + res.json({ error: "error" });
  317 + });
  318 + } catch (error) {
  319 + console.error("errorxx ::", error);
  320 + }
  321 +});
  322 +
  323 +const port = config.port;
  324 +app.listen(port, () => {
  325 + console.log(`listening on ${port}`);
  326 +});
... ...
index.js
1   -"use strict";
2   -
3   -const line = require("@line/bot-sdk");
  1 +const https = require("https");
4 2 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");
  3 +const app = express();
  4 +const PORT = process.env.PORT || 3000;
  5 +const axios = require("axios").default;
  6 +const TOKEN =
  7 + "NYy1k9OM7e/T7PgabnjafdqcxbRc58m7/K4A3kuNCVkoPxhBoZ/Jvg9gaarsqySG2BtvsoQcVgE4yulPaT1WJ7qTUyBaqegae+r8uh0oWrZO93zXIUILn3bOGUFtLmVFcTuBfRKgFHCaJhi1+wFQ6QdB04t89/1O/w1cDnyilFU=";
  8 +
  9 +app.use(express.json());
  10 +app.use(
  11 + express.urlencoded({
  12 + extended: true,
  13 + })
  14 +);
  15 +
11 16 const flexMsg = require("./flexMsg");
12   -const ContentService = require("./services/ContentService");
13   -const LineService = require("./services/LineService");
14 17  
15   -// create LINE SDK client
16   -const client = new line.Client(config);
  18 +app.get("/", (req, res) => {
  19 + res.sendStatus(200);
  20 +});
  21 +
  22 +app.post("/Rewebhook", async (req, res) => {
  23 + console.log("Rewebhook ::", req.body);
17 24  
18   -const app = express();
  25 + res.json({ OK: req.body });
19 26  
20   -// webhook callback
21   -let debugMode = false;
22   -app.use("/webhook", line.middleware(config));
23   -app.post("/webhook", (req, res) => {
24   - // req.body.events should be an array of events
25 27 if (!Array.isArray(req.body.events)) {
26 28 return res.status(500).end();
27 29 }
28   - console.log('req.body.events !',req.body.events)
29   - // handle events separately
  30 +
30 31 Promise.all(
31 32 req.body.events.map((event) => {
32 33 console.log("event", event);
... ... @@ -37,7 +38,7 @@ app.post("/webhook", (req, res) => {
37 38 ) {
38 39 return;
39 40 }
40   - return handleEvent(event);
  41 + return handleEvent(event, req.body);
41 42 })
42 43 )
43 44 .then(() => res.end())
... ... @@ -47,154 +48,219 @@ app.post("/webhook", (req, res) => {
47 48 });
48 49 });
49 50  
50   -const handleEvent = (event) => {
51   - let payload = {
52   - type: "text",
53   - text: "Hello From PUI",
  51 +const handleEvent = async (event, body) => {
  52 + const { Channel_access_token } = body;
  53 + const { replyToken } = event;
  54 + const _headers = {
  55 + Authorization: "Bearer " + Channel_access_token,
  56 + "Content-Type": "application/json",
54 57 };
  58 + const messages = [
  59 + {
  60 + type: "text",
  61 + text: "Hello, user",
  62 + },
  63 + {
  64 + type: "text",
  65 + text: "May I help you?",
  66 + },
  67 + ];
  68 +
  69 + let template_text = null;
55 70  
56   - if (event.type == "message" && event.message.type == "text") {
57   - let selecttext = String(event.message.text).toLowerCase();
58   - let get_text = ContentService.mockText()[selecttext];
  71 + if (event.message.type == "text") {
  72 + let selecttext = tolow(event.message.text);
  73 + let get_text = mockText()[selecttext];
59 74 if (get_text) {
60   - payload = get_text;
  75 + template_text = get_text;
61 76 }
62 77 } else {
63   - payload.text = "Other Message =>>>" + JSON.stringify(event);
  78 + template_text.text = "Other Message =>>>" + JSON.stringify(event);
64 79 }
65 80  
66   - console.log("SEND TO ==> " + JSON.stringify(payload));
  81 + console.log("template_text", template_text);
67 82  
68   - return client.replyMessage(event.replyToken, payload);
  83 + let URL = "https://api.line.me/v2/bot/message/reply";
  84 + let payload = {
  85 + replyToken: replyToken,
  86 + messages: template_text ? [template_text] : messages,
  87 + };
  88 + console.log("payload ::", payload);
  89 + try {
  90 + let res = await axios.post(URL, payload, {
  91 + headers: _headers,
  92 + });
  93 + console.log("res ::", res.data);
  94 + } catch (e) {
  95 + console.log("Error Reply::", e);
  96 + }
69 97 };
70 98  
71   -app.use(bodyParser.json());
72   -app.get("/", (req, res) => {
73   - res.json({ line: "ok" });
74   -});
  99 +const tolow = (str) => {
  100 + return str.toLowerCase();
  101 +};
75 102  
76   -app.post("/push", (req, res) => {
77   - let body = req.body;
78   - let { user_id, message } = body;
79   - console.log("push =>> body ::", body);
80   - if (!message) {
81   - message = {
82   - type: "text",
83   - text: `Push Message! to ${user_id}`,
  103 +app.post("/webhook", function (req, res) {
  104 + res.send("HTTP POST request sent to the webhook URL!");
  105 + // If the user sends a message to your bot, send a reply message
  106 + console.log("req.body.events ::", req.body.events);
  107 +
  108 + if (req.body.events[0].type === "message") {
  109 + // Message data, must be stringified
  110 + const dataString = JSON.stringify({
  111 + replyToken: req.body.events[0].replyToken,
  112 + messages: [
  113 + {
  114 + type: "text",
  115 + text: "Hello, user",
  116 + },
  117 + {
  118 + type: "text",
  119 + text: "May I help you?",
  120 + },
  121 + ],
  122 + });
  123 +
  124 + // Request header
  125 + const headers = {
  126 + "Content-Type": "application/json",
  127 + Authorization: "Bearer " + TOKEN,
84 128 };
85   - }
86   - client.pushMessage(user_id, message);
87   - res.json(message);
88   -});
89 129  
90   -app.post("/multicast", (req, res) => {
91   - let body = req.body;
92   - let { user_ids } = body;
93   - console.log("body ::", body);
94   - let message = [
95   - {
96   - type: "text",
97   - text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
98   - },
99   - {
100   - type: "text",
101   - text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
102   - },
103   - ];
  130 + // Options to pass into the request
  131 + const webhookOptions = {
  132 + hostname: "api.line.me",
  133 + path: "/v2/bot/message/reply",
  134 + method: "POST",
  135 + headers: headers,
  136 + body: dataString,
  137 + };
104 138  
105   - client.multicast(user_ids, message);
106   - res.json(message);
107   -});
  139 + // Define request
  140 + const request = https.request(webhookOptions, (res) => {
  141 + res.on("data", (d) => {
  142 + process.stdout.write(d);
  143 + });
  144 + });
108 145  
109   -app.post("/multicast", (req, res) => {
110   - let body = req.body;
111   - let { user_ids } = body;
112   - console.log("body ::", body);
113   - let message = [
114   - {
115   - type: "text",
116   - text: `use multicast Message1! to ${JSON.stringify(user_ids)}`,
117   - },
118   - {
119   - type: "text",
120   - text: `use multicast Message2! to ${JSON.stringify(user_ids)}`,
121   - },
122   - ];
  146 + // Handle error
  147 + request.on("error", (err) => {
  148 + console.error(err);
  149 + });
123 150  
124   - client.multicast(user_ids, message);
125   - res.json(message);
  151 + // Send data
  152 + request.write(dataString);
  153 + request.end();
  154 + }
126 155 });
127 156  
128   -app.post("/broadcast", async (req, res) => {
129   - let body = req.body;
130   - let { messages } = body;
131   - console.log("body ::", body);
  157 +app.listen(PORT, () => {
  158 + console.log(`Example app listening at http://localhost:${PORT}`);
  159 +});
132 160  
133   - let resx = await LineService.Broadcast(messages);
134   - console.log("resx", resx);
  161 +const flexs = flexMsg.flexs;
135 162  
136   - res.json({ message: "OK" });
137   -});
  163 +const mockText = () => {
  164 + return {
  165 + flex0: flexs.flex0,
  166 + flex1: flexs.flex1,
138 167  
139   -app.post("/save", bodyParser.json(), async (req, res) => {
140   - console.log("saveFile!");
141   - try {
142   - const downloadFile = function (uri, filename, callback) {
143   - request.head(uri, function (err, res, body) {
144   - console.log("content-type:", res.headers["content-type"]);
145   - console.log("content-length:", res.headers["content-length"]);
146   - console.log("Content-Type:", res.headers["Content-Type"]);
147   - console.log("res.headers ::", res.headers);
148   -
149   - request(uri, {
150   - headers: {
151   - Authorization:
152   - "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
  168 + bub1: flexs.bub1,
  169 + bub2: flexs.bub2,
  170 + bub3: flexs.bub3,
  171 + bub4: flexs.bub4,
  172 + bub5: flexs.bub5,
  173 + bub6: flexs.bub6,
  174 + confirm: {
  175 + type: "template",
  176 + altText: "this is a confirm template",
  177 + template: {
  178 + type: "confirm",
  179 + text: "Are you sure?",
  180 + actions: [
  181 + {
  182 + type: "message",
  183 + label: "Yes",
  184 + text: "yes",
153 185 },
154   - })
155   - .pipe(fs.createWriteStream(filename))
156   - .on("close", callback);
157   - });
158   - };
159   -
160   - let unquie_file = moment().format("YYYY-MM-DD_HHmmssss");
161   - let file_name = `filesave_${unquie_file}`;
162   - let message_id = req.body.message_id;
163   - let URI = `https://api-data.line.me/v2/bot/message/${message_id}/content`;
164   - console.log("message_id ::", message_id);
165   - console.log("file_name ::", file_name);
166   -
167   - axios
168   - .get(URI, {
169   - headers: {
170   - Authorization:
171   - "Bearer be/XHjQ+gMoypZE78Us7hk0h6PA04TyfpQciMOq+B/OVPmumozdhGzYUwopDgsOMCM7RymTK8m++q20GSj3c6B7gZkgEmuGYEYPvc6j+4as6X5bu7tEg+KAZKMfBVDnk+ekpAorC7FMwVPyt2frGRQdB04t89/1O/w1cDnyilFU=",
172   - },
173   - })
174   - .then(function (response) {
175   - // handle success
176   - console.log("axios =>>", response.headers["content-type"]);
177   - let sp = response.headers["content-type"].split("/");
178   - let type = sp[sp.length - 1];
179   - let full_file_name = file_name + "." + type;
180   - console.log("full_file_name =", full_file_name);
181   - downloadFile(URI, full_file_name, function () {
182   - console.log("done!");
183   - res.json({ LoadFlieName: "Success" });
184   - });
185   - })
186   - .catch(function (error) {
187   - // handle error
188   - console.log(error);
189   - console.error("errorxx ::", error);
190   - res.json({ error: "error" });
191   - });
192   - } catch (error) {
193   - console.error("errorxx ::", error);
194   - }
195   -});
  186 + {
  187 + type: "message",
  188 + label: "No",
  189 + text: "no",
  190 + },
  191 + ],
  192 + },
  193 + },
  194 + location: {
  195 + type: "text", // ①
  196 + text: "Select your favorite food category or send me your location!",
  197 + quickReply: {
  198 + // ②
  199 + items: [
  200 + {
  201 + type: "action", // ③
  202 + imageUrl: "https://example.com/sushi.png",
  203 + action: {
  204 + type: "message",
  205 + label: "Sushi",
  206 + text: "Sushi",
  207 + },
  208 + },
  209 + {
  210 + type: "action",
  211 + imageUrl: "https://example.com/tempura.png",
  212 + action: {
  213 + type: "message",
  214 + label: "Tempura",
  215 + text: "Tempura",
  216 + },
  217 + },
  218 + {
  219 + type: "action", // ④
  220 + action: {
  221 + type: "location",
  222 + label: "Send location",
  223 + },
  224 + },
  225 + ],
  226 + },
  227 + },
196 228  
197   -const port = config.port;
198   -app.listen(port, () => {
199   - console.log(`listening on ${port}`);
200   -});
  229 + image_carousel: {
  230 + type: "template",
  231 + altText: "this is a image carousel template",
  232 + template: {
  233 + type: "image_carousel",
  234 + columns: [
  235 + {
  236 + imageUrl:
  237 + "https://image.sistacafe.com/images/uploads/summary/image/26097/cat-200313-020.jpg",
  238 + action: {
  239 + type: "postback",
  240 + label: "Buy",
  241 + data: "action=buy&itemid=111",
  242 + },
  243 + },
  244 + {
  245 + imageUrl:
  246 + "https://image.sistacafe.com/images/uploads/summary/image/26097/cat-200313-020.jpg",
  247 + action: {
  248 + type: "message",
  249 + label: "Yes",
  250 + text: "yes",
  251 + },
  252 + },
  253 + {
  254 + imageUrl:
  255 + "https://image.sistacafe.com/images/uploads/summary/image/26097/cat-200313-020.jpg",
  256 + action: {
  257 + type: "uri",
  258 + label: "View detail",
  259 + uri: "http://example.com/page/222",
  260 + },
  261 + },
  262 + ],
  263 + },
  264 + },
  265 + };
  266 +};
... ...
services/LineService.js
... ... @@ -6,23 +6,63 @@ const headers = {
6 6 };
7 7  
8 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   - });
  9 + Message: {
  10 + Broadcast: async (messages) => {
  11 + console.log("");
  12 + return new Promise(async (resolve, reject) => {
  13 + let URL = "https://api.line.me/v2/bot/message/broadcast";
  14 + let payload = { messages: messages };
  15 + try {
  16 + let res = await axios.post(URL, payload, {
  17 + headers: headers,
  18 + });
  19 + // console.log("res ::", res);
  20 + resolve(res);
  21 + } catch (e) {
  22 + console.log("bbb!");
  23 + console.log("Error ::", e);
  24 + reject(null);
  25 + }
  26 + });
  27 + },
  28 + Narrowcast: async (messages) => {
  29 + console.log("");
  30 + return new Promise(async (resolve, reject) => {
  31 + let URL = "https://api.line.me/v2/bot/message/narrowcast";
  32 + let payload = { messages: messages };
  33 + try {
  34 + let res = await axios.post(URL, payload, {
  35 + headers: headers,
  36 + });
  37 + // console.log("res ::", res);
  38 + resolve(res);
  39 + } catch (e) {
  40 + console.log("bbb!");
  41 + console.log("Error ::", e);
  42 + reject(null);
  43 + }
  44 + });
  45 + },
  46 + },
  47 + ManagingAudience: {
  48 + createAudience: async (messages) => {
  49 + console.log("");
  50 + return new Promise(async (resolve, reject) => {
  51 + let URL = "https://api.line.me/v2/bot/audienceGroup/upload";
  52 + let payload = { messages: messages };
  53 + try {
  54 + let res = await axios.post(URL, payload, {
  55 + headers: headers,
  56 + });
  57 + // console.log("res ::", res);
  58 + resolve(res);
  59 + } catch (e) {
  60 + console.log("bbb!");
  61 + console.log("Error ::", e);
  62 + reject(null);
  63 + }
  64 + });
  65 + }
26 66 },
27 67 };
28 68  
... ...
test.json
... ... @@ -3,49 +3,58 @@
3 3 "altText": "GenContentFlex!0",
4 4 "contents": {
5 5 "type": "bubble",
6   - "direction": "ltr",
7   - "header": {
8   - "type": "box",
9   - "layout": "vertical",
10   - "contents": [
11   - {
12   - "type": "text",
13   - "text": "Header",
14   - "align": "center",
15   - "contents": []
16   - }
17   - ]
18   - },
19   - "hero": {
20   - "type": "image",
21   - "url": "https://1417094351.rsc.cdn77.org/articles/1439/1438984/thumbnail/small.gif?3",
22   - "size": "full",
23   - "aspectRatio": "1.51:1",
24   - "aspectMode": "fit"
25   - },
26 6 "body": {
27 7 "type": "box",
28 8 "layout": "vertical",
  9 + "spacing": "sm",
29 10 "contents": [
30 11 {
31 12 "type": "text",
32   - "text": "Body",
33   - "align": "center",
  13 + "text": "Arm Chair, White",
  14 + "weight": "bold",
  15 + "size": "xl",
  16 + "wrap": true,
34 17 "contents": []
  18 + },
  19 + {
  20 + "type": "box",
  21 + "layout": "baseline",
  22 + "contents": [
  23 + {
  24 + "type": "text",
  25 + "text": "$49",
  26 + "weight": "bold",
  27 + "size": "xl",
  28 + "flex": 0,
  29 + "wrap": true,
  30 + "contents": []
  31 + },
  32 + {
  33 + "type": "text",
  34 + "text": ".99",
  35 + "weight": "bold",
  36 + "size": "sm",
  37 + "flex": 0,
  38 + "wrap": true,
  39 + "contents": []
  40 + }
  41 + ]
35 42 }
36 43 ]
37 44 },
38 45 "footer": {
39 46 "type": "box",
40   - "layout": "horizontal",
  47 + "layout": "vertical",
  48 + "spacing": "sm",
41 49 "contents": [
42 50 {
43 51 "type": "button",
44 52 "action": {
45 53 "type": "uri",
46   - "label": "Button",
  54 + "label": "Add to Cart",
47 55 "uri": "https://linecorp.com"
48   - }
  56 + },
  57 + "style": "primary"
49 58 }
50 59 ]
51 60 }
... ...