@tiledesk/tiledesk-whatsapp-connector 1.0.32 → 1.0.33
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/.env +1 -1
- package/index.js +19 -3
- package/package.json +1 -1
- package/tiledesk/BotTestSubscriptions.js +41 -1
- package/tiledesk/TiledeskBotTester.js +8 -1
- package/tiledesk/TiledeskChannel.js +46 -1
package/.env
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# CUSTOM ENV
|
|
2
|
-
NPM_PUBLISH_TOKEN=
|
|
2
|
+
NPM_PUBLISH_TOKEN=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
|
package/index.js
CHANGED
|
@@ -31,7 +31,7 @@ const { TemplateManager } = require("./tiledesk/TemplateManager");
|
|
|
31
31
|
const { WhatsappLogger } = require("./tiledesk/WhatsappLogger");
|
|
32
32
|
const Utils = require("./tiledesk/Utils");
|
|
33
33
|
const whatsappService = require("./tiledesk/WhatsappService");
|
|
34
|
-
const { ensureGlobalSigninSubscription, ensureProjectTestSubscription } = require("./tiledesk/BotTestSubscriptions");
|
|
34
|
+
const { ensureGlobalSigninSubscription, ensureProjectTestSubscription, getActiveTest, isProjectId } = require("./tiledesk/BotTestSubscriptions");
|
|
35
35
|
|
|
36
36
|
// mongo
|
|
37
37
|
const { KVBaseMongo } = require("./tiledesk/KVBaseMongo");
|
|
@@ -931,7 +931,7 @@ router.post('/webhook', async (req, res) => {
|
|
|
931
931
|
winston.verbose("(wab) tiledeskJsonMessage: ", tiledeskJsonMessage);
|
|
932
932
|
|
|
933
933
|
try {
|
|
934
|
-
const response = await tdChannel
|
|
934
|
+
const response = await deliverInboundMessage(tdChannel, tiledeskJsonMessage, message_info, settings);
|
|
935
935
|
winston.verbose("(wab) Message sent to Tiledesk!");
|
|
936
936
|
winston.debug("(wab) response: ", response);
|
|
937
937
|
} catch (err) {
|
|
@@ -1166,7 +1166,7 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
1166
1166
|
|
|
1167
1167
|
if (tiledeskJsonMessage) {
|
|
1168
1168
|
winston.verbose("(wab) tiledeskJsonMessage: ", tiledeskJsonMessage);
|
|
1169
|
-
const response = await tdChannel
|
|
1169
|
+
const response = await deliverInboundMessage(tdChannel, tiledeskJsonMessage, message_info, settings);
|
|
1170
1170
|
winston.verbose("(wab) Message sent to Tiledesk!");
|
|
1171
1171
|
winston.debug("(wab) response: ", response);
|
|
1172
1172
|
} else {
|
|
@@ -1875,6 +1875,22 @@ async function getDepartments(project_id, token) {
|
|
|
1875
1875
|
}
|
|
1876
1876
|
}
|
|
1877
1877
|
|
|
1878
|
+
async function deliverInboundMessage(tdChannel, tiledeskJsonMessage, messageInfo, settings) {
|
|
1879
|
+
const whatsapp = messageInfo && messageInfo.whatsapp;
|
|
1880
|
+
const session = await getActiveTest(redis_client, whatsapp && whatsapp.phone_number_id, whatsapp && whatsapp.from);
|
|
1881
|
+
if (session && session.request_id && isProjectId(session.project_id)) {
|
|
1882
|
+
winston.verbose("(wab) Continue Try on WhatsApp in project " + session.project_id);
|
|
1883
|
+
const signinSubscription = await ensureGlobalSigninSubscription(db, BASE_URL);
|
|
1884
|
+
return tdChannel.sendToExistingRequest(tiledeskJsonMessage, messageInfo, {
|
|
1885
|
+
project_id: session.project_id,
|
|
1886
|
+
request_id: session.request_id,
|
|
1887
|
+
subscriptionId: String(signinSubscription._id),
|
|
1888
|
+
secret: signinSubscription.secret
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
return tdChannel.send(tiledeskJsonMessage, messageInfo, settings.department_id);
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1878
1894
|
/**
|
|
1879
1895
|
* Helper function to get or create user token with Redis caching
|
|
1880
1896
|
* @param {Object} tdChannel - TiledeskChannel instance
|
package/package.json
CHANGED
|
@@ -95,6 +95,44 @@ async function ensureProjectTestSubscription(kv, projectId, baseUrl, redisClient
|
|
|
95
95
|
return existing;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
function activeTestKey(phoneNumberId, from) {
|
|
99
|
+
return "bottest:active:" + phoneNumberId + ":" + from;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function saveActiveTest(redisClient, phoneNumberId, from, session) {
|
|
103
|
+
if (!redisClient || !phoneNumberId || !from || !session) {
|
|
104
|
+
return Promise.resolve();
|
|
105
|
+
}
|
|
106
|
+
const key = activeTestKey(phoneNumberId, from);
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
redisClient.set(key, JSON.stringify(session), "EX", 604800, function (err) {
|
|
109
|
+
if (err) {
|
|
110
|
+
return reject(err);
|
|
111
|
+
}
|
|
112
|
+
resolve();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getActiveTest(redisClient, phoneNumberId, from) {
|
|
118
|
+
if (!redisClient || !phoneNumberId || !from) {
|
|
119
|
+
return Promise.resolve(null);
|
|
120
|
+
}
|
|
121
|
+
const key = activeTestKey(phoneNumberId, from);
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
redisClient.get(key, function (err, value) {
|
|
124
|
+
if (err || !value) {
|
|
125
|
+
return resolve(null);
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
resolve(JSON.parse(value));
|
|
129
|
+
} catch (parseErr) {
|
|
130
|
+
resolve(null);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
98
136
|
function invalidateSubscriptionCache(redisClient, projectId, event) {
|
|
99
137
|
if (!redisClient || !projectId || !event) {
|
|
100
138
|
return Promise.resolve();
|
|
@@ -120,5 +158,7 @@ module.exports = {
|
|
|
120
158
|
WHATSAPP_MESSAGE_EVENT,
|
|
121
159
|
isProjectId,
|
|
122
160
|
ensureGlobalSigninSubscription,
|
|
123
|
-
ensureProjectTestSubscription
|
|
161
|
+
ensureProjectTestSubscription,
|
|
162
|
+
saveActiveTest,
|
|
163
|
+
getActiveTest
|
|
124
164
|
};
|
|
@@ -7,7 +7,7 @@ const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
|
7
7
|
const { TiledeskWhatsappTranslator } = require('./TiledeskWhatsappTranslator');
|
|
8
8
|
const { TiledeskChannel } = require('./TiledeskChannel');
|
|
9
9
|
const Utils = require("./Utils");
|
|
10
|
-
const { ensureGlobalSigninSubscription, ensureProjectTestSubscription, isProjectId } = require("./BotTestSubscriptions");
|
|
10
|
+
const { ensureGlobalSigninSubscription, ensureProjectTestSubscription, isProjectId, saveActiveTest } = require("./BotTestSubscriptions");
|
|
11
11
|
|
|
12
12
|
class TiledeskBotTester {
|
|
13
13
|
|
|
@@ -123,6 +123,13 @@ class TiledeskBotTester {
|
|
|
123
123
|
subscriptionId: String(signinSubscription._id),
|
|
124
124
|
secret: signinSubscription.secret
|
|
125
125
|
});
|
|
126
|
+
if (response && response.request_id) {
|
|
127
|
+
await saveActiveTest(this.redis_client, phoneNumberId, message_info.whatsapp.from, {
|
|
128
|
+
project_id: test_info.project_id,
|
|
129
|
+
bot_id: test_info.bot_id,
|
|
130
|
+
request_id: response.request_id
|
|
131
|
+
});
|
|
132
|
+
}
|
|
126
133
|
return resolve(response);
|
|
127
134
|
} catch (prepareErr) {
|
|
128
135
|
winston.error("(wab) [TiledeskBotTester] unable to open test conversation: " + prepareErr);
|
|
@@ -236,7 +236,9 @@ class TiledeskChannel {
|
|
|
236
236
|
data: tiledeskMessage,
|
|
237
237
|
method: 'POST'
|
|
238
238
|
}).then((response) => {
|
|
239
|
-
|
|
239
|
+
const data = response.data || {};
|
|
240
|
+
data.request_id = new_request_id;
|
|
241
|
+
return data;
|
|
240
242
|
}).catch((err) => {
|
|
241
243
|
const errorMessage = utils._extractErrorMessage(err);
|
|
242
244
|
winston.error("(wab) [TiledeskChannel] send message (open conversation) error: " + errorMessage);
|
|
@@ -247,6 +249,49 @@ class TiledeskChannel {
|
|
|
247
249
|
})
|
|
248
250
|
}
|
|
249
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Append a message to a Try on WhatsApp request that already lives in the bot's project.
|
|
254
|
+
*/
|
|
255
|
+
async sendToExistingRequest(tiledeskMessage, messageInfo, target) {
|
|
256
|
+
if (!target || !target.project_id || !target.request_id || !target.subscriptionId || !target.secret) {
|
|
257
|
+
throw new Error("Try on WhatsApp session is incomplete");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const channel = messageInfo.whatsapp || {};
|
|
261
|
+
const payload = {
|
|
262
|
+
_id: 'wab-' + channel.from,
|
|
263
|
+
first_name: channel.firstname,
|
|
264
|
+
last_name: channel.lastname,
|
|
265
|
+
sub: 'userexternal',
|
|
266
|
+
aud: 'https://tiledesk.com/subscriptions/' + target.subscriptionId
|
|
267
|
+
};
|
|
268
|
+
const customToken = jwt.sign(payload, target.secret);
|
|
269
|
+
|
|
270
|
+
const signinResponse = await axios({
|
|
271
|
+
url: this.API_URL + "/auth/signinWithCustomToken",
|
|
272
|
+
headers: {
|
|
273
|
+
'Content-Type': 'application/json',
|
|
274
|
+
'Authorization': 'JWT ' + customToken
|
|
275
|
+
},
|
|
276
|
+
data: { id_project: target.project_id },
|
|
277
|
+
method: 'POST'
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const token = this.fixToken(signinResponse.data.token);
|
|
281
|
+
delete tiledeskMessage.participants;
|
|
282
|
+
|
|
283
|
+
const sendResponse = await axios({
|
|
284
|
+
url: this.API_URL + `/${target.project_id}/requests/${target.request_id}/messages`,
|
|
285
|
+
headers: {
|
|
286
|
+
'Content-Type': 'application/json',
|
|
287
|
+
'Authorization': token
|
|
288
|
+
},
|
|
289
|
+
data: tiledeskMessage,
|
|
290
|
+
method: 'POST'
|
|
291
|
+
});
|
|
292
|
+
return sendResponse.data;
|
|
293
|
+
}
|
|
294
|
+
|
|
250
295
|
/**
|
|
251
296
|
* Get the project detail from Tiledesk
|
|
252
297
|
* @returns {Promise<Object>} - The response from the Tiledesk API
|