@unboundcx/sdk 2.7.6 → 2.8.0
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/base.js +76 -43
- package/index.js +4 -1
- package/package.json +1 -1
- package/services/ai.js +16 -3
- package/services/engagementMetrics.js +153 -0
- package/services/messaging/CampaignsService.js +10 -0
- package/services/messaging/EmailAddressesService.js +89 -0
- package/services/messaging/EmailAnalyticsService.js +109 -0
- package/services/messaging/EmailDomainsService.js +252 -0
- package/services/messaging/EmailMailboxesService.js +458 -0
- package/services/messaging/EmailQueueService.js +96 -0
- package/services/messaging/EmailService.js +690 -0
- package/services/messaging/EmailSuppressionService.js +189 -0
- package/services/messaging/EmailTemplatesService.js +145 -0
- package/services/messaging/MessagingService.js +12 -0
- package/services/messaging/SmsService.js +75 -0
- package/services/messaging/SmsTemplatesService.js +124 -0
- package/services/messaging/TenDlcBrandsService.js +446 -0
- package/services/messaging/TenDlcCampaignManagementService.js +390 -0
- package/services/messaging/TenDlcCampaignsService.js +32 -0
- package/services/messaging/TollFreeCampaignsService.js +304 -0
- package/services/messaging.js +37 -1986
- package/services/objects.js +28 -38
- package/services/recordTypes.js +227 -4
- package/services/sipEndpoints.js +12 -12
- package/services/storage.js +226 -1
- package/services/video.js +59 -1
package/base.js
CHANGED
|
@@ -30,7 +30,7 @@ export class BaseSDK {
|
|
|
30
30
|
this.token = token;
|
|
31
31
|
this.fwRequestId = fwRequestId;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
this.baseURL;
|
|
34
34
|
this.transports = new Map();
|
|
35
35
|
this.debugMode = false;
|
|
36
36
|
this._initializeEnvironment();
|
|
@@ -101,7 +101,7 @@ export class BaseSDK {
|
|
|
101
101
|
removeTransport(name) {
|
|
102
102
|
this.transports.delete(name);
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
_getJsonSafely(str, defaultValue) {
|
|
106
106
|
try {
|
|
107
107
|
return JSON.parse(str);
|
|
@@ -167,20 +167,21 @@ export class BaseSDK {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
async _fetch(endpoint, method, params = {}, forceFetch = false) {
|
|
170
|
-
const { body, query, headers = {} } = params;
|
|
170
|
+
const { body, query, headers = {}, returnRawResponse = false } = params;
|
|
171
171
|
|
|
172
172
|
this.validateParams(
|
|
173
|
-
{ endpoint, method, body, query, headers },
|
|
173
|
+
{ endpoint, method, body, query, headers, returnRawResponse },
|
|
174
174
|
{
|
|
175
175
|
endpoint: { type: 'string', required: true },
|
|
176
176
|
method: { type: 'string', required: true },
|
|
177
177
|
body: { type: 'object', required: false },
|
|
178
178
|
query: { type: 'object', required: false },
|
|
179
179
|
headers: { type: 'object', required: false },
|
|
180
|
+
returnRawResponse: { type: 'boolean', required: false },
|
|
180
181
|
},
|
|
181
182
|
);
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
// Add auth headers
|
|
184
185
|
if (this.token) {
|
|
185
186
|
headers.Authorization = `Bearer ${this.token}`;
|
|
186
187
|
}
|
|
@@ -205,68 +206,75 @@ export class BaseSDK {
|
|
|
205
206
|
fwRequestId: this.fwRequestId,
|
|
206
207
|
baseURL: this.baseURL || this.fullUrl,
|
|
207
208
|
});
|
|
208
|
-
|
|
209
|
-
|
|
210
209
|
} catch (err) {
|
|
211
210
|
// IMPORTANT: This catch block should ONLY handle transport-level failures
|
|
212
211
|
// (e.g., WebSocket disconnected, plugin unavailable, network errors)
|
|
213
|
-
//
|
|
212
|
+
//
|
|
214
213
|
// Transport plugins should:
|
|
215
214
|
// - RETURN API error responses normally (400, 500, etc.) as response objects
|
|
216
215
|
// - ONLY THROW for transport mechanism failures
|
|
217
|
-
|
|
216
|
+
|
|
218
217
|
console.warn(
|
|
219
218
|
`Transport ${transport.name} mechanism failed, falling back to HTTP:`,
|
|
220
219
|
err.message,
|
|
221
220
|
);
|
|
222
221
|
|
|
223
222
|
// Built-in HTTP transport (fallback)
|
|
224
|
-
return this._httpRequest(endpoint, method, params);
|
|
223
|
+
return this._httpRequest(endpoint, method, params, returnRawResponse);
|
|
225
224
|
}
|
|
226
225
|
} else {
|
|
227
226
|
// No transport available, fallback to HTTP
|
|
228
|
-
return this._httpRequest(endpoint, method, params);
|
|
227
|
+
return this._httpRequest(endpoint, method, params, returnRawResponse);
|
|
229
228
|
}
|
|
230
229
|
|
|
231
|
-
return
|
|
230
|
+
// For streaming requests, return the raw response from transports
|
|
231
|
+
if (returnRawResponse) {
|
|
232
|
+
return response;
|
|
233
|
+
}
|
|
232
234
|
|
|
235
|
+
return this._processResponse(response, transport.name, method, endpoint);
|
|
233
236
|
}
|
|
234
237
|
|
|
235
238
|
_isMultipartBody(body) {
|
|
236
239
|
// Check if body is FormData or multipart content
|
|
237
240
|
if (!body) return false;
|
|
238
|
-
|
|
241
|
+
|
|
239
242
|
// Browser FormData
|
|
240
243
|
if (typeof FormData !== 'undefined' && body instanceof FormData) {
|
|
241
244
|
return true;
|
|
242
245
|
}
|
|
243
|
-
|
|
246
|
+
|
|
244
247
|
// Node.js Buffer (our manual multipart construction)
|
|
245
248
|
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(body)) {
|
|
246
249
|
return true;
|
|
247
250
|
}
|
|
248
|
-
|
|
251
|
+
|
|
249
252
|
// Uint8Array (fallback multipart construction)
|
|
250
253
|
if (body instanceof Uint8Array) {
|
|
251
254
|
return true;
|
|
252
255
|
}
|
|
253
|
-
|
|
256
|
+
|
|
254
257
|
// String-based multipart (check for multipart boundaries)
|
|
255
|
-
if (
|
|
258
|
+
if (
|
|
259
|
+
typeof body === 'string' &&
|
|
260
|
+
body.includes('Content-Disposition: form-data')
|
|
261
|
+
) {
|
|
256
262
|
return true;
|
|
257
263
|
}
|
|
258
|
-
|
|
264
|
+
|
|
259
265
|
return false;
|
|
260
266
|
}
|
|
261
267
|
|
|
262
|
-
async _httpRequest(endpoint, method, params = {}) {
|
|
268
|
+
async _httpRequest(endpoint, method, params = {}, returnRawResponse = false) {
|
|
263
269
|
const { body, query, headers = {} } = params;
|
|
264
270
|
|
|
265
271
|
const options = {
|
|
266
272
|
method,
|
|
267
273
|
headers: {
|
|
268
274
|
// Smart content-type detection based on actual body content
|
|
269
|
-
...(this._isMultipartBody(body) ||
|
|
275
|
+
...(this._isMultipartBody(body) ||
|
|
276
|
+
headers?.['Content-Type'] ||
|
|
277
|
+
headers?.['content-type']
|
|
270
278
|
? {}
|
|
271
279
|
: { 'Content-Type': 'application/json' }),
|
|
272
280
|
...headers,
|
|
@@ -300,7 +308,10 @@ export class BaseSDK {
|
|
|
300
308
|
body &&
|
|
301
309
|
(body.constructor.name === 'FormData' ||
|
|
302
310
|
typeof body.getBoundary === 'function');
|
|
303
|
-
const isBuffer =
|
|
311
|
+
const isBuffer =
|
|
312
|
+
typeof Buffer !== 'undefined' &&
|
|
313
|
+
Buffer.isBuffer &&
|
|
314
|
+
Buffer.isBuffer(body);
|
|
304
315
|
|
|
305
316
|
if (isFormData || isBuffer) {
|
|
306
317
|
options.body = body;
|
|
@@ -310,9 +321,13 @@ export class BaseSDK {
|
|
|
310
321
|
}
|
|
311
322
|
|
|
312
323
|
const response = await fetch(url, options);
|
|
313
|
-
|
|
324
|
+
|
|
325
|
+
// For streaming requests, return the raw fetch response
|
|
326
|
+
if (returnRawResponse) {
|
|
327
|
+
return response;
|
|
328
|
+
}
|
|
329
|
+
|
|
314
330
|
return this._processResponse(response, 'https', method, endpoint);
|
|
315
|
-
|
|
316
331
|
}
|
|
317
332
|
|
|
318
333
|
async _processResponse(response, transport, method, endpoint) {
|
|
@@ -322,18 +337,24 @@ export class BaseSDK {
|
|
|
322
337
|
const responseHeaders = response.headers;
|
|
323
338
|
const responseRequestId =
|
|
324
339
|
responseHeaders?.get?.('x-request-id') ||
|
|
325
|
-
responseHeaders?.['x-request-id'] ||
|
|
340
|
+
responseHeaders?.['x-request-id'] ||
|
|
341
|
+
'';
|
|
326
342
|
|
|
327
|
-
const contentType =
|
|
343
|
+
const contentType =
|
|
344
|
+
responseHeaders?.get?.('content-type') ||
|
|
345
|
+
response?.headers?.['content-type'] ||
|
|
346
|
+
'application/json';
|
|
328
347
|
|
|
329
348
|
if (!response.ok) {
|
|
330
349
|
let errorBody;
|
|
331
350
|
if (response?.body) {
|
|
332
|
-
|
|
351
|
+
errorBody = response.body;
|
|
333
352
|
} else if (response?.headers?.['content-type']) {
|
|
334
|
-
|
|
335
353
|
try {
|
|
336
|
-
if (
|
|
354
|
+
if (
|
|
355
|
+
typeof response?.json === 'function' ||
|
|
356
|
+
typeof response?.text === 'function'
|
|
357
|
+
) {
|
|
337
358
|
if (contentType.includes('application/json')) {
|
|
338
359
|
errorBody = await response.json();
|
|
339
360
|
} else if (contentType.includes('text/')) {
|
|
@@ -341,7 +362,10 @@ export class BaseSDK {
|
|
|
341
362
|
}
|
|
342
363
|
} else {
|
|
343
364
|
if (contentType.includes('application/json')) {
|
|
344
|
-
errorBody = this._getJsonSafely(
|
|
365
|
+
errorBody = this._getJsonSafely(
|
|
366
|
+
response?.body,
|
|
367
|
+
response?.body || {},
|
|
368
|
+
);
|
|
345
369
|
} else if (contentType.includes('text/')) {
|
|
346
370
|
errorBody = response?.body || '';
|
|
347
371
|
}
|
|
@@ -355,29 +379,37 @@ export class BaseSDK {
|
|
|
355
379
|
} else {
|
|
356
380
|
errorBody = `HTTP ${response.status} ${response.statusText}`;
|
|
357
381
|
}
|
|
358
|
-
|
|
382
|
+
|
|
359
383
|
// Create a structured error for API/HTTP failures
|
|
360
|
-
const httpError = new Error(
|
|
384
|
+
const httpError = new Error(
|
|
385
|
+
`API :: Error :: ${transport} :: ${method.toUpperCase()} :: ${endpoint} :: ${
|
|
386
|
+
response.status
|
|
387
|
+
} :: ${response.statusText}`,
|
|
388
|
+
);
|
|
361
389
|
httpError.status = response.status;
|
|
362
390
|
httpError.statusText = response.statusText;
|
|
363
391
|
httpError.method = method;
|
|
364
392
|
httpError.endpoint = endpoint;
|
|
365
393
|
httpError.body = errorBody;
|
|
366
394
|
httpError.message = errorBody?.error || errorBody?.message || 'API Error';
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
395
|
+
|
|
396
|
+
// Debug logging for successful HTTP requests
|
|
397
|
+
if (this.debugMode) {
|
|
398
|
+
console.log(
|
|
399
|
+
`API :: ERROR :: ${transport} :: ${method.toUpperCase()} :: ${endpoint} :: ${
|
|
400
|
+
response?.status
|
|
401
|
+
} :: ${responseRequestId}`,
|
|
402
|
+
httpError,
|
|
403
|
+
);
|
|
404
|
+
}
|
|
372
405
|
|
|
373
406
|
throw httpError;
|
|
374
407
|
}
|
|
375
408
|
|
|
376
409
|
let responseBody;
|
|
377
410
|
if (response?.body && !contentType) {
|
|
378
|
-
|
|
411
|
+
responseBody = response.body;
|
|
379
412
|
} else if (contentType) {
|
|
380
|
-
|
|
381
413
|
try {
|
|
382
414
|
if (transport === 'https') {
|
|
383
415
|
if (contentType.includes('application/json')) {
|
|
@@ -403,15 +435,16 @@ export class BaseSDK {
|
|
|
403
435
|
} else {
|
|
404
436
|
responseBody = {};
|
|
405
437
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
438
|
|
|
410
439
|
// Debug logging for successful HTTP requests
|
|
411
440
|
if (this.debugMode) {
|
|
412
|
-
console.log(
|
|
441
|
+
console.log(
|
|
442
|
+
`API :: ${transport} :: ${method.toUpperCase()} :: ${endpoint} :: ${
|
|
443
|
+
response?.status
|
|
444
|
+
} :: ${responseRequestId}`,
|
|
445
|
+
);
|
|
413
446
|
}
|
|
414
|
-
|
|
447
|
+
|
|
415
448
|
return responseBody;
|
|
416
449
|
}
|
|
417
450
|
}
|
package/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { BaseSDK } from './base.js';
|
|
5
5
|
import { LoginService } from './services/login.js';
|
|
6
6
|
import { ObjectsService } from './services/objects.js';
|
|
7
|
-
import { MessagingService } from './services/messaging.js';
|
|
7
|
+
import { MessagingService } from './services/messaging/MessagingService.js';
|
|
8
8
|
import { VideoService } from './services/video.js';
|
|
9
9
|
import { VoiceService } from './services/voice.js';
|
|
10
10
|
import { AIService } from './services/ai.js';
|
|
@@ -23,6 +23,7 @@ import { EnrollService } from './services/enroll.js';
|
|
|
23
23
|
import { PhoneNumbersService } from './services/phoneNumbers.js';
|
|
24
24
|
import { RecordTypesService } from './services/recordTypes.js';
|
|
25
25
|
import { GenerateIdService } from './services/generateId.js';
|
|
26
|
+
import { EngagementMetricsService } from './services/engagementMetrics.js';
|
|
26
27
|
|
|
27
28
|
class UnboundSDK extends BaseSDK {
|
|
28
29
|
constructor(options = {}) {
|
|
@@ -87,6 +88,7 @@ class UnboundSDK extends BaseSDK {
|
|
|
87
88
|
this.phoneNumbers = new PhoneNumbersService(this);
|
|
88
89
|
this.recordTypes = new RecordTypesService(this);
|
|
89
90
|
this.generateId = new GenerateIdService(this);
|
|
91
|
+
this.engagementMetrics = new EngagementMetricsService(this);
|
|
90
92
|
|
|
91
93
|
// Add additional services that might be missing
|
|
92
94
|
this._initializeAdditionalServices();
|
|
@@ -190,4 +192,5 @@ export {
|
|
|
190
192
|
UserRecordTypeDefaultsService,
|
|
191
193
|
} from './services/recordTypes.js';
|
|
192
194
|
export { GenerateIdService } from './services/generateId.js';
|
|
195
|
+
export { EngagementMetricsService } from './services/engagementMetrics.js';
|
|
193
196
|
export { BaseSDK } from './base.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
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",
|
package/services/ai.js
CHANGED
|
@@ -22,11 +22,10 @@ export class GenerativeService {
|
|
|
22
22
|
method,
|
|
23
23
|
}) {
|
|
24
24
|
this.sdk.validateParams(
|
|
25
|
-
{ method },
|
|
25
|
+
{ method, stream, temperature, subscriptionId, model, prompt, messages },
|
|
26
26
|
{
|
|
27
27
|
prompt: { type: 'string', required: false },
|
|
28
28
|
messages: { type: 'array', required: false },
|
|
29
|
-
relatedId: { type: 'string', required: false },
|
|
30
29
|
model: { type: 'string', required: false },
|
|
31
30
|
temperature: { type: 'number', required: false },
|
|
32
31
|
subscriptionId: { type: 'string', required: false },
|
|
@@ -46,9 +45,18 @@ export class GenerativeService {
|
|
|
46
45
|
stream,
|
|
47
46
|
method,
|
|
48
47
|
},
|
|
48
|
+
// Return raw response for streaming to allow client-side stream handling
|
|
49
|
+
returnRawResponse: stream === true,
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
// Force HTTP transport when streaming is enabled since NATS doesn't support streaming responses
|
|
53
|
+
const forceFetch = stream === true;
|
|
54
|
+
const result = await this.sdk._fetch(
|
|
55
|
+
'/ai/generative/chat',
|
|
56
|
+
'POST',
|
|
57
|
+
params,
|
|
58
|
+
forceFetch,
|
|
59
|
+
);
|
|
52
60
|
return result;
|
|
53
61
|
}
|
|
54
62
|
|
|
@@ -135,12 +143,17 @@ export class GenerativeService {
|
|
|
135
143
|
stream,
|
|
136
144
|
method,
|
|
137
145
|
},
|
|
146
|
+
// Return raw response for streaming to allow client-side stream handling
|
|
147
|
+
returnRawResponse: stream === true,
|
|
138
148
|
};
|
|
139
149
|
|
|
150
|
+
// Force HTTP transport when streaming is enabled since NATS doesn't support streaming responses
|
|
151
|
+
const forceFetch = stream === true;
|
|
140
152
|
const result = await this.sdk._fetch(
|
|
141
153
|
'/ai/generative/ollama',
|
|
142
154
|
'POST',
|
|
143
155
|
params,
|
|
156
|
+
forceFetch,
|
|
144
157
|
);
|
|
145
158
|
return result;
|
|
146
159
|
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
export class EngagementMetricsService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get engagement metrics with flexible filtering and configurable response options
|
|
8
|
+
* @param {Object} options - Query options
|
|
9
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
10
|
+
* @param {string[]} [options.statuses] - Array of statuses to filter by (new, working, wrapUp, completed)
|
|
11
|
+
* @param {string[]} [options.userIds] - Array of user IDs to filter by
|
|
12
|
+
* @param {boolean} [options.includeSummary=true] - Include overall summary metrics
|
|
13
|
+
* @param {boolean} [options.includeByQueue=true] - Include metrics grouped by queue and status
|
|
14
|
+
* @param {boolean} [options.includeQueuePerformance=false] - Include queue performance metrics
|
|
15
|
+
* @param {boolean} [options.includeAgentPerformance=false] - Include agent performance metrics
|
|
16
|
+
* @returns {Promise<Object>} Metrics data
|
|
17
|
+
*/
|
|
18
|
+
async getMetrics({
|
|
19
|
+
queueIds = [],
|
|
20
|
+
statuses = [],
|
|
21
|
+
userIds = [],
|
|
22
|
+
includeSummary = true,
|
|
23
|
+
includeByQueue = true,
|
|
24
|
+
includeQueuePerformance = false,
|
|
25
|
+
includeAgentPerformance = false,
|
|
26
|
+
} = {}) {
|
|
27
|
+
this.sdk.validateParams(
|
|
28
|
+
{
|
|
29
|
+
queueIds,
|
|
30
|
+
statuses,
|
|
31
|
+
userIds,
|
|
32
|
+
includeSummary,
|
|
33
|
+
includeByQueue,
|
|
34
|
+
includeQueuePerformance,
|
|
35
|
+
includeAgentPerformance,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
queueIds: { type: 'array', required: false },
|
|
39
|
+
statuses: { type: 'array', required: false },
|
|
40
|
+
userIds: { type: 'array', required: false },
|
|
41
|
+
includeSummary: { type: 'boolean', required: false },
|
|
42
|
+
includeByQueue: { type: 'boolean', required: false },
|
|
43
|
+
includeQueuePerformance: { type: 'boolean', required: false },
|
|
44
|
+
includeAgentPerformance: { type: 'boolean', required: false },
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const params = {
|
|
49
|
+
query: {
|
|
50
|
+
queueIds: Array.isArray(queueIds) ? queueIds.join(',') : queueIds,
|
|
51
|
+
statuses: Array.isArray(statuses) ? statuses.join(',') : statuses,
|
|
52
|
+
userIds: Array.isArray(userIds) ? userIds.join(',') : userIds,
|
|
53
|
+
includeSummary,
|
|
54
|
+
includeByQueue,
|
|
55
|
+
includeQueuePerformance,
|
|
56
|
+
includeAgentPerformance,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const result = await this.sdk._fetch('/engagementMetrics/', 'GET', params);
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get basic engagement metrics summary
|
|
66
|
+
* @param {Object} options - Filter options
|
|
67
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
68
|
+
* @param {string[]} [options.statuses] - Array of statuses to filter by
|
|
69
|
+
* @returns {Promise<Object>} Summary metrics
|
|
70
|
+
*/
|
|
71
|
+
async getSummary({ queueIds = [], statuses = [] } = {}) {
|
|
72
|
+
return this.getMetrics({
|
|
73
|
+
queueIds,
|
|
74
|
+
statuses,
|
|
75
|
+
includeSummary: true,
|
|
76
|
+
includeByQueue: false,
|
|
77
|
+
includeQueuePerformance: false,
|
|
78
|
+
includeAgentPerformance: false,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get metrics grouped by queue and status
|
|
84
|
+
* @param {Object} options - Filter options
|
|
85
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
86
|
+
* @param {string[]} [options.statuses] - Array of statuses to filter by
|
|
87
|
+
* @returns {Promise<Object>} Queue-grouped metrics
|
|
88
|
+
*/
|
|
89
|
+
async getByQueue({ queueIds = [], statuses = [] } = {}) {
|
|
90
|
+
return this.getMetrics({
|
|
91
|
+
queueIds,
|
|
92
|
+
statuses,
|
|
93
|
+
includeSummary: false,
|
|
94
|
+
includeByQueue: true,
|
|
95
|
+
includeQueuePerformance: false,
|
|
96
|
+
includeAgentPerformance: false,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get queue performance metrics
|
|
102
|
+
* @param {Object} options - Filter options
|
|
103
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
104
|
+
* @returns {Promise<Object>} Queue performance metrics
|
|
105
|
+
*/
|
|
106
|
+
async getQueuePerformance({ queueIds = [] } = {}) {
|
|
107
|
+
return this.getMetrics({
|
|
108
|
+
queueIds,
|
|
109
|
+
includeSummary: false,
|
|
110
|
+
includeByQueue: false,
|
|
111
|
+
includeQueuePerformance: true,
|
|
112
|
+
includeAgentPerformance: false,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get agent performance metrics
|
|
118
|
+
* @param {Object} options - Filter options
|
|
119
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
120
|
+
* @param {string[]} [options.userIds] - Array of user IDs to filter by
|
|
121
|
+
* @returns {Promise<Object>} Agent performance metrics
|
|
122
|
+
*/
|
|
123
|
+
async getAgentPerformance({ queueIds = [], userIds = [] } = {}) {
|
|
124
|
+
return this.getMetrics({
|
|
125
|
+
queueIds,
|
|
126
|
+
userIds,
|
|
127
|
+
includeSummary: false,
|
|
128
|
+
includeByQueue: false,
|
|
129
|
+
includeQueuePerformance: false,
|
|
130
|
+
includeAgentPerformance: true,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get comprehensive metrics for dashboard
|
|
136
|
+
* @param {Object} options - Filter options
|
|
137
|
+
* @param {string[]} [options.queueIds] - Array of queue IDs to filter by
|
|
138
|
+
* @param {string[]} [options.statuses] - Array of statuses to filter by
|
|
139
|
+
* @param {string[]} [options.userIds] - Array of user IDs to filter by
|
|
140
|
+
* @returns {Promise<Object>} All metrics
|
|
141
|
+
*/
|
|
142
|
+
async getDashboardMetrics({ queueIds = [], statuses = [], userIds = [] } = {}) {
|
|
143
|
+
return this.getMetrics({
|
|
144
|
+
queueIds,
|
|
145
|
+
statuses,
|
|
146
|
+
userIds,
|
|
147
|
+
includeSummary: true,
|
|
148
|
+
includeByQueue: true,
|
|
149
|
+
includeQueuePerformance: true,
|
|
150
|
+
includeAgentPerformance: true,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TollFreeCampaignsService } from './TollFreeCampaignsService.js';
|
|
2
|
+
import { TenDlcCampaignsService } from './TenDlcCampaignsService.js';
|
|
3
|
+
|
|
4
|
+
export class CampaignsService {
|
|
5
|
+
constructor(sdk) {
|
|
6
|
+
this.sdk = sdk;
|
|
7
|
+
this.tollFree = new TollFreeCampaignsService(sdk);
|
|
8
|
+
this.tenDlc = new TenDlcCampaignsService(sdk);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export class EmailAddressesService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create email address verification
|
|
8
|
+
* @param {string} emailAddress - Email address to verify (required)
|
|
9
|
+
* @returns {Promise<Object>} Email verification details
|
|
10
|
+
*/
|
|
11
|
+
async create(emailAddress) {
|
|
12
|
+
this.sdk.validateParams(
|
|
13
|
+
{ emailAddress },
|
|
14
|
+
{
|
|
15
|
+
emailAddress: { type: 'string', required: true },
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const options = {
|
|
20
|
+
body: { emailAddress },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const result = await this.sdk._fetch(
|
|
24
|
+
'/messaging/email/validate/emailAddress',
|
|
25
|
+
'POST',
|
|
26
|
+
options,
|
|
27
|
+
);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Delete email address verification
|
|
33
|
+
* @param {string} emailAddress - Email address to remove (required)
|
|
34
|
+
* @returns {Promise<Object>} Deletion confirmation
|
|
35
|
+
*/
|
|
36
|
+
async delete(emailAddress) {
|
|
37
|
+
this.sdk.validateParams(
|
|
38
|
+
{ emailAddress },
|
|
39
|
+
{
|
|
40
|
+
emailAddress: { type: 'string', required: true },
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const result = await this.sdk._fetch(
|
|
45
|
+
`/messaging/email/validate/emailAddress/${encodeURIComponent(
|
|
46
|
+
emailAddress,
|
|
47
|
+
)}`,
|
|
48
|
+
'DELETE',
|
|
49
|
+
);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* List all verified email addresses
|
|
55
|
+
* @returns {Promise<Array>} List of verified email addresses
|
|
56
|
+
*/
|
|
57
|
+
async list() {
|
|
58
|
+
const result = await this.sdk._fetch(
|
|
59
|
+
'/messaging/email/validate/emailAddress',
|
|
60
|
+
'GET',
|
|
61
|
+
);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check email address verification status
|
|
67
|
+
* @param {string} emailAddress - Email address to check (required)
|
|
68
|
+
* @returns {Promise<Object>} Email verification status
|
|
69
|
+
*/
|
|
70
|
+
async checkStatus(emailAddress) {
|
|
71
|
+
this.sdk.validateParams(
|
|
72
|
+
{ emailAddress },
|
|
73
|
+
{
|
|
74
|
+
emailAddress: { type: 'string', required: true },
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const options = {
|
|
79
|
+
query: { emailAddress },
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const result = await this.sdk._fetch(
|
|
83
|
+
'/messaging/email/validate/emailAddress/status',
|
|
84
|
+
'GET',
|
|
85
|
+
options,
|
|
86
|
+
);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
}
|