@unboundcx/sdk 2.8.7 → 2.8.8

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.
@@ -3,6 +3,28 @@ export class PortalsService {
3
3
  this.sdk = sdk;
4
4
  }
5
5
 
6
+ /**
7
+ * Creates a new portal for the authenticated account.
8
+ *
9
+ * @param {object} params
10
+ * @param {string} params.name - Display name of the portal.
11
+ * @param {string} params.domain - Custom domain for the portal (e.g. `portal.example.com`).
12
+ * A CNAME DNS record pointing to the platform's portal host is required.
13
+ * @param {object} [params.settings] - Optional portal configuration settings.
14
+ * @param {boolean} [params.isPublic] - Whether the portal is publicly accessible without
15
+ * authentication. Defaults to private if omitted.
16
+ * @param {string} [params.customCss] - Optional custom CSS injected into the portal.
17
+ * @param {string} [params.customJs] - Optional custom JavaScript injected into the portal.
18
+ * @param {string} [params.favicon] - Optional URL or asset reference for the portal favicon.
19
+ * @param {string} [params.logo] - Optional URL or asset reference for the portal logo.
20
+ * @returns {Promise<{
21
+ * id: string,
22
+ * accountId: string,
23
+ * name: string,
24
+ * domain: string,
25
+ * dns: Array<{ type: string, name: string, value: string, description: string }>
26
+ * }>} The newly created portal, including DNS records needed to configure the custom domain.
27
+ */
6
28
  async create({
7
29
  name,
8
30
  domain,
@@ -43,6 +65,29 @@ export class PortalsService {
43
65
  return result;
44
66
  }
45
67
 
68
+ /**
69
+ * Updates an existing portal's properties.
70
+ *
71
+ * Only the fields provided will be updated; omitted fields are left unchanged.
72
+ *
73
+ * @param {string} portalId - The ID of the portal to update.
74
+ * @param {object} updates
75
+ * @param {string} [updates.name] - New display name for the portal.
76
+ * @param {string} [updates.domain] - New custom domain for the portal.
77
+ * @param {object} [updates.settings] - Updated portal configuration settings.
78
+ * @param {boolean} [updates.isPublic] - Updated public accessibility flag.
79
+ * @param {string} [updates.customCss] - Updated custom CSS for the portal.
80
+ * @param {string} [updates.customJs] - Updated custom JavaScript for the portal.
81
+ * @param {string} [updates.favicon] - Updated favicon URL or asset reference.
82
+ * @param {string} [updates.logo] - Updated logo URL or asset reference.
83
+ * @returns {Promise<{
84
+ * id: string,
85
+ * updatedBy: string,
86
+ * updatedAt: string,
87
+ * name?: string,
88
+ * domain?: string
89
+ * }>} The updated portal fields along with audit metadata.
90
+ */
46
91
  async update(
47
92
  portalId,
48
93
  { name, domain, settings, isPublic, customCss, customJs, favicon, logo },
@@ -80,6 +125,12 @@ export class PortalsService {
80
125
  return result;
81
126
  }
82
127
 
128
+ /**
129
+ * Deletes a portal by ID.
130
+ *
131
+ * @param {string} portalId - The ID of the portal to delete.
132
+ * @returns {Promise<{ message: string }>} Confirmation message on success.
133
+ */
83
134
  async delete(portalId) {
84
135
  this.sdk.validateParams(
85
136
  { portalId },
@@ -92,6 +143,12 @@ export class PortalsService {
92
143
  return result;
93
144
  }
94
145
 
146
+ /**
147
+ * Retrieves a portal by ID.
148
+ *
149
+ * @param {string} portalId - The ID of the portal to retrieve.
150
+ * @returns {Promise<object>} The full portal record.
151
+ */
95
152
  async get(portalId) {
96
153
  this.sdk.validateParams(
97
154
  { portalId },
@@ -104,6 +161,17 @@ export class PortalsService {
104
161
  return result;
105
162
  }
106
163
 
164
+ /**
165
+ * Retrieves public portal information by domain.
166
+ *
167
+ * This is an unauthenticated endpoint used by portal front-ends to look up
168
+ * their own configuration based on the domain they are served from.
169
+ *
170
+ * @param {string} domain - The custom domain of the portal to look up
171
+ * (e.g. `portal.example.com`).
172
+ * @returns {Promise<{ id: string, name: string, domain: string }>}
173
+ * The public-facing portal fields. Sensitive account data is excluded.
174
+ */
107
175
  async getPublic(domain) {
108
176
  this.sdk.validateParams(
109
177
  { domain },
@@ -120,11 +188,32 @@ export class PortalsService {
120
188
  return result;
121
189
  }
122
190
 
191
+ /**
192
+ * Lists all portals belonging to the authenticated account.
193
+ *
194
+ * @returns {Promise<{ portals: object[] }>} An object containing an array of portal records.
195
+ */
123
196
  async list() {
124
197
  const result = await this.sdk._fetch('/portals', 'GET');
125
198
  return result;
126
199
  }
127
200
 
201
+ /**
202
+ * Verifies that a portal's custom domain has the correct DNS configuration.
203
+ *
204
+ * Checks that the domain has a valid CNAME record pointing to the platform's
205
+ * portal host. Use the `dns` records returned from `create()` to know the
206
+ * expected target value.
207
+ *
208
+ * @param {string} portalId - The ID of the portal whose DNS should be verified.
209
+ * @returns {Promise<{
210
+ * portalId: string,
211
+ * domain: string,
212
+ * expectedTarget: string,
213
+ * dns: object
214
+ * }>} The DNS verification result, including the expected CNAME target and
215
+ * the actual resolution details.
216
+ */
128
217
  async verifyDns(portalId) {
129
218
  this.sdk.validateParams(
130
219
  { portalId },
@@ -378,6 +378,28 @@ Response:
378
378
  }
379
379
 
380
380
  */
381
+ /**
382
+ * Upload a file to storage with optional format conversion
383
+ * @param {Object} config - Configuration object
384
+ * @param {Object} config.file - File content (Buffer or File) - REQUIRED
385
+ * @param {string} [config.classification='generic'] - File classification (e.g., 'fax', 'files', 'generic')
386
+ * @param {string} [config.folder] - Folder path for organizing files
387
+ * @param {string} [config.fileName] - Original file name
388
+ * @param {boolean} [config.isPublic=false] - Whether file is publicly accessible
389
+ * @param {string} [config.country='US'] - Country code for region selection
390
+ * @param {string} [config.expireAfter] - Expiration time
391
+ * @param {string} [config.relatedId] - Related object ID
392
+ * @param {boolean} [config.createAccessKey=false] - Generate an access key for the file
393
+ * @param {number} [config.accessKeyExpiresIn] - Access key expiration in seconds
394
+ * @param {string} [config.convertTo] - Convert uploaded file to this format before storing. Supported: 'pdf', 'tiff'. Input must be PDF, DOC, or DOCX.
395
+ * @param {Object} [config.convertOptions] - Options for file conversion (used with convertTo)
396
+ * @param {('fine'|'normal')} [config.convertOptions.resolution='fine'] - Fax resolution: 'fine' (204x196) or 'normal' (204x98)
397
+ * @param {('letter'|'a4')} [config.convertOptions.paperSize='letter'] - Paper size for conversion
398
+ * @param {('g4'|'g3')} [config.convertOptions.compression='g4'] - TIFF compression: 'g4' (default) or 'g3' for older fax machines
399
+ * @param {Function} [config.onProgress] - Progress callback for browser uploads
400
+ * @param {Object} [config._options] - Internal options
401
+ * @returns {Promise<Object>} Upload result with uploaded files, viruses, and errors
402
+ */
381
403
  async upload({
382
404
  classification = 'generic',
383
405
  folder,
@@ -389,6 +411,8 @@ Response:
389
411
  relatedId,
390
412
  createAccessKey = false,
391
413
  accessKeyExpiresIn,
414
+ convertTo,
415
+ convertOptions,
392
416
  onProgress,
393
417
  _options,
394
418
  }) {
@@ -404,6 +428,8 @@ Response:
404
428
  relatedId,
405
429
  createAccessKey,
406
430
  accessKeyExpiresIn,
431
+ convertTo,
432
+ convertOptions,
407
433
  },
408
434
  {
409
435
  classification: { type: 'string', required: false },
@@ -416,6 +442,8 @@ Response:
416
442
  relatedId: { type: 'string', required: false },
417
443
  createAccessKey: { type: 'boolean', required: false },
418
444
  accessKeyExpiresIn: { type: 'number', required: false },
445
+ convertTo: { type: 'string', required: false },
446
+ convertOptions: { type: 'object', required: false },
419
447
  },
420
448
  );
421
449
 
@@ -432,6 +460,9 @@ Response:
432
460
  formFields.push(['createAccessKey', createAccessKey.toString()]);
433
461
  if (accessKeyExpiresIn)
434
462
  formFields.push(['accessKeyExpiresIn', accessKeyExpiresIn]);
463
+ if (convertTo) formFields.push(['convertTo', convertTo]);
464
+ if (convertOptions)
465
+ formFields.push(['convertOptions', JSON.stringify(convertOptions)]);
435
466
 
436
467
  return this._performUpload(
437
468
  file,
@@ -891,6 +922,109 @@ Response:
891
922
  return result;
892
923
  }
893
924
 
925
+ /**
926
+ * Convert an existing stored file to a different format and save it as a new storage record.
927
+ * The original file remains unchanged. Supported source formats: PDF, DOC, DOCX.
928
+ * Supported output formats: 'pdf', 'tiff'.
929
+ *
930
+ * Fields not provided in the request (classification, folder, relatedId, isPublic)
931
+ * are inherited from the source file. If expireAfter is not provided, the expireAt
932
+ * timestamp is copied directly from the source file.
933
+ *
934
+ * @param {string} storageId - ID of the existing storage file to convert (required)
935
+ * @param {Object} config - Conversion options
936
+ * @param {string} config.convertTo - Target format: 'pdf' or 'tiff' (required)
937
+ * @param {Object} [config.convertOptions] - Options controlling the conversion output
938
+ * @param {('fine'|'normal')} [config.convertOptions.resolution='fine'] - Fax resolution: 'fine' (204x196 DPI) or 'normal' (204x98 DPI)
939
+ * @param {('letter'|'a4')} [config.convertOptions.paperSize='letter'] - Paper size for conversion
940
+ * @param {('g4'|'g3')} [config.convertOptions.compression='g4'] - TIFF compression: 'g4' (modern, default) or 'g3' (legacy fax machines)
941
+ * @param {string} [config.classification] - Storage classification for the new file. Defaults to source file's classification.
942
+ * @param {string} [config.folder] - Folder path for the new file. Defaults to source file's folder.
943
+ * @param {string} [config.relatedId] - Related object ID for the new file. Defaults to source file's relatedId.
944
+ * @param {boolean} [config.isPublic] - Whether the new file is publicly accessible. Defaults to source file's isPublic.
945
+ * @param {string} [config.expireAfter] - Expiration duration for the new file (e.g., '7d', '1h'). If omitted, copies expireAt from source.
946
+ * @param {boolean} [config.createAccessKey=false] - Generate a temporary access key for the new file
947
+ * @param {string} [config.accessKeyExpiresIn] - Access key expiration duration (e.g., '7d')
948
+ * @returns {Promise<Object>} The newly created storage record for the converted file
949
+ * @returns {string} result.id - Storage ID of the converted file
950
+ * @returns {string} result.sourceStorageId - Storage ID of the original source file
951
+ * @returns {string} result.fileName - File name of the converted file
952
+ * @returns {number} result.fileSize - Size in bytes of the converted file
953
+ * @returns {string} result.url - URL to access the converted file
954
+ * @returns {string} result.mimeType - MIME type of the converted file
955
+ * @returns {string[]} result.s3Regions - Regions where the converted file is stored
956
+ * @returns {boolean} result.isPublic - Whether the converted file is public
957
+ * @returns {string} [result.expireAt] - Expiration timestamp if set
958
+ * @returns {string} [result.accessKey] - Access key if createAccessKey was true
959
+ *
960
+ * @example
961
+ * // Convert a stored PDF to TIFF for fax transmission
962
+ * const result = await sdk.storage.convertFile('017d01...', {
963
+ * convertTo: 'tiff',
964
+ * convertOptions: {
965
+ * resolution: 'fine',
966
+ * paperSize: 'letter',
967
+ * compression: 'g4',
968
+ * },
969
+ * });
970
+ * console.log(result.id); // new storage ID for the TIFF
971
+ * console.log(result.sourceStorageId); // original PDF storage ID
972
+ *
973
+ * @example
974
+ * // Convert a DOCX to PDF, overriding the classification and folder
975
+ * const result = await sdk.storage.convertFile('017d02...', {
976
+ * convertTo: 'pdf',
977
+ * classification: 'fax',
978
+ * folder: 'outbound/2026',
979
+ * });
980
+ */
981
+ async convertFile(
982
+ storageId,
983
+ {
984
+ convertTo,
985
+ convertOptions,
986
+ classification,
987
+ folder,
988
+ relatedId,
989
+ isPublic,
990
+ expireAfter,
991
+ createAccessKey,
992
+ accessKeyExpiresIn,
993
+ } = {},
994
+ ) {
995
+ this.sdk.validateParams(
996
+ { storageId, convertTo },
997
+ {
998
+ storageId: { type: 'string', required: true },
999
+ convertTo: { type: 'string', required: true },
1000
+ convertOptions: { type: 'object', required: false },
1001
+ classification: { type: 'string', required: false },
1002
+ folder: { type: 'string', required: false },
1003
+ relatedId: { type: 'string', required: false },
1004
+ isPublic: { type: 'boolean', required: false },
1005
+ expireAfter: { type: 'string', required: false },
1006
+ createAccessKey: { type: 'boolean', required: false },
1007
+ accessKeyExpiresIn: { type: 'string', required: false },
1008
+ },
1009
+ );
1010
+
1011
+ const body = { convertTo };
1012
+ if (convertOptions !== undefined)
1013
+ body.convertOptions = convertOptions;
1014
+ if (classification !== undefined) body.classification = classification;
1015
+ if (folder !== undefined) body.folder = folder;
1016
+ if (relatedId !== undefined) body.relatedId = relatedId;
1017
+ if (isPublic !== undefined) body.isPublic = isPublic;
1018
+ if (expireAfter !== undefined) body.expireAfter = expireAfter;
1019
+ if (createAccessKey !== undefined) body.createAccessKey = createAccessKey;
1020
+ if (accessKeyExpiresIn !== undefined)
1021
+ body.accessKeyExpiresIn = accessKeyExpiresIn;
1022
+
1023
+ const params = { body };
1024
+
1025
+ return await this.sdk._fetch(`/storage/${storageId}/convert`, 'POST', params);
1026
+ }
1027
+
894
1028
  /**
895
1029
  * Update file contents and metadata
896
1030
  * @param {string} storageId - Storage file ID (required)
@@ -81,6 +81,7 @@ export class TaskService {
81
81
  relatedId,
82
82
  cdrId,
83
83
  sipCallId,
84
+ aiChatSessionId,
84
85
  } = options;
85
86
 
86
87
  this.sdk.validateParams(
@@ -99,6 +100,7 @@ export class TaskService {
99
100
  relatedObject,
100
101
  relatedId,
101
102
  sipCallId,
103
+ aiChatSessionId,
102
104
  },
103
105
  {
104
106
  type: { type: 'string', required: true },
@@ -115,6 +117,7 @@ export class TaskService {
115
117
  relatedObject: { type: 'string', required: false },
116
118
  relatedId: { type: 'string', required: false },
117
119
  sipCallId: { type: 'string', required: false },
120
+ aiChatSessionId: { type: 'string', required: false },
118
121
  },
119
122
  );
120
123
 
@@ -168,10 +171,15 @@ export class TaskService {
168
171
  if (relatedId !== undefined) {
169
172
  params.body.relatedId = relatedId;
170
173
  }
174
+
171
175
  if (sipCallId !== undefined) {
172
176
  params.body.sipCallId = sipCallId;
173
177
  }
174
178
 
179
+ if (aiChatSessionId !== undefined) {
180
+ params.body.aiChatSessionId = aiChatSessionId;
181
+ }
182
+
175
183
  const result = await this.sdk._fetch('/taskRouter/tasks', 'POST', params);
176
184
  return result;
177
185
  }
@@ -30,6 +30,82 @@ export class WorkflowsService {
30
30
  const result = await this.sdk._fetch('/workflows/modules', 'GET', params);
31
31
  return result;
32
32
  }
33
+
34
+ async listFormulaFunctions() {
35
+ const result = await this.sdk._fetch(
36
+ '/workflows/formula-functions',
37
+ 'GET',
38
+ );
39
+ return result;
40
+ }
41
+
42
+ async getAvailableHolidaySets() {
43
+ const result = await this.sdk._fetch(
44
+ '/workflows/holiday-sets',
45
+ 'GET',
46
+ );
47
+ return result;
48
+ }
49
+
50
+ async simulateWebhook(webhookSettings) {
51
+ this.sdk.validateParams(
52
+ { webhookSettings },
53
+ {
54
+ webhookSettings: { type: 'object', required: true },
55
+ },
56
+ );
57
+
58
+ const params = {
59
+ body: { webhookSettings },
60
+ };
61
+
62
+ const result = await this.sdk._fetch(
63
+ '/workflows/webhook/simulate',
64
+ 'POST',
65
+ params,
66
+ );
67
+ return result;
68
+ }
69
+
70
+ async simulateLookup(lookupSettings) {
71
+ this.sdk.validateParams(
72
+ { lookupSettings },
73
+ {
74
+ lookupSettings: { type: 'object', required: true },
75
+ },
76
+ );
77
+
78
+ const params = {
79
+ body: { lookupSettings },
80
+ };
81
+
82
+ const result = await this.sdk._fetch(
83
+ '/workflows/lookup/simulate',
84
+ 'POST',
85
+ params,
86
+ );
87
+ return result;
88
+ }
89
+
90
+ async simulateTimeControl(timeControlSettings, testDateTime = null) {
91
+ this.sdk.validateParams(
92
+ { timeControlSettings },
93
+ {
94
+ timeControlSettings: { type: 'object', required: true },
95
+ },
96
+ );
97
+
98
+ const params = {
99
+ body: { timeControlSettings, testDateTime },
100
+ };
101
+
102
+ const result = await this.sdk._fetch(
103
+ '/workflows/timeControl/simulate',
104
+ 'POST',
105
+ params,
106
+ );
107
+ return result;
108
+ }
33
109
  }
34
110
 
35
111
  export class WorkflowItemsService {
@@ -386,4 +462,61 @@ export class WorkflowSessionsService {
386
462
  );
387
463
  return result;
388
464
  }
465
+
466
+ async logTranscript(sessionId, transcriptData) {
467
+ this.sdk.validateParams(
468
+ { sessionId },
469
+ {
470
+ sessionId: { type: 'string', required: true },
471
+ },
472
+ );
473
+
474
+ const params = {
475
+ body: transcriptData,
476
+ };
477
+
478
+ const result = await this.sdk._fetch(
479
+ `/workflows/session/${sessionId}/transcript`,
480
+ 'POST',
481
+ params,
482
+ );
483
+ return result;
484
+ }
485
+
486
+ async replay(sessionId) {
487
+ this.sdk.validateParams(
488
+ { sessionId },
489
+ {
490
+ sessionId: { type: 'string', required: true },
491
+ },
492
+ );
493
+
494
+ const result = await this.sdk._fetch(
495
+ `/workflows/session/${sessionId}/replay`,
496
+ 'GET',
497
+ );
498
+ return result;
499
+ }
500
+
501
+ async analytics(workflowVersionId, { startDate, endDate } = {}) {
502
+ this.sdk.validateParams(
503
+ { workflowVersionId, startDate, endDate },
504
+ {
505
+ workflowVersionId: { type: 'string', required: true },
506
+ startDate: { type: 'string', required: true },
507
+ endDate: { type: 'string', required: true },
508
+ },
509
+ );
510
+
511
+ const params = {
512
+ query: { startDate, endDate },
513
+ };
514
+
515
+ const result = await this.sdk._fetch(
516
+ `/workflows/${workflowVersionId}/analytics`,
517
+ 'GET',
518
+ params,
519
+ );
520
+ return result;
521
+ }
389
522
  }