@unboundcx/sdk 4.13.49 → 4.13.52

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 CHANGED
@@ -387,8 +387,15 @@ export class BaseSDK {
387
387
 
388
388
  // Add query parameters
389
389
  if (query) {
390
- const params = new URLSearchParams(query).toString();
391
- url += `?${params}`;
390
+ // Drop undefined/null so optional args don't serialize as the literal
391
+ // string "undefined" (URLSearchParams would send limit=undefined).
392
+ const cleanQuery = Object.fromEntries(
393
+ Object.entries(query).filter(
394
+ ([, v]) => v !== undefined && v !== null,
395
+ ),
396
+ );
397
+ const params = new URLSearchParams(cleanQuery).toString();
398
+ if (params) url += `?${params}`;
392
399
  }
393
400
 
394
401
  // Handle body
package/index.js CHANGED
@@ -74,10 +74,17 @@ class UnboundSDK extends BaseSDK {
74
74
  }
75
75
  } else {
76
76
  // New object-based parameters
77
- const { namespace, callId, token, fwRequestId, url, socketStore } =
78
- options;
77
+ const {
78
+ namespace,
79
+ callId,
80
+ token,
81
+ fwRequestId,
82
+ url,
83
+ socketStore,
84
+ baseURL,
85
+ } = options;
79
86
 
80
- super({ namespace, callId, token, fwRequestId });
87
+ super({ namespace, callId, token, fwRequestId, baseURL });
81
88
 
82
89
  // Handle client-side specific parameters
83
90
  if (url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboundcx/sdk",
3
- "version": "4.13.49",
3
+ "version": "4.13.52",
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",
@@ -27,7 +27,7 @@ export class AssistService {
27
27
  { taskId, utterances },
28
28
  {
29
29
  taskId: { type: 'string', required: true },
30
- utterances: { type: 'array', required: true },
30
+ utterances: { type: 'array', required: false },
31
31
  },
32
32
  );
33
33
 
@@ -62,4 +62,60 @@ export class AssistService {
62
62
  const result = await internalRequest(this.sdk, `/ai/assist/last/${taskId}`, 'GET');
63
63
  return result;
64
64
  }
65
+
66
+ async listQueueKnowledgeBases({ queueId }) {
67
+ this.sdk.validateParams(
68
+ { queueId },
69
+ { queueId: { type: 'string', required: true } },
70
+ );
71
+ return internalRequest(
72
+ this.sdk,
73
+ `/ai/assist/queues/${queueId}/knowledgeBases`,
74
+ 'GET',
75
+ );
76
+ }
77
+
78
+ async setQueueKnowledgeBases({ queueId, knowledgeBaseIds }) {
79
+ this.sdk.validateParams(
80
+ { queueId, knowledgeBaseIds },
81
+ {
82
+ queueId: { type: 'string', required: true },
83
+ knowledgeBaseIds: { type: 'array', required: true },
84
+ },
85
+ );
86
+ return internalRequest(
87
+ this.sdk,
88
+ `/ai/assist/queues/${queueId}/knowledgeBases`,
89
+ 'PUT',
90
+ { body: { knowledgeBaseIds } },
91
+ );
92
+ }
93
+
94
+ async listQueueObjects({ queueId }) {
95
+ this.sdk.validateParams(
96
+ { queueId },
97
+ { queueId: { type: 'string', required: true } },
98
+ );
99
+ return internalRequest(
100
+ this.sdk,
101
+ `/ai/assist/queues/${queueId}/objects`,
102
+ 'GET',
103
+ );
104
+ }
105
+
106
+ async setQueueObjects({ queueId, objectNames }) {
107
+ this.sdk.validateParams(
108
+ { queueId, objectNames },
109
+ {
110
+ queueId: { type: 'string', required: true },
111
+ objectNames: { type: 'array', required: true },
112
+ },
113
+ );
114
+ return internalRequest(
115
+ this.sdk,
116
+ `/ai/assist/queues/${queueId}/objects`,
117
+ 'PUT',
118
+ { body: { objectNames } },
119
+ );
120
+ }
65
121
  }
@@ -642,6 +642,7 @@ export class EmailService {
642
642
  limit = 25,
643
643
  offset = 0,
644
644
  assignedUserId,
645
+ includeTasked = false,
645
646
  } = {},
646
647
  ) {
647
648
  this.sdk.validateParams(
@@ -655,6 +656,7 @@ export class EmailService {
655
656
  limit,
656
657
  offset,
657
658
  assignedUserId,
659
+ includeTasked,
658
660
  },
659
661
  {
660
662
  mailboxId: { type: 'string', required: true },
@@ -666,12 +668,14 @@ export class EmailService {
666
668
  limit: { type: 'number', required: false },
667
669
  offset: { type: 'number', required: false },
668
670
  assignedUserId: { type: 'string', required: false },
671
+ includeTasked: { type: 'boolean', required: false },
669
672
  },
670
673
  );
671
674
 
672
675
  const query = { folder, includeDrafts, sortBy, sortOrder, limit, offset };
673
676
  if (search) query.search = search;
674
677
  if (assignedUserId) query.assignedUserId = assignedUserId;
678
+ if (includeTasked) query.includeTasked = true;
675
679
 
676
680
  const params = {
677
681
  query,
@@ -1291,6 +1291,81 @@ export class ObjectsService {
1291
1291
  });
1292
1292
  }
1293
1293
 
1294
+ /**
1295
+ * Engagement-session participant roster (requester + durable CCs).
1296
+ * `recordId` is an engagement session id.
1297
+ *
1298
+ * GET /object/:id/participants
1299
+ *
1300
+ * @param {string} recordId
1301
+ * @returns {Promise<{participants: Array<{
1302
+ * id: string,
1303
+ * engagementSessionId: string,
1304
+ * role: string,
1305
+ * email: string|null,
1306
+ * peopleId: string|null,
1307
+ * displayName: string|null,
1308
+ * addedBy: {id: string, name: string|null}|null,
1309
+ * createdAt: string
1310
+ * }>}>}
1311
+ */
1312
+ async listParticipants(recordId) {
1313
+ this.sdk.validateParams(
1314
+ { recordId },
1315
+ { recordId: { type: 'string', required: true } },
1316
+ );
1317
+ return internalRequest(
1318
+ this.sdk,
1319
+ `/object/${recordId}/participants`,
1320
+ 'GET',
1321
+ );
1322
+ }
1323
+
1324
+ /**
1325
+ * Add a durable CC on an engagement session (PR5).
1326
+ * PUT /object/:id/participants
1327
+ *
1328
+ * @param {string} recordId engagement session id
1329
+ * @param {{email: string, displayName?: string, peopleId?: string}} body
1330
+ */
1331
+ async addParticipant(recordId, body = {}) {
1332
+ this.sdk.validateParams(
1333
+ { recordId, email: body.email },
1334
+ {
1335
+ recordId: { type: 'string', required: true },
1336
+ email: { type: 'string', required: true },
1337
+ },
1338
+ );
1339
+ return internalRequest(
1340
+ this.sdk,
1341
+ `/object/${recordId}/participants`,
1342
+ 'PUT',
1343
+ { body },
1344
+ );
1345
+ }
1346
+
1347
+ /**
1348
+ * Remove a durable CC from an engagement session (PR5).
1349
+ * DELETE /object/:id/participants/:participantId
1350
+ *
1351
+ * @param {string} recordId engagement session id
1352
+ * @param {string} participantId
1353
+ */
1354
+ async removeParticipant(recordId, participantId) {
1355
+ this.sdk.validateParams(
1356
+ { recordId, participantId },
1357
+ {
1358
+ recordId: { type: 'string', required: true },
1359
+ participantId: { type: 'string', required: true },
1360
+ },
1361
+ );
1362
+ return internalRequest(
1363
+ this.sdk,
1364
+ `/object/${recordId}/participants/${participantId}`,
1365
+ 'DELETE',
1366
+ );
1367
+ }
1368
+
1294
1369
  /**
1295
1370
  * Marketing programs dashboard (programs + totals).
1296
1371
  * @returns {Promise<object>}
@@ -23,6 +23,9 @@ export class TaskService {
23
23
  * @param {boolean} [options.createEngagement=false] - Whether to automatically create an engagement session for this task
24
24
  * @param {string} [options.relatedObject] - Related object type for metadata tracking (automatically set if createEngagement is true)
25
25
  * @param {string} [options.relatedId] - Related object ID for metadata tracking (automatically set if createEngagement is true)
26
+ * @param {string} [options.parentTaskId] - Parent task id (wrapUp follow-up / requeue)
27
+ * @param {string} [options.preferredWorkerId] - Preferred worker id persisted on create INSERT
28
+ * @param {string} [options.source] - Engagement `source` when `createEngagement` is true (e.g. `'portal'`)
26
29
  * @param {Object} [options.metadata] - Arbitrary metadata to attach to the task at creation (e.g. `{ textConversationId }`). Passed through as-is; whether it is persisted depends on the receiving endpoint honoring `metadata` in the request body.
27
30
  * @returns {Promise<Object>} Object containing the created task information
28
31
  * @returns {string} result.id - The unique identifier for the created task
@@ -84,7 +87,10 @@ export class TaskService {
84
87
  cdrId,
85
88
  sipCallId,
86
89
  aiChatSessionId,
90
+ parentTaskId,
91
+ preferredWorkerId,
87
92
  metadata,
93
+ source,
88
94
  } = options;
89
95
 
90
96
  this.sdk.validateParams(
@@ -104,7 +110,10 @@ export class TaskService {
104
110
  relatedId,
105
111
  sipCallId,
106
112
  aiChatSessionId,
113
+ parentTaskId,
114
+ preferredWorkerId,
107
115
  metadata,
116
+ source,
108
117
  },
109
118
  {
110
119
  type: { type: 'string', required: true },
@@ -122,7 +131,10 @@ export class TaskService {
122
131
  relatedId: { type: 'string', required: false },
123
132
  sipCallId: { type: 'string', required: false },
124
133
  aiChatSessionId: { type: 'string', required: false },
134
+ parentTaskId: { type: 'string', required: false },
135
+ preferredWorkerId: { type: 'string', required: false },
125
136
  metadata: { type: 'object', required: false },
137
+ source: { type: 'string', required: false },
126
138
  },
127
139
  );
128
140
 
@@ -185,10 +197,22 @@ export class TaskService {
185
197
  params.body.aiChatSessionId = aiChatSessionId;
186
198
  }
187
199
 
200
+ if (parentTaskId !== undefined) {
201
+ params.body.parentTaskId = parentTaskId;
202
+ }
203
+
204
+ if (preferredWorkerId !== undefined) {
205
+ params.body.preferredWorkerId = preferredWorkerId;
206
+ }
207
+
188
208
  if (metadata !== undefined) {
189
209
  params.body.metadata = metadata;
190
210
  }
191
211
 
212
+ if (source !== undefined) {
213
+ params.body.source = source;
214
+ }
215
+
192
216
  const result = await internalRequest(this.sdk, '/taskRouter/tasks', 'POST', params);
193
217
  return result;
194
218
  }
@@ -880,6 +904,63 @@ export class TaskService {
880
904
  );
881
905
  }
882
906
 
907
+ /**
908
+ * Public reply on a ticket task: writes the customer-visible post and
909
+ * emails requester + CCs (transactional) from the queue mailbox.
910
+ *
911
+ * POST /taskRouter/tasks/:id/public-reply
912
+ *
913
+ * @param {Object} options
914
+ * @param {string} options.taskId
915
+ * @param {string} [options.html]
916
+ * @param {string} [options.text]
917
+ * @param {string|string[]} [options.extraTo]
918
+ * @param {string|string[]} [options.extraCc]
919
+ * @param {string|string[]} [options.extraBcc]
920
+ * @param {string|string[]} [options.attachments]
921
+ * @param {boolean} [options.addExtrasToTicket]
922
+ * @param {string} [options.retryVisitorMessageId]
923
+ */
924
+ async publicReply(options = {}) {
925
+ const {
926
+ taskId,
927
+ html,
928
+ text,
929
+ extraTo,
930
+ extraCc,
931
+ extraBcc,
932
+ attachments,
933
+ addExtrasToTicket,
934
+ retryVisitorMessageId,
935
+ } = options;
936
+
937
+ this.sdk.validateParams(
938
+ { taskId },
939
+ { taskId: { type: 'string', required: true } },
940
+ );
941
+
942
+ const body = {};
943
+ if (html !== undefined) body.html = html;
944
+ if (text !== undefined) body.text = text;
945
+ if (extraTo !== undefined) body.extraTo = extraTo;
946
+ if (extraCc !== undefined) body.extraCc = extraCc;
947
+ if (extraBcc !== undefined) body.extraBcc = extraBcc;
948
+ if (attachments !== undefined) body.attachments = attachments;
949
+ if (addExtrasToTicket !== undefined) {
950
+ body.addExtrasToTicket = addExtrasToTicket;
951
+ }
952
+ if (retryVisitorMessageId !== undefined) {
953
+ body.retryVisitorMessageId = retryVisitorMessageId;
954
+ }
955
+
956
+ return await internalRequest(
957
+ this.sdk,
958
+ `/taskRouter/tasks/${taskId}/public-reply`,
959
+ 'POST',
960
+ { body },
961
+ );
962
+ }
963
+
883
964
  /**
884
965
  * Mark a task's inbound messages as read for one channel (or all).
885
966
  * Channel ids: sms | webchat | email | whatsApp | rcs | all.