@dora-cell/sdk
v0.1.1-beta.26
Published
VoIP calling SDK for Dora Cell - Make calls from any JavaScript application
Maintainers
Readme
@dora-cell/sdk
VoIP calling SDK for Dora Cell - Make calls from any JavaScript application without logging into the Dora Cell web app.
Features
✅ Framework-agnostic - Works with vanilla JS, React, Vue, Angular, etc.
✅ TypeScript support - Full type definitions included
✅ WebRTC-based - High-quality voice calls using JsSIP
✅ Event-driven API - Listen to call state changes
✅ API token authentication - Secure, no user login required
✅ Auto-extension selection - Automatically selects first available extension
✅ React bindings - Optional React hooks for easy integration
Installation
npm install @dora-cell/sdk jssip
# or
yarn add @dora-cell/sdk jssip
# or
pnpm add @dora-cell/sdk jssipFor React projects:
npm install @dora-cell/sdk @dora-cell/sdk-react jssipQuick Start
Vanilla JavaScript
import { DoraCell } from '@dora-cell/sdk';
// Initialize SDK with API token
const sdk = new DoraCell({
auth: {
type: 'api-token',
apiToken: 'your-api-token-here',
apiBaseUrl: 'https://api.usedora.com'
},
debug: true // Enable console logging
});
// Initialize connection
await sdk.initialize();
// Listen for connection status
sdk.on('connection:status', (state) => {
console.log('Connection status:', state.status);
});
// Listen for call events
sdk.on('call:connected', (call) => {
console.log('Call connected:', call.remoteNumber);
});
sdk.on('call:ended', (call, reason) => {
console.log('Call ended:', reason);
});
// Make a call
const call = await sdk.call('+2348012345678');
// Mute/unmute
call.mute();
call.unmute();
// Hang up
call.hangup();React
import { DoraCellProvider, useCall, useConnectionStatus } from '@dora-cell/sdk-react';
function App() {
return (
<DoraCellProvider
config={{
auth: {
type: 'api-token',
apiToken: 'your-api-token-here',
apiBaseUrl: 'https://api.usedora.com'
}
}}
>
<CallInterface />
</DoraCellProvider>
);
}
function CallInterface() {
const { call, hangup, toggleMute, callStatus, callDuration, isMuted } = useCall();
const { isConnected } = useConnectionStatus();
const [number, setNumber] = useState('');
const handleCall = async () => {
try {
await call(number);
} catch (error) {
console.error('Call failed:', error);
}
};
return (
<div>
<p>Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
<input
value={number}
onChange={(e) => setNumber(e.target.value)}
placeholder="Enter phone number"
/>
<button onClick={handleCall} disabled={!isConnected}>
Call
</button>
{callStatus === 'ongoing' && (
<>
<p>Duration: {callDuration}</p>
<button onClick={toggleMute}>{isMuted ? 'Unmute' : 'Mute'}</button>
<button onClick={hangup}>Hang Up</button>
</>
)}
</div>
);
}API Reference
DoraCell Class
Constructor
new DoraCell(config: DoraCellConfig)Config options:
auth- Authentication configuration (required)type: 'api-token'- Use API token authenticationapiToken: string- Your Dora Cell API tokenapiBaseUrl?: string- API base URL (optional)
turnServers?: RTCIceServer[]- Custom TURN/STUN serversdebug?: boolean- Enable debug loggingautoSelectExtension?: boolean- Auto-select first extension (default: true)
Methods
initialize(): Promise<void>
Initialize the SDK and connect to SIP server.
call(phoneNumber: string, options?: CallOptions): Promise<Call>
Make an outbound call.
Options:
extension?: string- Specific extension to use for this call
hangup(): void
Hang up the current call.
answerCall(): void
Answer an incoming call.
getCurrentCall(): Call | null
Get the current active call.
getStatus(): ConnectionStatus
Get current connection status.
getExtensions(): string[]
Get list of available extensions.
on(event, handler): void
Register event listener.
off(event, handler): void
Remove event listener.
destroy(): void
Cleanup and destroy SDK instance.
Events
sdk.on('connection:status', (state: ConnectionState) => {});
sdk.on('call:incoming', (call: Call) => {});
sdk.on('call:outgoing', (call: Call) => {});
sdk.on('call:ringing', (call: Call) => {});
sdk.on('call:connected', (call: Call) => {});
sdk.on('call:ended', (call: Call, reason?: string) => {});
sdk.on('call:failed', (call: Call, error: string) => {});
sdk.on('error', (error: Error) => {});Call Object
interface Call {
id: string;
status: CallStatus;
direction: 'inbound' | 'outbound';
remoteNumber: string;
localExtension: string;
duration: number;
mute(): void;
unmute(): void;
hangup(): void;
isMuted(): boolean;
}Authentication
Getting an API Token
- Log in to your Dora Cell dashboard
- Navigate to Settings → API Tokens
- Generate a new API token
- Copy the token and use it in your SDK configuration
Backend API Endpoint
The SDK expects your backend to provide a /api/sip-credentials endpoint that:
- Accepts
Authorization: Bearer <token>header - Returns SIP credentials in this format:
{
"ws_url": "wss://cell.usedora.com:8089/ws",
"sip_uri": "sip:[email protected]",
"password": "your-password",
"extensions": [
{ "extension": "101", "displayName": "Main Line" }
]
}Phone Number Formatting
The SDK automatically handles Nigerian phone number formatting:
08012345678→sip:2348012345678@domain2348012345678→sip:2348012345678@domain101(extension) →sip:101@domain
Error Handling
import { AuthenticationError, CallError, ConnectionError } from '@dora-cell/sdk';
try {
await sdk.initialize();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
} else if (error instanceof ConnectionError) {
console.error('Connection failed:', error.message);
}
}Examples
See the /examples directory for complete working examples:
vanilla-js/- Pure JavaScript implementationreact-app/- React applicationnextjs-app/- Next.js application
License
MIT
