@unboundcx/sdk 4.13.57 → 4.13.59
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "4.13.
|
|
3
|
+
"version": "4.13.59",
|
|
4
4
|
"description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { internalRequest } from '../../base.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Participant Service - multi-party task participation: invite a user onto a
|
|
5
|
+
* task, request help from a queue, hold/drop/leave, and owner<->helper
|
|
6
|
+
* control swaps. Voice participants always dial the main bridge (P4);
|
|
7
|
+
* sidebar bridge, mute, and per-member bridgeRole changes arrive with the
|
|
8
|
+
* media update (P5).
|
|
9
|
+
*/
|
|
10
|
+
export class ParticipantService {
|
|
11
|
+
constructor(sdk) {
|
|
12
|
+
this.sdk = sdk;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* List a task's participants and any pending help requests.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} options - Options
|
|
19
|
+
* @param {string} options.taskId - Task ID
|
|
20
|
+
* @returns {Promise<Object>} { participants, helpRequests }
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const { participants, helpRequests } = await sdk.taskRouter.participants.list({ taskId: 'task_123' });
|
|
24
|
+
*/
|
|
25
|
+
async list({ taskId }) {
|
|
26
|
+
this.sdk.validateParams(
|
|
27
|
+
{ taskId },
|
|
28
|
+
{ taskId: { type: 'string', required: true } },
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return await internalRequest(
|
|
32
|
+
this.sdk,
|
|
33
|
+
`/taskRouter/tasks/${taskId}/participants`,
|
|
34
|
+
'GET',
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Add a participant to a task: invite a specific user to join, or request
|
|
40
|
+
* help from a queue.
|
|
41
|
+
*
|
|
42
|
+
* @param {Object} options - Options
|
|
43
|
+
* @param {string} options.taskId - Task ID
|
|
44
|
+
* @param {string} options.kind - 'user' | 'queue'
|
|
45
|
+
* @param {string} [options.userId] - Required when kind is 'user'
|
|
46
|
+
* @param {string} [options.queueId] - Required when kind is 'queue'
|
|
47
|
+
* @param {string} [options.note] - Optional note shown to the invitee
|
|
48
|
+
* @param {string} [options.bridgeRole='main'] - Voice bridge role (only 'main' is supported until the media update)
|
|
49
|
+
* @returns {Promise<Object>} { participant, offerId } for kind 'user'; { helpTaskId } for kind 'queue'
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* await sdk.taskRouter.participants.add({ taskId: 'task_123', kind: 'user', userId: 'user_456', note: 'Need a hand' });
|
|
53
|
+
* @example
|
|
54
|
+
* await sdk.taskRouter.participants.add({ taskId: 'task_123', kind: 'queue', queueId: 'queue_789' });
|
|
55
|
+
*/
|
|
56
|
+
async add({ taskId, kind, userId, queueId, note, bridgeRole } = {}) {
|
|
57
|
+
this.sdk.validateParams(
|
|
58
|
+
{ taskId, kind, userId, queueId, note, bridgeRole },
|
|
59
|
+
{
|
|
60
|
+
taskId: { type: 'string', required: true },
|
|
61
|
+
kind: { type: 'string', required: true },
|
|
62
|
+
userId: { type: 'string', required: false },
|
|
63
|
+
queueId: { type: 'string', required: false },
|
|
64
|
+
note: { type: 'string', required: false },
|
|
65
|
+
bridgeRole: { type: 'string', required: false },
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const params = { body: { kind } };
|
|
70
|
+
if (userId !== undefined) params.body.userId = userId;
|
|
71
|
+
if (queueId !== undefined) params.body.queueId = queueId;
|
|
72
|
+
if (note !== undefined) params.body.note = note;
|
|
73
|
+
if (bridgeRole !== undefined) params.body.bridgeRole = bridgeRole;
|
|
74
|
+
|
|
75
|
+
return await internalRequest(
|
|
76
|
+
this.sdk,
|
|
77
|
+
`/taskRouter/tasks/${taskId}/participants`,
|
|
78
|
+
'POST',
|
|
79
|
+
params,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Cancel a pending/assigned help request before it is joined.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} options - Options
|
|
87
|
+
* @param {string} options.taskId - Task ID
|
|
88
|
+
* @param {string} options.helpTaskId - The help shell task id returned by `add({ kind: 'queue' })`
|
|
89
|
+
* @returns {Promise<Object>}
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* await sdk.taskRouter.participants.cancelHelp({ taskId: 'task_123', helpTaskId: 'task_999' });
|
|
93
|
+
*/
|
|
94
|
+
async cancelHelp({ taskId, helpTaskId } = {}) {
|
|
95
|
+
this.sdk.validateParams(
|
|
96
|
+
{ taskId, helpTaskId },
|
|
97
|
+
{
|
|
98
|
+
taskId: { type: 'string', required: true },
|
|
99
|
+
helpTaskId: { type: 'string', required: true },
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return await internalRequest(
|
|
104
|
+
this.sdk,
|
|
105
|
+
`/taskRouter/tasks/${taskId}/help/${helpTaskId}`,
|
|
106
|
+
'DELETE',
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Update a participant. Only `held` is supported until the media update —
|
|
112
|
+
* `muted` and `bridgeRole` are reserved for P5 and will error server-side.
|
|
113
|
+
*
|
|
114
|
+
* @param {Object} options - Options
|
|
115
|
+
* @param {string} options.taskId - Task ID
|
|
116
|
+
* @param {string} options.participantId - Participant ID
|
|
117
|
+
* @param {boolean} [options.held] - Put the participant's leg on/off hold
|
|
118
|
+
* @param {boolean} [options.muted] - Reserved (media update)
|
|
119
|
+
* @param {string} [options.bridgeRole] - Reserved (media update)
|
|
120
|
+
* @returns {Promise<Object>}
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* await sdk.taskRouter.participants.update({ taskId: 'task_123', participantId: 'tp_456', held: true });
|
|
124
|
+
*/
|
|
125
|
+
async update({ taskId, participantId, held, muted, bridgeRole } = {}) {
|
|
126
|
+
this.sdk.validateParams(
|
|
127
|
+
{ taskId, participantId, held, muted, bridgeRole },
|
|
128
|
+
{
|
|
129
|
+
taskId: { type: 'string', required: true },
|
|
130
|
+
participantId: { type: 'string', required: true },
|
|
131
|
+
held: { type: 'boolean', required: false },
|
|
132
|
+
muted: { type: 'boolean', required: false },
|
|
133
|
+
bridgeRole: { type: 'string', required: false },
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const params = { body: {} };
|
|
138
|
+
if (held !== undefined) params.body.held = held;
|
|
139
|
+
if (muted !== undefined) params.body.muted = muted;
|
|
140
|
+
if (bridgeRole !== undefined) params.body.bridgeRole = bridgeRole;
|
|
141
|
+
|
|
142
|
+
return await internalRequest(
|
|
143
|
+
this.sdk,
|
|
144
|
+
`/taskRouter/tasks/${taskId}/participants/${participantId}`,
|
|
145
|
+
'PATCH',
|
|
146
|
+
params,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Remove a participant: drop them (owner/manager) or leave (self).
|
|
152
|
+
*
|
|
153
|
+
* @param {Object} options - Options
|
|
154
|
+
* @param {string} options.taskId - Task ID
|
|
155
|
+
* @param {string} options.participantId - Participant ID
|
|
156
|
+
* @returns {Promise<Object>}
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* await sdk.taskRouter.participants.remove({ taskId: 'task_123', participantId: 'tp_456' });
|
|
160
|
+
*/
|
|
161
|
+
async remove({ taskId, participantId }) {
|
|
162
|
+
this.sdk.validateParams(
|
|
163
|
+
{ taskId, participantId },
|
|
164
|
+
{
|
|
165
|
+
taskId: { type: 'string', required: true },
|
|
166
|
+
participantId: { type: 'string', required: true },
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return await internalRequest(
|
|
171
|
+
this.sdk,
|
|
172
|
+
`/taskRouter/tasks/${taskId}/participants/${participantId}`,
|
|
173
|
+
'DELETE',
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Swap task ownership between the current owner and a joined helper.
|
|
179
|
+
*
|
|
180
|
+
* @param {Object} options - Options
|
|
181
|
+
* @param {string} options.taskId - Task ID
|
|
182
|
+
* @param {string} options.participantId - The helper participant taking/giving control
|
|
183
|
+
* @param {string} options.action - 'give' | 'take'
|
|
184
|
+
* @returns {Promise<Object>} { taskId, workerId }
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* await sdk.taskRouter.participants.control({ taskId: 'task_123', participantId: 'tp_456', action: 'give' });
|
|
188
|
+
*/
|
|
189
|
+
async control({ taskId, participantId, action }) {
|
|
190
|
+
this.sdk.validateParams(
|
|
191
|
+
{ taskId, participantId, action },
|
|
192
|
+
{
|
|
193
|
+
taskId: { type: 'string', required: true },
|
|
194
|
+
participantId: { type: 'string', required: true },
|
|
195
|
+
action: { type: 'string', required: true },
|
|
196
|
+
},
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const params = { body: { action } };
|
|
200
|
+
|
|
201
|
+
return await internalRequest(
|
|
202
|
+
this.sdk,
|
|
203
|
+
`/taskRouter/tasks/${taskId}/participants/${participantId}/control`,
|
|
204
|
+
'POST',
|
|
205
|
+
params,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Connect-all / sidebar-all. Reserved for the media update (P5) — currently
|
|
211
|
+
* always errors server-side.
|
|
212
|
+
*
|
|
213
|
+
* @param {Object} options - Options
|
|
214
|
+
* @param {string} options.taskId - Task ID
|
|
215
|
+
* @param {string} [options.bridgeRole] - Reserved (media update)
|
|
216
|
+
* @returns {Promise<Object>}
|
|
217
|
+
*/
|
|
218
|
+
async all({ taskId, bridgeRole } = {}) {
|
|
219
|
+
this.sdk.validateParams(
|
|
220
|
+
{ taskId, bridgeRole },
|
|
221
|
+
{
|
|
222
|
+
taskId: { type: 'string', required: true },
|
|
223
|
+
bridgeRole: { type: 'string', required: false },
|
|
224
|
+
},
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const params = { body: {} };
|
|
228
|
+
if (bridgeRole !== undefined) params.body.bridgeRole = bridgeRole;
|
|
229
|
+
|
|
230
|
+
return await internalRequest(
|
|
231
|
+
this.sdk,
|
|
232
|
+
`/taskRouter/tasks/${taskId}/participants/all`,
|
|
233
|
+
'POST',
|
|
234
|
+
params,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* List tasks the caller is currently helping on (joined as a helper),
|
|
240
|
+
* for the mini-card strip.
|
|
241
|
+
*
|
|
242
|
+
* @returns {Promise<Array>} [{ task, participantId, role, joinedAt }]
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* const helping = await sdk.taskRouter.participants.participating();
|
|
246
|
+
*/
|
|
247
|
+
async participating() {
|
|
248
|
+
return await internalRequest(
|
|
249
|
+
this.sdk,
|
|
250
|
+
'/taskRouter/tasks/participating',
|
|
251
|
+
'GET',
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -3,6 +3,7 @@ import { TaskService } from './TaskService.js';
|
|
|
3
3
|
import { MetricsService } from './MetricsService.js';
|
|
4
4
|
import { CCService } from './CCService.js';
|
|
5
5
|
import { OfferService } from './OfferService.js';
|
|
6
|
+
import { ParticipantService } from './ParticipantService.js';
|
|
6
7
|
|
|
7
8
|
export class TaskRouterService {
|
|
8
9
|
constructor(sdk) {
|
|
@@ -12,5 +13,6 @@ export class TaskRouterService {
|
|
|
12
13
|
this.metrics = new MetricsService(sdk);
|
|
13
14
|
this.cc = new CCService(sdk);
|
|
14
15
|
this.offer = new OfferService(sdk);
|
|
16
|
+
this.participants = new ParticipantService(sdk);
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -385,11 +385,60 @@ export class WorkerService {
|
|
|
385
385
|
params.body.userId = userId;
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
const result = await internalRequest(this.sdk,
|
|
388
|
+
const result = await internalRequest(this.sdk,
|
|
389
389
|
'/taskRouter/worker/queueLogout',
|
|
390
390
|
'PUT',
|
|
391
391
|
params,
|
|
392
392
|
);
|
|
393
393
|
return result;
|
|
394
394
|
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Search for workers within a queue's scope
|
|
398
|
+
* Finds workers a caller can act on (transfer/invite/DM) for a given queue, with optional
|
|
399
|
+
* name/email/extension text search and skill-match flagging.
|
|
400
|
+
*
|
|
401
|
+
* @param {Object} options - Parameters
|
|
402
|
+
* @param {string} options.queueId - The queue ID to scope the search to (required)
|
|
403
|
+
* @param {string} [options.q] - Free-text filter matching name, email, or extension
|
|
404
|
+
* @param {string[]} [options.skills] - Skill IDs to flag matches for (joined as a comma-separated list)
|
|
405
|
+
* @param {number} [options.limit] - Max rows to return (default 50, max 200)
|
|
406
|
+
* @returns {Promise<Object>} Object containing the matching worker rows
|
|
407
|
+
* @returns {Array<Object>} result.rows - Worker rows with status/capacity/skills info
|
|
408
|
+
* @returns {number} result.total - Total matching rows
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* const { rows, total } = await sdk.taskRouter.worker.search({ queueId: 'queue123', q: 'sam' });
|
|
412
|
+
* console.log(rows.length, total);
|
|
413
|
+
*/
|
|
414
|
+
async search(options = {}) {
|
|
415
|
+
const { queueId, q, skills, limit } = options;
|
|
416
|
+
|
|
417
|
+
this.sdk.validateParams(
|
|
418
|
+
{ queueId, q, skills, limit },
|
|
419
|
+
{
|
|
420
|
+
queueId: { type: 'string', required: true },
|
|
421
|
+
q: { type: 'string', required: false },
|
|
422
|
+
skills: { type: 'array', required: false },
|
|
423
|
+
limit: { type: 'number', required: false },
|
|
424
|
+
},
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
const query = { queueId };
|
|
428
|
+
|
|
429
|
+
if (q) {
|
|
430
|
+
query.q = q;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (skills && skills.length) {
|
|
434
|
+
query.skills = skills.join(',');
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (limit) {
|
|
438
|
+
query.limit = limit;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const result = await internalRequest(this.sdk, '/taskRouter/workers/search', 'GET', { query });
|
|
442
|
+
return result;
|
|
443
|
+
}
|
|
395
444
|
}
|