@unboundcx/sdk 2.8.6 → 2.8.7
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/README.md +48 -1
- package/base.js +43 -12
- package/index.js +21 -3
- package/package.json +5 -2
- package/proto/transcription.proto +207 -0
- package/services/ai/SttStream.js +311 -0
- package/services/ai/playbooks.js +958 -0
- package/services/ai.js +773 -52
- package/services/engagementMetrics.js +6 -2
- package/services/objects.js +12 -3
- package/services/phoneNumbers.js +88 -3
- package/services/sipEndpoints.js +105 -33
- package/services/storage.js +176 -6
- package/services/taskRouter/MetricsService.js +111 -0
- package/services/taskRouter/TaskRouterService.js +12 -0
- package/services/taskRouter/TaskService.js +838 -0
- package/services/taskRouter/WorkerService.js +394 -0
- package/services/taskRouter.js +6 -0
- package/services/video.js +145 -5
- package/services/voice.js +124 -67
- package/services/workflows.js +34 -7
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
export class TaskService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a new task in the task router system
|
|
8
|
+
* Creates a task for routing to available workers based on skills and queue assignment.
|
|
9
|
+
* Tasks can be phone calls, chats, emails, or other custom types.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} options - Parameters
|
|
12
|
+
* @param {string} options.type - The type of task: 'chat', 'phoneCall', 'email', or 'other' (required)
|
|
13
|
+
* @param {string} options.queueId - The queue ID to route the task to (required)
|
|
14
|
+
* @param {string|string[]} [options.requiredSkills] - Required skill IDs that workers must have (single ID or array)
|
|
15
|
+
* @param {string|string[]} [options.optionalSkills] - Optional skill IDs that are preferred but not required (single ID or array)
|
|
16
|
+
* @param {string|string[]} [options.skills] - Alias for requiredSkills (single ID or array)
|
|
17
|
+
* @param {number} [options.priority=0] - Task priority (higher values = higher priority)
|
|
18
|
+
* @param {string} [options.subject] - Subject or title for the task (defaults to "New {type}" if not provided)
|
|
19
|
+
* @param {string} [options.cdrId] - Call detail record ID to associate with this task (for voice tasks)
|
|
20
|
+
* @param {string} [options.peopleId] - Person ID associated with this task
|
|
21
|
+
* @param {string} [options.companyId] - Company ID associated with this task
|
|
22
|
+
* @param {boolean} [options.createEngagement=false] - Whether to automatically create an engagement session for this task
|
|
23
|
+
* @param {string} [options.relatedObject] - Related object type for metadata tracking (automatically set if createEngagement is true)
|
|
24
|
+
* @param {string} [options.relatedId] - Related object ID for metadata tracking (automatically set if createEngagement is true)
|
|
25
|
+
* @returns {Promise<Object>} Object containing the created task information
|
|
26
|
+
* @returns {string} result.id - The unique identifier for the created task
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Create a basic phone call task
|
|
30
|
+
* const task = await sdk.taskRouter.task.create({
|
|
31
|
+
* type: 'phoneCall',
|
|
32
|
+
* queueId: 'queue123'
|
|
33
|
+
* });
|
|
34
|
+
* console.log(task.id); // "task789"
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Create a chat task with required skills
|
|
38
|
+
* const task = await sdk.taskRouter.task.create({
|
|
39
|
+
* type: 'chat',
|
|
40
|
+
* queueId: 'queue123',
|
|
41
|
+
* requiredSkills: ['skill456', 'skill789'],
|
|
42
|
+
* priority: 5,
|
|
43
|
+
* subject: 'Customer support inquiry'
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* // Create a voice task with CDR and auto-engagement
|
|
48
|
+
* const task = await sdk.taskRouter.task.create({
|
|
49
|
+
* type: 'phoneCall',
|
|
50
|
+
* queueId: 'queue123',
|
|
51
|
+
* cdrId: 'cdr456',
|
|
52
|
+
* peopleId: 'person789',
|
|
53
|
+
* companyId: 'company123',
|
|
54
|
+
* createEngagement: true,
|
|
55
|
+
* subject: 'Inbound sales call'
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Create an email task with metadata
|
|
60
|
+
* const task = await sdk.taskRouter.task.create({
|
|
61
|
+
* type: 'email',
|
|
62
|
+
* queueId: 'queue123',
|
|
63
|
+
* optionalSkills: 'skill999',
|
|
64
|
+
* relatedObject: 'supportTicket',
|
|
65
|
+
* relatedId: 'ticket123'
|
|
66
|
+
* });
|
|
67
|
+
*/
|
|
68
|
+
async create(options = {}) {
|
|
69
|
+
const {
|
|
70
|
+
type,
|
|
71
|
+
queueId,
|
|
72
|
+
requiredSkills,
|
|
73
|
+
optionalSkills,
|
|
74
|
+
skills,
|
|
75
|
+
priority,
|
|
76
|
+
subject,
|
|
77
|
+
peopleId,
|
|
78
|
+
companyId,
|
|
79
|
+
createEngagement,
|
|
80
|
+
relatedObject,
|
|
81
|
+
relatedId,
|
|
82
|
+
cdrId,
|
|
83
|
+
sipCallId,
|
|
84
|
+
} = options;
|
|
85
|
+
|
|
86
|
+
this.sdk.validateParams(
|
|
87
|
+
{
|
|
88
|
+
type,
|
|
89
|
+
queueId,
|
|
90
|
+
requiredSkills,
|
|
91
|
+
optionalSkills,
|
|
92
|
+
skills,
|
|
93
|
+
priority,
|
|
94
|
+
subject,
|
|
95
|
+
cdrId,
|
|
96
|
+
peopleId,
|
|
97
|
+
companyId,
|
|
98
|
+
createEngagement,
|
|
99
|
+
relatedObject,
|
|
100
|
+
relatedId,
|
|
101
|
+
sipCallId,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: { type: 'string', required: true },
|
|
105
|
+
queueId: { type: 'string', required: true },
|
|
106
|
+
// requiredSkills: { type: ['string', 'array'], required: false },
|
|
107
|
+
// optionalSkills: { type: ['string', 'array'], required: false },
|
|
108
|
+
// skills: { type: ['string', 'array'], required: false },
|
|
109
|
+
priority: { type: 'number', required: false },
|
|
110
|
+
subject: { type: 'string', required: false },
|
|
111
|
+
cdrId: { type: 'string', required: false },
|
|
112
|
+
peopleId: { type: 'string', required: false },
|
|
113
|
+
companyId: { type: 'string', required: false },
|
|
114
|
+
createEngagement: { type: 'boolean', required: false },
|
|
115
|
+
relatedObject: { type: 'string', required: false },
|
|
116
|
+
relatedId: { type: 'string', required: false },
|
|
117
|
+
sipCallId: { type: 'string', required: false },
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const params = {
|
|
122
|
+
body: {
|
|
123
|
+
type,
|
|
124
|
+
queueId,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
if (requiredSkills !== undefined) {
|
|
129
|
+
params.body.requiredSkills = requiredSkills;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (optionalSkills !== undefined) {
|
|
133
|
+
params.body.optionalSkills = optionalSkills;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (skills !== undefined) {
|
|
137
|
+
params.body.skills = skills;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (priority !== undefined) {
|
|
141
|
+
params.body.priority = priority;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (subject !== undefined) {
|
|
145
|
+
params.body.subject = subject;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (cdrId !== undefined) {
|
|
149
|
+
params.body.cdrId = cdrId;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (peopleId !== undefined) {
|
|
153
|
+
params.body.peopleId = peopleId;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (companyId !== undefined) {
|
|
157
|
+
params.body.companyId = companyId;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (createEngagement !== undefined) {
|
|
161
|
+
params.body.createEngagement = createEngagement;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (relatedObject !== undefined) {
|
|
165
|
+
params.body.relatedObject = relatedObject;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (relatedId !== undefined) {
|
|
169
|
+
params.body.relatedId = relatedId;
|
|
170
|
+
}
|
|
171
|
+
if (sipCallId !== undefined) {
|
|
172
|
+
params.body.sipCallId = sipCallId;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const result = await this.sdk._fetch('/taskRouter/tasks', 'POST', params);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Create a call to connect a user to a task
|
|
181
|
+
* Creates an outbound call to a user's extension to connect them with an active task.
|
|
182
|
+
* The task must have an associated CDR (call detail record) with a bridge ID.
|
|
183
|
+
* The task cannot be in 'completed' or 'wrapUp' status.
|
|
184
|
+
*
|
|
185
|
+
* @param {Object} options - Parameters
|
|
186
|
+
* @param {string} options.taskId - The task ID to create a call for (required)
|
|
187
|
+
* @param {string} [options.userId] - The user ID to call. If not provided, uses the authenticated user's ID
|
|
188
|
+
* @returns {Promise<Object>} Object containing the task, user, and bridge information
|
|
189
|
+
* @returns {string} result.taskId - The task ID that was connected
|
|
190
|
+
* @returns {string} result.userId - The user ID that was called
|
|
191
|
+
* @returns {string} result.bridgeId - The bridge ID used to connect the call
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* // Create a call to connect authenticated user to a task
|
|
195
|
+
* const result = await sdk.taskRouter.task.createCall({
|
|
196
|
+
* taskId: 'task123'
|
|
197
|
+
* });
|
|
198
|
+
* console.log(result.taskId); // "task123"
|
|
199
|
+
* console.log(result.bridgeId); // "bridge456"
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* // Create a call to connect specific user to a task
|
|
203
|
+
* const result = await sdk.taskRouter.task.createCall({
|
|
204
|
+
* taskId: 'task123',
|
|
205
|
+
* userId: 'user789'
|
|
206
|
+
* });
|
|
207
|
+
* console.log(result.userId); // "user789"
|
|
208
|
+
*/
|
|
209
|
+
async createCall(options = {}) {
|
|
210
|
+
const { taskId, userId } = options;
|
|
211
|
+
|
|
212
|
+
this.sdk.validateParams(
|
|
213
|
+
{ taskId, userId },
|
|
214
|
+
{
|
|
215
|
+
taskId: { type: 'string', required: true },
|
|
216
|
+
userId: { type: 'string', required: false },
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const params = {
|
|
221
|
+
body: {
|
|
222
|
+
taskId,
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
if (userId !== undefined) {
|
|
227
|
+
params.body.userId = userId;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const result = await this.sdk._fetch(
|
|
231
|
+
'/taskRouter/tasks/callWorker',
|
|
232
|
+
'PUT',
|
|
233
|
+
params,
|
|
234
|
+
);
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Accept an assigned task
|
|
240
|
+
* When a worker accepts a task that has been assigned to them, this changes the task status to 'connected'.
|
|
241
|
+
* The worker must match the task assignment. If userId is not provided, uses the authenticated user's ID.
|
|
242
|
+
*
|
|
243
|
+
* @param {Object} options - Parameters
|
|
244
|
+
* @param {string} options.taskId - The task ID to accept (required)
|
|
245
|
+
* @param {string} [options.userId] - The user ID accepting the task. If not provided, uses the authenticated user's ID
|
|
246
|
+
* @returns {Promise<Object>} Object containing the task and worker information
|
|
247
|
+
* @returns {string} result.taskId - The task ID that was accepted
|
|
248
|
+
* @returns {string} result.workerId - The worker ID that accepted the task
|
|
249
|
+
* @returns {string} result.userId - The user ID that accepted the task
|
|
250
|
+
* @returns {string} result.workerSipCallId - The sipCallId of the worker who accepted the task
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* // Accept a task as authenticated user
|
|
254
|
+
* const result = await sdk.taskRouter.task.accept({ taskId: 'task123' });
|
|
255
|
+
* console.log(result.taskId); // "task123"
|
|
256
|
+
* console.log(result.workerId); // "worker456"
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* // Accept a task for specific user
|
|
260
|
+
* const result = await sdk.taskRouter.task.accept({
|
|
261
|
+
* taskId: 'task123',
|
|
262
|
+
* userId: 'user789'
|
|
263
|
+
* });
|
|
264
|
+
* @example
|
|
265
|
+
* // Accept a task for specific user with a sipCallId
|
|
266
|
+
* const result = await sdk.taskRouter.task.accept({
|
|
267
|
+
* taskId: 'task123',
|
|
268
|
+
* userId: 'user789'
|
|
269
|
+
* workerSipCallId: "a19ka-ada9a-adkadi198"
|
|
270
|
+
* });
|
|
271
|
+
*/
|
|
272
|
+
async accept(options = {}) {
|
|
273
|
+
const { taskId, userId, workerId, workerSipCallId } = options;
|
|
274
|
+
|
|
275
|
+
this.sdk.validateParams(
|
|
276
|
+
{ taskId, userId, workerSipCallId, workerId },
|
|
277
|
+
{
|
|
278
|
+
taskId: { type: 'string', required: true },
|
|
279
|
+
userId: { type: 'string', required: false },
|
|
280
|
+
workerSipCallId: { type: 'string', required: false },
|
|
281
|
+
workerId: { type: 'string', required: false },
|
|
282
|
+
},
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const params = {
|
|
286
|
+
body: {
|
|
287
|
+
taskId,
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
if (userId) {
|
|
292
|
+
params.body.userId = userId;
|
|
293
|
+
}
|
|
294
|
+
if (workerId) {
|
|
295
|
+
params.body.workerId = workerId;
|
|
296
|
+
}
|
|
297
|
+
if (workerSipCallId) {
|
|
298
|
+
params.body.workerSipCallId = workerSipCallId;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const result = await this.sdk._fetch(
|
|
302
|
+
'/taskRouter/tasks/accept',
|
|
303
|
+
'PUT',
|
|
304
|
+
params,
|
|
305
|
+
);
|
|
306
|
+
return result;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Reject an assigned task
|
|
311
|
+
* When a worker rejects a task that has been assigned to them, the task is returned to the queue for reassignment.
|
|
312
|
+
* The worker must match the task assignment. If userId is not provided, uses the authenticated user's ID.
|
|
313
|
+
*
|
|
314
|
+
* @param {Object} options - Parameters
|
|
315
|
+
* @param {string} options.taskId - The task ID to reject (required)
|
|
316
|
+
* @param {string} [options.userId] - The user ID rejecting the task. If not provided, uses the authenticated user's ID
|
|
317
|
+
* @returns {Promise<Object>} Object containing the task and worker information
|
|
318
|
+
* @returns {string} result.taskId - The task ID that was rejected
|
|
319
|
+
* @returns {string} result.workerId - The worker ID that rejected the task
|
|
320
|
+
* @returns {string} result.userId - The user ID that rejected the task
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* // Reject a task as authenticated user
|
|
324
|
+
* const result = await sdk.taskRouter.task.reject({ taskId: 'task123' });
|
|
325
|
+
* console.log(result.taskId); // "task123"
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* // Reject a task for specific user
|
|
329
|
+
* const result = await sdk.taskRouter.task.reject({
|
|
330
|
+
* taskId: 'task123',
|
|
331
|
+
* userId: 'user789'
|
|
332
|
+
* });
|
|
333
|
+
*/
|
|
334
|
+
async reject(options = {}) {
|
|
335
|
+
const { taskId, userId } = options;
|
|
336
|
+
|
|
337
|
+
this.sdk.validateParams(
|
|
338
|
+
{ taskId, userId },
|
|
339
|
+
{
|
|
340
|
+
taskId: { type: 'string', required: true },
|
|
341
|
+
userId: { type: 'string', required: false },
|
|
342
|
+
},
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
const params = {
|
|
346
|
+
body: {
|
|
347
|
+
taskId,
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
if (userId) {
|
|
352
|
+
params.body.userId = userId;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const result = await this.sdk._fetch(
|
|
356
|
+
'/taskRouter/tasks/reject',
|
|
357
|
+
'PUT',
|
|
358
|
+
params,
|
|
359
|
+
);
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Change task priority
|
|
365
|
+
* Modify the priority of a task to increase or decrease its routing priority.
|
|
366
|
+
* Priority can be set to a specific value, increased, or decreased.
|
|
367
|
+
*
|
|
368
|
+
* @param {Object} options - Parameters
|
|
369
|
+
* @param {string} options.taskId - The task ID to modify (required)
|
|
370
|
+
* @param {string} [options.action='set'] - The action to perform: 'set', 'increase', or 'decrease' (default: 'set')
|
|
371
|
+
* @param {number} [options.value=0] - The priority value to set, increase by, or decrease by (default: 0)
|
|
372
|
+
* @returns {Promise<Object>} Object containing the task ID and new priority
|
|
373
|
+
* @returns {string} result.taskId - The task ID that was modified
|
|
374
|
+
* @returns {number} result.priority - The new priority value (cannot be less than 0)
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* // Set task priority to 10
|
|
378
|
+
* const result = await sdk.taskRouter.task.changePriority({
|
|
379
|
+
* taskId: 'task123',
|
|
380
|
+
* action: 'set',
|
|
381
|
+
* value: 10
|
|
382
|
+
* });
|
|
383
|
+
* console.log(result.priority); // 10
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* // Increase task priority by 5
|
|
387
|
+
* const result = await sdk.taskRouter.task.changePriority({
|
|
388
|
+
* taskId: 'task123',
|
|
389
|
+
* action: 'increase',
|
|
390
|
+
* value: 5
|
|
391
|
+
* });
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* // Decrease task priority by 3
|
|
395
|
+
* const result = await sdk.taskRouter.task.changePriority({
|
|
396
|
+
* taskId: 'task123',
|
|
397
|
+
* action: 'decrease',
|
|
398
|
+
* value: 3
|
|
399
|
+
* });
|
|
400
|
+
*/
|
|
401
|
+
async changePriority(options = {}) {
|
|
402
|
+
const { taskId, action = 'set', value = 0 } = options;
|
|
403
|
+
|
|
404
|
+
this.sdk.validateParams(
|
|
405
|
+
{ taskId, action, value },
|
|
406
|
+
{
|
|
407
|
+
taskId: { type: 'string', required: true },
|
|
408
|
+
action: { type: 'string', required: false },
|
|
409
|
+
value: { type: 'number', required: false },
|
|
410
|
+
},
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
const params = {
|
|
414
|
+
body: {
|
|
415
|
+
taskId,
|
|
416
|
+
action,
|
|
417
|
+
value,
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const result = await this.sdk._fetch(
|
|
422
|
+
'/taskRouter/tasks/priority',
|
|
423
|
+
'PUT',
|
|
424
|
+
params,
|
|
425
|
+
);
|
|
426
|
+
return result;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Toggle task hold status
|
|
431
|
+
* Place a connected task on hold or resume a held task.
|
|
432
|
+
* If the task is currently 'connected', it will be set to 'hold'.
|
|
433
|
+
* If the task is currently 'hold', it will be set back to 'connected'.
|
|
434
|
+
*
|
|
435
|
+
* @param {Object} options - Parameters
|
|
436
|
+
* @param {string} options.taskId - The task ID to hold/resume (required)
|
|
437
|
+
* @returns {Promise<Object>} Object containing the task ID and new status
|
|
438
|
+
* @returns {string} result.taskId - The task ID that was modified
|
|
439
|
+
* @returns {string} result.status - The new status ('hold' or 'connected')
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* // Put a connected task on hold
|
|
443
|
+
* const result = await sdk.taskRouter.task.hold({ taskId: 'task123' });
|
|
444
|
+
* console.log(result.status); // "hold"
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* // Resume a held task
|
|
448
|
+
* const result = await sdk.taskRouter.task.hold({ taskId: 'task123' });
|
|
449
|
+
* console.log(result.status); // "connected"
|
|
450
|
+
*/
|
|
451
|
+
async hold(options = {}) {
|
|
452
|
+
const { taskId } = options;
|
|
453
|
+
|
|
454
|
+
this.sdk.validateParams(
|
|
455
|
+
{ taskId },
|
|
456
|
+
{
|
|
457
|
+
taskId: { type: 'string', required: true },
|
|
458
|
+
},
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
const params = {
|
|
462
|
+
body: {
|
|
463
|
+
taskId,
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const result = await this.sdk._fetch(
|
|
468
|
+
'/taskRouter/tasks/hold',
|
|
469
|
+
'PUT',
|
|
470
|
+
params,
|
|
471
|
+
);
|
|
472
|
+
return result;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Update task skill requirements
|
|
477
|
+
* Add or remove required or optional skills from a task while it's pending, assigned, connected, or on hold.
|
|
478
|
+
* This allows dynamic modification of routing requirements based on task progression.
|
|
479
|
+
*
|
|
480
|
+
* @param {Object} options - Parameters
|
|
481
|
+
* @param {string} options.taskId - The task ID to modify (required)
|
|
482
|
+
* @param {string|string[]} options.skills - Skill ID or array of skill IDs to add/remove (required)
|
|
483
|
+
* @param {string} options.action - The action to perform: 'add' or 'remove' (required)
|
|
484
|
+
* @param {boolean} [options.required=false] - Whether to modify required skills (true) or optional skills (false). Default: false
|
|
485
|
+
* @returns {Promise<Object>} Object containing the task ID and update parameters
|
|
486
|
+
* @returns {string} result.taskId - The task ID that was modified
|
|
487
|
+
* @returns {Object} result.params - The update parameters that were applied
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* // Add required skills to a task
|
|
491
|
+
* const result = await sdk.taskRouter.task.updateSkills({
|
|
492
|
+
* taskId: 'task123',
|
|
493
|
+
* skills: ['skill456', 'skill789'],
|
|
494
|
+
* action: 'add',
|
|
495
|
+
* required: true
|
|
496
|
+
* });
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* // Remove optional skills from a task
|
|
500
|
+
* const result = await sdk.taskRouter.task.updateSkills({
|
|
501
|
+
* taskId: 'task123',
|
|
502
|
+
* skills: 'skill999',
|
|
503
|
+
* action: 'remove',
|
|
504
|
+
* required: false
|
|
505
|
+
* });
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* // Add optional skills (default behavior)
|
|
509
|
+
* const result = await sdk.taskRouter.task.updateSkills({
|
|
510
|
+
* taskId: 'task123',
|
|
511
|
+
* skills: ['skill111'],
|
|
512
|
+
* action: 'add'
|
|
513
|
+
* });
|
|
514
|
+
*/
|
|
515
|
+
async updateSkills(options = {}) {
|
|
516
|
+
const { taskId, skills, action, required = false } = options;
|
|
517
|
+
|
|
518
|
+
this.sdk.validateParams(
|
|
519
|
+
{ taskId, skills, action, required },
|
|
520
|
+
{
|
|
521
|
+
taskId: { type: 'string', required: true },
|
|
522
|
+
skills: { type: ['string', 'array'], required: true },
|
|
523
|
+
action: { type: 'string', required: true },
|
|
524
|
+
required: { type: 'boolean', required: false },
|
|
525
|
+
},
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
const params = {
|
|
529
|
+
body: {
|
|
530
|
+
taskId,
|
|
531
|
+
skills,
|
|
532
|
+
action,
|
|
533
|
+
required,
|
|
534
|
+
},
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
const result = await this.sdk._fetch(
|
|
538
|
+
'/taskRouter/tasks/skills',
|
|
539
|
+
'PUT',
|
|
540
|
+
params,
|
|
541
|
+
);
|
|
542
|
+
return result;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Move task to wrap-up status
|
|
547
|
+
* Transitions a connected or held task to 'wrapUp' status, indicating the worker is completing post-task activities.
|
|
548
|
+
* This status allows workers to complete notes, dispositions, or other follow-up work before completing the task.
|
|
549
|
+
*
|
|
550
|
+
* @param {Object} options - Parameters
|
|
551
|
+
* @param {string} options.taskId - The task ID to move to wrap-up (required)
|
|
552
|
+
* @returns {Promise<Object>} Object containing the task ID and new status
|
|
553
|
+
* @returns {string} result.taskId - The task ID that was modified
|
|
554
|
+
* @returns {string} result.status - The new status ('wrapUp')
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* // Move a connected task to wrap-up
|
|
558
|
+
* const result = await sdk.taskRouter.task.wrapUp({ taskId: 'task123' });
|
|
559
|
+
* console.log(result.status); // "wrapUp"
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* // Move a held task to wrap-up
|
|
563
|
+
* const result = await sdk.taskRouter.task.wrapUp({ taskId: 'task456' });
|
|
564
|
+
* console.log(result.taskId); // "task456"
|
|
565
|
+
*/
|
|
566
|
+
async wrapUp(options = {}) {
|
|
567
|
+
const { taskId } = options;
|
|
568
|
+
|
|
569
|
+
this.sdk.validateParams(
|
|
570
|
+
{ taskId },
|
|
571
|
+
{
|
|
572
|
+
taskId: { type: 'string', required: true },
|
|
573
|
+
},
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
const params = {
|
|
577
|
+
body: {
|
|
578
|
+
taskId,
|
|
579
|
+
},
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
const result = await this.sdk._fetch(
|
|
583
|
+
'/taskRouter/tasks/wrapUp',
|
|
584
|
+
'PUT',
|
|
585
|
+
params,
|
|
586
|
+
);
|
|
587
|
+
return result;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Extend wrap-up time for a task
|
|
592
|
+
* Extends the wrap-up timer for a task that is currently in 'wrapUp' status.
|
|
593
|
+
* This gives the worker additional time to complete post-task activities before the task is automatically completed.
|
|
594
|
+
* If extend time is not provided, the queue's default wrapUpExtend value is used (typically 30 seconds).
|
|
595
|
+
*
|
|
596
|
+
* @param {Object} options - Parameters
|
|
597
|
+
* @param {string} options.taskId - The task ID to extend wrap-up time for (required)
|
|
598
|
+
* @param {number} [options.extend] - Number of seconds to extend the wrap-up timer. If not provided, uses the queue's default wrapUpExtend value (typically 30 seconds)
|
|
599
|
+
* @returns {Promise<Object>} Object containing the task ID and extend duration
|
|
600
|
+
* @returns {string} result.taskId - The task ID that was extended
|
|
601
|
+
* @returns {number} result.extend - The number of seconds the wrap-up was extended by
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* // Extend wrap-up time by queue default (typically 30 seconds)
|
|
605
|
+
* const result = await sdk.taskRouter.task.wrapUpExtend({ taskId: 'task123' });
|
|
606
|
+
* console.log(result.extend); // 30
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* // Extend wrap-up time by 60 seconds
|
|
610
|
+
* const result = await sdk.taskRouter.task.wrapUpExtend({
|
|
611
|
+
* taskId: 'task123',
|
|
612
|
+
* extend: 60
|
|
613
|
+
* });
|
|
614
|
+
* console.log(result.extend); // 60
|
|
615
|
+
*
|
|
616
|
+
* @example
|
|
617
|
+
* // Give worker more time to complete notes
|
|
618
|
+
* const result = await sdk.taskRouter.task.wrapUpExtend({
|
|
619
|
+
* taskId: 'task456',
|
|
620
|
+
* extend: 120
|
|
621
|
+
* });
|
|
622
|
+
* console.log(result.taskId); // "task456"
|
|
623
|
+
*/
|
|
624
|
+
async wrapUpExtend(options = {}) {
|
|
625
|
+
const { taskId, extend } = options;
|
|
626
|
+
|
|
627
|
+
this.sdk.validateParams(
|
|
628
|
+
{ taskId, extend },
|
|
629
|
+
{
|
|
630
|
+
taskId: { type: 'string', required: true },
|
|
631
|
+
extend: { type: 'number', required: false },
|
|
632
|
+
},
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
const params = {
|
|
636
|
+
body: {
|
|
637
|
+
taskId,
|
|
638
|
+
},
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
if (extend !== undefined) {
|
|
642
|
+
params.body.extend = extend;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const result = await this.sdk._fetch(
|
|
646
|
+
'/taskRouter/tasks/wrapUp/extend',
|
|
647
|
+
'PUT',
|
|
648
|
+
params,
|
|
649
|
+
);
|
|
650
|
+
return result;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Complete a task
|
|
655
|
+
* Marks a task as completed, ending its lifecycle in the task router.
|
|
656
|
+
* Can be called from any status except 'completed'.
|
|
657
|
+
*
|
|
658
|
+
* @param {Object} options - Parameters
|
|
659
|
+
* @param {string} options.taskId - The task ID to complete (required)
|
|
660
|
+
* @returns {Promise<Object>} Object containing the task ID and new status
|
|
661
|
+
* @returns {string} result.taskId - The task ID that was completed
|
|
662
|
+
* @returns {string} result.status - The new status ('completed')
|
|
663
|
+
*
|
|
664
|
+
* @example
|
|
665
|
+
* // Complete a task in wrap-up status
|
|
666
|
+
* const result = await sdk.taskRouter.task.complete({ taskId: 'task123' });
|
|
667
|
+
* console.log(result.status); // "completed"
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
* // Complete a task directly from connected status
|
|
671
|
+
* const result = await sdk.taskRouter.task.complete({ taskId: 'task456' });
|
|
672
|
+
* console.log(result.taskId); // "task456"
|
|
673
|
+
*/
|
|
674
|
+
async complete(options = {}) {
|
|
675
|
+
const { taskId } = options;
|
|
676
|
+
|
|
677
|
+
this.sdk.validateParams(
|
|
678
|
+
{ taskId },
|
|
679
|
+
{
|
|
680
|
+
taskId: { type: 'string', required: true },
|
|
681
|
+
},
|
|
682
|
+
);
|
|
683
|
+
|
|
684
|
+
const params = {
|
|
685
|
+
body: {
|
|
686
|
+
taskId,
|
|
687
|
+
},
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const result = await this.sdk._fetch(
|
|
691
|
+
'/taskRouter/tasks/complete',
|
|
692
|
+
'PUT',
|
|
693
|
+
params,
|
|
694
|
+
);
|
|
695
|
+
return result;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Status Change task event
|
|
700
|
+
* Automated event anytime the status of a task is changed.
|
|
701
|
+
*
|
|
702
|
+
* @param {Object} options - Parameters
|
|
703
|
+
* @param {string} options.taskId - The task ID to complete (required)
|
|
704
|
+
* @param {string} options.status - The new status (required)
|
|
705
|
+
* @param {string} options.previousStatus - The previous status (required)
|
|
706
|
+
* @returns {Promise<Object>} Object containing the task ID and new status
|
|
707
|
+
* @returns {string} result.taskId - The task ID that was completed
|
|
708
|
+
*
|
|
709
|
+
* @example
|
|
710
|
+
* const result = await sdk.taskRouter.task.statusEvent({ taskId: 'task123', status: 'completed', previousStatus: 'wrapUp' });
|
|
711
|
+
* console.log(result.taskId); // "085000202601400010000345713108739"
|
|
712
|
+
*
|
|
713
|
+
*/
|
|
714
|
+
async statusEvent(options = {}) {
|
|
715
|
+
const { taskId, status, previousStatus } = options;
|
|
716
|
+
|
|
717
|
+
this.sdk.validateParams(
|
|
718
|
+
{ taskId, status, previousStatus },
|
|
719
|
+
{
|
|
720
|
+
taskId: { type: 'string', required: true },
|
|
721
|
+
status: { type: 'string', required: true },
|
|
722
|
+
previousStatus: { type: 'string', required: true },
|
|
723
|
+
},
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
const params = {
|
|
727
|
+
body: {
|
|
728
|
+
taskId,
|
|
729
|
+
status,
|
|
730
|
+
previousStatus,
|
|
731
|
+
},
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
const result = await this.sdk._fetch(
|
|
735
|
+
'/taskRouter/tasks/statusEvent',
|
|
736
|
+
'PUT',
|
|
737
|
+
params,
|
|
738
|
+
);
|
|
739
|
+
return result;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Update task details
|
|
744
|
+
* Updates the subject, disposition, or other metadata of an existing task.
|
|
745
|
+
* This allows you to modify task information while it's in progress.
|
|
746
|
+
* At least one of subject or disposition must be provided.
|
|
747
|
+
*
|
|
748
|
+
* @param {Object} options - Parameters
|
|
749
|
+
* @param {string} options.taskId - The task ID to update (required)
|
|
750
|
+
* @param {string} [options.subject] - The new subject/title for the task
|
|
751
|
+
* @param {string} [options.summary] - The overall summary for the task
|
|
752
|
+
* @param {string} [options.disposition] - The disposition code or outcome for the task (e.g., 'resolved', 'escalated', 'callback-scheduled')
|
|
753
|
+
* @returns {Promise<Object>} Object containing the task ID
|
|
754
|
+
* @returns {string} result.taskId - The task ID that was updated
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* // Update task subject
|
|
758
|
+
* const result = await sdk.taskRouter.task.update({
|
|
759
|
+
* taskId: 'task123',
|
|
760
|
+
* subject: 'Updated customer inquiry about billing'
|
|
761
|
+
* });
|
|
762
|
+
* console.log(result.taskId); // "task123"
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* // Update task disposition
|
|
766
|
+
* const result = await sdk.taskRouter.task.update({
|
|
767
|
+
* taskId: 'task456',
|
|
768
|
+
* disposition: 'resolved'
|
|
769
|
+
* });
|
|
770
|
+
* console.log(result.taskId); // "task456"
|
|
771
|
+
*
|
|
772
|
+
* @example
|
|
773
|
+
* // Update both subject and disposition
|
|
774
|
+
* const result = await sdk.taskRouter.task.update({
|
|
775
|
+
* taskId: 'task789',
|
|
776
|
+
* subject: 'Technical support - printer issue',
|
|
777
|
+
* disposition: 'escalated'
|
|
778
|
+
* });
|
|
779
|
+
* console.log(result.taskId); // "task789"
|
|
780
|
+
*/
|
|
781
|
+
async update(options = {}) {
|
|
782
|
+
const {
|
|
783
|
+
taskId,
|
|
784
|
+
subject,
|
|
785
|
+
disposition,
|
|
786
|
+
sipCallId,
|
|
787
|
+
cdrId,
|
|
788
|
+
summary,
|
|
789
|
+
sentiment,
|
|
790
|
+
} = options;
|
|
791
|
+
|
|
792
|
+
this.sdk.validateParams(
|
|
793
|
+
{ taskId, subject, disposition, sipCallId, cdrId, summary, sentiment },
|
|
794
|
+
{
|
|
795
|
+
taskId: { type: 'string', required: true },
|
|
796
|
+
subject: { type: 'string', required: false },
|
|
797
|
+
disposition: { type: 'string', required: false },
|
|
798
|
+
cdrId: { type: 'string', required: false },
|
|
799
|
+
sipCallId: { type: 'string', required: false },
|
|
800
|
+
summary: { type: 'string', required: false },
|
|
801
|
+
sentiment: { type: 'object', required: false },
|
|
802
|
+
},
|
|
803
|
+
);
|
|
804
|
+
|
|
805
|
+
const params = {
|
|
806
|
+
body: {
|
|
807
|
+
taskId,
|
|
808
|
+
},
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
if (subject !== undefined) {
|
|
812
|
+
params.body.subject = subject;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
if (summary !== undefined) {
|
|
816
|
+
params.body.summary = summary;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
if (disposition !== undefined) {
|
|
820
|
+
params.body.disposition = disposition;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (cdrId !== undefined) {
|
|
824
|
+
params.body.cdrId = cdrId;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
if (sipCallId !== undefined) {
|
|
828
|
+
params.body.sipCallId = sipCallId;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (sentiment !== undefined) {
|
|
832
|
+
params.body.sentiment = sentiment;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
const result = await this.sdk._fetch('/taskRouter/tasks/', 'PUT', params);
|
|
836
|
+
return result;
|
|
837
|
+
}
|
|
838
|
+
}
|