@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 +239 -0
- package/index.js +63 -0
- package/package.json +63 -0
- package/services/email.js +62 -0
- package/services/programmableVoice.js +378 -0
- package/services/servers.js +130 -0
- package/services/sip.js +249 -0
- package/services/socket.js +103 -0
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Unbound Internal SDK
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/%40unbound%2Fsdk-internal)
|
|
4
|
+
[](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
|
+
}
|
package/services/sip.js
ADDED
|
@@ -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
|
+
}
|