@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.
- package/index.js +6 -0
- package/package.json +1 -1
- package/services/ai.js +242 -2
- package/services/externalOAuth.js +45 -0
- package/services/fax.js +249 -0
- package/services/knowledgeBase.js +229 -0
- package/services/messaging/EmailTemplatesService.js +31 -11
- package/services/messaging/TenDlcCampaignManagementService.js +187 -105
- package/services/messaging/TollFreeCampaignsService.js +263 -110
- package/services/notes.js +27 -2
- package/services/objects.js +80 -0
- package/services/portals.js +89 -0
- package/services/storage.js +134 -0
- package/services/taskRouter/TaskService.js +8 -0
- package/services/workflows.js +133 -0
package/index.js
CHANGED
|
@@ -25,6 +25,8 @@ import { RecordTypesService } from './services/recordTypes.js';
|
|
|
25
25
|
import { GenerateIdService } from './services/generateId.js';
|
|
26
26
|
import { EngagementMetricsService } from './services/engagementMetrics.js';
|
|
27
27
|
import { TaskRouterService } from './services/taskRouter.js';
|
|
28
|
+
import { KnowledgeBaseService } from './services/knowledgeBase.js';
|
|
29
|
+
import { FaxService } from './services/fax.js';
|
|
28
30
|
|
|
29
31
|
class UnboundSDK extends BaseSDK {
|
|
30
32
|
constructor(options = {}) {
|
|
@@ -91,6 +93,8 @@ class UnboundSDK extends BaseSDK {
|
|
|
91
93
|
this.generateId = new GenerateIdService(this);
|
|
92
94
|
this.engagementMetrics = new EngagementMetricsService(this);
|
|
93
95
|
this.taskRouter = new TaskRouterService(this);
|
|
96
|
+
this.knowledgeBase = new KnowledgeBaseService(this);
|
|
97
|
+
this.fax = new FaxService(this);
|
|
94
98
|
|
|
95
99
|
// Add additional services that might be missing
|
|
96
100
|
this._initializeAdditionalServices();
|
|
@@ -268,4 +272,6 @@ export { GenerateIdService } from './services/generateId.js';
|
|
|
268
272
|
export { EngagementMetricsService } from './services/engagementMetrics.js';
|
|
269
273
|
export { TaskRouterService } from './services/taskRouter.js';
|
|
270
274
|
export { WorkerService } from './services/taskRouter/WorkerService.js';
|
|
275
|
+
export { KnowledgeBaseService } from './services/knowledgeBase.js';
|
|
276
|
+
export { FaxService } from './services/fax.js';
|
|
271
277
|
export { BaseSDK } from './base.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.8",
|
|
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
|
@@ -20,39 +20,81 @@ export class GenerativeService {
|
|
|
20
20
|
prompt,
|
|
21
21
|
messages,
|
|
22
22
|
systemPrompt,
|
|
23
|
+
appendSystemPrompt,
|
|
23
24
|
relatedId,
|
|
25
|
+
peopleId,
|
|
26
|
+
companyId,
|
|
24
27
|
provider,
|
|
25
28
|
model,
|
|
26
29
|
temperature,
|
|
30
|
+
maxTokens,
|
|
27
31
|
subscriptionId,
|
|
28
32
|
stream,
|
|
29
33
|
isPlayground = false,
|
|
30
34
|
responseFormat,
|
|
35
|
+
sessionId,
|
|
36
|
+
scope,
|
|
37
|
+
manageSession,
|
|
38
|
+
tools,
|
|
39
|
+
toolConfig,
|
|
40
|
+
maxToolRounds,
|
|
41
|
+
recordTypeId,
|
|
42
|
+
meta,
|
|
43
|
+
qualityCheck,
|
|
44
|
+
isPublic,
|
|
31
45
|
}) {
|
|
32
46
|
this.sdk.validateParams(
|
|
33
47
|
{
|
|
34
48
|
stream,
|
|
35
49
|
temperature,
|
|
50
|
+
maxTokens,
|
|
36
51
|
subscriptionId,
|
|
37
52
|
provider,
|
|
38
53
|
model,
|
|
39
54
|
prompt,
|
|
40
55
|
messages,
|
|
41
56
|
systemPrompt,
|
|
57
|
+
appendSystemPrompt,
|
|
42
58
|
isPlayground,
|
|
43
59
|
responseFormat,
|
|
60
|
+
sessionId,
|
|
61
|
+
scope,
|
|
62
|
+
manageSession,
|
|
63
|
+
tools,
|
|
64
|
+
toolConfig,
|
|
65
|
+
maxToolRounds,
|
|
66
|
+
recordTypeId,
|
|
67
|
+
peopleId,
|
|
68
|
+
companyId,
|
|
69
|
+
meta,
|
|
70
|
+
qualityCheck,
|
|
71
|
+
isPublic,
|
|
44
72
|
},
|
|
45
73
|
{
|
|
46
74
|
prompt: { type: 'string', required: false },
|
|
47
75
|
messages: { type: 'array', required: false },
|
|
48
76
|
systemPrompt: { type: 'string', required: false },
|
|
77
|
+
appendSystemPrompt: { type: 'string', required: false },
|
|
49
78
|
provider: { type: 'string', required: false },
|
|
50
79
|
model: { type: 'string', required: false },
|
|
51
80
|
temperature: { type: 'number', required: false },
|
|
81
|
+
maxTokens: { type: 'number', required: false },
|
|
52
82
|
subscriptionId: { type: 'string', required: false },
|
|
53
83
|
stream: { type: 'boolean', required: false },
|
|
54
84
|
isPlayground: { type: 'boolean', required: false },
|
|
55
85
|
responseFormat: { type: 'object', required: false },
|
|
86
|
+
sessionId: { type: 'string', required: false },
|
|
87
|
+
scope: { type: 'string', required: false },
|
|
88
|
+
manageSession: { type: 'boolean', required: false },
|
|
89
|
+
tools: { type: 'array', required: false },
|
|
90
|
+
toolConfig: { type: 'object', required: false },
|
|
91
|
+
maxToolRounds: { type: 'number', required: false },
|
|
92
|
+
recordTypeId: { type: 'string', required: false },
|
|
93
|
+
peopleId: { type: 'string', required: false },
|
|
94
|
+
companyId: { type: 'string', required: false },
|
|
95
|
+
meta: { type: 'object', required: false },
|
|
96
|
+
qualityCheck: { type: 'boolean', required: false },
|
|
97
|
+
isPublic: { type: 'boolean', required: false },
|
|
56
98
|
},
|
|
57
99
|
);
|
|
58
100
|
|
|
@@ -62,20 +104,44 @@ export class GenerativeService {
|
|
|
62
104
|
prompt,
|
|
63
105
|
messages,
|
|
64
106
|
systemPrompt,
|
|
107
|
+
appendSystemPrompt,
|
|
65
108
|
relatedId,
|
|
109
|
+
peopleId,
|
|
110
|
+
companyId,
|
|
66
111
|
provider,
|
|
67
112
|
model,
|
|
68
113
|
temperature,
|
|
114
|
+
maxTokens,
|
|
69
115
|
subscriptionId,
|
|
70
116
|
stream,
|
|
71
117
|
responseFormat,
|
|
118
|
+
sessionId,
|
|
119
|
+
scope,
|
|
120
|
+
manageSession,
|
|
121
|
+
tools,
|
|
122
|
+
toolConfig,
|
|
123
|
+
maxToolRounds,
|
|
124
|
+
recordTypeId,
|
|
125
|
+
meta,
|
|
126
|
+
qualityCheck,
|
|
127
|
+
isPublic,
|
|
72
128
|
},
|
|
73
129
|
// Return raw response for streaming to allow client-side stream handling
|
|
74
130
|
returnRawResponse: stream === true,
|
|
75
131
|
};
|
|
76
132
|
|
|
77
|
-
// Force HTTP transport when streaming
|
|
78
|
-
const
|
|
133
|
+
// Force HTTP transport when streaming or when messages contain large content (too large for NATS)
|
|
134
|
+
const hasLargeContent = messages?.some(
|
|
135
|
+
(m) =>
|
|
136
|
+
Array.isArray(m.content) &&
|
|
137
|
+
m.content.some(
|
|
138
|
+
(c) =>
|
|
139
|
+
c.type === 'image' ||
|
|
140
|
+
c.type === 'image_url' ||
|
|
141
|
+
c.type === 'document',
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
const forceFetch = stream === true || hasLargeContent;
|
|
79
145
|
const result = await this.sdk._fetch(
|
|
80
146
|
'/ai/generative/chat',
|
|
81
147
|
'POST',
|
|
@@ -85,6 +151,180 @@ export class GenerativeService {
|
|
|
85
151
|
return result;
|
|
86
152
|
}
|
|
87
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Clone an existing chat session into a new one, importing conversation context.
|
|
156
|
+
* Filters out system prompts and tool calls, keeps user/assistant turns.
|
|
157
|
+
* If the transcript exceeds ~50k tokens it is summarized automatically.
|
|
158
|
+
*
|
|
159
|
+
* @param {Object} options
|
|
160
|
+
* @param {string} options.sourceSessionId - Session to clone from (required)
|
|
161
|
+
* @param {string} [options.systemPrompt] - New system prompt (appended after conversation context)
|
|
162
|
+
* @param {string} [options.provider] - LLM provider (falls back to source session)
|
|
163
|
+
* @param {string} [options.model] - Model ID (falls back to source session)
|
|
164
|
+
* @param {Array} [options.tools] - Tool names (falls back to source session)
|
|
165
|
+
* @param {Object} [options.toolConfig] - Tool config (falls back to source session)
|
|
166
|
+
* @param {string} [options.scope] - 'user' or 'account'
|
|
167
|
+
* @param {string} [options.userId] - Owner user ID
|
|
168
|
+
* @param {string} [options.peopleId] - Linked people record
|
|
169
|
+
* @param {string} [options.companyId] - Linked company record
|
|
170
|
+
* @param {string} [options.relatedId] - Linked related record
|
|
171
|
+
* @returns {Promise<Object>} { id, sourceSessionId, wasSummarized }
|
|
172
|
+
*/
|
|
173
|
+
async cloneSession({
|
|
174
|
+
sourceSessionId,
|
|
175
|
+
systemPrompt,
|
|
176
|
+
provider,
|
|
177
|
+
model,
|
|
178
|
+
tools,
|
|
179
|
+
toolConfig,
|
|
180
|
+
scope,
|
|
181
|
+
userId,
|
|
182
|
+
peopleId,
|
|
183
|
+
companyId,
|
|
184
|
+
relatedId,
|
|
185
|
+
}) {
|
|
186
|
+
this.sdk.validateParams(
|
|
187
|
+
{ sourceSessionId },
|
|
188
|
+
{
|
|
189
|
+
sourceSessionId: { type: 'string', required: true },
|
|
190
|
+
systemPrompt: { type: 'string', required: false },
|
|
191
|
+
provider: { type: 'string', required: false },
|
|
192
|
+
model: { type: 'string', required: false },
|
|
193
|
+
tools: { type: 'array', required: false },
|
|
194
|
+
toolConfig: { type: 'object', required: false },
|
|
195
|
+
scope: { type: 'string', required: false },
|
|
196
|
+
userId: { type: 'string', required: false },
|
|
197
|
+
peopleId: { type: 'string', required: false },
|
|
198
|
+
companyId: { type: 'string', required: false },
|
|
199
|
+
relatedId: { type: 'string', required: false },
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
const params = {
|
|
204
|
+
body: {
|
|
205
|
+
sourceSessionId,
|
|
206
|
+
systemPrompt,
|
|
207
|
+
provider,
|
|
208
|
+
model,
|
|
209
|
+
tools,
|
|
210
|
+
toolConfig,
|
|
211
|
+
scope,
|
|
212
|
+
userId,
|
|
213
|
+
peopleId,
|
|
214
|
+
companyId,
|
|
215
|
+
relatedId,
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const result = await this.sdk._fetch(
|
|
220
|
+
'/ai/generative/chat/clone',
|
|
221
|
+
'POST',
|
|
222
|
+
params,
|
|
223
|
+
);
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* List available chat tools and their metadata
|
|
229
|
+
* @returns {Promise<Object>} { tools: Array<{ name, label, description, configRequirements }>, count: number }
|
|
230
|
+
*/
|
|
231
|
+
async listTools() {
|
|
232
|
+
return await this.sdk._fetch('/ai/generative/tools', 'GET');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* List chat sessions visible to the current user
|
|
237
|
+
* @param {Object} [options] - Filter options
|
|
238
|
+
* @param {string} [options.relatedId] - Filter by related object ID
|
|
239
|
+
* @param {string} [options.scope] - Filter by scope ('user' or 'account')
|
|
240
|
+
* @param {number} [options.limit=25] - Results limit
|
|
241
|
+
* @param {number} [options.offset=0] - Pagination offset
|
|
242
|
+
* @returns {Promise<Object>} { sessions: Array }
|
|
243
|
+
*/
|
|
244
|
+
async listSessions({ relatedId, scope, limit, offset } = {}) {
|
|
245
|
+
this.sdk.validateParams(
|
|
246
|
+
{ relatedId, scope, limit, offset },
|
|
247
|
+
{
|
|
248
|
+
relatedId: { type: 'string', required: false },
|
|
249
|
+
scope: { type: 'string', required: false },
|
|
250
|
+
limit: { type: 'number', required: false },
|
|
251
|
+
offset: { type: 'number', required: false },
|
|
252
|
+
},
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const params = { query: { relatedId, scope, limit, offset } };
|
|
256
|
+
const result = await this.sdk._fetch(
|
|
257
|
+
'/ai/generative/sessions',
|
|
258
|
+
'GET',
|
|
259
|
+
params,
|
|
260
|
+
);
|
|
261
|
+
return result;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Get a chat session with its message history
|
|
266
|
+
* @param {Object} options
|
|
267
|
+
* @param {string} options.sessionId - Session ID to retrieve
|
|
268
|
+
* @returns {Promise<Object>} { session: { id, name, scope, relatedId, provider, model, messages, messageCount, lastMessageAt, createdAt } }
|
|
269
|
+
*/
|
|
270
|
+
async getSession({ sessionId }) {
|
|
271
|
+
this.sdk.validateParams(
|
|
272
|
+
{ sessionId },
|
|
273
|
+
{ sessionId: { type: 'string', required: true } },
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const result = await this.sdk._fetch(
|
|
277
|
+
`/ai/generative/sessions/${sessionId}`,
|
|
278
|
+
'GET',
|
|
279
|
+
);
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Update a chat session (name, scope)
|
|
285
|
+
* @param {Object} options
|
|
286
|
+
* @param {string} options.sessionId - Session ID to update
|
|
287
|
+
* @param {string} [options.name] - New session name
|
|
288
|
+
* @param {string} [options.scope] - New scope ('user' or 'account')
|
|
289
|
+
* @returns {Promise<Object>} { success: true }
|
|
290
|
+
*/
|
|
291
|
+
async updateSession({ sessionId, name, scope }) {
|
|
292
|
+
this.sdk.validateParams(
|
|
293
|
+
{ sessionId, name, scope },
|
|
294
|
+
{
|
|
295
|
+
sessionId: { type: 'string', required: true },
|
|
296
|
+
name: { type: 'string', required: false },
|
|
297
|
+
scope: { type: 'string', required: false },
|
|
298
|
+
},
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
const result = await this.sdk._fetch(
|
|
302
|
+
`/ai/generative/sessions/${sessionId}`,
|
|
303
|
+
'PUT',
|
|
304
|
+
{ body: { name, scope } },
|
|
305
|
+
);
|
|
306
|
+
return result;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Delete a chat session
|
|
311
|
+
* @param {Object} options
|
|
312
|
+
* @param {string} options.sessionId - Session ID to delete
|
|
313
|
+
* @returns {Promise<Object>} { success: true }
|
|
314
|
+
*/
|
|
315
|
+
async deleteSession({ sessionId }) {
|
|
316
|
+
this.sdk.validateParams(
|
|
317
|
+
{ sessionId },
|
|
318
|
+
{ sessionId: { type: 'string', required: true } },
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const result = await this.sdk._fetch(
|
|
322
|
+
`/ai/generative/sessions/${sessionId}`,
|
|
323
|
+
'DELETE',
|
|
324
|
+
);
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
|
|
88
328
|
async playbook({
|
|
89
329
|
prompt,
|
|
90
330
|
messages,
|
|
@@ -122,4 +122,49 @@ export class ExternalOAuthService {
|
|
|
122
122
|
const result = await this.sdk._fetch('/externalOAuth', 'GET');
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
125
|
+
|
|
126
|
+
async listUnified() {
|
|
127
|
+
const result = await this.sdk._fetch('/externalOAuth/unified', 'GET');
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async providers() {
|
|
132
|
+
const result = await this.sdk._fetch('/externalOAuth/providers', 'GET');
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async authorize({
|
|
137
|
+
name,
|
|
138
|
+
provider,
|
|
139
|
+
clientId,
|
|
140
|
+
clientSecret,
|
|
141
|
+
scopes,
|
|
142
|
+
authorizationUrl,
|
|
143
|
+
tokenUrl,
|
|
144
|
+
}) {
|
|
145
|
+
this.sdk.validateParams(
|
|
146
|
+
{ name, provider },
|
|
147
|
+
{
|
|
148
|
+
name: { type: 'string', required: true },
|
|
149
|
+
provider: { type: 'string', required: true },
|
|
150
|
+
clientId: { type: 'string', required: false },
|
|
151
|
+
clientSecret: { type: 'string', required: false },
|
|
152
|
+
scopes: { type: 'array', required: false },
|
|
153
|
+
authorizationUrl: { type: 'string', required: false },
|
|
154
|
+
tokenUrl: { type: 'string', required: false },
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const body = { name, provider };
|
|
159
|
+
if (clientId) body.clientId = clientId;
|
|
160
|
+
if (clientSecret) body.clientSecret = clientSecret;
|
|
161
|
+
if (scopes) body.scopes = scopes;
|
|
162
|
+
if (authorizationUrl) body.authorizationUrl = authorizationUrl;
|
|
163
|
+
if (tokenUrl) body.tokenUrl = tokenUrl;
|
|
164
|
+
|
|
165
|
+
const result = await this.sdk._fetch('/externalOAuth/authorize', 'POST', {
|
|
166
|
+
body,
|
|
167
|
+
});
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
125
170
|
}
|
package/services/fax.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
export class FaxService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create an inbound fax document record with status 'receiving'.
|
|
8
|
+
* Called by the media manager when an inbound fax is first detected.
|
|
9
|
+
* After the fax is fully received, call sdk.fax.status() to update
|
|
10
|
+
* with the final storage IDs and completion metadata.
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} options - Parameters
|
|
13
|
+
* @param {string} options.faxMailboxId - ID of the fax mailbox receiving the fax (required)
|
|
14
|
+
* @param {string} [options.sipCallId] - SIP call correlation ID
|
|
15
|
+
* @param {string} [options.name] - Display name for the fax document
|
|
16
|
+
* @param {string} [options.faxHeader] - TSI header string from the sender
|
|
17
|
+
* @param {string} [options.resolution] - Fax resolution (e.g. 'fine', 'standard')
|
|
18
|
+
* @param {string} [options.toNumber] - Destination number in E.164 format
|
|
19
|
+
* @param {string} [options.fromNumber] - Sender number in E.164 format
|
|
20
|
+
* @returns {Promise<Object>} Created fax document
|
|
21
|
+
* @returns {string} result.id - The fax document ID (use in subsequent status calls)
|
|
22
|
+
* @returns {string} result.status - 'receiving'
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const { id } = await sdk.fax.receive({
|
|
26
|
+
* faxMailboxId: '157abc123...',
|
|
27
|
+
* sipCallId: 'sip-call-uuid',
|
|
28
|
+
* name: 'Fax from +15551234567',
|
|
29
|
+
* toNumber: '+15559876543',
|
|
30
|
+
* fromNumber: '+15551234567',
|
|
31
|
+
* });
|
|
32
|
+
* // Save id for use with sdk.fax.status() after reception completes
|
|
33
|
+
*/
|
|
34
|
+
async receive({
|
|
35
|
+
faxMailboxId,
|
|
36
|
+
sipCallId,
|
|
37
|
+
name,
|
|
38
|
+
faxHeader,
|
|
39
|
+
resolution,
|
|
40
|
+
toNumber,
|
|
41
|
+
fromNumber,
|
|
42
|
+
cId,
|
|
43
|
+
}) {
|
|
44
|
+
this.sdk.validateParams(
|
|
45
|
+
{ faxMailboxId },
|
|
46
|
+
{
|
|
47
|
+
faxMailboxId: { type: 'string', required: true },
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const params = {
|
|
52
|
+
body: {
|
|
53
|
+
faxMailboxId,
|
|
54
|
+
sipCallId,
|
|
55
|
+
name,
|
|
56
|
+
faxHeader,
|
|
57
|
+
resolution,
|
|
58
|
+
toNumber,
|
|
59
|
+
fromNumber,
|
|
60
|
+
cId,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return await this.sdk._fetch('/fax/receive', 'POST', params);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Send an outbound fax.
|
|
69
|
+
* Creates a fax document record, retrieves the document from storage,
|
|
70
|
+
* and publishes to the media manager via NATS to initiate the fax call.
|
|
71
|
+
*
|
|
72
|
+
* @param {Object} options - Parameters
|
|
73
|
+
* @param {string} options.faxMailboxId - ID of the fax mailbox to send from (required)
|
|
74
|
+
* @param {string} options.toNumber - Destination number in E.164 format (required)
|
|
75
|
+
* @param {string} options.fromNumber - Caller ID number in E.164 format (required)
|
|
76
|
+
* @param {string} [options.storageId] - Storage ID of a PDF or TIFF file to fax. The server will
|
|
77
|
+
* automatically convert it to the missing format so both PDF and TIFF are stored.
|
|
78
|
+
* Required if pdfStorageId and tiffStorageId are not provided.
|
|
79
|
+
* @param {string} [options.pdfStorageId] - Storage ID of the PDF version. Required if storageId is not provided.
|
|
80
|
+
* @param {string} [options.tiffStorageId] - Storage ID of the TIFF version. Required if storageId is not provided.
|
|
81
|
+
* @param {string} [options.faxHeader] - TSI header text (defaults to mailbox faxHeader)
|
|
82
|
+
* @param {string} [options.resolution] - Fax resolution (defaults to mailbox resolution)
|
|
83
|
+
* @param {boolean} [options.ecm] - Enable Error Correction Mode (default: true)
|
|
84
|
+
* @param {number} [options.timeout] - Dial timeout in seconds (defaults to mailbox dialTimeout)
|
|
85
|
+
* @returns {Promise<Object>} Send result
|
|
86
|
+
* @returns {string} result.id - The fax document ID
|
|
87
|
+
* @returns {string} result.status - 'sending' on success, 'failed' on NATS error
|
|
88
|
+
* @returns {string} [result.requestId] - NATS request ID (on success)
|
|
89
|
+
* @returns {string} [result.error] - Error message (on failure)
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* // Send using a single storageId (PDF or TIFF — server auto-converts the missing format)
|
|
93
|
+
* const result = await sdk.fax.send({
|
|
94
|
+
* faxMailboxId: '157abc123...',
|
|
95
|
+
* toNumber: '+15551234567',
|
|
96
|
+
* fromNumber: '+15559876543',
|
|
97
|
+
* storageId: '017xyz788...',
|
|
98
|
+
* });
|
|
99
|
+
* console.log(result.id); // '158def456...'
|
|
100
|
+
* console.log(result.status); // 'sending'
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* // Send using explicit PDF and TIFF storage IDs
|
|
104
|
+
* const result = await sdk.fax.send({
|
|
105
|
+
* faxMailboxId: '157abc123...',
|
|
106
|
+
* toNumber: '+15551234567',
|
|
107
|
+
* fromNumber: '+15559876543',
|
|
108
|
+
* pdfStorageId: '017xyz789...',
|
|
109
|
+
* tiffStorageId: '017xyz788...',
|
|
110
|
+
* faxHeader: 'My Company',
|
|
111
|
+
* resolution: 'fine',
|
|
112
|
+
* ecm: true,
|
|
113
|
+
* timeout: 90,
|
|
114
|
+
* });
|
|
115
|
+
*/
|
|
116
|
+
async send({
|
|
117
|
+
faxMailboxId,
|
|
118
|
+
toNumber,
|
|
119
|
+
fromNumber,
|
|
120
|
+
storageId,
|
|
121
|
+
pdfStorageId,
|
|
122
|
+
tiffStorageId,
|
|
123
|
+
faxHeader,
|
|
124
|
+
resolution,
|
|
125
|
+
ecm,
|
|
126
|
+
timeout,
|
|
127
|
+
}) {
|
|
128
|
+
this.sdk.validateParams(
|
|
129
|
+
{ faxMailboxId, toNumber, fromNumber },
|
|
130
|
+
{
|
|
131
|
+
faxMailboxId: { type: 'string', required: true },
|
|
132
|
+
toNumber: { type: 'string', required: true },
|
|
133
|
+
fromNumber: { type: 'string', required: true },
|
|
134
|
+
storageId: { type: 'string', required: false },
|
|
135
|
+
pdfStorageId: { type: 'string', required: false },
|
|
136
|
+
tiffStorageId: { type: 'string', required: false },
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
if (!storageId && (!pdfStorageId || !tiffStorageId)) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
'Either storageId or both pdfStorageId and tiffStorageId are required.',
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const params = {
|
|
147
|
+
body: {
|
|
148
|
+
faxMailboxId,
|
|
149
|
+
toNumber,
|
|
150
|
+
fromNumber,
|
|
151
|
+
storageId,
|
|
152
|
+
pdfStorageId,
|
|
153
|
+
tiffStorageId,
|
|
154
|
+
faxHeader,
|
|
155
|
+
resolution,
|
|
156
|
+
ecm,
|
|
157
|
+
timeout,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
return await this.sdk._fetch('/fax/send', 'POST', params);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Update the status and metadata of a fax document.
|
|
166
|
+
* Called by the media manager to report progress and completion
|
|
167
|
+
* of both inbound and outbound faxes.
|
|
168
|
+
*
|
|
169
|
+
* @param {Object} options - Parameters
|
|
170
|
+
* @param {string} options.faxDocumentId - ID of the fax document to update (required)
|
|
171
|
+
* @param {string} options.status - New status (required): 'receiving', 'sending', 'sent', 'completed', 'failed'
|
|
172
|
+
* @param {string} [options.sipCallId] - SIP call correlation ID
|
|
173
|
+
* @param {number} [options.pages] - Number of pages transmitted/received
|
|
174
|
+
* @param {number} [options.duration] - Call duration in seconds
|
|
175
|
+
* @param {number} [options.transferRate] - Baud rate (e.g. 14400)
|
|
176
|
+
* @param {number} [options.ecmUsed] - Whether ECM was used (1 or 0)
|
|
177
|
+
* @param {number} [options.isError] - Whether an error occurred (1 or 0)
|
|
178
|
+
* @param {string} [options.errorMessage] - Error description
|
|
179
|
+
* @param {number} [options.sendAttempts] - Number of send attempts made
|
|
180
|
+
* @param {string} [options.pdfStorageId] - Storage ID of the PDF version
|
|
181
|
+
* @param {string} [options.tiffStorageId] - Storage ID of the TIFF version
|
|
182
|
+
* @returns {Promise<Object>} Updated fields
|
|
183
|
+
* @returns {string} result.id - The fax document ID
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* // Complete an inbound fax with storage files and metadata
|
|
187
|
+
* await sdk.fax.status({
|
|
188
|
+
* faxDocumentId: '158abc123...',
|
|
189
|
+
* status: 'completed',
|
|
190
|
+
* pdfStorageId: '017pdf456...',
|
|
191
|
+
* tiffStorageId: '017tiff789...',
|
|
192
|
+
* pages: 3,
|
|
193
|
+
* duration: 45,
|
|
194
|
+
* transferRate: 14400,
|
|
195
|
+
* ecmUsed: 1,
|
|
196
|
+
* });
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* // Report a fax failure
|
|
200
|
+
* await sdk.fax.status({
|
|
201
|
+
* faxDocumentId: '158abc123...',
|
|
202
|
+
* status: 'failed',
|
|
203
|
+
* isError: 1,
|
|
204
|
+
* errorMessage: 'Remote side disconnected',
|
|
205
|
+
* sendAttempts: 2,
|
|
206
|
+
* });
|
|
207
|
+
*/
|
|
208
|
+
async status({
|
|
209
|
+
faxDocumentId,
|
|
210
|
+
status,
|
|
211
|
+
sipCallId,
|
|
212
|
+
pages,
|
|
213
|
+
duration,
|
|
214
|
+
transferRate,
|
|
215
|
+
ecmUsed,
|
|
216
|
+
isError,
|
|
217
|
+
errorMessage,
|
|
218
|
+
sendAttempts,
|
|
219
|
+
pdfStorageId,
|
|
220
|
+
tiffStorageId,
|
|
221
|
+
}) {
|
|
222
|
+
this.sdk.validateParams(
|
|
223
|
+
{ faxDocumentId, status },
|
|
224
|
+
{
|
|
225
|
+
faxDocumentId: { type: 'string', required: true },
|
|
226
|
+
status: { type: 'string', required: true },
|
|
227
|
+
},
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const params = {
|
|
231
|
+
body: {
|
|
232
|
+
faxDocumentId,
|
|
233
|
+
status,
|
|
234
|
+
sipCallId,
|
|
235
|
+
pages,
|
|
236
|
+
duration,
|
|
237
|
+
transferRate,
|
|
238
|
+
ecmUsed,
|
|
239
|
+
isError,
|
|
240
|
+
errorMessage,
|
|
241
|
+
sendAttempts,
|
|
242
|
+
pdfStorageId,
|
|
243
|
+
tiffStorageId,
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
return await this.sdk._fetch('/fax/status', 'POST', params);
|
|
248
|
+
}
|
|
249
|
+
}
|