@tiledesk/tiledesk-server 2.10.86 → 2.10.88
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/CHANGELOG.md +15 -0
- package/app.js +4 -0
- package/errorCodes.js +6 -0
- package/event/botEvent.js +89 -42
- package/jobsManager.js +4 -1
- package/models/chatbotTemplates.js +22 -0
- package/models/faq.js +14 -1
- package/models/faq_kb.js +64 -2
- package/models/flowLogs.js +64 -0
- package/models/user.js +7 -0
- package/models/webhook.js +30 -0
- package/package.json +4 -4
- package/routes/auth.js +1 -1
- package/routes/faq.js +6 -0
- package/routes/faq_kb.js +123 -85
- package/routes/logs.js +80 -3
- package/routes/request.js +2 -2
- package/routes/users.js +3 -0
- package/routes/webhook.js +54 -25
- package/routes/webhooks.js +119 -2
- package/services/chatbotService.js +24 -18
- package/services/faqService.js +35 -331
- package/services/logsService.js +59 -0
- package/services/userService.js +3 -2
- package/services/webhookService.js +21 -2
- package/template/chatbot/blank.js +79 -0
- package/template/chatbot/blank_copilot.js +43 -0
- package/template/chatbot/blank_voice.js +108 -0
- package/template/chatbot/blank_voice_twilio.js +115 -0
- package/template/chatbot/blank_webhook.js +43 -0
- package/template/chatbot/empty.js +3 -0
- package/template/chatbot/example.js +88 -0
- package/template/chatbot/handoff.js +25 -0
- package/template/chatbot/index.js +12 -0
- package/template/chatbot/official_copilot.js +717 -0
- package/test/faqkbRoute.js +165 -23
- package/test/webhookRoute.js +247 -2
- package/utils/TdCache.js +3 -3
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,21 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.10.88
|
9
|
+
- Added: modified field in faq_kb model
|
10
|
+
- Added: chatbot template refactoring
|
11
|
+
- Added: clearing logic for chatbot
|
12
|
+
- Added: ttl when a chatbot is deleted
|
13
|
+
- Added: flow logs apis
|
14
|
+
- Added: webhooks apis
|
15
|
+
- Added: user_phone field in user model
|
16
|
+
|
17
|
+
# 2.10.87
|
18
|
+
- Updated voice-twilio-connector to 0.1.18
|
19
|
+
|
20
|
+
# 2.10.86
|
21
|
+
- Updated voice-twilio-connector to 0.1.16
|
22
|
+
|
8
23
|
# 2.10.85
|
9
24
|
- Updated: default system context for gpt-4.1 models
|
10
25
|
|
package/app.js
CHANGED
@@ -202,6 +202,10 @@ let whatsappQueue = require('@tiledesk/tiledesk-whatsapp-jobworker');
|
|
202
202
|
winston.info("whatsappQueue");
|
203
203
|
jobsManager.listenWhatsappQueue(whatsappQueue);
|
204
204
|
|
205
|
+
let multiWorkerQueue = require('@tiledesk/tiledesk-multi-worker');
|
206
|
+
winston.info("multiWorkerQueue from App")
|
207
|
+
jobsManager.listenMultiWorker(multiWorkerQueue);
|
208
|
+
|
205
209
|
var channelManager = require('./channels/channelManager');
|
206
210
|
channelManager.listen();
|
207
211
|
|
package/errorCodes.js
CHANGED
package/event/botEvent.js
CHANGED
@@ -2,25 +2,24 @@ const EventEmitter = require('events');
|
|
2
2
|
const messageEvent = require('../event/messageEvent');
|
3
3
|
const Faq_kb = require('../models/faq_kb');
|
4
4
|
var winston = require('../config/winston');
|
5
|
-
|
6
|
-
|
7
5
|
const cacheUtil = require("../utils/cacheUtil");
|
8
6
|
const cacheEnabler = require("../services/cacheEnabler");
|
7
|
+
var Faq = require("../models/faq");
|
8
|
+
const { Webhook } = require('../models/webhook');
|
9
9
|
|
10
10
|
// class BotEvent extends EventEmitter {}
|
11
11
|
class BotEvent extends EventEmitter {
|
12
|
+
|
12
13
|
constructor() {
|
13
14
|
super();
|
14
15
|
this.queueEnabled = false;
|
15
16
|
this.setMaxListeners(11);
|
16
|
-
|
17
|
+
}
|
17
18
|
|
18
19
|
|
19
|
-
|
20
|
+
listen() {
|
20
21
|
//TODO modify to async
|
21
22
|
//messageEvent.on('message.received', function(message) {
|
22
|
-
|
23
|
-
|
24
23
|
var messageCreateKey = 'message.create';
|
25
24
|
if (messageEvent.queueEnabled) {
|
26
25
|
messageCreateKey = 'message.create.queue';
|
@@ -28,7 +27,7 @@ class BotEvent extends EventEmitter {
|
|
28
27
|
|
29
28
|
winston.info("Listening " + messageCreateKey + " event for Chatbot messages");
|
30
29
|
|
31
|
-
messageEvent.on(messageCreateKey, function(message) {
|
30
|
+
messageEvent.on(messageCreateKey, function (message) {
|
32
31
|
|
33
32
|
winston.debug("message", message);
|
34
33
|
|
@@ -49,7 +48,7 @@ class BotEvent extends EventEmitter {
|
|
49
48
|
// }
|
50
49
|
|
51
50
|
if (message.sender === "system") {
|
52
|
-
if (message.text && (message.text=="\\start" || message.text=="/start")
|
51
|
+
if (message.text && (message.text == "\\start" || message.text == "/start")) {
|
53
52
|
winston.debug("it s a start message");
|
54
53
|
} else {
|
55
54
|
winston.debug("it s a message sent from system, exit");
|
@@ -58,28 +57,28 @@ class BotEvent extends EventEmitter {
|
|
58
57
|
} else {
|
59
58
|
winston.debug("it s a message sent from other let s go");
|
60
59
|
}
|
61
|
-
|
62
|
-
if (message.text && (
|
60
|
+
|
61
|
+
if (message.text && (message.text.indexOf("\\agent") > -1 || message.text.indexOf("\\close") > -1)) { //not reply to a message containing \\agent
|
63
62
|
return 0;
|
64
63
|
}
|
65
64
|
|
66
65
|
// if (message.text.startsWith("\\")) { //not reply to a message containing \
|
67
66
|
// return null;
|
68
67
|
// }
|
69
|
-
|
70
|
-
var botId = getBotId(message);
|
71
68
|
|
72
|
-
|
69
|
+
var botId = getBotId(message);
|
73
70
|
|
74
|
-
|
71
|
+
winston.debug("botId: " + botId);
|
72
|
+
|
73
|
+
if (!botId) {
|
75
74
|
return null;
|
76
|
-
}else {
|
77
|
-
|
75
|
+
} else {
|
76
|
+
//loop fix for messages sent from external bot
|
78
77
|
// botprefix
|
79
|
-
if (message.sender === 'bot_'+botId || message.sender === botId) {
|
78
|
+
if (message.sender === 'bot_' + botId || message.sender === botId) {
|
80
79
|
winston.debug("it s a message sent from bot, exit");
|
81
|
-
return null;
|
82
|
-
}else {
|
80
|
+
return null;
|
81
|
+
} else {
|
83
82
|
messageEvent.emit('message.received.for.bot', message); //UNUSED
|
84
83
|
}
|
85
84
|
|
@@ -88,51 +87,99 @@ class BotEvent extends EventEmitter {
|
|
88
87
|
// qui potresti leggere anche +secret ed evitare prossima query in botNotification
|
89
88
|
// let qbot = Faq_kb.findById(botId); //TODO add cache_bot_here
|
90
89
|
let qbot = Faq_kb.findById(botId).select('+secret')
|
91
|
-
|
92
|
-
|
93
|
-
if (cacheEnabler.faq_kb) {
|
94
|
-
winston.debug('message.id_project+":faq_kbs:id:"+botId: '+ message.id_project+":faq_kbs:id:"+botId);
|
95
|
-
// qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
|
96
|
-
qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId+":secret")
|
97
|
-
winston.debug('faq_kb cache enabled');
|
98
|
-
}
|
90
|
+
//TODO unselect secret. secret is unselectable by default in the model
|
99
91
|
|
100
|
-
|
92
|
+
if (cacheEnabler.faq_kb) {
|
93
|
+
winston.debug('message.id_project+":faq_kbs:id:"+botId: ' + message.id_project + ":faq_kbs:id:" + botId);
|
94
|
+
// qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
|
95
|
+
qbot.cache(cacheUtil.defaultTTL, message.id_project + ":faq_kbs:id:" + botId + ":secret")
|
96
|
+
winston.debug('faq_kb cache enabled');
|
97
|
+
}
|
101
98
|
|
99
|
+
qbot.exec(function (err, bot) {
|
102
100
|
|
103
|
-
|
104
101
|
if (err) {
|
105
|
-
|
106
|
-
|
102
|
+
winston.error('Error getting object.', err);
|
103
|
+
return 0;
|
107
104
|
}
|
108
105
|
if (!bot) {
|
109
|
-
winston.warn('Bot not found with id '+botId);
|
106
|
+
winston.warn('Bot not found with id ' + botId);
|
110
107
|
}
|
111
108
|
|
112
109
|
winston.debug("bot debug", bot);
|
113
|
-
winston.debug('bot debug secret: '+ bot.secret);
|
110
|
+
winston.debug('bot debug secret: ' + bot.secret);
|
114
111
|
|
115
112
|
if (bot) {
|
116
|
-
if (bot.type==="internal") {
|
113
|
+
if (bot.type === "internal") {
|
117
114
|
botEvent.emit('bot.message.received.notify.internal', message);
|
118
|
-
|
119
|
-
}else { //external
|
115
|
+
|
116
|
+
} else { //external
|
120
117
|
if (bot.url) {
|
121
|
-
var botNotification = {bot: bot, message: message};
|
118
|
+
var botNotification = { bot: bot, message: message };
|
122
119
|
botEvent.emit('bot.message.received.notify.external', botNotification);
|
123
|
-
}else {
|
120
|
+
} else {
|
124
121
|
winston.warn("bot url is not defined", bot);
|
125
122
|
}
|
126
123
|
}
|
127
|
-
}
|
124
|
+
}
|
128
125
|
|
129
126
|
});
|
130
|
-
|
131
|
-
|
132
127
|
|
133
128
|
});
|
134
129
|
|
135
|
-
|
130
|
+
botEvent.on('faqbot.update.virtual.delete', async (chatbot) => {
|
131
|
+
winston.verbose("botEvent ON faqbot.update.virtual.delete: ", chatbot);
|
132
|
+
|
133
|
+
if (chatbot.publishedAt) {
|
134
|
+
// Stop the flow if the chatbot is a published one
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
|
138
|
+
await Faq.updateMany({ id_faq_kb: chatbot._id }, { trashed: true, trashedAt: chatbot.trashedAt }).catch((err) => {
|
139
|
+
winston.error("Event faqbot.update.virtual.delete error updating faqs ", err);
|
140
|
+
})
|
141
|
+
|
142
|
+
let deletedW = await Webhook.findOneAndDelete({ chatbot_id: chatbot._id }).catch((err) => {
|
143
|
+
winston.error("Error deleting webhook on chatbot deleting: ", err);
|
144
|
+
})
|
145
|
+
|
146
|
+
let publishedChatbots = await Faq_kb.find({ root_id: chatbot._id }, { _id: 1 }).catch((err) => {
|
147
|
+
winston.error("Event faqbot.update.virtual.delete error getting all published chatbots ", err);
|
148
|
+
})
|
149
|
+
|
150
|
+
const publishedChatbotIds = publishedChatbots.map(c => c._id);
|
151
|
+
|
152
|
+
if (publishedChatbotIds.length > 0) {
|
153
|
+
|
154
|
+
const batchSize = 20;
|
155
|
+
const sleep_ms = 500;
|
156
|
+
const batches = [];
|
157
|
+
for (let i = 0; i < publishedChatbotIds.length; i += batchSize) {
|
158
|
+
batches.push(publishedChatbotIds.slice(i, i + batchSize));
|
159
|
+
}
|
160
|
+
|
161
|
+
for (const batch of batches) {
|
162
|
+
await Faq_kb.updateMany(
|
163
|
+
{ _id: { $in: batch } },
|
164
|
+
{ $set: { trashed: true, trashedAt: chatbot.trashedAt } }
|
165
|
+
);
|
166
|
+
|
167
|
+
await Faq.updateMany(
|
168
|
+
{ id_faq_kb: { $in: batch } },
|
169
|
+
{ $set: { trashed: true, trashedAt: chatbot.trashedAt } }
|
170
|
+
);
|
171
|
+
|
172
|
+
await sleep(sleep_ms);
|
173
|
+
}
|
174
|
+
|
175
|
+
}
|
176
|
+
})
|
177
|
+
|
178
|
+
function sleep(ms) {
|
179
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
180
|
+
}
|
181
|
+
|
182
|
+
}
|
136
183
|
|
137
184
|
}
|
138
185
|
|
package/jobsManager.js
CHANGED
@@ -12,7 +12,8 @@ class JobsManager {
|
|
12
12
|
this.emailNotificatio = undefined;
|
13
13
|
this.activityArchiver = undefined;
|
14
14
|
this.whatsappWorker = undefined;
|
15
|
-
|
15
|
+
this.multiWorkerQueue = undefined;
|
16
|
+
|
16
17
|
this.jobWorkerEnabled = jobWorkerEnabled;
|
17
18
|
// this.jobWorkerEnabled = false;
|
18
19
|
// if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED == true) {
|
@@ -93,6 +94,8 @@ class JobsManager {
|
|
93
94
|
if (this.jobWorkerEnabled == true) {
|
94
95
|
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for MultiWorker Queue");
|
95
96
|
}
|
97
|
+
this.multiWorkerQueue = multiWorkerQueue;
|
98
|
+
this.multiWorkerQueue.startJobsWorker();
|
96
99
|
}
|
97
100
|
|
98
101
|
// listenTrainingQueue(trainingQueue) {
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module.exports = {
|
2
|
+
chatbot: {
|
3
|
+
default: 'blank',
|
4
|
+
templates: ['empty', 'blank', 'handoff', 'example']
|
5
|
+
},
|
6
|
+
webhook: {
|
7
|
+
default: 'blank_webhook',
|
8
|
+
templates: ['empty', 'blank_webhook']
|
9
|
+
},
|
10
|
+
copilot: {
|
11
|
+
default: 'official_copilot',
|
12
|
+
templates: ['empty', 'blank_copilot', 'official_copilot']
|
13
|
+
},
|
14
|
+
voice: {
|
15
|
+
default: 'blank_voice',
|
16
|
+
templates: ['empty', 'blank_voice']
|
17
|
+
},
|
18
|
+
voice_twilio: {
|
19
|
+
default: 'blank_voice_twilio',
|
20
|
+
templates: ['empty', 'blank_voice_twilio']
|
21
|
+
}
|
22
|
+
}
|
package/models/faq.js
CHANGED
@@ -5,6 +5,7 @@ var { nanoid } = require("nanoid");
|
|
5
5
|
const uuidv4 = require('uuid/v4');
|
6
6
|
|
7
7
|
var defaultFullTextLanguage = process.env.DEFAULT_FULLTEXT_INDEX_LANGUAGE || "none";
|
8
|
+
let trashExpirationTime = Number(process.env.CHATBOT_TRASH_TTL_SECONDS) || 60 * 60 * 24 * 30; // 30 days
|
8
9
|
|
9
10
|
var FaqSchema = new Schema({
|
10
11
|
// _id: {
|
@@ -107,7 +108,15 @@ var FaqSchema = new Schema({
|
|
107
108
|
default: function () {
|
108
109
|
return this.isNew ? false : undefined;
|
109
110
|
},
|
110
|
-
}
|
111
|
+
},
|
112
|
+
trashed: {
|
113
|
+
type: Boolean,
|
114
|
+
index: true
|
115
|
+
},
|
116
|
+
trashedAt: {
|
117
|
+
type: Date,
|
118
|
+
required: false
|
119
|
+
},
|
111
120
|
}, {
|
112
121
|
timestamps: true,
|
113
122
|
toJSON: { virtuals: true } //used to polulate messages in toJSON// https://mongoosejs.com/docs/populate.html
|
@@ -183,6 +192,10 @@ FaqSchema.index(
|
|
183
192
|
{ partialFilterExpression: { "actions.namespace": { $exists: true } } }
|
184
193
|
);
|
185
194
|
|
195
|
+
FaqSchema.index(
|
196
|
+
{ trashedAt: 1 },
|
197
|
+
{ expireAfterSeconds: trashExpirationTime }
|
198
|
+
);
|
186
199
|
|
187
200
|
var faq = mongoose.model('faq', FaqSchema);
|
188
201
|
|
package/models/faq_kb.js
CHANGED
@@ -5,7 +5,7 @@ var winston = require('../config/winston');
|
|
5
5
|
const { stringify } = require('uuid');
|
6
6
|
|
7
7
|
var defaultFullTextLanguage = process.env.DEFAULT_FULLTEXT_INDEX_LANGUAGE || "none";
|
8
|
-
|
8
|
+
let trashExpirationTime = Number(process.env.CHATBOT_TRASH_TTL_SECONDS) || 60 * 60 * 24 * 30; // 30 days
|
9
9
|
|
10
10
|
var Faq_kbSchema = new Schema({
|
11
11
|
name: {
|
@@ -58,6 +58,10 @@ var Faq_kbSchema = new Schema({
|
|
58
58
|
type: Boolean,
|
59
59
|
index: true
|
60
60
|
},
|
61
|
+
trashedAt: {
|
62
|
+
type: Date,
|
63
|
+
required: false
|
64
|
+
},
|
61
65
|
secret: {
|
62
66
|
type: String,
|
63
67
|
required: true,
|
@@ -107,8 +111,13 @@ var Faq_kbSchema = new Schema({
|
|
107
111
|
index: true,
|
108
112
|
default: 0
|
109
113
|
},
|
114
|
+
// publishedBy: {
|
115
|
+
// type: String,
|
116
|
+
// },
|
110
117
|
publishedBy: {
|
111
|
-
type:
|
118
|
+
type: Schema.Types.ObjectId,
|
119
|
+
ref: 'user',
|
120
|
+
required: false
|
112
121
|
},
|
113
122
|
publishedAt: {
|
114
123
|
type: Date
|
@@ -140,6 +149,18 @@ var Faq_kbSchema = new Schema({
|
|
140
149
|
type: String,
|
141
150
|
required: false,
|
142
151
|
index: true
|
152
|
+
},
|
153
|
+
modified: {
|
154
|
+
type: Boolean,
|
155
|
+
required: false
|
156
|
+
},
|
157
|
+
root_id: {
|
158
|
+
type: String,
|
159
|
+
required: false
|
160
|
+
},
|
161
|
+
release_note: {
|
162
|
+
type: String,
|
163
|
+
required: false
|
143
164
|
}
|
144
165
|
},{
|
145
166
|
timestamps: true
|
@@ -171,6 +192,37 @@ Faq_kbSchema.pre("save", async function (next) {
|
|
171
192
|
next();
|
172
193
|
});
|
173
194
|
|
195
|
+
Faq_kbSchema.pre('findOneAndUpdate', async function (next) {
|
196
|
+
|
197
|
+
const update = this.getUpdate();
|
198
|
+
const isUnsetSlug = update?.$unset?.slug !== undefined;
|
199
|
+
|
200
|
+
// $unset.slug is used only on publishing. In this case, skip the slug change and the set of trashedAt
|
201
|
+
if (update.trashed === true && !isUnsetSlug) {
|
202
|
+
|
203
|
+
const docToUpdate = await this.model.findOne(this.getQuery());
|
204
|
+
const timestamp = Date.now();
|
205
|
+
|
206
|
+
if (docToUpdate && docToUpdate.slug) {
|
207
|
+
let slug;
|
208
|
+
slug = docToUpdate.slug;
|
209
|
+
update.trashedAt = new Date();
|
210
|
+
update.slug = `${slug || 'undefined'}-trashed-${timestamp}`;
|
211
|
+
}
|
212
|
+
this.setUpdate(update);
|
213
|
+
}
|
214
|
+
|
215
|
+
next();
|
216
|
+
|
217
|
+
});
|
218
|
+
|
219
|
+
Faq_kbSchema.post('findOneAndUpdate', async function (doc) {
|
220
|
+
if (doc && doc.trashed === true) {
|
221
|
+
botEvent.emit('faqbot.update.virtual.delete', doc)
|
222
|
+
}
|
223
|
+
})
|
224
|
+
|
225
|
+
|
174
226
|
Faq_kbSchema.virtual('fullName').get(function () {
|
175
227
|
// winston.debug("faq_kb fullName virtual called");
|
176
228
|
return (this.name);
|
@@ -188,6 +240,11 @@ Faq_kbSchema.index(
|
|
188
240
|
{ unique: true, partialFilterExpression: { slug: { $exists: true } } }
|
189
241
|
);
|
190
242
|
|
243
|
+
Faq_kbSchema.index(
|
244
|
+
{ trashedAt: 1 },
|
245
|
+
{ expireAfterSeconds: trashExpirationTime }
|
246
|
+
);
|
247
|
+
|
191
248
|
|
192
249
|
var faq_kb = mongoose.model('faq_kb', Faq_kbSchema);
|
193
250
|
|
@@ -209,3 +266,8 @@ function generateSlug(name) {
|
|
209
266
|
}
|
210
267
|
|
211
268
|
module.exports = faq_kb
|
269
|
+
|
270
|
+
|
271
|
+
|
272
|
+
// Import botEvent after model declaration to avoid circular dependency issues
|
273
|
+
const botEvent = require('../event/botEvent');
|
@@ -0,0 +1,64 @@
|
|
1
|
+
const mongoose = require('mongoose');
|
2
|
+
const Schema = mongoose.Schema;
|
3
|
+
|
4
|
+
const RowSchema = new Schema(
|
5
|
+
{
|
6
|
+
text: {
|
7
|
+
type: String,
|
8
|
+
required: true
|
9
|
+
},
|
10
|
+
level: {
|
11
|
+
type: String,
|
12
|
+
required: true
|
13
|
+
},
|
14
|
+
timestamp: {
|
15
|
+
type: Date,
|
16
|
+
required: true,
|
17
|
+
default: Date.now
|
18
|
+
}
|
19
|
+
}
|
20
|
+
);
|
21
|
+
|
22
|
+
const FlowLogsSchema = new Schema(
|
23
|
+
{
|
24
|
+
id_project: {
|
25
|
+
type: String,
|
26
|
+
required: false,
|
27
|
+
},
|
28
|
+
request_id: {
|
29
|
+
type: String,
|
30
|
+
required: false,
|
31
|
+
},
|
32
|
+
level: {
|
33
|
+
type: String,
|
34
|
+
required: true,
|
35
|
+
},
|
36
|
+
rows: {
|
37
|
+
type: [RowSchema],
|
38
|
+
required: false,
|
39
|
+
},
|
40
|
+
}, {
|
41
|
+
timestamps: true
|
42
|
+
}
|
43
|
+
);
|
44
|
+
|
45
|
+
FlowLogsSchema.index({ request_id: 1 }, { unique: true });
|
46
|
+
|
47
|
+
// FlowLogsSchema.pre('findOneAndUpdate', async function (next) {
|
48
|
+
// const update = this.getUpdate();
|
49
|
+
|
50
|
+
// if (update.$push && update.$push.rows) {
|
51
|
+
// const doc = await this.model.findOne(this.getQuery());
|
52
|
+
|
53
|
+
// if (!doc) {
|
54
|
+
// update.$push.rows.index = 0;
|
55
|
+
// } else {
|
56
|
+
// update.$push.rows.index = doc.rows.length;
|
57
|
+
// }
|
58
|
+
// }
|
59
|
+
// next();
|
60
|
+
// });
|
61
|
+
|
62
|
+
const FlowLogs = mongoose.model('FlowLogs', FlowLogsSchema);
|
63
|
+
|
64
|
+
module.exports = { FlowLogs };
|
package/models/user.js
CHANGED
@@ -65,6 +65,13 @@ var UserSchema = new Schema({
|
|
65
65
|
public_website: {
|
66
66
|
type: String,
|
67
67
|
required: false
|
68
|
+
},
|
69
|
+
phone: {
|
70
|
+
type: String,
|
71
|
+
required: false,
|
72
|
+
unique: true,
|
73
|
+
trim: true,
|
74
|
+
match: [/^\+?[1-9]\d{1,14}$/, 'Invalid phone number format'], // E.164 format
|
68
75
|
}
|
69
76
|
// authType: { // update db old data
|
70
77
|
// type: String,
|
package/models/webhook.js
CHANGED
@@ -13,6 +13,10 @@ const WebhookSchema = mongoose.Schema({
|
|
13
13
|
type: String,
|
14
14
|
required: true
|
15
15
|
},
|
16
|
+
name: {
|
17
|
+
type: String,
|
18
|
+
required: false
|
19
|
+
},
|
16
20
|
chatbot_id: {
|
17
21
|
type: String,
|
18
22
|
required: true
|
@@ -29,12 +33,38 @@ const WebhookSchema = mongoose.Schema({
|
|
29
33
|
copilot: {
|
30
34
|
type: Boolean,
|
31
35
|
required: false
|
36
|
+
},
|
37
|
+
enabled: {
|
38
|
+
type: Boolean,
|
39
|
+
required: true,
|
40
|
+
default: true
|
32
41
|
}
|
33
42
|
}, {
|
34
43
|
timestamps: true
|
35
44
|
})
|
36
45
|
|
46
|
+
// Indexes
|
37
47
|
WebhookSchema.index({ id_project: 1, chatbot_id: 1}, { unique: true })
|
48
|
+
WebhookSchema.index({ id_project: 1, webhook_id: 1}, { unique: true })
|
49
|
+
|
50
|
+
// Middlewares
|
51
|
+
WebhookSchema.pre("save", async function (next) {
|
52
|
+
if (this.isNew) {
|
53
|
+
|
54
|
+
try {
|
55
|
+
const chatbot = await mongoose.model("faq_kb").findById(this.chatbot_id);
|
56
|
+
if (chatbot) {
|
57
|
+
this.name = chatbot.name + "-webhook";
|
58
|
+
}
|
59
|
+
|
60
|
+
next();
|
61
|
+
|
62
|
+
} catch(error) {
|
63
|
+
next(error);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
38
68
|
|
39
69
|
const Webhook = mongoose.model("Webhook", WebhookSchema);
|
40
70
|
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tiledesk/tiledesk-server",
|
3
3
|
"description": "The Tiledesk server module",
|
4
|
-
"version": "2.10.
|
4
|
+
"version": "2.10.88",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -47,13 +47,13 @@
|
|
47
47
|
"@tiledesk/tiledesk-messenger-connector": "^0.1.23",
|
48
48
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
49
49
|
"@tiledesk/tiledesk-telegram-connector": "^0.1.14",
|
50
|
-
"@tiledesk/tiledesk-tybot-connector": "^2.0.
|
50
|
+
"@tiledesk/tiledesk-tybot-connector": "^2.0.12",
|
51
51
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.83",
|
52
52
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.12",
|
53
53
|
"@tiledesk/tiledesk-sms-connector": "^0.1.11",
|
54
54
|
"@tiledesk/tiledesk-vxml-connector": "^0.1.76",
|
55
|
-
"@tiledesk/tiledesk-voice-twilio-connector": "^0.1.
|
56
|
-
"@tiledesk/tiledesk-multi-worker": "^0.1
|
55
|
+
"@tiledesk/tiledesk-voice-twilio-connector": "^0.1.21",
|
56
|
+
"@tiledesk/tiledesk-multi-worker": "^0.3.1",
|
57
57
|
"passport-oauth2": "^1.8.0",
|
58
58
|
"amqplib": "^0.5.5",
|
59
59
|
"app-root-path": "^3.0.0",
|
package/routes/auth.js
CHANGED
@@ -85,7 +85,7 @@ router.post('/signup',
|
|
85
85
|
// return res.status(403).send({ success: false, message: "The password does not meet the minimum vulnerability requirements"})
|
86
86
|
// }
|
87
87
|
|
88
|
-
return userService.signup(req.body.email, req.body.password, req.body.firstname, req.body.lastname, false)
|
88
|
+
return userService.signup(req.body.email, req.body.password, req.body.firstname, req.body.lastname, false, req.body.phone)
|
89
89
|
.then( async function (savedUser) {
|
90
90
|
|
91
91
|
winston.debug('-- >> -- >> savedUser ', savedUser.toObject());
|
package/routes/faq.js
CHANGED
@@ -16,6 +16,7 @@ const axios = require("axios").default;
|
|
16
16
|
var configGlobal = require('../config/global');
|
17
17
|
const roleConstants = require('../models/roleConstants');
|
18
18
|
const roleChecker = require('../middleware/has-role');
|
19
|
+
const { ChatbotService } = require('../services/chatbotService');
|
19
20
|
|
20
21
|
const apiUrl = process.env.API_URL || configGlobal.apiUrl;
|
21
22
|
|
@@ -222,6 +223,7 @@ router.post('/ops_update', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscrip
|
|
222
223
|
|
223
224
|
let id_faq_kb = req.body.id_faq_kb;
|
224
225
|
let operations = req.body.operations;
|
226
|
+
let chatbotService = new ChatbotService();
|
225
227
|
|
226
228
|
for (let op of operations) {
|
227
229
|
let HTTPREQUEST;
|
@@ -246,6 +248,7 @@ router.post('/ops_update', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscrip
|
|
246
248
|
winston.error("err performing operation: ", err);
|
247
249
|
} else {
|
248
250
|
winston.debug("\n\nresbody operation: ", resbody);
|
251
|
+
chatbotService.setModified(id_faq_kb, true)
|
249
252
|
}
|
250
253
|
}
|
251
254
|
)
|
@@ -273,6 +276,7 @@ router.post('/ops_update', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscrip
|
|
273
276
|
winston.error("err performing operation: ", err);
|
274
277
|
} else {
|
275
278
|
winston.debug("\n\nresbody operation: ", resbody);
|
279
|
+
chatbotService.setModified(id_faq_kb, true)
|
276
280
|
}
|
277
281
|
}
|
278
282
|
)
|
@@ -296,6 +300,7 @@ router.post('/ops_update', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscrip
|
|
296
300
|
winston.error("err performing operation: ", err);
|
297
301
|
} else {
|
298
302
|
winston.debug("\n\nresbody operation: ", resbody);
|
303
|
+
chatbotService.setModified(id_faq_kb, true)
|
299
304
|
}
|
300
305
|
}
|
301
306
|
)
|
@@ -322,6 +327,7 @@ router.post('/ops_update', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscrip
|
|
322
327
|
winston.error("err performing operation: ", err);
|
323
328
|
} else {
|
324
329
|
winston.debug("\n\nresbody operation: ", resbody);
|
330
|
+
chatbotService.setModified(id_faq_kb, true)
|
325
331
|
}
|
326
332
|
}
|
327
333
|
)
|