@dora-cell/sdk 0.1.1-beta.26 → 0.1.1-beta.30
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 +68 -214
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +982 -508
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +982 -508
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@ 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
|
|
|
@@ -22,110 +22,68 @@ yarn add @dora-cell/sdk jssip
|
|
|
22
22
|
pnpm add @dora-cell/sdk jssip
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
For React projects:
|
|
26
|
-
```bash
|
|
27
|
-
npm install @dora-cell/sdk @dora-cell/sdk-react jssip
|
|
28
|
-
```
|
|
29
|
-
|
|
30
25
|
## Quick Start
|
|
31
26
|
|
|
32
|
-
###
|
|
27
|
+
### 1. Initialize the SDK
|
|
28
|
+
|
|
29
|
+
Choose your preferred authentication method:
|
|
30
|
+
|
|
31
|
+
#### Option A: Extension Authentication (Recommended for Testing)
|
|
32
|
+
|
|
33
|
+
Best for quick testing or internal apps where default credentials are used.
|
|
33
34
|
|
|
34
35
|
```javascript
|
|
35
|
-
import { DoraCell } from
|
|
36
|
+
import { DoraCell } from "@dora-cell/sdk";
|
|
36
37
|
|
|
37
|
-
// Initialize SDK with API token
|
|
38
38
|
const sdk = new DoraCell({
|
|
39
39
|
auth: {
|
|
40
|
-
type:
|
|
41
|
-
|
|
42
|
-
apiBaseUrl: 'https://api.usedora.com'
|
|
40
|
+
type: "extension",
|
|
41
|
+
extension: "1001",
|
|
43
42
|
},
|
|
44
|
-
debug: true // Enable console logging
|
|
45
43
|
});
|
|
44
|
+
```
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
await sdk.initialize();
|
|
46
|
+
#### Option B: API Token Authentication (Production)
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
sdk.on('connection:status', (state) => {
|
|
52
|
-
console.log('Connection status:', state.status);
|
|
53
|
-
});
|
|
48
|
+
Securely fetch credentials from your backend.
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
sdk
|
|
57
|
-
|
|
50
|
+
```javascript
|
|
51
|
+
const sdk = new DoraCell({
|
|
52
|
+
auth: {
|
|
53
|
+
type: "api-token",
|
|
54
|
+
apiToken: "your-api-token-here",
|
|
55
|
+
apiBaseUrl: "https://api.yourdomain.com",
|
|
56
|
+
},
|
|
58
57
|
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Connect and Register
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
```javascript
|
|
63
|
+
// Listen for registration
|
|
64
|
+
sdk.on("connection:status", (state) => {
|
|
65
|
+
if (state.status === "registered") {
|
|
66
|
+
console.log("SIP Ready to make calls!");
|
|
67
|
+
}
|
|
62
68
|
});
|
|
63
69
|
|
|
64
|
-
//
|
|
65
|
-
|
|
70
|
+
// Initialize connection
|
|
71
|
+
await sdk.initialize();
|
|
72
|
+
```
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
call.mute();
|
|
69
|
-
call.unmute();
|
|
74
|
+
### 3. Make a Call
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
```javascript
|
|
77
|
+
try {
|
|
78
|
+
const call = await sdk.call("+2348012345678");
|
|
74
79
|
|
|
75
|
-
|
|
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
|
-
}
|
|
80
|
+
// Mute/unmute
|
|
81
|
+
call.mute();
|
|
95
82
|
|
|
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
|
-
);
|
|
83
|
+
// Hang up
|
|
84
|
+
call.hangup();
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error("Call failed:", error.message);
|
|
129
87
|
}
|
|
130
88
|
```
|
|
131
89
|
|
|
@@ -133,143 +91,39 @@ function CallInterface() {
|
|
|
133
91
|
|
|
134
92
|
### DoraCell Class
|
|
135
93
|
|
|
136
|
-
####
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
new DoraCell(config: DoraCellConfig)
|
|
140
|
-
```
|
|
94
|
+
#### `new DoraCell(config)`
|
|
141
95
|
|
|
142
|
-
|
|
143
|
-
- `
|
|
144
|
-
- `
|
|
145
|
-
- `apiToken: string` -
|
|
146
|
-
|
|
147
|
-
- `turnServers?: RTCIceServer[]` - Custom TURN/STUN servers
|
|
148
|
-
- `debug?: boolean` - Enable debug logging
|
|
149
|
-
- `autoSelectExtension?: boolean` - Auto-select first extension (default: true)
|
|
96
|
+
- `config.auth` (Required)
|
|
97
|
+
- `type: 'extension' | 'api-token'`
|
|
98
|
+
- `extension: string` (for extension type)
|
|
99
|
+
- `apiToken: string` (for api-token type)
|
|
100
|
+
- `config.debug?: boolean` - Enable JsSIP debug logs (default: false)
|
|
150
101
|
|
|
151
102
|
#### Methods
|
|
152
103
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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.
|
|
104
|
+
- `initialize(): Promise<void>` - Connect to the SIP server.
|
|
105
|
+
- `call(number, options?): Promise<Call>` - Initiate an outbound call.
|
|
106
|
+
- `answerCall(): void` - Answer a pending incoming call.
|
|
107
|
+
- `hangup(): void` - End the current active call.
|
|
108
|
+
- `on(event, handler): void` - Listen for events (e.g., `call:incoming`, `connection:status`).
|
|
109
|
+
- `destroy(): void` - Cleanup and disconnect.
|
|
167
110
|
|
|
168
|
-
|
|
169
|
-
Get the current active call.
|
|
111
|
+
## Events
|
|
170
112
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
```
|
|
113
|
+
| Event | Description | Data |
|
|
114
|
+
| ------------------- | ------------------------------ | ------------------------------------ |
|
|
115
|
+
| `connection:status` | SIP registration status change | `{ status: string, error?: string }` |
|
|
116
|
+
| `call:incoming` | New incoming call detected | `Call` object |
|
|
117
|
+
| `call:outgoing` | New outbound call started | `Call` object |
|
|
118
|
+
| `call:connected` | Call answered and connected | `Call` object |
|
|
119
|
+
| `call:ended` | Call terminated | `Call` object, `reason: string` |
|
|
120
|
+
| `error` | General SDK error | `Error` object |
|
|
266
121
|
|
|
267
122
|
## Examples
|
|
268
123
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
- `
|
|
272
|
-
- `nextjs-app/` - Next.js application
|
|
124
|
+
Check the [`examples/`](../../examples) directory in the main repository:
|
|
125
|
+
|
|
126
|
+
- `next-js-demo/` - Complete Next.js implementation with React components
|
|
273
127
|
|
|
274
128
|
## License
|
|
275
129
|
|
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;
|