@dora-cell/sdk 0.1.1-beta.6
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 +276 -0
- package/dist/index.d.mts +210 -0
- package/dist/index.d.ts +210 -0
- package/dist/index.js +664 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +645 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# @dora-cell/sdk
|
|
2
|
+
|
|
3
|
+
VoIP calling SDK for Dora Cell - Make calls from any JavaScript application without logging into the Dora Cell web app.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✅ **Framework-agnostic** - Works with vanilla JS, React, Vue, Angular, etc.
|
|
8
|
+
✅ **TypeScript support** - Full type definitions included
|
|
9
|
+
✅ **WebRTC-based** - High-quality voice calls using JsSIP
|
|
10
|
+
✅ **Event-driven API** - Listen to call state changes
|
|
11
|
+
✅ **API token authentication** - Secure, no user login required
|
|
12
|
+
✅ **Auto-extension selection** - Automatically selects first available extension
|
|
13
|
+
✅ **React bindings** - Optional React hooks for easy integration
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @dora-cell/sdk jssip
|
|
19
|
+
# or
|
|
20
|
+
yarn add @dora-cell/sdk jssip
|
|
21
|
+
# or
|
|
22
|
+
pnpm add @dora-cell/sdk jssip
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For React projects:
|
|
26
|
+
```bash
|
|
27
|
+
npm install @dora-cell/sdk @dora-cell/sdk-react jssip
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Vanilla JavaScript
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
import { DoraCell } from '@dora-cell/sdk';
|
|
36
|
+
|
|
37
|
+
// Initialize SDK with API token
|
|
38
|
+
const sdk = new DoraCell({
|
|
39
|
+
auth: {
|
|
40
|
+
type: 'api-token',
|
|
41
|
+
apiToken: 'your-api-token-here',
|
|
42
|
+
apiBaseUrl: 'https://api.usedora.com'
|
|
43
|
+
},
|
|
44
|
+
debug: true // Enable console logging
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Initialize connection
|
|
48
|
+
await sdk.initialize();
|
|
49
|
+
|
|
50
|
+
// Listen for connection status
|
|
51
|
+
sdk.on('connection:status', (state) => {
|
|
52
|
+
console.log('Connection status:', state.status);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Listen for call events
|
|
56
|
+
sdk.on('call:connected', (call) => {
|
|
57
|
+
console.log('Call connected:', call.remoteNumber);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
sdk.on('call:ended', (call, reason) => {
|
|
61
|
+
console.log('Call ended:', reason);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Make a call
|
|
65
|
+
const call = await sdk.call('+2348012345678');
|
|
66
|
+
|
|
67
|
+
// Mute/unmute
|
|
68
|
+
call.mute();
|
|
69
|
+
call.unmute();
|
|
70
|
+
|
|
71
|
+
// Hang up
|
|
72
|
+
call.hangup();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### React
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { DoraCellProvider, useCall, useConnectionStatus } from '@dora-cell/sdk-react';
|
|
79
|
+
|
|
80
|
+
function App() {
|
|
81
|
+
return (
|
|
82
|
+
<DoraCellProvider
|
|
83
|
+
config={{
|
|
84
|
+
auth: {
|
|
85
|
+
type: 'api-token',
|
|
86
|
+
apiToken: 'your-api-token-here',
|
|
87
|
+
apiBaseUrl: 'https://api.usedora.com'
|
|
88
|
+
}
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<CallInterface />
|
|
92
|
+
</DoraCellProvider>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function CallInterface() {
|
|
97
|
+
const { call, hangup, toggleMute, callStatus, callDuration, isMuted } = useCall();
|
|
98
|
+
const { isConnected } = useConnectionStatus();
|
|
99
|
+
const [number, setNumber] = useState('');
|
|
100
|
+
|
|
101
|
+
const handleCall = async () => {
|
|
102
|
+
try {
|
|
103
|
+
await call(number);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('Call failed:', error);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div>
|
|
111
|
+
<p>Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
|
|
112
|
+
<input
|
|
113
|
+
value={number}
|
|
114
|
+
onChange={(e) => setNumber(e.target.value)}
|
|
115
|
+
placeholder="Enter phone number"
|
|
116
|
+
/>
|
|
117
|
+
<button onClick={handleCall} disabled={!isConnected}>
|
|
118
|
+
Call
|
|
119
|
+
</button>
|
|
120
|
+
{callStatus === 'ongoing' && (
|
|
121
|
+
<>
|
|
122
|
+
<p>Duration: {callDuration}</p>
|
|
123
|
+
<button onClick={toggleMute}>{isMuted ? 'Unmute' : 'Mute'}</button>
|
|
124
|
+
<button onClick={hangup}>Hang Up</button>
|
|
125
|
+
</>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## API Reference
|
|
133
|
+
|
|
134
|
+
### DoraCell Class
|
|
135
|
+
|
|
136
|
+
#### Constructor
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
new DoraCell(config: DoraCellConfig)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Config options:**
|
|
143
|
+
- `auth` - Authentication configuration (required)
|
|
144
|
+
- `type: 'api-token'` - Use API token authentication
|
|
145
|
+
- `apiToken: string` - Your Dora Cell API token
|
|
146
|
+
- `apiBaseUrl?: string` - API base URL (optional)
|
|
147
|
+
- `turnServers?: RTCIceServer[]` - Custom TURN/STUN servers
|
|
148
|
+
- `debug?: boolean` - Enable debug logging
|
|
149
|
+
- `autoSelectExtension?: boolean` - Auto-select first extension (default: true)
|
|
150
|
+
|
|
151
|
+
#### Methods
|
|
152
|
+
|
|
153
|
+
**`initialize(): Promise<void>`**
|
|
154
|
+
Initialize the SDK and connect to SIP server.
|
|
155
|
+
|
|
156
|
+
**`call(phoneNumber: string, options?: CallOptions): Promise<Call>`**
|
|
157
|
+
Make an outbound call.
|
|
158
|
+
|
|
159
|
+
Options:
|
|
160
|
+
- `extension?: string` - Specific extension to use for this call
|
|
161
|
+
|
|
162
|
+
**`hangup(): void`**
|
|
163
|
+
Hang up the current call.
|
|
164
|
+
|
|
165
|
+
**`answerCall(): void`**
|
|
166
|
+
Answer an incoming call.
|
|
167
|
+
|
|
168
|
+
**`getCurrentCall(): Call | null`**
|
|
169
|
+
Get the current active call.
|
|
170
|
+
|
|
171
|
+
**`getStatus(): ConnectionStatus`**
|
|
172
|
+
Get current connection status.
|
|
173
|
+
|
|
174
|
+
**`getExtensions(): string[]`**
|
|
175
|
+
Get list of available extensions.
|
|
176
|
+
|
|
177
|
+
**`on(event, handler): void`**
|
|
178
|
+
Register event listener.
|
|
179
|
+
|
|
180
|
+
**`off(event, handler): void`**
|
|
181
|
+
Remove event listener.
|
|
182
|
+
|
|
183
|
+
**`destroy(): void`**
|
|
184
|
+
Cleanup and destroy SDK instance.
|
|
185
|
+
|
|
186
|
+
### Events
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
sdk.on('connection:status', (state: ConnectionState) => {});
|
|
190
|
+
sdk.on('call:incoming', (call: Call) => {});
|
|
191
|
+
sdk.on('call:outgoing', (call: Call) => {});
|
|
192
|
+
sdk.on('call:ringing', (call: Call) => {});
|
|
193
|
+
sdk.on('call:connected', (call: Call) => {});
|
|
194
|
+
sdk.on('call:ended', (call: Call, reason?: string) => {});
|
|
195
|
+
sdk.on('call:failed', (call: Call, error: string) => {});
|
|
196
|
+
sdk.on('error', (error: Error) => {});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Call Object
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
interface Call {
|
|
203
|
+
id: string;
|
|
204
|
+
status: CallStatus;
|
|
205
|
+
direction: 'inbound' | 'outbound';
|
|
206
|
+
remoteNumber: string;
|
|
207
|
+
localExtension: string;
|
|
208
|
+
duration: number;
|
|
209
|
+
|
|
210
|
+
mute(): void;
|
|
211
|
+
unmute(): void;
|
|
212
|
+
hangup(): void;
|
|
213
|
+
isMuted(): boolean;
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Authentication
|
|
218
|
+
|
|
219
|
+
### Getting an API Token
|
|
220
|
+
|
|
221
|
+
1. Log in to your Dora Cell dashboard
|
|
222
|
+
2. Navigate to Settings → API Tokens
|
|
223
|
+
3. Generate a new API token
|
|
224
|
+
4. Copy the token and use it in your SDK configuration
|
|
225
|
+
|
|
226
|
+
### Backend API Endpoint
|
|
227
|
+
|
|
228
|
+
The SDK expects your backend to provide a `/api/sip-credentials` endpoint that:
|
|
229
|
+
- Accepts `Authorization: Bearer <token>` header
|
|
230
|
+
- Returns SIP credentials in this format:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"ws_url": "wss://cell.usedora.com:8089/ws",
|
|
235
|
+
"sip_uri": "sip:101@64.227.10.164",
|
|
236
|
+
"password": "your-password",
|
|
237
|
+
"extensions": [
|
|
238
|
+
{ "extension": "101", "displayName": "Main Line" }
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Phone Number Formatting
|
|
244
|
+
|
|
245
|
+
The SDK automatically handles Nigerian phone number formatting:
|
|
246
|
+
|
|
247
|
+
- `08012345678` → `sip:2348012345678@domain`
|
|
248
|
+
- `2348012345678` → `sip:2348012345678@domain`
|
|
249
|
+
- `101` (extension) → `sip:101@domain`
|
|
250
|
+
|
|
251
|
+
## Error Handling
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
import { AuthenticationError, CallError, ConnectionError } from '@dora-cell/sdk';
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
await sdk.initialize();
|
|
258
|
+
} catch (error) {
|
|
259
|
+
if (error instanceof AuthenticationError) {
|
|
260
|
+
console.error('Authentication failed:', error.message);
|
|
261
|
+
} else if (error instanceof ConnectionError) {
|
|
262
|
+
console.error('Connection failed:', error.message);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Examples
|
|
268
|
+
|
|
269
|
+
See the `/examples` directory for complete working examples:
|
|
270
|
+
- `vanilla-js/` - Pure JavaScript implementation
|
|
271
|
+
- `react-app/` - React application
|
|
272
|
+
- `nextjs-app/` - Next.js application
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Core TypeScript type definitions for Dora Cell SDK
|
|
5
|
+
*/
|
|
6
|
+
interface ApiTokenAuth {
|
|
7
|
+
type: 'api-token';
|
|
8
|
+
apiToken: string;
|
|
9
|
+
apiBaseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
interface DirectCredentialsAuth {
|
|
12
|
+
type: 'direct';
|
|
13
|
+
sipUri: string;
|
|
14
|
+
password: string;
|
|
15
|
+
wsUrl: string;
|
|
16
|
+
}
|
|
17
|
+
type AuthConfig = ApiTokenAuth | DirectCredentialsAuth;
|
|
18
|
+
interface DoraCellConfig {
|
|
19
|
+
auth: AuthConfig;
|
|
20
|
+
sipServer?: string;
|
|
21
|
+
turnServers?: RTCIceServer[];
|
|
22
|
+
debug?: boolean;
|
|
23
|
+
autoSelectExtension?: boolean;
|
|
24
|
+
}
|
|
25
|
+
interface SipCredentials {
|
|
26
|
+
wsUrl: string;
|
|
27
|
+
sipUri: string;
|
|
28
|
+
password: string;
|
|
29
|
+
sipDomain?: string;
|
|
30
|
+
extensions?: Extension[];
|
|
31
|
+
expiresIn?: number;
|
|
32
|
+
}
|
|
33
|
+
interface Extension {
|
|
34
|
+
extension: string;
|
|
35
|
+
displayName?: string;
|
|
36
|
+
isPrimary?: boolean;
|
|
37
|
+
}
|
|
38
|
+
type CallStatus = 'idle' | 'connecting' | 'ringing' | 'ongoing' | 'ended';
|
|
39
|
+
type CallDirection = 'inbound' | 'outbound';
|
|
40
|
+
interface CallOptions {
|
|
41
|
+
extension?: string;
|
|
42
|
+
mediaConstraints?: MediaStreamConstraints;
|
|
43
|
+
}
|
|
44
|
+
interface Call {
|
|
45
|
+
id: string;
|
|
46
|
+
status: CallStatus;
|
|
47
|
+
direction: CallDirection;
|
|
48
|
+
remoteNumber: string;
|
|
49
|
+
localExtension: string;
|
|
50
|
+
duration: number;
|
|
51
|
+
startTime?: number;
|
|
52
|
+
endTime?: number;
|
|
53
|
+
mute(): void;
|
|
54
|
+
unmute(): void;
|
|
55
|
+
hangup(): void;
|
|
56
|
+
isMuted(): boolean;
|
|
57
|
+
}
|
|
58
|
+
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
|
|
59
|
+
interface ConnectionState {
|
|
60
|
+
status: ConnectionStatus;
|
|
61
|
+
extension?: string;
|
|
62
|
+
error?: string;
|
|
63
|
+
}
|
|
64
|
+
type DoraCellEventMap = {
|
|
65
|
+
'connection:status': (state: ConnectionState) => void;
|
|
66
|
+
'call:incoming': (call: Call) => void;
|
|
67
|
+
'call:outgoing': (call: Call) => void;
|
|
68
|
+
'call:ringing': (call: Call) => void;
|
|
69
|
+
'call:connected': (call: Call) => void;
|
|
70
|
+
'call:ended': (call: Call, reason?: string) => void;
|
|
71
|
+
'call:failed': (call: Call, error: string) => void;
|
|
72
|
+
'error': (error: Error) => void;
|
|
73
|
+
};
|
|
74
|
+
type DoraCellEvent = keyof DoraCellEventMap;
|
|
75
|
+
declare class DoraCellError extends Error {
|
|
76
|
+
code?: string | undefined;
|
|
77
|
+
details?: any | undefined;
|
|
78
|
+
constructor(message: string, code?: string | undefined, details?: any | undefined);
|
|
79
|
+
}
|
|
80
|
+
declare class AuthenticationError extends DoraCellError {
|
|
81
|
+
constructor(message: string, details?: any);
|
|
82
|
+
}
|
|
83
|
+
declare class CallError extends DoraCellError {
|
|
84
|
+
constructor(message: string, details?: any);
|
|
85
|
+
}
|
|
86
|
+
declare class ConnectionError extends DoraCellError {
|
|
87
|
+
constructor(message: string, details?: any);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Dora Cell SDK - Main entry point
|
|
92
|
+
* Framework-agnostic VoIP calling SDK using JsSIP
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
declare class DoraCell {
|
|
96
|
+
private config;
|
|
97
|
+
private events;
|
|
98
|
+
private authProvider;
|
|
99
|
+
private credentials;
|
|
100
|
+
private ua;
|
|
101
|
+
private callManager;
|
|
102
|
+
private connectionStatus;
|
|
103
|
+
private retryCount;
|
|
104
|
+
private maxRetries;
|
|
105
|
+
constructor(config: DoraCellConfig);
|
|
106
|
+
/**
|
|
107
|
+
* Initialize the SDK - authenticate and connect to SIP server
|
|
108
|
+
*/
|
|
109
|
+
initialize(): Promise<void>;
|
|
110
|
+
private initializeUserAgent;
|
|
111
|
+
private setupUserAgentHandlers;
|
|
112
|
+
private initializeCallManager;
|
|
113
|
+
/**
|
|
114
|
+
* Make an outbound call
|
|
115
|
+
*/
|
|
116
|
+
call(phoneNumber: string, options?: CallOptions): Promise<Call>;
|
|
117
|
+
/**
|
|
118
|
+
* Answer an incoming call
|
|
119
|
+
*/
|
|
120
|
+
answerCall(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Hangup the current call
|
|
123
|
+
*/
|
|
124
|
+
hangup(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Get current call
|
|
127
|
+
*/
|
|
128
|
+
getCurrentCall(): Call | null;
|
|
129
|
+
/**
|
|
130
|
+
* Get connection status
|
|
131
|
+
*/
|
|
132
|
+
getStatus(): ConnectionStatus;
|
|
133
|
+
/**
|
|
134
|
+
* Get available extensions
|
|
135
|
+
*/
|
|
136
|
+
getExtensions(): string[];
|
|
137
|
+
/**
|
|
138
|
+
* Event listener management
|
|
139
|
+
*/
|
|
140
|
+
on<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
141
|
+
off<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
142
|
+
once<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
143
|
+
/**
|
|
144
|
+
* Cleanup and destroy the SDK instance
|
|
145
|
+
*/
|
|
146
|
+
destroy(): void;
|
|
147
|
+
private emitConnectionStatus;
|
|
148
|
+
private emitError;
|
|
149
|
+
private getDefaultTurnServers;
|
|
150
|
+
private getDisplayName;
|
|
151
|
+
private generateInstanceId;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Call Manager - Handles individual call sessions
|
|
156
|
+
* Extracted and refactored from JsSIPProvider.tsx
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
declare class CallSession implements Call {
|
|
160
|
+
id: string;
|
|
161
|
+
status: CallStatus;
|
|
162
|
+
direction: CallDirection;
|
|
163
|
+
remoteNumber: string;
|
|
164
|
+
localExtension: string;
|
|
165
|
+
duration: number;
|
|
166
|
+
startTime?: number;
|
|
167
|
+
endTime?: number;
|
|
168
|
+
private session;
|
|
169
|
+
private _isMuted;
|
|
170
|
+
private remoteStreamValue;
|
|
171
|
+
private durationInterval?;
|
|
172
|
+
private events;
|
|
173
|
+
constructor(session: any, direction: CallDirection, remoteNumber: string, localExtension: string, events: EventEmitter);
|
|
174
|
+
private generateCallId;
|
|
175
|
+
private setupSessionHandlers;
|
|
176
|
+
private handleCallEnd;
|
|
177
|
+
private startDurationTimer;
|
|
178
|
+
private stopDurationTimer;
|
|
179
|
+
mute(): void;
|
|
180
|
+
unmute(): void;
|
|
181
|
+
hangup(): void;
|
|
182
|
+
isMuted(): boolean;
|
|
183
|
+
getRemoteStream(): MediaStream | null;
|
|
184
|
+
getFormattedDuration(): string;
|
|
185
|
+
destroy(): void;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Phone number formatting utilities
|
|
190
|
+
* Extracted from JsSIPProvider.tsx
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Format a phone number to SIP URI format
|
|
194
|
+
* Handles Nigerian numbers, international format, and local extensions
|
|
195
|
+
*/
|
|
196
|
+
declare function formatPhoneToSIP(phone: string, sipDomain: string): string;
|
|
197
|
+
/**
|
|
198
|
+
* Normalize a phone number to E.164 format
|
|
199
|
+
*/
|
|
200
|
+
declare function normalizePhoneNumber(phone: string, countryCode?: string): string;
|
|
201
|
+
/**
|
|
202
|
+
* Extract extension/number from SIP URI
|
|
203
|
+
*/
|
|
204
|
+
declare function extractNumberFromSipUri(sipUri: string): string;
|
|
205
|
+
/**
|
|
206
|
+
* Validate phone number format
|
|
207
|
+
*/
|
|
208
|
+
declare function isValidPhoneNumber(phone: string, minLength?: number): boolean;
|
|
209
|
+
|
|
210
|
+
export { type ApiTokenAuth, type AuthConfig, AuthenticationError, type Call, type CallDirection, CallError, type CallOptions, CallSession, type CallStatus, ConnectionError, type ConnectionState, type ConnectionStatus, type DirectCredentialsAuth, DoraCell, type DoraCellConfig, DoraCellError, type DoraCellEvent, type DoraCellEventMap, type Extension, type SipCredentials, DoraCell as default, extractNumberFromSipUri, formatPhoneToSIP, isValidPhoneNumber, normalizePhoneNumber };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Core TypeScript type definitions for Dora Cell SDK
|
|
5
|
+
*/
|
|
6
|
+
interface ApiTokenAuth {
|
|
7
|
+
type: 'api-token';
|
|
8
|
+
apiToken: string;
|
|
9
|
+
apiBaseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
interface DirectCredentialsAuth {
|
|
12
|
+
type: 'direct';
|
|
13
|
+
sipUri: string;
|
|
14
|
+
password: string;
|
|
15
|
+
wsUrl: string;
|
|
16
|
+
}
|
|
17
|
+
type AuthConfig = ApiTokenAuth | DirectCredentialsAuth;
|
|
18
|
+
interface DoraCellConfig {
|
|
19
|
+
auth: AuthConfig;
|
|
20
|
+
sipServer?: string;
|
|
21
|
+
turnServers?: RTCIceServer[];
|
|
22
|
+
debug?: boolean;
|
|
23
|
+
autoSelectExtension?: boolean;
|
|
24
|
+
}
|
|
25
|
+
interface SipCredentials {
|
|
26
|
+
wsUrl: string;
|
|
27
|
+
sipUri: string;
|
|
28
|
+
password: string;
|
|
29
|
+
sipDomain?: string;
|
|
30
|
+
extensions?: Extension[];
|
|
31
|
+
expiresIn?: number;
|
|
32
|
+
}
|
|
33
|
+
interface Extension {
|
|
34
|
+
extension: string;
|
|
35
|
+
displayName?: string;
|
|
36
|
+
isPrimary?: boolean;
|
|
37
|
+
}
|
|
38
|
+
type CallStatus = 'idle' | 'connecting' | 'ringing' | 'ongoing' | 'ended';
|
|
39
|
+
type CallDirection = 'inbound' | 'outbound';
|
|
40
|
+
interface CallOptions {
|
|
41
|
+
extension?: string;
|
|
42
|
+
mediaConstraints?: MediaStreamConstraints;
|
|
43
|
+
}
|
|
44
|
+
interface Call {
|
|
45
|
+
id: string;
|
|
46
|
+
status: CallStatus;
|
|
47
|
+
direction: CallDirection;
|
|
48
|
+
remoteNumber: string;
|
|
49
|
+
localExtension: string;
|
|
50
|
+
duration: number;
|
|
51
|
+
startTime?: number;
|
|
52
|
+
endTime?: number;
|
|
53
|
+
mute(): void;
|
|
54
|
+
unmute(): void;
|
|
55
|
+
hangup(): void;
|
|
56
|
+
isMuted(): boolean;
|
|
57
|
+
}
|
|
58
|
+
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
|
|
59
|
+
interface ConnectionState {
|
|
60
|
+
status: ConnectionStatus;
|
|
61
|
+
extension?: string;
|
|
62
|
+
error?: string;
|
|
63
|
+
}
|
|
64
|
+
type DoraCellEventMap = {
|
|
65
|
+
'connection:status': (state: ConnectionState) => void;
|
|
66
|
+
'call:incoming': (call: Call) => void;
|
|
67
|
+
'call:outgoing': (call: Call) => void;
|
|
68
|
+
'call:ringing': (call: Call) => void;
|
|
69
|
+
'call:connected': (call: Call) => void;
|
|
70
|
+
'call:ended': (call: Call, reason?: string) => void;
|
|
71
|
+
'call:failed': (call: Call, error: string) => void;
|
|
72
|
+
'error': (error: Error) => void;
|
|
73
|
+
};
|
|
74
|
+
type DoraCellEvent = keyof DoraCellEventMap;
|
|
75
|
+
declare class DoraCellError extends Error {
|
|
76
|
+
code?: string | undefined;
|
|
77
|
+
details?: any | undefined;
|
|
78
|
+
constructor(message: string, code?: string | undefined, details?: any | undefined);
|
|
79
|
+
}
|
|
80
|
+
declare class AuthenticationError extends DoraCellError {
|
|
81
|
+
constructor(message: string, details?: any);
|
|
82
|
+
}
|
|
83
|
+
declare class CallError extends DoraCellError {
|
|
84
|
+
constructor(message: string, details?: any);
|
|
85
|
+
}
|
|
86
|
+
declare class ConnectionError extends DoraCellError {
|
|
87
|
+
constructor(message: string, details?: any);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Dora Cell SDK - Main entry point
|
|
92
|
+
* Framework-agnostic VoIP calling SDK using JsSIP
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
declare class DoraCell {
|
|
96
|
+
private config;
|
|
97
|
+
private events;
|
|
98
|
+
private authProvider;
|
|
99
|
+
private credentials;
|
|
100
|
+
private ua;
|
|
101
|
+
private callManager;
|
|
102
|
+
private connectionStatus;
|
|
103
|
+
private retryCount;
|
|
104
|
+
private maxRetries;
|
|
105
|
+
constructor(config: DoraCellConfig);
|
|
106
|
+
/**
|
|
107
|
+
* Initialize the SDK - authenticate and connect to SIP server
|
|
108
|
+
*/
|
|
109
|
+
initialize(): Promise<void>;
|
|
110
|
+
private initializeUserAgent;
|
|
111
|
+
private setupUserAgentHandlers;
|
|
112
|
+
private initializeCallManager;
|
|
113
|
+
/**
|
|
114
|
+
* Make an outbound call
|
|
115
|
+
*/
|
|
116
|
+
call(phoneNumber: string, options?: CallOptions): Promise<Call>;
|
|
117
|
+
/**
|
|
118
|
+
* Answer an incoming call
|
|
119
|
+
*/
|
|
120
|
+
answerCall(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Hangup the current call
|
|
123
|
+
*/
|
|
124
|
+
hangup(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Get current call
|
|
127
|
+
*/
|
|
128
|
+
getCurrentCall(): Call | null;
|
|
129
|
+
/**
|
|
130
|
+
* Get connection status
|
|
131
|
+
*/
|
|
132
|
+
getStatus(): ConnectionStatus;
|
|
133
|
+
/**
|
|
134
|
+
* Get available extensions
|
|
135
|
+
*/
|
|
136
|
+
getExtensions(): string[];
|
|
137
|
+
/**
|
|
138
|
+
* Event listener management
|
|
139
|
+
*/
|
|
140
|
+
on<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
141
|
+
off<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
142
|
+
once<K extends DoraCellEvent>(event: K, handler: DoraCellEventMap[K]): void;
|
|
143
|
+
/**
|
|
144
|
+
* Cleanup and destroy the SDK instance
|
|
145
|
+
*/
|
|
146
|
+
destroy(): void;
|
|
147
|
+
private emitConnectionStatus;
|
|
148
|
+
private emitError;
|
|
149
|
+
private getDefaultTurnServers;
|
|
150
|
+
private getDisplayName;
|
|
151
|
+
private generateInstanceId;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Call Manager - Handles individual call sessions
|
|
156
|
+
* Extracted and refactored from JsSIPProvider.tsx
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
declare class CallSession implements Call {
|
|
160
|
+
id: string;
|
|
161
|
+
status: CallStatus;
|
|
162
|
+
direction: CallDirection;
|
|
163
|
+
remoteNumber: string;
|
|
164
|
+
localExtension: string;
|
|
165
|
+
duration: number;
|
|
166
|
+
startTime?: number;
|
|
167
|
+
endTime?: number;
|
|
168
|
+
private session;
|
|
169
|
+
private _isMuted;
|
|
170
|
+
private remoteStreamValue;
|
|
171
|
+
private durationInterval?;
|
|
172
|
+
private events;
|
|
173
|
+
constructor(session: any, direction: CallDirection, remoteNumber: string, localExtension: string, events: EventEmitter);
|
|
174
|
+
private generateCallId;
|
|
175
|
+
private setupSessionHandlers;
|
|
176
|
+
private handleCallEnd;
|
|
177
|
+
private startDurationTimer;
|
|
178
|
+
private stopDurationTimer;
|
|
179
|
+
mute(): void;
|
|
180
|
+
unmute(): void;
|
|
181
|
+
hangup(): void;
|
|
182
|
+
isMuted(): boolean;
|
|
183
|
+
getRemoteStream(): MediaStream | null;
|
|
184
|
+
getFormattedDuration(): string;
|
|
185
|
+
destroy(): void;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Phone number formatting utilities
|
|
190
|
+
* Extracted from JsSIPProvider.tsx
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Format a phone number to SIP URI format
|
|
194
|
+
* Handles Nigerian numbers, international format, and local extensions
|
|
195
|
+
*/
|
|
196
|
+
declare function formatPhoneToSIP(phone: string, sipDomain: string): string;
|
|
197
|
+
/**
|
|
198
|
+
* Normalize a phone number to E.164 format
|
|
199
|
+
*/
|
|
200
|
+
declare function normalizePhoneNumber(phone: string, countryCode?: string): string;
|
|
201
|
+
/**
|
|
202
|
+
* Extract extension/number from SIP URI
|
|
203
|
+
*/
|
|
204
|
+
declare function extractNumberFromSipUri(sipUri: string): string;
|
|
205
|
+
/**
|
|
206
|
+
* Validate phone number format
|
|
207
|
+
*/
|
|
208
|
+
declare function isValidPhoneNumber(phone: string, minLength?: number): boolean;
|
|
209
|
+
|
|
210
|
+
export { type ApiTokenAuth, type AuthConfig, AuthenticationError, type Call, type CallDirection, CallError, type CallOptions, CallSession, type CallStatus, ConnectionError, type ConnectionState, type ConnectionStatus, type DirectCredentialsAuth, DoraCell, type DoraCellConfig, DoraCellError, type DoraCellEvent, type DoraCellEventMap, type Extension, type SipCredentials, DoraCell as default, extractNumberFromSipUri, formatPhoneToSIP, isValidPhoneNumber, normalizePhoneNumber };
|