@unboundcx/sdk-internal 1.0.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/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # Unbound Internal SDK
2
+
3
+ [![npm version](https://badge.fury.io/js/%40unbound%2Fsdk-internal.svg)](https://badge.fury.io/js/%40unbound%2Fsdk-internal)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Internal SDK extension for Unbound that provides access to internal APIs and administrative functions. This package is designed for use within Unbound's internal infrastructure and requires the main `@unbound/sdk` package.
7
+
8
+ ## ⚠️ Important Notice
9
+
10
+ This package contains internal APIs and is intended for use within Unbound's infrastructure only. It provides access to administrative functions that should not be exposed to external developers or applications.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @unbound/sdk-internal
16
+ ```
17
+
18
+ **Requirements:**
19
+ - `@unbound/sdk` ^1.0.0
20
+ - Node.js environment (browser usage not supported)
21
+
22
+ ## Usage
23
+
24
+ ### Basic Setup
25
+
26
+ ```javascript
27
+ import SDK from '@unbound/sdk';
28
+ import InternalSDK from '@unbound/sdk-internal';
29
+
30
+ const api = new SDK({
31
+ namespace: 'namespace',
32
+ callId: 'call-id',
33
+ token: 'jwt-token'
34
+ });
35
+
36
+ // Extend with internal functionality
37
+ api.use(InternalSDK);
38
+
39
+ // Now has access to internal methods
40
+ await api.buildMasterAuth({
41
+ namespace: 'target-namespace',
42
+ accountId: 'account-123',
43
+ userId: 'user-456'
44
+ });
45
+ ```
46
+
47
+ ### Extension Pattern
48
+
49
+ ```javascript
50
+ import SDK from '@unbound/sdk';
51
+ import { InternalSDK } from '@unbound/sdk-internal';
52
+
53
+ const api = new SDK({ namespace: 'namespace' });
54
+ api.extend(InternalSDK);
55
+
56
+ // Access internal services
57
+ await api.internal.sip.router('+1234567890', '+0987654321', 'call-123');
58
+ ```
59
+
60
+ ## API Reference
61
+
62
+ ### Master Authentication
63
+
64
+ Build master authentication tokens for cross-account access:
65
+
66
+ ```javascript
67
+ const token = await api.buildMasterAuth({
68
+ namespace: 'target-namespace', // Target namespace
69
+ accountId: 'account-123', // Target account ID
70
+ userId: 'user-456' // Target user ID
71
+ });
72
+
73
+ // Token is automatically set on the SDK instance
74
+ console.log(api.token); // JWT token for the target account/user
75
+ ```
76
+
77
+ ### Internal SIP Service (`api.internal.sip`)
78
+
79
+ Administrative SIP functions for call routing and registration:
80
+
81
+ #### Router
82
+ ```javascript
83
+ await api.internal.sip.router(
84
+ '+1234567890', // to
85
+ '+0987654321', // from
86
+ 'call-123', // callId
87
+ { /* auth */ }, // auth object
88
+ 'inbound' // peerDirection
89
+ );
90
+ ```
91
+
92
+ #### Server Management
93
+ ```javascript
94
+ const server = await api.internal.sip.getServer(
95
+ 'voice', // type
96
+ 'us-east-1', // regionCode
97
+ 'call-123' // callId
98
+ );
99
+ ```
100
+
101
+ #### Registration Management
102
+ ```javascript
103
+ // Register SIP endpoint
104
+ await api.internal.sip.register({
105
+ accountId: 'account-123',
106
+ serverId: 'server-456',
107
+ callId: 'call-789',
108
+ username: 'user123',
109
+ userId: 'user-456',
110
+ clientIp: '192.168.1.100',
111
+ isWebRtc: false,
112
+ transport: 'UDP',
113
+ contact: 'sip:user@example.com',
114
+ domain: 'sip.example.com',
115
+ userAgent: 'Unbound-SIP/1.0',
116
+ expiresAt: Date.now() + 3600000 // 1 hour from now
117
+ });
118
+
119
+ // Unregister SIP endpoint
120
+ await api.internal.sip.unregister('call-123', 'user123', 'account-123');
121
+ ```
122
+
123
+ #### Authentication Validation
124
+ ```javascript
125
+ await api.internal.sip.validate({
126
+ method: 'INVITE',
127
+ username: 'user123',
128
+ realm: 'sip.example.com',
129
+ uri: 'sip:+1234567890@sip.example.com',
130
+ nonce: 'abc123',
131
+ nc: '00000001',
132
+ cnonce: 'xyz789',
133
+ qop: 'auth',
134
+ response: 'hash-response',
135
+ authType: 'digest',
136
+ ip: '192.168.1.100',
137
+ peerDirection: 'inbound',
138
+ location: 'us-east-1'
139
+ });
140
+ ```
141
+
142
+ #### Logging
143
+ ```javascript
144
+ await api.internal.sip.log({
145
+ callId: 'call-123',
146
+ level: 'info',
147
+ message: 'Call established',
148
+ data: { /* additional data */ }
149
+ });
150
+ ```
151
+
152
+ ## Environment Requirements
153
+
154
+ This package is designed for **Node.js environments only** and will throw errors when used in browser environments. The internal APIs require server-side authentication and access patterns.
155
+
156
+ ### Supported Environments
157
+ - ✅ Node.js servers
158
+ - ✅ AWS Lambda functions
159
+ - ✅ Docker containers
160
+ - ✅ Kubernetes pods
161
+ - ❌ Browser applications
162
+ - ❌ Client-side JavaScript
163
+
164
+ ## Security Considerations
165
+
166
+ ### Access Control
167
+ - All internal APIs require elevated authentication
168
+ - Methods may bypass normal user permission checks
169
+ - Use with extreme caution in production environments
170
+
171
+ ### Authentication
172
+ - Requires valid JWT tokens with administrative privileges
173
+ - `buildMasterAuth` provides cross-account access capabilities
174
+ - Always validate target accounts/users before authentication
175
+
176
+ ### Network Security
177
+ - Internal APIs may be accessible only from specific IP ranges
178
+ - SIP functions interact with core telephony infrastructure
179
+ - Audit all usage for security compliance
180
+
181
+ ## Error Handling
182
+
183
+ ```javascript
184
+ try {
185
+ await api.buildMasterAuth({
186
+ namespace: 'invalid-namespace',
187
+ accountId: 'invalid-account'
188
+ });
189
+ } catch (error) {
190
+ if (error.message.includes('Master authentication failed')) {
191
+ // Handle authentication failure
192
+ } else if (error.message.includes('only available in Node.js')) {
193
+ // Handle environment error
194
+ }
195
+ }
196
+ ```
197
+
198
+ ## Development
199
+
200
+ ### Setup
201
+ ```bash
202
+ git clone https://github.com/unbound/sdk-js-internal.git
203
+ cd sdk-js-internal
204
+ npm install
205
+ ```
206
+
207
+ ### Testing
208
+ ```bash
209
+ npm test # Run tests
210
+ npm run test:watch # Watch mode
211
+ ```
212
+
213
+ ### Building
214
+ ```bash
215
+ npm run build # Build for production
216
+ npm run lint # Check code style
217
+ ```
218
+
219
+ ## Contributing
220
+
221
+ Internal package contributions require:
222
+
223
+ 1. Security review for all changes
224
+ 2. Infrastructure team approval
225
+ 3. Testing in isolated environments
226
+ 4. Documentation of security implications
227
+
228
+ ## Support
229
+
230
+ For internal support:
231
+ - 📧 [Internal Support](mailto:internal-support@unbound.cx)
232
+ - 📚 [Internal Documentation](https://internal-docs.unbound.cx/sdk)
233
+ - 🚨 [Security Issues](mailto:security@unbound.cx)
234
+
235
+ ## License
236
+
237
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
238
+
239
+ **Note**: While the code is MIT licensed, access to Unbound's internal APIs requires proper authentication and authorization.
package/index.js ADDED
@@ -0,0 +1,63 @@
1
+ /* eslint-disable indent */
2
+ /* eslint-disable prettier/prettier */
3
+
4
+ import { InternalSipService } from './services/sip.js';
5
+ import { InternalEmailService } from './services/email.js';
6
+ import { InternalProgrammableVoiceService } from './services/programmableVoice.js';
7
+ import { InternalServersService } from './services/servers.js';
8
+ import { InternalSocketService } from './services/socket.js';
9
+
10
+ export class InternalSDK {
11
+ constructor(sdk) {
12
+ this.sdk = sdk;
13
+ this.sip = new InternalSipService(sdk);
14
+ this.email = new InternalEmailService(sdk);
15
+ this.programmableVoice = new InternalProgrammableVoiceService(sdk);
16
+ this.servers = new InternalServersService(sdk);
17
+ this.socket = new InternalSocketService(sdk);
18
+ }
19
+
20
+ // Master auth method - only available in Node.js
21
+ async buildMasterAuth({ namespace, accountId, userId }) {
22
+ if (typeof window !== 'undefined') {
23
+ throw new Error('buildMasterAuth is only available in Node.js environment');
24
+ }
25
+
26
+ const { buildMasterApiAuth } = await import('../src/utils/index.js');
27
+ if (namespace) {
28
+ this.sdk.setNamespace(namespace);
29
+ }
30
+ const auth = await buildMasterApiAuth(this.sdk.namespace, accountId, userId);
31
+ if (auth?.token?.jwt) {
32
+ this.sdk.token = auth.token.jwt;
33
+ }
34
+ return this.sdk.token;
35
+ }
36
+ }
37
+
38
+ // Extension pattern for the main SDK
39
+ export function install(sdk) {
40
+ const internal = new InternalSDK(sdk);
41
+
42
+ // Add buildMasterAuth to the main SDK instance
43
+ sdk.buildMasterAuth = internal.buildMasterAuth.bind(internal);
44
+
45
+ // Add internal services
46
+ sdk.internal = {
47
+ sip: internal.sip,
48
+ email: internal.email,
49
+ programmableVoice: internal.programmableVoice,
50
+ servers: internal.servers,
51
+ socket: internal.socket,
52
+ };
53
+ }
54
+
55
+ // Default export for ease of use
56
+ export default { install };
57
+
58
+ // Individual service exports
59
+ export { InternalSipService } from './services/sip.js';
60
+ export { InternalEmailService } from './services/email.js';
61
+ export { InternalProgrammableVoiceService, VoiceChannelService, TranscriptionService } from './services/programmableVoice.js';
62
+ export { InternalServersService, AwsServersService } from './services/servers.js';
63
+ export { InternalSocketService } from './services/socket.js';
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@unboundcx/sdk-internal",
3
+ "version": "1.0.0",
4
+ "description": "Internal SDK extension for Unbound - Provides access to internal APIs and administrative functions",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=16.0.0"
9
+ },
10
+ "keywords": [
11
+ "unbound",
12
+ "sdk",
13
+ "internal",
14
+ "sip",
15
+ "administrative",
16
+ "extension"
17
+ ],
18
+ "author": {
19
+ "name": "Unbound Team",
20
+ "email": "support@unbound.cx",
21
+ "url": "https://unbound.cx"
22
+ },
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/unbound/sdk-js-internal.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/unbound/sdk-js-internal/issues"
30
+ },
31
+ "homepage": "https://docs.unbound.cx/sdk/internal",
32
+ "files": [
33
+ "*.js",
34
+ "services/**/*.js",
35
+ "types/**/*.d.ts",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "exports": {
40
+ ".": {
41
+ "import": "./index.js",
42
+ "require": "./index.cjs"
43
+ },
44
+ "./services/*": {
45
+ "import": "./services/*.js"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "echo 'Build complete - ESM modules ready'",
50
+ "test": "echo 'Tests would run here'",
51
+ "lint": "echo 'Linting would run here'",
52
+ "prepublishOnly": "npm run build"
53
+ },
54
+ "dependencies": {},
55
+ "peerDependencies": {
56
+ "@unboundcx/sdk": "^1.0.0"
57
+ },
58
+ "devDependencies": {},
59
+ "publishConfig": {
60
+ "registry": "https://registry.npmjs.org/",
61
+ "access": "restricted"
62
+ }
63
+ }
@@ -0,0 +1,62 @@
1
+ export class InternalEmailService {
2
+ constructor(sdk) {
3
+ this.sdk = sdk;
4
+ }
5
+
6
+ async incrementOpen(emailId) {
7
+ this.sdk.validateParams(
8
+ { emailId },
9
+ {
10
+ emailId: { type: 'string', required: true },
11
+ },
12
+ );
13
+
14
+ const result = await this.sdk._fetch(
15
+ `/internal/email/open/${emailId}`,
16
+ 'POST',
17
+ );
18
+ return result;
19
+ }
20
+
21
+ async incrementLinkClick(linkId, { trackingCookie }) {
22
+ this.sdk.validateParams(
23
+ { linkId, trackingCookie },
24
+ {
25
+ linkId: { type: 'string', required: true },
26
+ trackingCookie: { type: 'string', required: false },
27
+ },
28
+ );
29
+
30
+ const params = {
31
+ body: { trackingCookie },
32
+ };
33
+
34
+ const result = await this.sdk._fetch(
35
+ `/internal/email/click/${linkId}`,
36
+ 'POST',
37
+ params,
38
+ );
39
+ return result;
40
+ }
41
+
42
+ async processUnsubscribe(emailId, { to }) {
43
+ this.sdk.validateParams(
44
+ { emailId, to },
45
+ {
46
+ emailId: { type: 'string', required: true },
47
+ to: { type: 'string', required: true },
48
+ },
49
+ );
50
+
51
+ const params = {
52
+ body: { to },
53
+ };
54
+
55
+ const result = await this.sdk._fetch(
56
+ `/internal/email/unsubscribe/${emailId}`,
57
+ 'POST',
58
+ params,
59
+ );
60
+ return result;
61
+ }
62
+ }
@@ -0,0 +1,378 @@
1
+ export class InternalProgrammableVoiceService {
2
+ constructor(sdk) {
3
+ this.sdk = sdk;
4
+ this.voiceChannel = new VoiceChannelService(sdk);
5
+ this.transcription = new TranscriptionService(sdk);
6
+ }
7
+
8
+ async streamProxy(streamData) {
9
+ this.sdk.validateParams(
10
+ { streamData },
11
+ {
12
+ streamData: { type: 'object', required: true },
13
+ },
14
+ );
15
+
16
+ const params = {
17
+ body: streamData,
18
+ };
19
+
20
+ const result = await this.sdk._fetch('/internal/programmableVoice/streamProxy', 'POST', params);
21
+ return result;
22
+ }
23
+
24
+ async webhookProxy(webhookData) {
25
+ this.sdk.validateParams(
26
+ { webhookData },
27
+ {
28
+ webhookData: { type: 'object', required: true },
29
+ },
30
+ );
31
+
32
+ const params = {
33
+ body: webhookData,
34
+ };
35
+
36
+ const result = await this.sdk._fetch('/internal/programmableVoice/proxy', 'POST', params);
37
+ return result;
38
+ }
39
+
40
+ async setVariable({ channelId, serverId, variable, value }) {
41
+ if (!serverId) {
42
+ serverId = process.env.SERVER_ID;
43
+ }
44
+
45
+ this.sdk.validateParams(
46
+ { channelId, serverId, variable, value },
47
+ {
48
+ channelId: { type: 'string', required: true },
49
+ serverId: { type: 'string', required: true },
50
+ variable: { type: 'string', required: true },
51
+ value: { type: 'string', required: true },
52
+ },
53
+ );
54
+
55
+ const params = {
56
+ body: {
57
+ channelId,
58
+ serverId,
59
+ variable,
60
+ value,
61
+ },
62
+ };
63
+
64
+ const result = await this.sdk._fetch('/internal/programmableVoice/setVariable', 'POST', params);
65
+ return result;
66
+ }
67
+
68
+ async getVariable({ channelId, serverId, variables }) {
69
+ if (!serverId) {
70
+ serverId = process.env.SERVER_ID;
71
+ }
72
+
73
+ this.sdk.validateParams(
74
+ { channelId, serverId, variables },
75
+ {
76
+ channelId: { type: 'string', required: true },
77
+ serverId: { type: 'string', required: true },
78
+ variables: { type: 'array', required: true },
79
+ },
80
+ );
81
+
82
+ const params = {
83
+ body: {
84
+ channelId,
85
+ serverId,
86
+ variables,
87
+ },
88
+ };
89
+
90
+ const result = await this.sdk._fetch('/internal/programmableVoice/getVariable', 'POST', params);
91
+ return result;
92
+ }
93
+
94
+ async joinMeetingRoom({
95
+ meetingId,
96
+ meetingPassword,
97
+ meetingJoinType,
98
+ numberCalled,
99
+ callerIdNumber,
100
+ channelId,
101
+ loopCount,
102
+ engagementSessionId,
103
+ voiceChannelId,
104
+ serverId
105
+ }) {
106
+ this.sdk.validateParams(
107
+ { meetingId },
108
+ {
109
+ meetingId: { type: 'string', required: true },
110
+ meetingPassword: { type: 'string', required: false },
111
+ meetingJoinType: { type: 'string', required: false },
112
+ numberCalled: { type: 'string', required: false },
113
+ callerIdNumber: { type: 'string', required: false },
114
+ channelId: { type: 'string', required: false },
115
+ loopCount: { type: 'number', required: false },
116
+ engagementSessionId: { type: 'string', required: false },
117
+ voiceChannelId: { type: 'string', required: false },
118
+ serverId: { type: 'string', required: false },
119
+ },
120
+ );
121
+
122
+ const meetingData = { meetingId };
123
+ if (meetingPassword) meetingData.meetingPassword = meetingPassword;
124
+ if (meetingJoinType) meetingData.meetingJoinType = meetingJoinType;
125
+ if (numberCalled) meetingData.numberCalled = numberCalled;
126
+ if (callerIdNumber) meetingData.callerIdNumber = callerIdNumber;
127
+ if (channelId) meetingData.channelId = channelId;
128
+ if (loopCount) meetingData.loopCount = loopCount;
129
+ if (engagementSessionId) meetingData.engagementSessionId = engagementSessionId;
130
+ if (voiceChannelId) meetingData.voiceChannelId = voiceChannelId;
131
+ if (serverId) meetingData.serverId = serverId;
132
+
133
+ const params = {
134
+ body: meetingData,
135
+ };
136
+
137
+ const result = await this.sdk._fetch('/internal/programmableVoice/joinMeetingRoom', 'POST', params);
138
+ return result;
139
+ }
140
+
141
+ async createNewVoiceAppSession(location, sessionData) {
142
+ this.sdk.validateParams(
143
+ { location, sessionData },
144
+ {
145
+ location: { type: 'string', required: true },
146
+ sessionData: { type: 'object', required: true },
147
+ },
148
+ );
149
+
150
+ const params = {
151
+ body: sessionData,
152
+ };
153
+
154
+ const result = await this.sdk._fetch(`/internal/programmableVoice/${location}`, 'POST', params);
155
+ return result;
156
+ }
157
+ }
158
+
159
+ export class VoiceChannelService {
160
+ constructor(sdk) {
161
+ this.sdk = sdk;
162
+ }
163
+
164
+ async create({
165
+ channelId,
166
+ serverId,
167
+ isVoice,
168
+ accountId,
169
+ engagementSessionId,
170
+ to,
171
+ from,
172
+ direction,
173
+ isCopy,
174
+ originalChannelId,
175
+ isComplete,
176
+ }) {
177
+ if (!serverId) {
178
+ serverId = process.env.SERVER_ID;
179
+ }
180
+
181
+ this.sdk.validateParams(
182
+ {
183
+ channelId,
184
+ serverId,
185
+ isVoice,
186
+ accountId,
187
+ engagementSessionId,
188
+ to,
189
+ from,
190
+ direction,
191
+ isCopy,
192
+ originalChannelId,
193
+ isComplete,
194
+ },
195
+ {
196
+ channelId: { type: 'string', required: true },
197
+ serverId: { type: 'string', required: true },
198
+ isVoice: { type: 'boolean', required: true },
199
+ accountId: { type: 'string', required: false },
200
+ engagementSessionId: { type: 'string', required: false },
201
+ to: { type: 'string', required: true },
202
+ from: { type: 'string', required: true },
203
+ direction: { type: 'string', required: true },
204
+ isCopy: { type: 'boolean', required: false },
205
+ originalChannelId: { type: 'string', required: false },
206
+ isComplete: { type: 'boolean', required: false },
207
+ },
208
+ );
209
+
210
+ const params = {
211
+ body: {
212
+ channelId,
213
+ serverId,
214
+ isVoice,
215
+ accountId,
216
+ engagementSessionId,
217
+ to,
218
+ from,
219
+ direction,
220
+ isCopy,
221
+ originalChannelId,
222
+ isComplete,
223
+ },
224
+ };
225
+
226
+ const result = await this.sdk._fetch('/internal/programmableVoice/voiceChannel', 'POST', params);
227
+ return result;
228
+ }
229
+
230
+ async update({
231
+ channelId,
232
+ serverId,
233
+ isVoice,
234
+ accountId,
235
+ engagementSessionId,
236
+ to,
237
+ from,
238
+ direction,
239
+ voiceChannelId,
240
+ isCopy,
241
+ originalChannelId,
242
+ isComplete,
243
+ }) {
244
+ if (!serverId) {
245
+ serverId = process.env.SERVER_ID;
246
+ }
247
+
248
+ this.sdk.validateParams(
249
+ {
250
+ channelId,
251
+ serverId,
252
+ isVoice,
253
+ accountId,
254
+ engagementSessionId,
255
+ to,
256
+ from,
257
+ direction,
258
+ voiceChannelId,
259
+ isCopy,
260
+ originalChannelId,
261
+ isComplete,
262
+ },
263
+ {
264
+ channelId: { type: 'string', required: true },
265
+ serverId: { type: 'string', required: true },
266
+ isVoice: { type: 'boolean', required: true },
267
+ accountId: { type: 'string', required: false },
268
+ engagementSessionId: { type: 'string', required: false },
269
+ to: { type: 'string', required: true },
270
+ from: { type: 'string', required: true },
271
+ direction: { type: 'string', required: true },
272
+ voiceChannelId: { type: 'string', required: false },
273
+ isCopy: { type: 'boolean', required: false },
274
+ originalChannelId: { type: 'string', required: false },
275
+ isComplete: { type: 'boolean', required: false },
276
+ },
277
+ );
278
+
279
+ const params = {
280
+ body: {
281
+ channelId,
282
+ serverId,
283
+ isVoice,
284
+ accountId,
285
+ engagementSessionId,
286
+ to,
287
+ from,
288
+ direction,
289
+ voiceChannelId,
290
+ isCopy,
291
+ originalChannelId,
292
+ isComplete,
293
+ },
294
+ };
295
+
296
+ const result = await this.sdk._fetch('/internal/programmableVoice/voiceChannel', 'PUT', params);
297
+ return result;
298
+ }
299
+ }
300
+
301
+ export class TranscriptionService {
302
+ constructor(sdk) {
303
+ this.sdk = sdk;
304
+ }
305
+
306
+ async create({
307
+ voiceChannelId,
308
+ engagementSessionId,
309
+ accountId,
310
+ name,
311
+ direction,
312
+ role,
313
+ userId,
314
+ playbookId
315
+ }) {
316
+ this.sdk.validateParams(
317
+ { voiceChannelId, engagementSessionId, accountId },
318
+ {
319
+ voiceChannelId: { type: 'string', required: true },
320
+ engagementSessionId: { type: 'string', required: true },
321
+ accountId: { type: 'string', required: true },
322
+ name: { type: 'string', required: false },
323
+ direction: { type: 'string', required: false },
324
+ role: { type: 'string', required: false },
325
+ userId: { type: 'string', required: false },
326
+ playbookId: { type: 'string', required: false },
327
+ },
328
+ );
329
+
330
+ const transcriptionData = { voiceChannelId, engagementSessionId, accountId };
331
+ if (name) transcriptionData.name = name;
332
+ if (direction) transcriptionData.direction = direction;
333
+ if (role) transcriptionData.role = role;
334
+ if (userId) transcriptionData.userId = userId;
335
+ if (playbookId) transcriptionData.playbookId = playbookId;
336
+
337
+ const params = {
338
+ body: transcriptionData,
339
+ };
340
+
341
+ const result = await this.sdk._fetch('/internal/programmableVoice/transcription/', 'POST', params);
342
+ return result;
343
+ }
344
+
345
+ async complete(id, completionData) {
346
+ this.sdk.validateParams(
347
+ { id, completionData },
348
+ {
349
+ id: { type: 'string', required: true },
350
+ completionData: { type: 'object', required: true },
351
+ },
352
+ );
353
+
354
+ const params = {
355
+ body: completionData,
356
+ };
357
+
358
+ const result = await this.sdk._fetch(`/internal/programmableVoice/transcription/${id}`, 'PUT', params);
359
+ return result;
360
+ }
361
+
362
+ async logMessage(id, messageData) {
363
+ this.sdk.validateParams(
364
+ { id, messageData },
365
+ {
366
+ id: { type: 'string', required: true },
367
+ messageData: { type: 'object', required: true },
368
+ },
369
+ );
370
+
371
+ const params = {
372
+ body: messageData,
373
+ };
374
+
375
+ const result = await this.sdk._fetch(`/internal/programmableVoice/transcription/${id}`, 'POST', params);
376
+ return result;
377
+ }
378
+ }
@@ -0,0 +1,130 @@
1
+ export class InternalServersService {
2
+ constructor(sdk) {
3
+ this.sdk = sdk;
4
+ this.aws = new AwsServersService(sdk);
5
+ }
6
+
7
+ async create({
8
+ type,
9
+ region,
10
+ privateIp,
11
+ publicIp,
12
+ status,
13
+ arch,
14
+ podName,
15
+ namespace,
16
+ K8S_SERVICE_NAME,
17
+ K8S_DEPLOYMENT_TYPE
18
+ }) {
19
+ this.sdk.validateParams(
20
+ { type, region },
21
+ {
22
+ type: { type: 'string', required: true },
23
+ region: { type: 'string', required: true },
24
+ privateIp: { type: 'string', required: false },
25
+ publicIp: { type: 'string', required: false },
26
+ status: { type: 'string', required: false },
27
+ arch: { type: 'string', required: false },
28
+ podName: { type: 'string', required: false },
29
+ namespace: { type: 'string', required: false },
30
+ K8S_SERVICE_NAME: { type: 'string', required: false },
31
+ K8S_DEPLOYMENT_TYPE: { type: 'string', required: false },
32
+ },
33
+ );
34
+
35
+ const serverData = { type, region };
36
+ if (privateIp) serverData.privateIp = privateIp;
37
+ if (publicIp) serverData.publicIp = publicIp;
38
+ if (status) serverData.status = status;
39
+ if (arch) serverData.arch = arch;
40
+ if (podName) serverData.podName = podName;
41
+ if (namespace) serverData.namespace = namespace;
42
+ if (K8S_SERVICE_NAME) serverData.K8S_SERVICE_NAME = K8S_SERVICE_NAME;
43
+ if (K8S_DEPLOYMENT_TYPE) serverData.K8S_DEPLOYMENT_TYPE = K8S_DEPLOYMENT_TYPE;
44
+
45
+ const params = {
46
+ body: serverData,
47
+ };
48
+
49
+ const result = await this.sdk._fetch('/internal/servers/', 'POST', params);
50
+ return result;
51
+ }
52
+
53
+ async update(id, { status, region, privateIp }) {
54
+ this.sdk.validateParams(
55
+ { id },
56
+ {
57
+ id: { type: 'string', required: true },
58
+ status: { type: 'string', required: false },
59
+ region: { type: 'string', required: false },
60
+ privateIp: { type: 'string', required: false },
61
+ },
62
+ );
63
+
64
+ // Validate status if provided
65
+ if (status) {
66
+ const validStatuses = ['booting', 'ready', 'maintenance', 'error', 'stopped', 'stopping'];
67
+ if (!validStatuses.includes(status)) {
68
+ throw new Error(`Invalid status. Must be one of: ${validStatuses.join(', ')}`);
69
+ }
70
+ }
71
+
72
+ const updateData = {};
73
+ if (status) updateData.status = status;
74
+ if (region) updateData.region = region;
75
+ if (privateIp) updateData.privateIp = privateIp;
76
+
77
+ const params = {
78
+ body: updateData,
79
+ };
80
+
81
+ const result = await this.sdk._fetch(`/internal/servers/${id}`, 'PUT', params);
82
+ return result;
83
+ }
84
+
85
+ async delete(id) {
86
+ this.sdk.validateParams(
87
+ { id },
88
+ {
89
+ id: { type: 'string', required: true },
90
+ },
91
+ );
92
+
93
+ const result = await this.sdk._fetch(`/internal/servers/${id}`, 'DELETE');
94
+ return result;
95
+ }
96
+
97
+ async shutdownCheck(id) {
98
+ this.sdk.validateParams(
99
+ { id },
100
+ {
101
+ id: { type: 'string', required: true },
102
+ },
103
+ );
104
+
105
+ const result = await this.sdk._fetch(`/internal/servers/${id}/shutdownCheck`, 'GET');
106
+ return result;
107
+ }
108
+ }
109
+
110
+ export class AwsServersService {
111
+ constructor(sdk) {
112
+ this.sdk = sdk;
113
+ }
114
+
115
+ async assignElasticIp(assignmentData) {
116
+ this.sdk.validateParams(
117
+ { assignmentData },
118
+ {
119
+ assignmentData: { type: 'object', required: true },
120
+ },
121
+ );
122
+
123
+ const params = {
124
+ body: assignmentData,
125
+ };
126
+
127
+ const result = await this.sdk._fetch('/internal/servers/aws/assignElasticIp', 'POST', params);
128
+ return result;
129
+ }
130
+ }
@@ -0,0 +1,249 @@
1
+ export class InternalSipService {
2
+ constructor(sdk) {
3
+ this.sdk = sdk;
4
+ }
5
+
6
+ async router(to, from, callId, auth, peerDirection) {
7
+ this.sdk.validateParams(
8
+ { to, from, callId, auth, peerDirection },
9
+ {
10
+ to: { type: 'string', required: true },
11
+ from: { type: 'string', required: false },
12
+ callId: { type: 'string', required: false },
13
+ auth: { type: 'object', required: false },
14
+ peerDirection: { type: 'string', required: false },
15
+ },
16
+ );
17
+
18
+ const options = {
19
+ body: { to, from, callId, auth, peerDirection },
20
+ };
21
+ const result = await this.sdk._fetch(
22
+ `/internal/sip/router/${to}?from=${from}&callId=${callId}`,
23
+ 'POST',
24
+ options,
25
+ true,
26
+ );
27
+ return result;
28
+ }
29
+
30
+ async getServer(type, regionCode, callId) {
31
+ this.sdk.validateParams(
32
+ { type, regionCode, callId },
33
+ {
34
+ type: { type: 'string', required: true },
35
+ regionCode: { type: 'string', required: true },
36
+ callId: { type: 'string', required: false },
37
+ },
38
+ );
39
+
40
+ const options = {};
41
+ const result = await this.sdk._fetch(
42
+ `/internal/sip/server/${type}?regionCode=${regionCode}&callId=${callId}`,
43
+ 'GET',
44
+ options,
45
+ true,
46
+ );
47
+ return result;
48
+ }
49
+
50
+ async log(params) {
51
+ const options = {
52
+ body: {
53
+ ...params,
54
+ },
55
+ };
56
+ const result = await this.sdk._fetch(
57
+ `/internal/sip/log`,
58
+ 'POST',
59
+ options,
60
+ true,
61
+ false,
62
+ );
63
+ return result;
64
+ }
65
+
66
+ async register({
67
+ accountId,
68
+ serverId,
69
+ callId,
70
+ username,
71
+ userId,
72
+ clientIp,
73
+ isWebRtc = false,
74
+ connnectionId,
75
+ transport,
76
+ contact,
77
+ domain,
78
+ host,
79
+ port,
80
+ userAgent,
81
+ expiresAt,
82
+ }) {
83
+ this.sdk.validateParams(
84
+ {
85
+ accountId,
86
+ serverId,
87
+ callId,
88
+ username,
89
+ userId,
90
+ clientIp,
91
+ isWebRtc,
92
+ connnectionId,
93
+ transport,
94
+ contact,
95
+ domain,
96
+ host,
97
+ port,
98
+ userAgent,
99
+ expiresAt,
100
+ },
101
+ {
102
+ accountId: { type: 'string', required: true },
103
+ serverId: { type: 'string', required: true },
104
+ callId: { type: 'string', required: true },
105
+ username: { type: 'string', required: true },
106
+ userId: { type: 'string', required: false },
107
+ clientIp: { type: 'string', required: true },
108
+ isWebRtc: { type: 'boolean', required: true },
109
+ connnectionId: { type: 'string', required: false },
110
+ transport: { type: 'string', required: true },
111
+ contact: { type: 'string', required: true },
112
+ domain: { type: 'string', required: true },
113
+ port: { type: 'number', required: false },
114
+ userAgent: { type: 'string', required: true },
115
+ expiresAt: { type: 'number', required: true },
116
+ },
117
+ );
118
+
119
+ const options = {
120
+ body: {
121
+ accountId,
122
+ serverId,
123
+ callId,
124
+ username,
125
+ userId,
126
+ clientIp,
127
+ isWebRtc,
128
+ contact,
129
+ connnectionId,
130
+ transport,
131
+ host,
132
+ port,
133
+ userAgent,
134
+ expiresAt,
135
+ },
136
+ };
137
+
138
+ const result = await this.sdk._fetch(
139
+ `/internal/sip/register`,
140
+ 'POST',
141
+ options,
142
+ true,
143
+ false,
144
+ );
145
+ return result;
146
+ }
147
+
148
+ async unregister(callId, username, accountId) {
149
+ this.sdk.validateParams(
150
+ { callId, username, accountId },
151
+ {
152
+ username: { type: 'string', required: true },
153
+ callId: { type: 'string', required: true },
154
+ accountId: { type: 'string', required: true },
155
+ },
156
+ );
157
+
158
+ const options = {
159
+ body: {
160
+ callId,
161
+ username,
162
+ accountId,
163
+ },
164
+ };
165
+ const result = await this.sdk._fetch(
166
+ `/internal/sip/register/`,
167
+ 'DELETE',
168
+ options,
169
+ true,
170
+ false,
171
+ );
172
+ return result;
173
+ }
174
+
175
+ async validate({
176
+ method,
177
+ username,
178
+ realm,
179
+ uri,
180
+ nonce,
181
+ nc,
182
+ cnonce,
183
+ qop,
184
+ response,
185
+ authType,
186
+ ip,
187
+ peerDirection,
188
+ location,
189
+ }) {
190
+ this.sdk.validateParams(
191
+ {
192
+ method,
193
+ username,
194
+ realm,
195
+ uri,
196
+ nonce,
197
+ nc,
198
+ cnonce,
199
+ qop,
200
+ response,
201
+ authType,
202
+ ip,
203
+ peerDirection,
204
+ location,
205
+ },
206
+ {
207
+ method: { type: 'string', required: false },
208
+ username: { type: 'string', required: false },
209
+ realm: { type: 'string', required: false },
210
+ uri: { type: 'string', required: false },
211
+ nonce: { type: 'string', required: false },
212
+ nc: { type: 'string', required: false },
213
+ cnonce: { type: 'string', required: false },
214
+ qop: { type: 'string', required: false },
215
+ response: { type: 'string', required: false },
216
+ authType: { type: 'string', required: false },
217
+ ip: { type: 'string', required: false },
218
+ peerDirection: { type: 'string', required: false },
219
+ location: { type: 'string', required: false },
220
+ },
221
+ );
222
+
223
+ const options = {
224
+ body: {
225
+ method,
226
+ username,
227
+ realm,
228
+ uri,
229
+ nonce,
230
+ nc,
231
+ cnonce,
232
+ qop,
233
+ response,
234
+ authType,
235
+ ip,
236
+ peerDirection,
237
+ location,
238
+ },
239
+ };
240
+ const result = await this.sdk._fetch(
241
+ `/internal/sip/register/validate`,
242
+ 'POST',
243
+ options,
244
+ false,
245
+ false,
246
+ );
247
+ return result;
248
+ }
249
+ }
@@ -0,0 +1,103 @@
1
+ export class InternalSocketService {
2
+ constructor(sdk) {
3
+ this.sdk = sdk;
4
+ }
5
+
6
+ async createConnection({
7
+ userId,
8
+ sessionId,
9
+ socketId,
10
+ accountCode,
11
+ accountId,
12
+ tokenId,
13
+ serverId,
14
+ clientIp,
15
+ clientOs,
16
+ clientBrowser
17
+ }) {
18
+ this.sdk.validateParams(
19
+ { socketId, accountCode, accountId, serverId },
20
+ {
21
+ userId: { type: 'string', required: false },
22
+ sessionId: { type: 'string', required: false },
23
+ socketId: { type: 'string', required: true },
24
+ accountCode: { type: 'string', required: true },
25
+ accountId: { type: 'string', required: true },
26
+ tokenId: { type: 'string', required: false },
27
+ serverId: { type: 'string', required: true },
28
+ clientIp: { type: 'string', required: false },
29
+ clientOs: { type: 'string', required: false },
30
+ clientBrowser: { type: 'string', required: false },
31
+ },
32
+ );
33
+
34
+ const connectionData = { socketId, accountCode, accountId, serverId };
35
+ if (userId) connectionData.userId = userId;
36
+ if (sessionId) connectionData.sessionId = sessionId;
37
+ if (tokenId) connectionData.tokenId = tokenId;
38
+ if (clientIp) connectionData.clientIp = clientIp;
39
+ if (clientOs) connectionData.clientOs = clientOs;
40
+ if (clientBrowser) connectionData.clientBrowser = clientBrowser;
41
+
42
+ const params = {
43
+ body: connectionData,
44
+ };
45
+
46
+ const result = await this.sdk._fetch('/internal/socket/connection', 'POST', params);
47
+ return result;
48
+ }
49
+
50
+ async updateConnection(id, { rtt, clientIp, clientOs, clientBrowser }) {
51
+ this.sdk.validateParams(
52
+ { id },
53
+ {
54
+ id: { type: 'string', required: true },
55
+ rtt: { type: 'number', required: false },
56
+ clientIp: { type: 'string', required: false },
57
+ clientOs: { type: 'string', required: false },
58
+ clientBrowser: { type: 'string', required: false },
59
+ },
60
+ );
61
+
62
+ const updateData = {};
63
+ if (rtt !== undefined) updateData.rtt = rtt;
64
+ if (clientIp) updateData.clientIp = clientIp;
65
+ if (clientOs) updateData.clientOs = clientOs;
66
+ if (clientBrowser) updateData.clientBrowser = clientBrowser;
67
+
68
+ const params = {
69
+ body: updateData,
70
+ };
71
+
72
+ const result = await this.sdk._fetch(`/internal/socket/connection/${id}`, 'PUT', params);
73
+ return result;
74
+ }
75
+
76
+ async deleteConnection(id) {
77
+ this.sdk.validateParams(
78
+ { id },
79
+ {
80
+ id: { type: 'string', required: true },
81
+ },
82
+ );
83
+
84
+ const result = await this.sdk._fetch(`/internal/socket/connection/${id}`, 'DELETE');
85
+ return result;
86
+ }
87
+
88
+ async deleteAllConnectionsByServer(serverId) {
89
+ this.sdk.validateParams(
90
+ { serverId },
91
+ {
92
+ serverId: { type: 'string', required: true },
93
+ },
94
+ );
95
+
96
+ const params = {
97
+ body: { serverId },
98
+ };
99
+
100
+ const result = await this.sdk._fetch('/internal/socket/connection/byServerId', 'DELETE', params);
101
+ return result;
102
+ }
103
+ }