posiflow-telegram-connector 1.0.3
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 +795 -0
- package/models/Setting.js +32 -0
- package/package.json +32 -0
- package/publish.sh +22 -0
- package/template/configure.html +349 -0
- package/template/css/configure.css +477 -0
- package/template/css/detail.css +186 -0
- package/template/css/error.css +67 -0
- package/template/css/style.css +93 -0
- package/template/detail.html +278 -0
- package/template/error.html +65 -0
- package/template/img/arrow-right.png +0 -0
- package/template/img/check.png +0 -0
- package/template/img/telegram-header.png +0 -0
- package/test/test_translate_telegram.js +464 -0
- package/tiledesk/KVBaseMongo.js +104 -0
- package/tiledesk/MessageHandler.js +31 -0
- package/tiledesk/TiledeskAppsClient.js +163 -0
- package/tiledesk/TiledeskChannel.js +175 -0
- package/tiledesk/TiledeskSubscriptionClient.js +138 -0
- package/tiledesk/TiledeskTelegram.js +304 -0
- package/tiledesk/TiledeskTelegramTranslator.js +300 -0
- package/winston.js +41 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const FormData = require('form-data');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const winston = require('../winston');
|
|
6
|
+
|
|
7
|
+
class TiledeskAppsClient {
|
|
8
|
+
/**
|
|
9
|
+
* Constructor for TiledeskChannel
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { TiledeskAppsClient } = require('tiledesk-apps-client');
|
|
13
|
+
* const appClient = new TiledeskAppsClient({ APPS_API_URL: APPS_API_URL});
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} config JSON configuration.
|
|
16
|
+
* @param {string} config.APPS_API_URL Mandatory. The api url for tiledesk apps.
|
|
17
|
+
* @param {boolean} options.log Optional. If true HTTP requests are logged.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
constructor(config) {
|
|
21
|
+
if (!config) {
|
|
22
|
+
throw new Error('config is mandatory');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!config.APPS_API_URL) {
|
|
26
|
+
throw new Error('config.APPS_URL is mandatory');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.APPS_API_URL = config.APPS_API_URL;
|
|
30
|
+
|
|
31
|
+
this.log = true;
|
|
32
|
+
if (config.log) {
|
|
33
|
+
this.log = config.log;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
install(installation_info, callback) {
|
|
39
|
+
|
|
40
|
+
const URL = this.APPS_API_URL + `/api/installation`;
|
|
41
|
+
const HTTPREQUEST = {
|
|
42
|
+
url: URL,
|
|
43
|
+
headers: {
|
|
44
|
+
'Content-Type': 'application/json',
|
|
45
|
+
},
|
|
46
|
+
json: installation_info,
|
|
47
|
+
method: 'POST'
|
|
48
|
+
};
|
|
49
|
+
let promise = new Promise((resolve, reject) => {
|
|
50
|
+
TiledeskAppsClient.myrequest(
|
|
51
|
+
HTTPREQUEST,
|
|
52
|
+
function(err, resbody) {
|
|
53
|
+
if (err) {
|
|
54
|
+
if (callback) {
|
|
55
|
+
callback(err);
|
|
56
|
+
}
|
|
57
|
+
reject(err);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (callback) {
|
|
61
|
+
callback(null, resbody);
|
|
62
|
+
}
|
|
63
|
+
winston.verbose("(tgm) [TiledeskAppsClient] Installed!");
|
|
64
|
+
resolve(resbody);
|
|
65
|
+
}
|
|
66
|
+
}, true);
|
|
67
|
+
})
|
|
68
|
+
return promise;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getInstallations(project_id, app_id) {
|
|
72
|
+
const URL = this.APPS_API_URL + `/api/installation/${project_id}`;
|
|
73
|
+
const HTTPREQUEST = {
|
|
74
|
+
url: URL,
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json',
|
|
77
|
+
},
|
|
78
|
+
method: 'GET'
|
|
79
|
+
};
|
|
80
|
+
let promise = new Promise((resolve, reject) => {
|
|
81
|
+
TiledeskAppsClient.myrequest(
|
|
82
|
+
HTTPREQUEST,
|
|
83
|
+
function(err, resbody) {
|
|
84
|
+
if (err) {
|
|
85
|
+
reject(err);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
let obj = resbody.find(o => o.app_id === app_id);
|
|
89
|
+
if (obj) {
|
|
90
|
+
resolve(obj);
|
|
91
|
+
} else {
|
|
92
|
+
resolve(null);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}, true);
|
|
96
|
+
})
|
|
97
|
+
return promise;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
uninstall(project_id, app_id, callback) {
|
|
101
|
+
const URL = this.APPS_API_URL + `/api/installation/${project_id}/${app_id}`;
|
|
102
|
+
const HTTPREQUEST = {
|
|
103
|
+
url: URL,
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'application/json',
|
|
106
|
+
},
|
|
107
|
+
method: 'DELETE'
|
|
108
|
+
};
|
|
109
|
+
let promise = new Promise((resolve, reject) => {
|
|
110
|
+
TiledeskAppsClient.myrequest(
|
|
111
|
+
HTTPREQUEST,
|
|
112
|
+
function(err, resbody) {
|
|
113
|
+
if (err) {
|
|
114
|
+
if (callback) {
|
|
115
|
+
callback(err);
|
|
116
|
+
}
|
|
117
|
+
reject(err);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
if (callback) {
|
|
121
|
+
callback(null, resbody);
|
|
122
|
+
}
|
|
123
|
+
winston.verbose("(tgm) [TiledeskAppsClient] Uninstalled!");
|
|
124
|
+
resolve(resbody);
|
|
125
|
+
}
|
|
126
|
+
}, true);
|
|
127
|
+
})
|
|
128
|
+
return promise;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
// HTTP REQUEST
|
|
134
|
+
|
|
135
|
+
static async myrequest(options, callback, log) {
|
|
136
|
+
|
|
137
|
+
return await axios({
|
|
138
|
+
url: options.url,
|
|
139
|
+
method: options.method,
|
|
140
|
+
data: options.json,
|
|
141
|
+
params: options.params,
|
|
142
|
+
headers: options.headers
|
|
143
|
+
}).then((res) => {
|
|
144
|
+
if (res && res.status == 200 && res.data) {
|
|
145
|
+
if (callback) {
|
|
146
|
+
callback(null, res.data);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (callback) {
|
|
151
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}).catch((err) => {
|
|
155
|
+
if (callback) {
|
|
156
|
+
callback(err, null, null);
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = { TiledeskAppsClient }
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const jwt = require('jsonwebtoken');
|
|
3
|
+
const { v4: uuidv4 } = require('uuid');
|
|
4
|
+
const winston = require('../winston');
|
|
5
|
+
|
|
6
|
+
class TiledeskChannel {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Constructor for TiledeskChannel
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { TiledeskChannel } = require('tiledesk-channel');
|
|
13
|
+
* const tdChannel = new TiledeskChannel({tiledeskJsonMessage: replyFromWhatsapp, settings: appSettings, whatsappJsonMessage: originalWhatsappMessage, API_URL: tiledeskApiUrl });
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} config JSON configuration.
|
|
16
|
+
* @param {string} config.tiledeskJsonMessage Mandatory. Message translated from Whatsapp to Tiledesk
|
|
17
|
+
* @param {string} config.whatsappJsonMessage Mandatory. Original whatsapp message.
|
|
18
|
+
* @param {string} config.settings Mandatory. Installation settings.
|
|
19
|
+
* @param {string} config.API_URL Mandatory. Tiledesk api url.
|
|
20
|
+
* @param {boolean} options.log Optional. If true HTTP requests are logged.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
constructor(config) {
|
|
24
|
+
if (!config) {
|
|
25
|
+
throw new Error('config is mandatory');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!config.settings) {
|
|
29
|
+
throw new Error('config.settings is mandatory');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!config.API_URL) {
|
|
33
|
+
throw new Error('config.API_URL is mandatory');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.log = false;
|
|
37
|
+
if (config.log) {
|
|
38
|
+
this.log = config.log;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.settings = config.settings;
|
|
42
|
+
this.API_URL = config.API_URL;
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async send(tiledeskMessage, messageInfo, department_id) {
|
|
47
|
+
|
|
48
|
+
let channel;
|
|
49
|
+
let new_request_id;
|
|
50
|
+
var payload = {};
|
|
51
|
+
|
|
52
|
+
if (department_id) {
|
|
53
|
+
tiledeskMessage.departmentid = department_id;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (messageInfo.channel == "whatsapp") {
|
|
57
|
+
channel = messageInfo.whatsapp;
|
|
58
|
+
new_request_id = "support-group-" + this.settings.project_id + "-" + uuidv4().substring(0, 8) + "-wab-" + channel.phone_number_id + "-" + channel.from;
|
|
59
|
+
|
|
60
|
+
payload = {
|
|
61
|
+
_id: 'wab-' + channel.from,
|
|
62
|
+
first_name: channel.firstname,
|
|
63
|
+
last_name: channel.lastname,
|
|
64
|
+
email: 'na@whatsapp.com',
|
|
65
|
+
sub: 'userexternal',
|
|
66
|
+
aud: 'https://tiledesk.com/subscriptions/' + this.settings.subscriptionId
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
} else if (messageInfo.channel == "telegram") {
|
|
70
|
+
channel = messageInfo.telegram;
|
|
71
|
+
new_request_id = "support-group-" + this.settings.project_id + "-" + uuidv4().substring(0, 8) + "-telegram-" + channel.from;
|
|
72
|
+
|
|
73
|
+
payload = {
|
|
74
|
+
_id: 'telegram-' + channel.from,
|
|
75
|
+
first_name: channel.firstname,
|
|
76
|
+
last_name: channel.lastname,
|
|
77
|
+
email: 'na@telegram.com',
|
|
78
|
+
sub: 'userexternal',
|
|
79
|
+
aud: 'https://tiledesk.com/subscriptions/' + this.settings.subscriptionId
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
} else if (messageInfo.channel == "messenger") {
|
|
83
|
+
channel = messageInfo.messenger;
|
|
84
|
+
// Check it
|
|
85
|
+
//new_request_id = hased_request_id = "support-group-" + projectId + "-" + uuidv4() + "-" + sender_id + "-" + webhook_event.recipient.id;
|
|
86
|
+
|
|
87
|
+
} else {
|
|
88
|
+
winston.verbose("(tgm) [TiledeskChannel] Channel not supported")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var customToken = jwt.sign(payload, this.settings.secret);
|
|
92
|
+
|
|
93
|
+
return await axios({
|
|
94
|
+
url: this.API_URL + "/auth/signinWithCustomToken",
|
|
95
|
+
headers: {
|
|
96
|
+
'Content-Type': 'application/json',
|
|
97
|
+
'Authorization': "JWT " + customToken
|
|
98
|
+
},
|
|
99
|
+
data: {},
|
|
100
|
+
method: 'POST'
|
|
101
|
+
}).then((response) => {
|
|
102
|
+
|
|
103
|
+
let token = response.data.token;
|
|
104
|
+
|
|
105
|
+
return axios({
|
|
106
|
+
url: this.API_URL + `/${this.settings.project_id}/requests/me?channel=${messageInfo.channel}`,
|
|
107
|
+
headers: {
|
|
108
|
+
'Content-Type': 'application/json',
|
|
109
|
+
'Authorization': token
|
|
110
|
+
},
|
|
111
|
+
method: 'GET'
|
|
112
|
+
}).then((response) => {
|
|
113
|
+
|
|
114
|
+
let request_id;
|
|
115
|
+
if (response.data.requests[0]) {
|
|
116
|
+
request_id = response.data.requests[0].request_id;
|
|
117
|
+
winston.debug("(tgm) [TiledeskChannel] Old request id: ", request_id);
|
|
118
|
+
} else {
|
|
119
|
+
request_id = new_request_id;
|
|
120
|
+
winston.debug("(tgm) [TiledeskChannel] New request id: ", request_id);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
winston.debug("(tgm) [TiledeskChannel] tiledeskMessage:", tiledeskMessage);
|
|
124
|
+
|
|
125
|
+
return axios({
|
|
126
|
+
url: this.API_URL + `/${this.settings.project_id}/requests/${request_id}/messages`,
|
|
127
|
+
headers: {
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
'Authorization': token
|
|
130
|
+
},
|
|
131
|
+
data: tiledeskMessage,
|
|
132
|
+
method: 'POST'
|
|
133
|
+
}).then((response) => {
|
|
134
|
+
return response;
|
|
135
|
+
|
|
136
|
+
}).catch((err) => {
|
|
137
|
+
winston.error("(tgm) [TiledeskChannel] send message error: " + err);
|
|
138
|
+
return err;
|
|
139
|
+
})
|
|
140
|
+
}).catch((err) => {
|
|
141
|
+
winston.error("(tgm) [TiledeskChannel] get requests error: " + err);
|
|
142
|
+
return err;
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
}).catch((err) => {
|
|
147
|
+
winston.error("(tgm) [TiledeskChannel] sign in error: " + err);
|
|
148
|
+
return err;
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async getDepartments() {
|
|
155
|
+
|
|
156
|
+
return await axios({
|
|
157
|
+
url: this.API_URL + "/" + this.settings.project_id + "/departments/allstatus",
|
|
158
|
+
headers: {
|
|
159
|
+
'Content-Type': 'application/json',
|
|
160
|
+
'Authorization': this.settings.token
|
|
161
|
+
},
|
|
162
|
+
method: 'GET'
|
|
163
|
+
}).then((response) => {
|
|
164
|
+
winston.debug("(tgm) [TiledeskChannel] get departments response.data: ", response.data)
|
|
165
|
+
return response.data;
|
|
166
|
+
}).catch((err) => {
|
|
167
|
+
winston.error("(tgm) [TiledeskChannel] get departments error: " + err.response.data);
|
|
168
|
+
return null;
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
module.exports = { TiledeskChannel }
|
|
175
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const winston = require('../winston');
|
|
3
|
+
|
|
4
|
+
class TiledeskSubscriptionClient {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Constructor for TiledeskSubscriptionClient
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const { TiledeskSubscriptionClient } = require('tiledesk-subscription-client');
|
|
11
|
+
* const tdClient = new TiledeskSubscriptionClient({API_URL: tiledeskApiUrl, token: jwt_token, log: log});
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} config JSON configuration.
|
|
14
|
+
* @param {Object} config..
|
|
15
|
+
* @param {string} config.API_URL Mandatory. The Tiledesk api url.
|
|
16
|
+
* @param {string} config.token Optional. Token required for authentication.
|
|
17
|
+
* @param {boolean} config.log Optional. If true HTTP requests are logged.
|
|
18
|
+
*/
|
|
19
|
+
constructor(config) {
|
|
20
|
+
if (!config) {
|
|
21
|
+
throw new Error('config is mandatory');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!config.API_URL) {
|
|
25
|
+
throw new Error('config.API_URL is mandatory');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.project_id = config.project_id
|
|
29
|
+
this.API_URL = config.API_URL;
|
|
30
|
+
this.token = config.token;
|
|
31
|
+
this.config = config;
|
|
32
|
+
this.log = false;
|
|
33
|
+
if (config.log) {
|
|
34
|
+
this.log = config.log;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async subscribe(subscription_info, callback) {
|
|
39
|
+
|
|
40
|
+
const URL = this.API_URL + `/${this.project_id}/subscriptions`;
|
|
41
|
+
const HTTPREQUEST = {
|
|
42
|
+
url: URL,
|
|
43
|
+
headers: {
|
|
44
|
+
'Content-Type': 'application/json',
|
|
45
|
+
'Authorization': this.token
|
|
46
|
+
},
|
|
47
|
+
json: subscription_info,
|
|
48
|
+
method: 'POST'
|
|
49
|
+
};
|
|
50
|
+
let promise = new Promise((resolve, reject) => {
|
|
51
|
+
TiledeskSubscriptionClient.myrequest(
|
|
52
|
+
HTTPREQUEST,
|
|
53
|
+
function(err, resbody) {
|
|
54
|
+
if (err) {
|
|
55
|
+
if (callback) {
|
|
56
|
+
callback(err);
|
|
57
|
+
}
|
|
58
|
+
reject(err);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (callback) {
|
|
62
|
+
callback(null, resbody);
|
|
63
|
+
}
|
|
64
|
+
winston.verbose("(tgm) [TiledeskSubscriptionClient] Subscribed");
|
|
65
|
+
resolve(resbody);
|
|
66
|
+
}
|
|
67
|
+
}, true);
|
|
68
|
+
|
|
69
|
+
})
|
|
70
|
+
return promise;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
unsubscribe(subscriptionId, callback) {
|
|
74
|
+
const URL = this.API_URL + `/${this.project_id}/subscriptions/${subscriptionId}`;
|
|
75
|
+
const HTTPREQUEST = {
|
|
76
|
+
url: URL,
|
|
77
|
+
headers: {
|
|
78
|
+
'Content-Type': 'application/json',
|
|
79
|
+
'Authorization': this.token
|
|
80
|
+
},
|
|
81
|
+
method: 'DELETE'
|
|
82
|
+
};
|
|
83
|
+
let promise = new Promise((resolve, reject) => {
|
|
84
|
+
TiledeskSubscriptionClient.myrequest(
|
|
85
|
+
HTTPREQUEST,
|
|
86
|
+
function(err, resbody) {
|
|
87
|
+
if (err) {
|
|
88
|
+
if (callback) {
|
|
89
|
+
callback(err);
|
|
90
|
+
}
|
|
91
|
+
reject(err);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
if (callback) {
|
|
95
|
+
callback(null, resbody);
|
|
96
|
+
}
|
|
97
|
+
winston.verbose("(tgm) [TiledeskSubscriptionClient] Unsubscribed");
|
|
98
|
+
resolve(resbody);
|
|
99
|
+
}
|
|
100
|
+
}, true);
|
|
101
|
+
})
|
|
102
|
+
return promise;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
// HTTP REQUEST
|
|
107
|
+
|
|
108
|
+
static async myrequest(options, callback, log) {
|
|
109
|
+
|
|
110
|
+
return await axios({
|
|
111
|
+
url: options.url,
|
|
112
|
+
method: options.method,
|
|
113
|
+
data: options.json,
|
|
114
|
+
params: options.params,
|
|
115
|
+
headers: options.headers
|
|
116
|
+
}).then((res) => {
|
|
117
|
+
winston.debug("(tgm) [TiledeskSubscriptionClient] Response headers:\n", res.headers);
|
|
118
|
+
if (res && res.status == 200 && res.data) {
|
|
119
|
+
if (callback) {
|
|
120
|
+
callback(null, res.data);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
if (callback) {
|
|
125
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}).catch((err) => {
|
|
129
|
+
winston.error("(tgm) [TiledeskSubscriptionClient] An error occured: ", err);
|
|
130
|
+
if (callback) {
|
|
131
|
+
callback(err, null, null);
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = { TiledeskSubscriptionClient }
|