@dora-cell/sdk 0.1.1-beta.9 → 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 +103 -209
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +23026 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23028 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -8
package/README.md
CHANGED
|
@@ -8,124 +8,100 @@ VoIP calling SDK for Dora Cell - Make calls from any JavaScript application with
|
|
|
8
8
|
✅ **TypeScript support** - Full type definitions included
|
|
9
9
|
✅ **WebRTC-based** - High-quality voice calls using JsSIP
|
|
10
10
|
✅ **Event-driven API** - Listen to call state changes
|
|
11
|
-
✅ **
|
|
11
|
+
✅ **Multiple Auth Modes** - Support for API Token and Direct Extension login
|
|
12
12
|
✅ **Auto-extension selection** - Automatically selects first available extension
|
|
13
|
-
✅ **React bindings** - Optional React hooks for easy integration
|
|
13
|
+
✅ **React bindings** - Optional React hooks for easy integration
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npm install @dora-cell/sdk
|
|
18
|
+
npm install @dora-cell/sdk
|
|
19
19
|
# or
|
|
20
|
-
yarn add @dora-cell/sdk
|
|
20
|
+
yarn add @dora-cell/sdk
|
|
21
21
|
# or
|
|
22
|
-
pnpm add @dora-cell/sdk
|
|
22
|
+
pnpm add @dora-cell/sdk
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
npm install @dora-cell/sdk @dora-cell/sdk-react jssip
|
|
28
|
-
```
|
|
25
|
+
> [!NOTE]
|
|
26
|
+
> `jssip` is a dependency of this SDK and will be installed automatically. You only need to install it manually if you want to use a specific version.
|
|
29
27
|
|
|
30
28
|
## Quick Start
|
|
31
29
|
|
|
32
|
-
###
|
|
30
|
+
### 1. Initialize the SDK
|
|
31
|
+
|
|
32
|
+
Choose your preferred authentication method:
|
|
33
|
+
|
|
34
|
+
#### Option A: Extension Authentication (Recommended for Testing)
|
|
35
|
+
|
|
36
|
+
Best for quick testing or internal apps where default credentials are used.
|
|
33
37
|
|
|
34
38
|
```javascript
|
|
35
|
-
import { DoraCell } from
|
|
39
|
+
import { DoraCell } from "@dora-cell/sdk";
|
|
36
40
|
|
|
37
|
-
// Initialize SDK with API token
|
|
38
41
|
const sdk = new DoraCell({
|
|
39
42
|
auth: {
|
|
40
|
-
type:
|
|
41
|
-
|
|
42
|
-
apiBaseUrl: 'https://api.usedora.com'
|
|
43
|
+
type: "extension",
|
|
44
|
+
extension: "1001",
|
|
43
45
|
},
|
|
44
|
-
debug: true // Enable console logging
|
|
45
46
|
});
|
|
47
|
+
```
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
await sdk.initialize();
|
|
49
|
+
#### Option B: API Token Authentication (Production)
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
sdk.on('connection:status', (state) => {
|
|
52
|
-
console.log('Connection status:', state.status);
|
|
53
|
-
});
|
|
51
|
+
Securely fetch credentials from your backend.
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
sdk
|
|
57
|
-
|
|
53
|
+
```javascript
|
|
54
|
+
const sdk = new DoraCell({
|
|
55
|
+
auth: {
|
|
56
|
+
type: "api-token",
|
|
57
|
+
apiToken: "your-api-token-here",
|
|
58
|
+
// apiBaseUrl: "https://api.yourdomain.com", // Optional override
|
|
59
|
+
},
|
|
58
60
|
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Option C: Direct Credentials (Advanced)
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
If you already have SIP credentials.
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
const sdk = new DoraCell({
|
|
69
|
+
auth: {
|
|
70
|
+
type: "direct",
|
|
71
|
+
sipUri: "sip:1001@voice.example.com",
|
|
72
|
+
password: "your-password",
|
|
73
|
+
wsUrl: "wss://voice.example.com:8089/ws",
|
|
74
|
+
},
|
|
62
75
|
});
|
|
76
|
+
```
|
|
63
77
|
|
|
64
|
-
|
|
65
|
-
const call = await sdk.call('+2348012345678');
|
|
78
|
+
### 2. Connect and Register
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
```javascript
|
|
81
|
+
// Listen for registration
|
|
82
|
+
sdk.on("connection:status", (state) => {
|
|
83
|
+
if (state.status === "registered") {
|
|
84
|
+
console.log("SIP Ready to make calls!");
|
|
85
|
+
}
|
|
86
|
+
});
|
|
70
87
|
|
|
71
|
-
//
|
|
72
|
-
|
|
88
|
+
// Initialize connection
|
|
89
|
+
await sdk.initialize();
|
|
73
90
|
```
|
|
74
91
|
|
|
75
|
-
###
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
}
|
|
92
|
+
### 3. Make a Call
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
try {
|
|
96
|
+
const call = await sdk.call("+2348012345678");
|
|
97
|
+
|
|
98
|
+
// Mute/unmute
|
|
99
|
+
call.mute();
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
);
|
|
101
|
+
// Hang up
|
|
102
|
+
call.hangup();
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error("Call failed:", error.message);
|
|
129
105
|
}
|
|
130
106
|
```
|
|
131
107
|
|
|
@@ -133,143 +109,61 @@ function CallInterface() {
|
|
|
133
109
|
|
|
134
110
|
### DoraCell Class
|
|
135
111
|
|
|
136
|
-
####
|
|
112
|
+
#### `new DoraCell(config)`
|
|
137
113
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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)
|
|
114
|
+
- `config.auth` (Required)
|
|
115
|
+
- `type: 'extension' | 'api-token'`
|
|
116
|
+
- `extension: string` (for extension type)
|
|
117
|
+
- `apiToken: string` (for api-token type)
|
|
118
|
+
- `config.debug?: boolean` - Enable JsSIP debug logs (default: false)
|
|
150
119
|
|
|
151
120
|
#### Methods
|
|
152
121
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- `
|
|
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
|
-
```
|
|
122
|
+
- `initialize(): Promise<void>` - Connect to the SIP server and register the extension.
|
|
123
|
+
- `call(number, options?): Promise<Call>` - Initiate an outbound call.
|
|
124
|
+
- `options.extension`: Specify a specific extension to call from.
|
|
125
|
+
- `options.mediaConstraints`: Custom WebRTC media constraints.
|
|
126
|
+
- `answerCall(): void` - Answer a pending incoming call.
|
|
127
|
+
- `hangup(): void` - End the current active call.
|
|
128
|
+
- `on(event, handler): void` - Listen for events (see below).
|
|
129
|
+
- `destroy(): void` - Cleanup and disconnect.
|
|
198
130
|
|
|
199
131
|
### Call Object
|
|
200
132
|
|
|
201
|
-
|
|
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
|
|
133
|
+
Returned by `call()` and emitted in events.
|
|
244
134
|
|
|
245
|
-
|
|
135
|
+
- `id`: Unique call ID.
|
|
136
|
+
- `status`: `'idle' | 'connecting' | 'ringing' | 'ongoing' | 'ended'`.
|
|
137
|
+
- `direction`: `'inbound' | 'outbound'`.
|
|
138
|
+
- `remoteNumber`: The other party's number.
|
|
139
|
+
- `duration`: Call duration in seconds.
|
|
140
|
+
- `mute()` / `unmute()`: Control microphone.
|
|
141
|
+
- `hangup()`: End this specific call.
|
|
142
|
+
- `getRemoteStream()`: Returns the WebRTC `MediaStream` for audio playback.
|
|
246
143
|
|
|
247
|
-
|
|
248
|
-
- `2348012345678` → `sip:2348012345678@domain`
|
|
249
|
-
- `101` (extension) → `sip:101@domain`
|
|
144
|
+
## Events
|
|
250
145
|
|
|
251
|
-
|
|
146
|
+
| Event | Description | Data |
|
|
147
|
+
| ------------------- | ------------------------------ | ---------------------------------- |
|
|
148
|
+
| `connection:status` | SIP registration status change | `{ status: string, error?: string }` |
|
|
149
|
+
| `call:incoming` | New incoming call detected | `Call` object |
|
|
150
|
+
| `call:outgoing` | New outbound call started | `Call` object |
|
|
151
|
+
| `call:ringing` | Remote party is ringing | `Call` object |
|
|
152
|
+
| `call:connected` | Call answered and connected | `Call` object |
|
|
153
|
+
| `call:ended` | Call terminated | `Call` object, `reason: string` |
|
|
154
|
+
| `call:failed` | Call failed to connect | `Call` object, `error: string` |
|
|
155
|
+
| `error` | General SDK error | `Error` object |
|
|
252
156
|
|
|
253
|
-
|
|
254
|
-
import { AuthenticationError, CallError, ConnectionError } from '@dora-cell/sdk';
|
|
157
|
+
## Browser Requirements
|
|
255
158
|
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
```
|
|
159
|
+
- **HTTPS**: WebRTC and microphone access require a secure context (HTTPS or localhost).
|
|
160
|
+
- **Environment**: Modern browsers with WebRTC support (Chrome, Firefox, Safari, Edge).
|
|
266
161
|
|
|
267
162
|
## Examples
|
|
268
163
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
- `
|
|
272
|
-
- `nextjs-app/` - Next.js application
|
|
164
|
+
Check the [`examples/`](../../examples) directory in the main repository:
|
|
165
|
+
|
|
166
|
+
- `next-js-demo/` - Complete Next.js implementation with React components
|
|
273
167
|
|
|
274
168
|
## License
|
|
275
169
|
|
package/dist/index.d.mts
CHANGED
|
@@ -60,6 +60,7 @@ interface Call {
|
|
|
60
60
|
unmute(): void;
|
|
61
61
|
hangup(): void;
|
|
62
62
|
isMuted(): boolean;
|
|
63
|
+
getRemoteStream(): MediaStream | null;
|
|
63
64
|
}
|
|
64
65
|
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
|
|
65
66
|
interface ConnectionState {
|
|
@@ -113,6 +114,7 @@ declare class DoraCell {
|
|
|
113
114
|
* Initialize the SDK - authenticate and connect to SIP server
|
|
114
115
|
*/
|
|
115
116
|
initialize(): Promise<void>;
|
|
117
|
+
private waitForRegistration;
|
|
116
118
|
private initializeUserAgent;
|
|
117
119
|
private setupUserAgentHandlers;
|
|
118
120
|
private initializeCallManager;
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ interface Call {
|
|
|
60
60
|
unmute(): void;
|
|
61
61
|
hangup(): void;
|
|
62
62
|
isMuted(): boolean;
|
|
63
|
+
getRemoteStream(): MediaStream | null;
|
|
63
64
|
}
|
|
64
65
|
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
|
|
65
66
|
interface ConnectionState {
|
|
@@ -113,6 +114,7 @@ declare class DoraCell {
|
|
|
113
114
|
* Initialize the SDK - authenticate and connect to SIP server
|
|
114
115
|
*/
|
|
115
116
|
initialize(): Promise<void>;
|
|
117
|
+
private waitForRegistration;
|
|
116
118
|
private initializeUserAgent;
|
|
117
119
|
private setupUserAgentHandlers;
|
|
118
120
|
private initializeCallManager;
|