@tiledesk/tiledesk-whatsapp-connector 0.1.42 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +95 -82
- package/package.json +1 -1
- package/template/configure.html +2 -2
- package/template/css/detail.css +22 -0
- package/template/css/error.css +67 -0
- package/template/detail.html +35 -12
- package/template/error.html +91 -0
- package/tiledesk/TiledeskAppsClient.js +1 -0
- package/tiledesk/TiledeskChannel.js +52 -1
- package/tiledesk/TiledeskWhatsappTranslator.js +20 -2
- package/template/old_configure.html +0 -206
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const pjson = require('./package.json');
|
|
|
10
10
|
const { v4: uuidv4 } = require('uuid');
|
|
11
11
|
const cors = require('cors');
|
|
12
12
|
var winston = require('./winston');
|
|
13
|
+
const url = require('url');
|
|
13
14
|
|
|
14
15
|
// tiledesk clients
|
|
15
16
|
//const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
@@ -65,12 +66,16 @@ router.get('/detail', async (req, res) => {
|
|
|
65
66
|
|
|
66
67
|
winston.verbose("(wab) /detail")
|
|
67
68
|
|
|
68
|
-
let
|
|
69
|
+
let project_id = req.query.project_id;
|
|
69
70
|
let token = req.query.token;
|
|
70
71
|
let app_id = req.query.app_id;
|
|
71
72
|
|
|
73
|
+
const tdChannel = new TiledeskChannel({ settings: { project_id: project_id, token: token }, API_URL: API_URL })
|
|
74
|
+
let isAvailable = await tdChannel.getProjectDetail();
|
|
75
|
+
winston.debug("(wab) app is available: ", isAvailable);
|
|
76
|
+
|
|
72
77
|
const appClient = new TiledeskAppsClient({ APPS_API_URL: APPS_API_URL });
|
|
73
|
-
let installation = await appClient.getInstallations(
|
|
78
|
+
let installation = await appClient.getInstallations(project_id, app_id);
|
|
74
79
|
|
|
75
80
|
let installed = false;
|
|
76
81
|
if (installation) {
|
|
@@ -81,10 +86,11 @@ router.get('/detail', async (req, res) => {
|
|
|
81
86
|
var template = handlebars.compile(html);
|
|
82
87
|
var replacements = {
|
|
83
88
|
app_version: pjson.version,
|
|
84
|
-
project_id:
|
|
89
|
+
project_id: project_id,
|
|
85
90
|
token: token,
|
|
86
91
|
app_id: app_id,
|
|
87
|
-
installed: installed
|
|
92
|
+
installed: installed,
|
|
93
|
+
isAvailable: isAvailable
|
|
88
94
|
}
|
|
89
95
|
var html = template(replacements);
|
|
90
96
|
res.send(html);
|
|
@@ -110,20 +116,14 @@ router.post('/install', async (req, res) => {
|
|
|
110
116
|
appClient.install(installation_info).then((installation) => {
|
|
111
117
|
winston.debug("(wab) installation response: " + installation);
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
project_id: project_id,
|
|
120
|
-
token: token,
|
|
121
|
-
app_id: app_id,
|
|
122
|
-
installed: installed
|
|
119
|
+
res.redirect(url.format({
|
|
120
|
+
pathname: "/detail",
|
|
121
|
+
query: {
|
|
122
|
+
"project_id": project_id,
|
|
123
|
+
"app_id": app_id,
|
|
124
|
+
"token": token
|
|
123
125
|
}
|
|
124
|
-
|
|
125
|
-
res.send(html);
|
|
126
|
-
})
|
|
126
|
+
}));
|
|
127
127
|
|
|
128
128
|
}).catch((err) => {
|
|
129
129
|
winston.error("(wab) installation error: " + err.data)
|
|
@@ -144,20 +144,14 @@ router.post('/uninstall', async (req, res) => {
|
|
|
144
144
|
|
|
145
145
|
winston.debug("(wab) uninstallation response: " + response);
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
project_id: project_id,
|
|
154
|
-
token: token,
|
|
155
|
-
app_id: app_id,
|
|
156
|
-
installed: installed
|
|
147
|
+
res.redirect(url.format({
|
|
148
|
+
pathname: "/detail",
|
|
149
|
+
query: {
|
|
150
|
+
"project_id": project_id,
|
|
151
|
+
"app_id": app_id,
|
|
152
|
+
"token": token
|
|
157
153
|
}
|
|
158
|
-
|
|
159
|
-
res.send(html);
|
|
160
|
-
})
|
|
154
|
+
}));
|
|
161
155
|
|
|
162
156
|
}).catch((err) => {
|
|
163
157
|
winston.error("(wab) uninsallation error: " + err.data)
|
|
@@ -169,65 +163,79 @@ router.get('/configure', async (req, res) => {
|
|
|
169
163
|
|
|
170
164
|
winston.verbose("(wab) /configure");
|
|
171
165
|
|
|
172
|
-
let
|
|
173
|
-
let token =
|
|
174
|
-
|
|
175
|
-
projectId = req.query.project_id;
|
|
176
|
-
token = req.query.token;
|
|
177
|
-
|
|
178
|
-
let proxy_url = BASE_URL + "/webhook/" + projectId;
|
|
179
|
-
|
|
180
|
-
let CONTENT_KEY = "whatsapp-" + projectId;
|
|
181
|
-
|
|
182
|
-
let settings = await db.get(CONTENT_KEY);
|
|
183
|
-
winston.debug("(wab) settings: " + settings);
|
|
184
|
-
|
|
185
|
-
// get departments
|
|
186
|
-
const tdChannel = new TiledeskChannel({ settings: { project_id: projectId, token: token }, API_URL: API_URL })
|
|
187
|
-
let departments = await tdChannel.getDepartments(token);
|
|
188
|
-
winston.debug("(wab) found " + departments.length + " departments")
|
|
189
|
-
|
|
190
|
-
if (settings) {
|
|
166
|
+
let project_id = req.query.project_id;
|
|
167
|
+
let token = req.query.token;
|
|
191
168
|
|
|
192
|
-
|
|
169
|
+
if (!project_id || !token) {
|
|
170
|
+
let error_message = "Query params project_id and token are required."
|
|
171
|
+
readHTMLFile('/error.html', (err, html) => {
|
|
193
172
|
var template = handlebars.compile(html);
|
|
173
|
+
|
|
194
174
|
var replacements = {
|
|
195
175
|
app_version: pjson.version,
|
|
196
|
-
|
|
197
|
-
token: token,
|
|
198
|
-
proxy_url: proxy_url,
|
|
199
|
-
wab_token: settings.wab_token,
|
|
200
|
-
verify_token: settings.verify_token,
|
|
201
|
-
subscription_id: settings.subscriptionId,
|
|
202
|
-
department_id: settings.department_id,
|
|
203
|
-
departments: departments
|
|
176
|
+
error_message: error_message
|
|
204
177
|
}
|
|
205
178
|
var html = template(replacements);
|
|
206
|
-
res.send(html);
|
|
207
|
-
|
|
179
|
+
return res.send(html);
|
|
208
180
|
})
|
|
209
181
|
|
|
210
182
|
} else {
|
|
211
183
|
|
|
212
|
-
|
|
184
|
+
let proxy_url = BASE_URL + "/webhook/" + project_id;
|
|
213
185
|
|
|
214
|
-
|
|
215
|
-
winston.error("(wab) error read html file: " + err);
|
|
216
|
-
}
|
|
186
|
+
let CONTENT_KEY = "whatsapp-" + project_id;
|
|
217
187
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
app_version: pjson.version,
|
|
221
|
-
project_id: projectId,
|
|
222
|
-
token: token,
|
|
223
|
-
proxy_url: proxy_url,
|
|
224
|
-
departments: departments
|
|
225
|
-
}
|
|
226
|
-
var html = template(replacements);
|
|
227
|
-
res.send(html);
|
|
188
|
+
let settings = await db.get(CONTENT_KEY);
|
|
189
|
+
winston.debug("(wab) settings: " + settings);
|
|
228
190
|
|
|
229
|
-
|
|
191
|
+
// get departments
|
|
192
|
+
const tdChannel = new TiledeskChannel({ settings: { project_id: project_id, token: token }, API_URL: API_URL })
|
|
193
|
+
let departments = await tdChannel.getDepartments(token);
|
|
194
|
+
winston.debug("(wab) found " + departments.length + " departments")
|
|
195
|
+
|
|
196
|
+
if (settings) {
|
|
197
|
+
|
|
198
|
+
readHTMLFile('/configure.html', (err, html) => {
|
|
199
|
+
var template = handlebars.compile(html);
|
|
200
|
+
var replacements = {
|
|
201
|
+
app_version: pjson.version,
|
|
202
|
+
project_id: project_id,
|
|
203
|
+
token: token,
|
|
204
|
+
proxy_url: proxy_url,
|
|
205
|
+
wab_token: settings.wab_token,
|
|
206
|
+
verify_token: settings.verify_token,
|
|
207
|
+
subscription_id: settings.subscriptionId,
|
|
208
|
+
department_id: settings.department_id,
|
|
209
|
+
departments: departments
|
|
210
|
+
}
|
|
211
|
+
var html = template(replacements);
|
|
212
|
+
res.send(html);
|
|
213
|
+
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
} else {
|
|
217
|
+
|
|
218
|
+
readHTMLFile('/configure.html', (err, html) => {
|
|
219
|
+
|
|
220
|
+
if (err) {
|
|
221
|
+
winston.error("(wab) error read html file: " + err);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
var template = handlebars.compile(html);
|
|
225
|
+
var replacements = {
|
|
226
|
+
app_version: pjson.version,
|
|
227
|
+
project_id: project_id,
|
|
228
|
+
token: token,
|
|
229
|
+
proxy_url: proxy_url,
|
|
230
|
+
departments: departments
|
|
231
|
+
}
|
|
232
|
+
var html = template(replacements);
|
|
233
|
+
res.send(html);
|
|
234
|
+
|
|
235
|
+
})
|
|
236
|
+
}
|
|
230
237
|
}
|
|
238
|
+
|
|
231
239
|
})
|
|
232
240
|
|
|
233
241
|
router.post('/update', async (req, res) => {
|
|
@@ -535,7 +543,7 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
535
543
|
) {
|
|
536
544
|
|
|
537
545
|
if (req.body.entry[0].changes[0].value.messages[0].type == "system") {
|
|
538
|
-
winston.
|
|
546
|
+
winston.verbose("(wab) Skip system message")
|
|
539
547
|
return res.sendStatus(200);
|
|
540
548
|
}
|
|
541
549
|
|
|
@@ -756,32 +764,37 @@ async function startApp(settings, callback) {
|
|
|
756
764
|
winston.info("(wab) Starting Whatsapp App")
|
|
757
765
|
|
|
758
766
|
if (!settings.MONGODB_URL) {
|
|
759
|
-
|
|
767
|
+
winston.error("(wab) MONGODB_URL is mandatory. Exit...");
|
|
768
|
+
return callback('Missing parameter: MONGODB_URL');
|
|
760
769
|
}
|
|
761
770
|
|
|
762
771
|
if (!settings.API_URL) {
|
|
763
|
-
|
|
772
|
+
winston.error("(wab) API_URL is mandatory. Exit...");
|
|
773
|
+
return callback('Missing parameter: API_URL');
|
|
764
774
|
} else {
|
|
765
775
|
API_URL = settings.API_URL;
|
|
766
776
|
winston.info("(wab) API_URL: " + API_URL);
|
|
767
777
|
}
|
|
768
778
|
|
|
769
779
|
if (!settings.BASE_URL) {
|
|
770
|
-
|
|
780
|
+
winston.error("(wab) BASE_URL is mandatory. Exit...");
|
|
781
|
+
return callback('Missing parameter: BASE_URL');
|
|
771
782
|
} else {
|
|
772
783
|
BASE_URL = settings.BASE_URL;
|
|
773
784
|
winston.info("(wab) BASE_URL: " + BASE_URL);
|
|
774
785
|
}
|
|
775
786
|
|
|
776
787
|
if (!settings.GRAPH_URL) {
|
|
777
|
-
|
|
788
|
+
winston.error("(wab) GRAPH_URL is mandatory. Exit...");
|
|
789
|
+
return callback('Missing parameter: GRAPH_URL');
|
|
778
790
|
} else {
|
|
779
791
|
GRAPH_URL = settings.GRAPH_URL;
|
|
780
792
|
winston.info("(wab) GRAPH_URL: " + GRAPH_URL);
|
|
781
793
|
}
|
|
782
794
|
|
|
783
795
|
if (!settings.APPS_API_URL) {
|
|
784
|
-
|
|
796
|
+
winston.error("(wab) APPS_API_URL is mandatory. Exit...");
|
|
797
|
+
return callback('Missing parameter: APPS_API_URL');
|
|
785
798
|
} else {
|
|
786
799
|
APPS_API_URL = settings.APPS_API_URL;
|
|
787
800
|
winston.info("(wab) APPS_API_URL: " + APPS_API_URL);
|
|
@@ -800,7 +813,7 @@ async function startApp(settings, callback) {
|
|
|
800
813
|
winston.info("(wab) KVBaseMongo successfully connected.");
|
|
801
814
|
|
|
802
815
|
if (callback) {
|
|
803
|
-
callback();
|
|
816
|
+
callback(null);
|
|
804
817
|
}
|
|
805
818
|
})
|
|
806
819
|
}
|
package/package.json
CHANGED
package/template/configure.html
CHANGED
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
<div class="header-content">
|
|
68
68
|
<div class="logo-title">
|
|
69
69
|
<div class="logo-container">
|
|
70
|
-
<img src="https://
|
|
70
|
+
<img src="https://user-images.githubusercontent.com/45603238/200829081-e6a9c7a0-9d8c-431c-a477-4880a8fd752f.png" width="60px" height="60px">
|
|
71
71
|
</div>
|
|
72
72
|
<div class="title-version">
|
|
73
73
|
<p class="title">WhatsApp Business Connector</p>
|
|
@@ -300,6 +300,6 @@
|
|
|
300
300
|
console.error('Async: Could not copy text: ', err);
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
|
-
</script>
|
|
303
|
+
</script>
|
|
304
304
|
|
|
305
305
|
</body>
|
package/template/css/detail.css
CHANGED
|
@@ -211,3 +211,25 @@ div.scrollmenu a:hover {
|
|
|
211
211
|
.btn:focus {
|
|
212
212
|
outline: none !important;
|
|
213
213
|
}
|
|
214
|
+
|
|
215
|
+
.plans-div {
|
|
216
|
+
display: flex;
|
|
217
|
+
flex-direction: row;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.plan {
|
|
221
|
+
margin-right: 6px;
|
|
222
|
+
padding: 2px 6px;
|
|
223
|
+
border-radius: 4px;
|
|
224
|
+
font-size: 11px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.scale-plan {
|
|
228
|
+
background-color: #eb459e;
|
|
229
|
+
color: white;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.plus-plan {
|
|
233
|
+
background-color: #5865f2;
|
|
234
|
+
color: white;
|
|
235
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
body {
|
|
5
|
+
padding: 20px 0px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.header {
|
|
9
|
+
width: 100%;
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.header-content {
|
|
15
|
+
width: 50%;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: row;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: space-between;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.logo-title {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: row;
|
|
25
|
+
align-items: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.title {
|
|
29
|
+
margin-bottom: 0px;
|
|
30
|
+
font-size: 22px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.title-version {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
align-items: flex-start;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.logo-container {
|
|
40
|
+
margin: 0px 20px 0px 0px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.logo-title {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: row;
|
|
46
|
+
align-items: center;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.error {
|
|
50
|
+
width: 100%;
|
|
51
|
+
display: flex;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
margin-top: 60px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.error-box {
|
|
57
|
+
width: 50%;
|
|
58
|
+
background-color: #f79a9a;
|
|
59
|
+
min-height: 100px;
|
|
60
|
+
border-radius: 8px;
|
|
61
|
+
padding: 10px 10px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.error-title {
|
|
65
|
+
font-size: 18px;
|
|
66
|
+
font-weight: 500;
|
|
67
|
+
}
|
package/template/detail.html
CHANGED
|
@@ -42,7 +42,11 @@
|
|
|
42
42
|
<hr style="margin-top: 10px; margin-bottom: 10px">
|
|
43
43
|
|
|
44
44
|
<div class="installation-info-box">
|
|
45
|
+
{{#if isAvailable}}
|
|
45
46
|
<p style="margin: 0px; color: #676767; font-size: 13px;">You can install this application for free.</p>
|
|
47
|
+
{{else}}
|
|
48
|
+
<p style="margin: 0px; color: #676767; font-size: 13px;">This app is available for Scale and Plus plans</p>
|
|
49
|
+
{{/if}}
|
|
46
50
|
</div>
|
|
47
51
|
|
|
48
52
|
|
|
@@ -56,19 +60,32 @@
|
|
|
56
60
|
<p style="font-size: 26px; font-weight: 500; margin-bottom: 0px;">WhatsApp Business</p>
|
|
57
61
|
<p style="color: #676767; font-size: 16px; margin-bottom: 5px;">Connect your WhatsApp number with Tiledesk</p>
|
|
58
62
|
<a style="font-size: 18px;" href="https://tiledesk.com/" target="_blank">Tiledesk</a>
|
|
59
|
-
|
|
63
|
+
{{#if isAvailable}}
|
|
64
|
+
<p style="font-size: 15px; color: #676767; font-style: italic; margin-bottom: 0px; margin-top: 20px;">Free</p>
|
|
65
|
+
{{else}}
|
|
66
|
+
<p style="font-size: 15px; color: #676767; font-style: italic; margin-bottom: 0px; margin-top: 20px;">Free for</p>
|
|
67
|
+
<div class="plans-div">
|
|
68
|
+
<div class="plan scale-plan">Scale Plan</div>
|
|
69
|
+
<div class="plan plus-plan">Plus Plan</div>
|
|
70
|
+
</div>
|
|
71
|
+
{{/if}}
|
|
60
72
|
</div>
|
|
61
73
|
|
|
62
74
|
<div style="display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-end;">
|
|
63
75
|
|
|
64
76
|
{{#if installed}}
|
|
77
|
+
|
|
65
78
|
<!-- Open button -->
|
|
79
|
+
{{#if isAvailable}}
|
|
66
80
|
<form action="./configure" method="get">
|
|
67
81
|
<input type="hidden" name="project_id" value="{{ project_id }}" />
|
|
68
82
|
<input type="hidden" name="app_id" value="{{ app_id }}" />
|
|
69
83
|
<input type="hidden" name="token" value="{{ token }}" />
|
|
70
84
|
<input type="submit" class="btn install-button" value="Open">
|
|
71
85
|
</form>
|
|
86
|
+
{{else}}
|
|
87
|
+
<button class="btn install-button" disabled>Open</button>
|
|
88
|
+
{{/if}}
|
|
72
89
|
|
|
73
90
|
<!-- Uninstall button -->
|
|
74
91
|
<button class="btn uninstall-button" onclick="document.getElementById('uninstall-modal').style.display='flex'">Uninstall</button>
|
|
@@ -97,7 +114,13 @@
|
|
|
97
114
|
</div>
|
|
98
115
|
|
|
99
116
|
{{else}}
|
|
100
|
-
|
|
117
|
+
|
|
118
|
+
{{#if isAvailable}}
|
|
119
|
+
<button class="btn install-button" onclick="document.getElementById('install-modal').style.display='flex'">Install</button>
|
|
120
|
+
{{else}}
|
|
121
|
+
<button class="btn install-button" disabled>Install</button>
|
|
122
|
+
{{/if}}
|
|
123
|
+
|
|
101
124
|
<!-- Install modal -->
|
|
102
125
|
<div id="install-modal" class="modal">
|
|
103
126
|
<div class="modal-content">
|
|
@@ -184,22 +207,22 @@
|
|
|
184
207
|
</div>
|
|
185
208
|
</div>
|
|
186
209
|
</div>
|
|
187
|
-
|
|
188
|
-
|
|
210
|
+
</div>
|
|
211
|
+
|
|
189
212
|
<hr style="margin-top: 20px; margin-bottom: 20px">
|
|
190
213
|
|
|
191
214
|
<p style="font-size: 18px;"><b>What's new?</b></p>
|
|
192
215
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
</div>
|
|
199
|
-
<p style="font-size: 12px; color: #676767; margin-bottom: 0px;">Version <b>0.1.34</b></p>
|
|
216
|
+
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 15px;">
|
|
217
|
+
<div>
|
|
218
|
+
<p style="margin-bottom: 0px">Added possibility to select a department for Whatsapp conversations.</p>
|
|
219
|
+
<p style="margin-bottom: 0px">Bug fixes and minor improvements</p>
|
|
220
|
+
<!--<p>Bug fixes and performance improvements</p>-->
|
|
200
221
|
</div>
|
|
222
|
+
<p style="font-size: 12px; color: #676767; margin-bottom: 0px;">Version <b>0.1.34</b></p>
|
|
223
|
+
</div>
|
|
201
224
|
|
|
202
|
-
|
|
225
|
+
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 15px;">
|
|
203
226
|
<div>
|
|
204
227
|
<p style="margin-bottom: 0px">Bug Fixes</p>
|
|
205
228
|
<p style="margin-bottom: 0px">Minor improvements</p>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
|
|
9
|
+
<!-- Latest compiled and minified CSS -->
|
|
10
|
+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
|
|
11
|
+
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
|
|
12
|
+
|
|
13
|
+
<!-- Optional theme -->
|
|
14
|
+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
|
|
15
|
+
integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
|
|
16
|
+
|
|
17
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
18
|
+
|
|
19
|
+
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
|
|
20
|
+
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
|
|
21
|
+
|
|
22
|
+
<!-- Latest compiled and minified JavaScript -->
|
|
23
|
+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
|
|
24
|
+
integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous">
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
28
|
+
<link rel="stylesheet" href="./css/error.css">
|
|
29
|
+
|
|
30
|
+
<style>
|
|
31
|
+
body {
|
|
32
|
+
font-family: 'Poppins', serif;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
|
|
36
|
+
</head>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<body>
|
|
40
|
+
|
|
41
|
+
<!-- Success modal -->
|
|
42
|
+
<!--
|
|
43
|
+
{{#if show_success_modal}}
|
|
44
|
+
<div id="success-update-modal" class="success-modal">
|
|
45
|
+
<div class="modal-content">
|
|
46
|
+
<img src="https://www.pngall.com/wp-content/uploads/9/Green-Tick-Vector-PNG-Images.png" width="80" height="auto" />
|
|
47
|
+
<p class="modal-text" style="margin-top: 20px; margin-bottom: 20px;">Configuration updated successfully</p>
|
|
48
|
+
<button class="btn cancel-btn" onclick="document.getElementById('success-update-modal').style.display='none'">Close</button>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
{{/if}}
|
|
52
|
+
-->
|
|
53
|
+
|
|
54
|
+
<!-- Error modal -->
|
|
55
|
+
<!--
|
|
56
|
+
{{#if show_error_modal}}
|
|
57
|
+
<div id="error-update-modal" class="error-modal">
|
|
58
|
+
<div class="modal-content">
|
|
59
|
+
<img src="https://cdn-icons-png.flaticon.com/512/148/148766.png" width="80" height="auto" />
|
|
60
|
+
<p style="margin-top: 20px; margin-bottom: 20px;">An error occurred while updating the configuration</p>
|
|
61
|
+
<button class="btn cancel-btn" onclick="document.getElementById('error-update-modal').style.display='none'">Close</button>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
{{/if}}
|
|
65
|
+
-->
|
|
66
|
+
|
|
67
|
+
<!-- HEADER -->
|
|
68
|
+
<div class="header">
|
|
69
|
+
<div class="header-content">
|
|
70
|
+
<div class="logo-title">
|
|
71
|
+
<div class="logo-container">
|
|
72
|
+
<img src="https://user-images.githubusercontent.com/45603238/200829081-e6a9c7a0-9d8c-431c-a477-4880a8fd752f.png" width="60px" height="60px">
|
|
73
|
+
</div>
|
|
74
|
+
<div class="title-version">
|
|
75
|
+
<p class="title">WhatsApp Business Connector</p>
|
|
76
|
+
<div class="status-box" style="padding: 0px 8px; letter-spacing: 1px; height: 18px;">
|
|
77
|
+
<p style="margin-bottom: 0px;">{{ app_version }}</p>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="error">
|
|
85
|
+
<div class="error-box">
|
|
86
|
+
<p class="error-title">Ops! Something went wrong.</p>
|
|
87
|
+
<p>{{ error_message }}</p>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
</body>
|
|
@@ -217,7 +217,58 @@ class TiledeskChannel {
|
|
|
217
217
|
winston.error("(wab) [TiledeskChannel] sign in error: " + err);
|
|
218
218
|
})
|
|
219
219
|
}
|
|
220
|
-
|
|
220
|
+
|
|
221
|
+
async getProjectDetail() {
|
|
222
|
+
|
|
223
|
+
return await axios({
|
|
224
|
+
url: this.API_URL + '/projects/' + this.settings.project_id,
|
|
225
|
+
headers: {
|
|
226
|
+
'Content-Type': 'application/json',
|
|
227
|
+
'Authorization': this.settings.token
|
|
228
|
+
},
|
|
229
|
+
method: 'GET'
|
|
230
|
+
}).then((response) => {
|
|
231
|
+
return this.checkPlan(response.data);
|
|
232
|
+
}).catch((err) => {
|
|
233
|
+
winston.error("(wab) [TiledeskChannel] get project detail error: " + err);
|
|
234
|
+
return null;
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
checkPlan(project) {
|
|
239
|
+
let profile_name = project.profile.name;
|
|
240
|
+
let profile_type = project.profile.type;
|
|
241
|
+
let isActiveSubscription = project.isActiveSubscription;
|
|
242
|
+
let trialExpired = project.trialExpired;
|
|
243
|
+
|
|
244
|
+
winston.debug("profile_name: " + profile_name)
|
|
245
|
+
winston.debug("profile_type: " + profile_type)
|
|
246
|
+
winston.debug("isActiveSubscription: " + isActiveSubscription)
|
|
247
|
+
|
|
248
|
+
return new Promise((resolve, reject) => {
|
|
249
|
+
if (
|
|
250
|
+
(profile_name === 'Growth') ||
|
|
251
|
+
(profile_name === 'Scale' && isActiveSubscription === false) ||
|
|
252
|
+
(profile_name === 'Plus' && isActiveSubscription === false) ||
|
|
253
|
+
(profile_type === 'free' && trialExpired === true)
|
|
254
|
+
) {
|
|
255
|
+
winston.verbose('Feature not available')
|
|
256
|
+
resolve(false);
|
|
257
|
+
|
|
258
|
+
} else if (
|
|
259
|
+
(profile_name === 'Scale' && isActiveSubscription === true) ||
|
|
260
|
+
(profile_name === 'Plus' && isActiveSubscription === true) ||
|
|
261
|
+
(profile_type === 'free' && trialExpired === false)
|
|
262
|
+
) {
|
|
263
|
+
winston.verbose('Feature available')
|
|
264
|
+
resolve(true);
|
|
265
|
+
|
|
266
|
+
} else {
|
|
267
|
+
winston.verbose('Other case: feature not available');
|
|
268
|
+
resolve(false);
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
}
|
|
221
272
|
|
|
222
273
|
}
|
|
223
274
|
|
|
@@ -271,8 +271,26 @@ const path = require('path');
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
} else {
|
|
274
|
-
|
|
275
|
-
|
|
274
|
+
|
|
275
|
+
// template
|
|
276
|
+
console.log("tiledeskChannelMessage.text: ", tiledeskChannelMessage.text);
|
|
277
|
+
if (tiledeskChannelMessage.text.startsWith("/template:")) {
|
|
278
|
+
let template_name = tiledeskChannelMessage.text.substring(tiledeskChannelMessage.text.lastIndexOf(':') + 1);
|
|
279
|
+
console.log("template name to send: ", template_name);
|
|
280
|
+
whatsapp_message.type = "template";
|
|
281
|
+
whatsapp_message.template = {
|
|
282
|
+
name: template_name,
|
|
283
|
+
language: {
|
|
284
|
+
code: "en_US"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return whatsapp_message;
|
|
288
|
+
}
|
|
289
|
+
// standard message
|
|
290
|
+
else {
|
|
291
|
+
whatsapp_message.text = { body: text };
|
|
292
|
+
return whatsapp_message;
|
|
293
|
+
}
|
|
276
294
|
}
|
|
277
295
|
}
|
|
278
296
|
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
-
|
|
9
|
-
<!-- Latest compiled and minified CSS -->
|
|
10
|
-
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
|
|
11
|
-
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
|
|
12
|
-
|
|
13
|
-
<!-- Optional theme -->
|
|
14
|
-
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
|
|
15
|
-
integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
|
|
16
|
-
|
|
17
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
18
|
-
|
|
19
|
-
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
|
|
20
|
-
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
|
|
21
|
-
|
|
22
|
-
<!-- Latest compiled and minified JavaScript -->
|
|
23
|
-
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
|
|
24
|
-
integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous">
|
|
25
|
-
</script>
|
|
26
|
-
|
|
27
|
-
<link rel="stylesheet" href="./css/style.css">
|
|
28
|
-
|
|
29
|
-
</head>
|
|
30
|
-
|
|
31
|
-
<body>
|
|
32
|
-
|
|
33
|
-
<div style="padding: 100px 230px; background-color: #efefef; min-width: 800px; display: flex; justify-content: center;" >
|
|
34
|
-
|
|
35
|
-
<div style="background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0px 0px 5px 0px #cfcfcf; min-width: 800px;">
|
|
36
|
-
|
|
37
|
-
<div>
|
|
38
|
-
|
|
39
|
-
<div style="display: flex; flex-direction: row; align-items: center;">
|
|
40
|
-
|
|
41
|
-
<div style="margin-right: 80px;">
|
|
42
|
-
<img width="130" height="auto" style="margin-top: 6px;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6b/WhatsApp.svg/479px-WhatsApp.svg.png" alt="..." class="img-rounded">
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<div>
|
|
46
|
-
|
|
47
|
-
<h1 style="margin-top: 0px; margin-bottom: 2px; min-width: 500px;">WhatsApp Business</h1>
|
|
48
|
-
<div style="display: flex; flex-direction: row; align-items: flex-end;">
|
|
49
|
-
<h7 style="color: rgb(140, 140, 140); margin-right: 10px;">by Tiledesk</h7>
|
|
50
|
-
<div class="version">
|
|
51
|
-
<a class="npm-link" href="https://www.npmjs.com/package/@tiledesk/tiledesk-whatsapp-connector" target="_blank">{{ app_version }}</a>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
{{#if wab_token}}
|
|
56
|
-
<div style="margin-top: 20px;">
|
|
57
|
-
<h7 style="color: rgb(140, 140, 140);">The Whatsapp Business App is configured on your Tildesk project.</h7>
|
|
58
|
-
<form action="./disconnect" method="post">
|
|
59
|
-
<input type="hidden" name="project_id" value="{{ project_id }}">
|
|
60
|
-
<input type="hidden" name="token" value="{{ token }}">
|
|
61
|
-
<input type="hidden" name="subscription_id" value="{{ subscription_id }}">
|
|
62
|
-
<input type="submit" class="btn btn-danger" style="margin-top: 10px; width: 160px;" value="Disconnect">
|
|
63
|
-
</form>
|
|
64
|
-
</div>
|
|
65
|
-
{{/if}}
|
|
66
|
-
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<!--
|
|
71
|
-
<button onClick="javascript:window.open('https://gethelp.tiledesk.com/articles/telegram/', '_blank');" class="btn btn- primary">View Documentation</button>
|
|
72
|
-
-->
|
|
73
|
-
|
|
74
|
-
<div style="margin-top: 40px; padding: 20px; background-color: aliceblue; border-radius: 8px; min-width: 600px;">
|
|
75
|
-
<h7>Receive Whatsapp bot conversations in your Tiledesk dashboard. Seamlessly Chat with your targeted audience on Whatsapp right from the Tiledesk dashboard.</h7>
|
|
76
|
-
<ul>
|
|
77
|
-
<li>
|
|
78
|
-
<h7>Integrate your Whatsapp number with Tiledesk.</h7>
|
|
79
|
-
</li>
|
|
80
|
-
<li>
|
|
81
|
-
<h7>Once a chat is initiated on your Whatsapp number, receive an alert on your Tiledesk account.</h7>
|
|
82
|
-
</li>
|
|
83
|
-
<li>
|
|
84
|
-
<h7>Enable instant messaging and answer multiple conversations - everything from Tiledesk account.</h7>
|
|
85
|
-
</li>
|
|
86
|
-
</ul>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<div style="margin-top: 10px;">
|
|
90
|
-
<a href="https://gethelp.tiledesk.com/categories/whatsapp-business/" target="_blank">View documentation</a>
|
|
91
|
-
</div>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<hr>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
<div>
|
|
98
|
-
<h4>Your Configuration</h4>
|
|
99
|
-
|
|
100
|
-
<div style="min-width: 600px">
|
|
101
|
-
<form action="./update" method="post">
|
|
102
|
-
|
|
103
|
-
<div class="form-group" style="width: 490px;">
|
|
104
|
-
<label for="proxy_url">Webhook Endpoint
|
|
105
|
-
<span style="margin-left: 10px;">
|
|
106
|
-
<i class="fa fa-question-circle custom-tooltip" style="color: #337ab7;">
|
|
107
|
-
<span class="custom-tooltiptext">This is the endpoint to be reached by WhatsApp. Copy it to the Facebook Developer console in "Callback URL" in Whatsapp Configuration. See documention for more info.</span>
|
|
108
|
-
</i>
|
|
109
|
-
</span>
|
|
110
|
-
</label>
|
|
111
|
-
<!--<p style="margin-bottom: 5px; font-size: 12px; color: #a7a7a7;">Copy this URL in the Facebook Developer Dashboad. See documentation for more info.</p> -->
|
|
112
|
-
<div style="display: flex; flex-direction: row; justify-content: space-between">
|
|
113
|
-
<div style="width: 400px;">
|
|
114
|
-
<input type="text" readonly class="form-control" name="proxy_url" id="proxy_url"
|
|
115
|
-
value="{{ proxy_url}}">
|
|
116
|
-
</div>
|
|
117
|
-
<div style="width: 80px;">
|
|
118
|
-
<!--
|
|
119
|
-
<input type="button" class="btn btn-primary" style="width: 100%;"
|
|
120
|
-
onclick="copyTextToClipboard(this, document.getElementById('proxy_url').value)"
|
|
121
|
-
value="Copy"></input>
|
|
122
|
-
-->
|
|
123
|
-
<input type="button" id="copy-btn" class="btn btn-primary" style="width: 100%;"
|
|
124
|
-
onclick="copyTextToClipboard()"
|
|
125
|
-
value="Copy"></input>
|
|
126
|
-
</div>
|
|
127
|
-
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div class="form-group" style="width: 400px;">
|
|
132
|
-
<label for="wab_token">Whatsapp Token
|
|
133
|
-
<span style="margin-left: 10px;">
|
|
134
|
-
<i class="fa fa-question-circle custom-tooltip" style="color: #337ab7;">
|
|
135
|
-
<span class="custom-tooltiptext">Paste it the permanent WhatsApp Business token. See documention for more info.</span>
|
|
136
|
-
</i>
|
|
137
|
-
</span>
|
|
138
|
-
</label>
|
|
139
|
-
<input type="text" class="form-control" name="wab_token" value="{{ wab_token }}"
|
|
140
|
-
placeholder="Enter the Whatsapp Token">
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div class="form-group" style="width: 400px;">
|
|
144
|
-
<label for="verify_token">Verify Token
|
|
145
|
-
<span style="margin-left: 10px;">
|
|
146
|
-
<i class="fa fa-question-circle custom-tooltip" style="color: #337ab7;">
|
|
147
|
-
<span class="custom-tooltiptext">This is a verification token of your choice. Copy it to the Facebook Developer console in "Verify Token" in Whatsapp Configuration.
|
|
148
|
-
See documention for more info.</span>
|
|
149
|
-
</i>
|
|
150
|
-
</span>
|
|
151
|
-
</label>
|
|
152
|
-
<input type="password" class="form-control" name="verify_token" value="{{ verify_token }}"
|
|
153
|
-
placeholder="Enter your Verify Token">
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
<input type="hidden" name="project_id" value="{{ project_id }}" />
|
|
157
|
-
<input type="hidden" name="token" value="{{ token }}" />
|
|
158
|
-
|
|
159
|
-
{{#if wab_token}}
|
|
160
|
-
<div style="width: 400px; text-align: right;">
|
|
161
|
-
<input type="submit" class="btn btn-primary" style="width: 35%;" value="Update">
|
|
162
|
-
</div>
|
|
163
|
-
{{else}}
|
|
164
|
-
<div style="width: 400px; text-align: right;">
|
|
165
|
-
<input type="submit" class="btn btn-primary" style="width: 35%;" value="Connect">
|
|
166
|
-
</div>
|
|
167
|
-
{{/if}}
|
|
168
|
-
|
|
169
|
-
</form>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
</div>
|
|
176
|
-
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
|
|
180
|
-
<script>
|
|
181
|
-
|
|
182
|
-
function copyTextToClipboard2(btn, text) {
|
|
183
|
-
console.log("Button clicked")
|
|
184
|
-
btn.value = "Copied!"
|
|
185
|
-
navigator.clipboard.writeText(text).then(function () {
|
|
186
|
-
console.log('Async: Copied to clipboard!');
|
|
187
|
-
}, function (err) {
|
|
188
|
-
console.error('Async: Could not copy text: ', err);
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function copyTextToClipboard() {
|
|
193
|
-
const proxyUrl = document.getElementById('proxy_url').select()
|
|
194
|
-
try {
|
|
195
|
-
document.execCommand('copy');
|
|
196
|
-
console.log('Async: Copied to clipboard!');
|
|
197
|
-
let btn = document.getElementById('copy-btn');
|
|
198
|
-
btn.value = "Copied!";
|
|
199
|
-
} catch (err) {
|
|
200
|
-
console.error('Async: Could not copy text: ', err);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
</script>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
</body>
|