@dora-cell/sdk
v4.2.9
Published
VoIP calling SDK for Dora Cell - Make calls from any JavaScript application
Maintainers
Readme
@dora-cell/sdk
Framework-agnostic VoIP calling SDK for Dora Cell. Use it to register a browser SIP user, place and receive WebRTC calls, switch caller IDs, and read wallet balance from any JavaScript or TypeScript application.
Features
- Framework-agnostic JavaScript API for React, Vue, Angular, vanilla JS, and other browser apps
- TypeScript types included
- WebRTC voice calls powered by
sip.js - Authentication using user login credentials (
type: "login"for Agent and Admin accounts) - Automatic SIP provisioning for both Agent and Admin accounts (
/agent/...and/...routes) - Persistent browser cookie sessions (
dora_cell_auth_token,dora_cell_user_type) with automatic reconnect recovery across page reloads - Comprehensive session cleanup and backend sign-out via
sdk.logout() - Event-driven call and connection state
- DID/extension discovery and active extension switching
- Wallet balance lookup
- Configurable TURN/STUN servers
Installation
npm install @dora-cell/sdk
# or
yarn add @dora-cell/sdk
# or
pnpm add @dora-cell/sdksip.js is installed as a dependency of this package.
Quick Start
1. Create a SDK instance
The SDK authenticates using User Login Credentials (for Agent or Admin accounts).
You can log in as either an Agent (using email and password) or an Admin (using username and password). The SDK automatically handles token persistence across page reloads in document.cookie.
1. Agent Account Login (userType: "agent" — requires email):
import { DoraCell } from "@dora-cell/sdk";
const sdk = new DoraCell({
auth: {
type: "login",
userType: "agent",
email: "[email protected]", // Agent accounts must provide email
password: "secure_password",
},
environment: "production",
});2. Admin Account Login (userType: "admin" — requires username):
import { DoraCell } from "@dora-cell/sdk";
const sdk = new DoraCell({
auth: {
type: "login",
userType: "admin",
username: "admin_user", // Admin accounts must provide username instead of email
password: "secure_password",
},
environment: "production",
});Note on Cookie Persistence: When a user logs in, the SDK automatically saves
dora_cell_auth_tokenanddora_cell_user_typeindocument.cookie(7-day duration,SameSite=Lax). On subsequent page refreshes, initializing the SDK withtype: "login"will automatically recover the stored session token and connect without requiringusername, orpasswordagain untilsdk.logout()is called.
Use environment: "dev" | "staging" | "production" | "local" for the built-in API URLs, or pass apiBaseUrl when you need an explicit API endpoint.
2. Listen for registration and initialize
sdk.on("connection:status", ({ status, extension, error }) => {
console.log("Connection status:", status, extension, error);
});
await sdk.initialize();initialize() authenticates your credentials (or restores from cookies), fetches wallet and extension data, provisions SIP credentials for the first available extension, starts the SIP.js user agent, and waits for registration.
3. Make a call
const call = await sdk.call("+2348012345678", {
metadata: { customerId: "cus_123" },
});
call.mute();
call.unmute();
call.hangup();4. Receive a call
sdk.on("call:incoming", async (call) => {
console.log("Incoming call from:", call.remoteNumber);
await sdk.answerCall();
});
sdk.on("call:stream", (call, stream) => {
const audio = document.querySelector<HTMLAudioElement>("audio#remote-audio");
if (audio) audio.srcObject = stream;
});5. Logging Out
To disconnect the SIP User Agent, call the backend logout endpoint (/agent/logout or /logout), clear stored browser cookies (dora_cell_auth_token and dora_cell_user_type), and wipe session data:
await sdk.logout();API Reference
new DoraCell(config)
// Example for Agent login (uses email):
const agentSdk = new DoraCell({
auth: {
type: "login",
userType: "agent",
email: "[email protected]",
password: "password",
},
environment: "production",
});
// Example for Admin login (uses username):
const adminSdk = new DoraCell({
auth: {
type: "login",
userType: "admin",
username: "admin_user",
password: "password",
},
environment: "production",
});Config Options
auth(required): Authentication credentials configuration.type: Must be"login".userType: Must be"agent"or"admin".email: Agent login email (required ifuserType: "agent"and no cookie exists).username: Admin login username (required ifuserType: "admin"and no cookie exists).password: Account password (required if no cookie exists).
environment:"dev" | "staging" | "production" | "local". Defaults to production URLs.apiBaseUrl: Override the API URL directly.turnServers: CustomRTCIceServer[]for WebRTC ICE negotiation. Defaults to Google STUN servers.debug: Enable SDK logs.autoSelectExtension: Defaults totrue.
Methods
initialize(): Promise<void>: Authenticate, provision SIP, connect, and register.call(phoneNumber, options?): Promise<Call>: Start an outbound call.optionsmay includeextension,mediaConstraints, andmetadata.answerCall(): Promise<void>: Answer the current inbound call.hangup(): void: End the current active call.logout(): Promise<void>: Destroy active SIP connection, call backend logout route (/agent/logoutor/logout), clear browser cookies (dora_cell_auth_token,dora_cell_user_type), and reset state.getCurrentCall(): Call | null: Return the active or latest call object.getCallStatus(): CallStatus: Return the current call status.getCallError(): string | null: Return the latest call failure message.getStatus(): ConnectionStatus: Return the current connection status.getWallet(): Promise<{ balance: number; currency: string }>: Fetch the wallet balance for the authenticated account.fetchExtensions(): Promise<any[]>: Fetch available DID numbers/extensions.getExtensions(): any[]: Return the extensions currently stored by the SDK.setExtension(extension): Promise<void>: Re-provision SIP and register with a different extension.isAuthenticated(): boolean: Return whether credentials are currently available.on(event, handler): void: Subscribe to an SDK event.off(event, handler): void: Remove an SDK event listener.once(event, handler): void: Subscribe to one event emission.destroy(): Promise<void>: Unregister, stop the user agent, remove listeners, and clean up (without calling backend logout).
Call Object
Returned by call() and emitted by call events.
id: Unique call ID.status:"idle" | "connecting" | "ringing" | "ongoing" | "ended" | "terminating".direction:"inbound" | "outbound".remoteNumber: The other party's number.duration: Call duration in seconds.startTime/endTime: Optional call timestamps.mute()/unmute(): Control microphone.isMuted(): Return current mute state.hangup(): End this call.getRemoteStream(): Return the remoteMediaStream, when available.
Events
| Event | Description | Handler data |
| ------------------- | -------------------------------------- | -------------------------------- |
| connection:status | SIP connection or registration changed | { status, extension?, error? } |
| call:incoming | New incoming call | Call |
| call:outgoing | Outbound call started | Call |
| call:ringing | Call is ringing | Call |
| call:connected | Call connected | Call |
| call:ended | Call ended | Call, reason? |
| call:failed | Call failed | Call, error |
| call:stream | Remote audio stream is available | Call, MediaStream |
| error | SDK-level error | Error |
Browser Requirements
- WebRTC-capable modern browser.
- HTTPS or
localhostfor microphone and WebRTC access. - Microphone permission granted by the user.
For best results, use a Chromium-based browser such as Chrome, Edge, Brave, or Opera.
License
MIT
