@tiledesk/tiledesk-server 2.19.12 → 2.19.14
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 +7 -0
- package/app.js +3 -0
- package/channels/chat21/chat21WebHook.js +13 -2
- package/docs/activities-client.md +864 -0
- package/event/requestEvent.js +14 -0
- package/jobs.js +1 -0
- package/jobsManager.js +2 -0
- package/models/dataTable.js +64 -0
- package/package.json +2 -2
- package/pubmodules/activities/activityArchiver.js +699 -377
- package/pubmodules/activities/activityMessageUtil.js +336 -0
- package/pubmodules/activities/index.js +1 -1
- package/pubmodules/activities/models/activity.js +99 -2
- package/pubmodules/activities/routes/activity.js +114 -144
- package/pubmodules/messageActions/messageActionsInterceptor.js +15 -2
- package/pubmodules/queue/reconnect.js +307 -2
- package/pubmodules/rules/conciergeBot.js +7 -1
- package/pubmodules/trigger/rulesTrigger.js +33 -5
- package/routes/dataTable.js +280 -0
- package/routes/faq_kb.js +24 -1
- package/routes/kb.js +90 -2
- package/routes/project_user.js +66 -17
- package/routes/request.js +20 -8
- package/services/chatbotService.js +6 -3
- package/services/dataTableService.js +545 -0
- package/services/requestService.js +180 -27
- package/test/dataTablesRoute.test.js +844 -0
- package/test/faqkbRoute.js +1 -0
- package/test/kbRoute.js +59 -0
- package/utils/activityActorUtil.js +167 -0
- package/utils/assignmentContextUtil.js +283 -0
- package/utils/dataTableBsonUtils.js +12 -0
- package/utils/dataTableUtils.js +353 -0
- package/utils/projectUserUpdateContextUtil.js +325 -0
package/test/faqkbRoute.js
CHANGED
|
@@ -1217,6 +1217,7 @@ describe('FaqKBRoute', () => {
|
|
|
1217
1217
|
if (err) { console.error("err: ", err); }
|
|
1218
1218
|
if (log) { console.log("res.body", res.body); }
|
|
1219
1219
|
|
|
1220
|
+
console.log("chatbot trashed: ", res.body);
|
|
1220
1221
|
res.should.have.status(200);
|
|
1221
1222
|
res.body.should.be.a('object');
|
|
1222
1223
|
expect(res.body.trashed).to.equal(true);
|
package/test/kbRoute.js
CHANGED
|
@@ -9,6 +9,7 @@ process.env.PINECONE_INDEX_HYBRID = "test-index-hybrid";
|
|
|
9
9
|
process.env.PINECONE_TYPE_HYBRID = "serverless";
|
|
10
10
|
process.env.ADMIN_EMAIL = "admin@tiledesk.com";
|
|
11
11
|
process.env.KB_ENDPOINT_TRAIN = "http://kb-train.test";
|
|
12
|
+
process.env.ACTIVITY_HISTORY_ENABLED = true;
|
|
12
13
|
|
|
13
14
|
var userService = require('../services/userService');
|
|
14
15
|
var projectService = require('../services/projectService');
|
|
@@ -792,6 +793,64 @@ describe('KbRoute', () => {
|
|
|
792
793
|
});
|
|
793
794
|
}).timeout(10000)
|
|
794
795
|
|
|
796
|
+
it('delete-content', (done) => {
|
|
797
|
+
|
|
798
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
|
799
|
+
var pwd = "pwd";
|
|
800
|
+
|
|
801
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
|
802
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
|
803
|
+
|
|
804
|
+
chai.request(server)
|
|
805
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
806
|
+
.auth(email, pwd)
|
|
807
|
+
.end((err, res) => {
|
|
808
|
+
if (err) { console.error("err: ", err); }
|
|
809
|
+
if (log) { console.log("get namespaces res.body: ", res.body); }
|
|
810
|
+
|
|
811
|
+
res.should.have.status(200);
|
|
812
|
+
|
|
813
|
+
let namespace_id = res.body[0].id;
|
|
814
|
+
|
|
815
|
+
let kb = {
|
|
816
|
+
name: "example_text_delete",
|
|
817
|
+
type: "text",
|
|
818
|
+
source: "example_text_delete",
|
|
819
|
+
content: "Example text",
|
|
820
|
+
namespace: namespace_id
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
chai.request(server)
|
|
824
|
+
.post('/' + savedProject._id + '/kb')
|
|
825
|
+
.auth(email, pwd)
|
|
826
|
+
.send(kb)
|
|
827
|
+
.end((err, res) => {
|
|
828
|
+
if (err) { console.error("err: ", err); }
|
|
829
|
+
if (log) { console.log("create kb res.body: ", res.body); }
|
|
830
|
+
|
|
831
|
+
res.should.have.status(200);
|
|
832
|
+
|
|
833
|
+
let kb_id = res.body.data.value._id;
|
|
834
|
+
|
|
835
|
+
chai.request(server)
|
|
836
|
+
.delete('/' + savedProject._id + '/kb/' + kb_id)
|
|
837
|
+
.auth(email, pwd)
|
|
838
|
+
.end((err, res) => {
|
|
839
|
+
if (err) { console.error("err: ", err); }
|
|
840
|
+
if (log) { console.log("delete kb res.body: ", res.body); }
|
|
841
|
+
|
|
842
|
+
res.should.have.status(200);
|
|
843
|
+
expect(res.body.success).to.equal(true);
|
|
844
|
+
expect(res.body.message).to.equal("Content deleted successfully");
|
|
845
|
+
|
|
846
|
+
done();
|
|
847
|
+
})
|
|
848
|
+
})
|
|
849
|
+
})
|
|
850
|
+
})
|
|
851
|
+
})
|
|
852
|
+
})
|
|
853
|
+
|
|
795
854
|
it('get-content-chunks', (done) => {
|
|
796
855
|
|
|
797
856
|
var email = "test-signup-" + Date.now() + "@email.com";
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const User = require('../models/user');
|
|
4
|
+
const winston = require('../config/winston');
|
|
5
|
+
const projectUserUpdateContextUtil = require('./projectUserUpdateContextUtil');
|
|
6
|
+
|
|
7
|
+
function actorFromReq(req) {
|
|
8
|
+
if (!req || !req.user) {
|
|
9
|
+
return { type: 'system', id: 'system', name: 'System' };
|
|
10
|
+
}
|
|
11
|
+
return projectUserUpdateContextUtil.actorFromPrincipal(req.user);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function actorFromUserId(userId) {
|
|
15
|
+
if (!userId) {
|
|
16
|
+
return { type: 'system', id: 'system', name: 'System' };
|
|
17
|
+
}
|
|
18
|
+
const id = String(userId);
|
|
19
|
+
return { type: 'user', id: id, name: id };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function resolveId(value) {
|
|
23
|
+
if (!value) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (value._id) {
|
|
27
|
+
return String(value._id);
|
|
28
|
+
}
|
|
29
|
+
return String(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveUserFromParticipatingAgents(agents, userId) {
|
|
33
|
+
if (!Array.isArray(agents) || !userId) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const agent of agents) {
|
|
38
|
+
const id = agent._id || agent.id;
|
|
39
|
+
if (id && String(id) === String(userId)) {
|
|
40
|
+
return agent;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function resolveUserFromSnapshotAgents(agents, userId) {
|
|
48
|
+
if (!Array.isArray(agents) || !userId) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const projectUser of agents) {
|
|
53
|
+
const user = projectUser.id_user || projectUser;
|
|
54
|
+
const id = (user && (user._id || user.id)) || projectUser._id;
|
|
55
|
+
if (id && String(id) === String(userId)) {
|
|
56
|
+
return user;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isSystemClosedBy(closedBy) {
|
|
64
|
+
if (!closedBy) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const value = String(closedBy).toLowerCase();
|
|
68
|
+
return value === 'system' || value === '_trigger';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function actorFromClosedBy(request) {
|
|
72
|
+
if (!request) {
|
|
73
|
+
return { type: 'system', id: 'system', name: 'System' };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const closedBy = request.closed_by;
|
|
77
|
+
if (isSystemClosedBy(closedBy)) {
|
|
78
|
+
return { type: 'system', id: 'system', name: 'System' };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const userId = String(closedBy);
|
|
82
|
+
let user = resolveUserFromParticipatingAgents(request.participatingAgents, userId);
|
|
83
|
+
if (!user && request.snapshot) {
|
|
84
|
+
user = resolveUserFromSnapshotAgents(request.snapshot.agents, userId);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const name = (user && projectUserUpdateContextUtil.userDisplayName(user)) ||
|
|
88
|
+
request.closed_by_name ||
|
|
89
|
+
userId;
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
type: 'user',
|
|
93
|
+
id: userId,
|
|
94
|
+
name: name
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function actorFromRequestCreate(request) {
|
|
99
|
+
const requesterId = request && request.requester_id;
|
|
100
|
+
const lead = request && request.lead;
|
|
101
|
+
const leadId = lead && (lead._id || lead.id);
|
|
102
|
+
const leadFullname = lead && (lead.fullname || lead.fullName);
|
|
103
|
+
const participantsBots = (request && request.participantsBots) || [];
|
|
104
|
+
const participatingBotIds = (request && request.participatingBots || []).map(function (bot) {
|
|
105
|
+
return String((bot && (bot._id || bot.id)) || bot);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
winston.info('ActivityArchiver REQUEST_CREATE actor resolution', {
|
|
109
|
+
request_id: request && request.request_id,
|
|
110
|
+
request_mongo_id: request && request._id && String(request._id),
|
|
111
|
+
requester_id: requesterId != null ? String(requesterId) : null,
|
|
112
|
+
requester_name: request && request.requester_name,
|
|
113
|
+
createdBy: request && request.createdBy,
|
|
114
|
+
lead_id: leadId != null ? String(leadId) : null,
|
|
115
|
+
lead_fullname: leadFullname,
|
|
116
|
+
participantsBots: participantsBots,
|
|
117
|
+
participatingBotIds: participatingBotIds,
|
|
118
|
+
hasBot: request && request.hasBot,
|
|
119
|
+
note: 'REQUEST_CREATE actor is always type=user with id=requester_id (lead virtual). JWT/token is not used here.'
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const actor = {
|
|
123
|
+
type: 'user',
|
|
124
|
+
id: requesterId != null ? String(requesterId) : undefined,
|
|
125
|
+
name: (request && request.requester_name) || leadFullname || undefined
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
if (participantsBots.length > 0 || participatingBotIds.length > 0) {
|
|
129
|
+
winston.info('ActivityArchiver REQUEST_CREATE bot participants present (not used as actor)', {
|
|
130
|
+
request_id: request && request.request_id,
|
|
131
|
+
actor: actor,
|
|
132
|
+
participantsBots: participantsBots,
|
|
133
|
+
participatingBotIds: participatingBotIds
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return actor;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function resolveActorFromClosedBy(request) {
|
|
141
|
+
const actor = actorFromClosedBy(request);
|
|
142
|
+
|
|
143
|
+
if (actor.type !== 'user' || actor.name !== actor.id) {
|
|
144
|
+
return actor;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const user = await User.findById(actor.id).select('firstname lastname email').lean().exec();
|
|
149
|
+
const displayName = user && projectUserUpdateContextUtil.userDisplayName(user);
|
|
150
|
+
if (displayName) {
|
|
151
|
+
return Object.assign({}, actor, { name: displayName });
|
|
152
|
+
}
|
|
153
|
+
} catch (err) {
|
|
154
|
+
// keep id fallback
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return actor;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = {
|
|
161
|
+
actorFromReq,
|
|
162
|
+
actorFromUserId,
|
|
163
|
+
actorFromRequestCreate,
|
|
164
|
+
actorFromClosedBy,
|
|
165
|
+
resolveActorFromClosedBy,
|
|
166
|
+
resolveId
|
|
167
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const projectUserUpdateContextUtil = require('./projectUserUpdateContextUtil');
|
|
4
|
+
const winston = require('../config/winston');
|
|
5
|
+
|
|
6
|
+
function systemActor() {
|
|
7
|
+
return { type: 'system', id: 'system', name: 'System' };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function actorFromUser(user) {
|
|
11
|
+
return projectUserUpdateContextUtil.actorFromPrincipal(user);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function assignmentActorContext(req, defaultSource) {
|
|
15
|
+
const source = defaultSource || 'api';
|
|
16
|
+
|
|
17
|
+
if (!req || !req.user) {
|
|
18
|
+
return { actor: systemActor(), source: 'system' };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (projectUserUpdateContextUtil.isSubscriptionActor(req.user)) {
|
|
22
|
+
return { actor: systemActor(), source: 'subscription' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const actor = actorFromUser(req.user);
|
|
26
|
+
const isBot = projectUserUpdateContextUtil.isBotActor(req.user);
|
|
27
|
+
|
|
28
|
+
if (isBot && actor.type !== 'bot') {
|
|
29
|
+
winston.warn('assignmentActorContext bot principal resolved as non-bot actor', {
|
|
30
|
+
actor: actor,
|
|
31
|
+
principal_id: projectUserUpdateContextUtil.resolveUserId(req.user),
|
|
32
|
+
principal_name: req.user && req.user.name,
|
|
33
|
+
principal_type: req.user && req.user.type,
|
|
34
|
+
principal_subtype: req.user && req.user.subtype,
|
|
35
|
+
principal_sub: req.user && req.user.sub,
|
|
36
|
+
principal_model: req.user && req.user.constructor && req.user.constructor.modelName,
|
|
37
|
+
source: source,
|
|
38
|
+
url: req.originalUrl
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
winston.info('assignmentActorContext actor resolution', {
|
|
42
|
+
actor: actor,
|
|
43
|
+
principal_id: projectUserUpdateContextUtil.resolveUserId(req.user),
|
|
44
|
+
principal_name: req.user && req.user.name,
|
|
45
|
+
principal_type: req.user && req.user.type,
|
|
46
|
+
principal_subtype: req.user && req.user.subtype,
|
|
47
|
+
principal_sub: req.user && req.user.sub,
|
|
48
|
+
principal_model: req.user && req.user.constructor && req.user.constructor.modelName,
|
|
49
|
+
isBotActor: isBot,
|
|
50
|
+
source: source,
|
|
51
|
+
url: req.originalUrl
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { actor: actor, source: source };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function reconcileAssignmentPayload(data) {
|
|
59
|
+
const source = (data && data.source) || 'system';
|
|
60
|
+
let actor = (data && data.actor) || systemActor();
|
|
61
|
+
|
|
62
|
+
if (source === 'subscription' || actor.type === 'system') {
|
|
63
|
+
return {
|
|
64
|
+
actor: systemActor(),
|
|
65
|
+
source: source === 'subscription' ? 'subscription' : source
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { actor: actor, source: source };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isHumanParticipant(participantId) {
|
|
73
|
+
return participantId && !String(participantId).startsWith('bot_');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function filterHumanParticipants(participantIds) {
|
|
77
|
+
return (participantIds || []).filter(isHumanParticipant);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isBotParticipant(participantId) {
|
|
81
|
+
return participantId && String(participantId).startsWith('bot_');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function filterBotParticipants(participantIds) {
|
|
85
|
+
return (participantIds || []).filter(isBotParticipant);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function botIdFromParticipant(participantId) {
|
|
89
|
+
return String(participantId).replace('bot_', '');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function resolveBotName(requestComplete, botParticipantOrId) {
|
|
93
|
+
const botId = isBotParticipant(botParticipantOrId)
|
|
94
|
+
? botIdFromParticipant(botParticipantOrId)
|
|
95
|
+
: String(botParticipantOrId);
|
|
96
|
+
const bots = requestComplete && requestComplete.participatingBots;
|
|
97
|
+
if (Array.isArray(bots)) {
|
|
98
|
+
for (const bot of bots) {
|
|
99
|
+
const id = String(bot._id || bot.id);
|
|
100
|
+
if (id === botId) {
|
|
101
|
+
return bot.name || id;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return botId;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function resolveDepartmentName(requestComplete) {
|
|
109
|
+
const dep = requestComplete && requestComplete.department;
|
|
110
|
+
if (!dep) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
if (dep.name) {
|
|
114
|
+
return dep.name;
|
|
115
|
+
}
|
|
116
|
+
return dep._id ? String(dep._id) : undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function deriveAssignmentType({ actor, assigneeIds, isUnassign }) {
|
|
120
|
+
if (isUnassign) {
|
|
121
|
+
return 'unassign';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const humanAssignees = filterHumanParticipants(assigneeIds);
|
|
125
|
+
if (humanAssignees.length === 0) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!actor || actor.type === 'system') {
|
|
130
|
+
return 'auto';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const assigneeId = String(humanAssignees[0]);
|
|
134
|
+
if (String(actor.id) === assigneeId) {
|
|
135
|
+
return 'self_join';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return 'manual_reassign';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function verbFromAssignmentType(assignmentType) {
|
|
142
|
+
switch (assignmentType) {
|
|
143
|
+
case 'auto':
|
|
144
|
+
return 'REQUEST_ASSIGNED_AUTO';
|
|
145
|
+
case 'self_join':
|
|
146
|
+
return 'REQUEST_ASSIGNED_SELF';
|
|
147
|
+
case 'manual_reassign':
|
|
148
|
+
case 'manual_reassign_bot':
|
|
149
|
+
case 'manual_reassign_department':
|
|
150
|
+
return 'REQUEST_ASSIGNED_MANUAL';
|
|
151
|
+
case 'unassign':
|
|
152
|
+
return 'REQUEST_UNASSIGNED';
|
|
153
|
+
default:
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function buildSetParticipantsOptions(req, participants) {
|
|
159
|
+
const { actor, source } = assignmentActorContext(req, 'api');
|
|
160
|
+
|
|
161
|
+
if (!participants || participants.length === 0) {
|
|
162
|
+
return {
|
|
163
|
+
actor,
|
|
164
|
+
source,
|
|
165
|
+
assignmentType: 'unassign'
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const botParticipants = filterBotParticipants(participants);
|
|
170
|
+
const humanParticipants = filterHumanParticipants(participants);
|
|
171
|
+
|
|
172
|
+
if (botParticipants.length > 0 && humanParticipants.length === 0) {
|
|
173
|
+
return {
|
|
174
|
+
actor,
|
|
175
|
+
source,
|
|
176
|
+
assignmentType: 'manual_reassign_bot'
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
actor,
|
|
182
|
+
source,
|
|
183
|
+
assignmentType: deriveAssignmentType({
|
|
184
|
+
actor,
|
|
185
|
+
assigneeIds: participants,
|
|
186
|
+
isUnassign: false
|
|
187
|
+
})
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function buildAddParticipantOptions(req, member) {
|
|
192
|
+
const { actor, source } = assignmentActorContext(req, 'api');
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
actor,
|
|
196
|
+
source,
|
|
197
|
+
assignmentType: deriveAssignmentType({
|
|
198
|
+
actor,
|
|
199
|
+
assigneeIds: [member],
|
|
200
|
+
isUnassign: false
|
|
201
|
+
})
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function buildRemoveParticipantOptions(req, member) {
|
|
206
|
+
if (!isHumanParticipant(member)) {
|
|
207
|
+
return { trackLeave: false };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const { actor: reqActor, source } = assignmentActorContext(req, 'api');
|
|
211
|
+
const actor = req && req.user && String(reqActor.id) === String(member)
|
|
212
|
+
? reqActor
|
|
213
|
+
: { type: 'user', id: String(member), name: String(member) };
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
actor,
|
|
217
|
+
source,
|
|
218
|
+
member,
|
|
219
|
+
trackLeave: true
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function buildLeaveParticipantOptions(source, member) {
|
|
224
|
+
if (!isHumanParticipant(member)) {
|
|
225
|
+
return { trackLeave: false };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
actor: { type: 'user', id: String(member), name: String(member) },
|
|
230
|
+
source: source || 'webhook',
|
|
231
|
+
member,
|
|
232
|
+
trackLeave: true
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function buildAutoRouteOptions(req, source) {
|
|
237
|
+
const ctx = assignmentActorContext(req, source || 'api');
|
|
238
|
+
return {
|
|
239
|
+
actor: ctx.actor,
|
|
240
|
+
source: ctx.source,
|
|
241
|
+
assignmentType: 'auto'
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function buildDepartmentRouteOptions(req, source) {
|
|
246
|
+
const ctx = assignmentActorContext(req, source || 'api');
|
|
247
|
+
return {
|
|
248
|
+
actor: ctx.actor,
|
|
249
|
+
source: ctx.source,
|
|
250
|
+
assignmentType: 'manual_reassign_department'
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function buildInternalOptions(source, assignmentType) {
|
|
255
|
+
return {
|
|
256
|
+
actor: systemActor(),
|
|
257
|
+
source: source || 'system',
|
|
258
|
+
assignmentType: assignmentType || 'auto'
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
module.exports = {
|
|
263
|
+
systemActor,
|
|
264
|
+
actorFromUser,
|
|
265
|
+
assignmentActorContext,
|
|
266
|
+
reconcileAssignmentPayload,
|
|
267
|
+
isHumanParticipant,
|
|
268
|
+
filterHumanParticipants,
|
|
269
|
+
isBotParticipant,
|
|
270
|
+
filterBotParticipants,
|
|
271
|
+
botIdFromParticipant,
|
|
272
|
+
resolveBotName,
|
|
273
|
+
resolveDepartmentName,
|
|
274
|
+
deriveAssignmentType,
|
|
275
|
+
verbFromAssignmentType,
|
|
276
|
+
buildSetParticipantsOptions,
|
|
277
|
+
buildAddParticipantOptions,
|
|
278
|
+
buildRemoveParticipantOptions,
|
|
279
|
+
buildLeaveParticipantOptions,
|
|
280
|
+
buildAutoRouteOptions,
|
|
281
|
+
buildDepartmentRouteOptions,
|
|
282
|
+
buildInternalOptions
|
|
283
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const BSON = require('bson');
|
|
2
|
+
const bson = new BSON();
|
|
3
|
+
|
|
4
|
+
function calculateBsonSize(document) {
|
|
5
|
+
if (document == null) return 0;
|
|
6
|
+
const plain = document.toObject ? document.toObject({ depopulate: true }) : document;
|
|
7
|
+
return bson.calculateObjectSize(plain);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
calculateBsonSize: calculateBsonSize,
|
|
12
|
+
};
|