@ruut/voice-sdk/browser provides a WebRTC softphone device that registers an agent extension over SIP/WSS and handles incoming and outgoing calls in the browser.1npm install @ruut/voice-sdk
RuutDevice:1234567891011121314import { RuutDevice } from "@ruut/voice-sdk/browser"; const device = new RuutDevice({ credentials: { username: creds.username, password: creds.password, domain: creds.domain, wsUrl: creds.ws_url, }, autoPresence: false, // Keep the account Auth Token on your server. audioElement: document.querySelector("audio"), logLevel: "info", // "debug" to trace SIP traceSip: false, });
agentExtensions.credentials() result also contains restAuthToken, restAccountSid, and restBaseUrl. Do not return the full object to a browser. Return only the SIP credentials and WebSocket URL to an authenticated user. Set autoPresence: false and update presence through your own authenticated server endpoint; the default auto-presence implementation requires REST credentials in the browser.12345678910111213device.on("registered", () => setStatus("online")); device.on("unregistered", () => setStatus("offline")); device.on("stateChanged", (state, prev) => console.log(state, prev)); device.on("transportDisconnected", (err) => console.warn("WSS dropped", err)); device.on("error", (err) => console.error(err)); device.on("incoming", (call) => { // Show an Accept / Reject UI, then: call.accept(); // or call.reject(); }); device.on("callStarted", (call) => showCall(call)); device.on("callEnded", (call) => clearCall(call));
1234await device.start(); // connects + registers await device.register(); // re-register await device.unregister(); // unregister (idle) await device.stop(); // teardown
123const call = await device.connect("+2348000000001"); // E.164 number const call2 = await device.connect("agent-1001"); // extension const call3 = await device.connect("sip:trunk@pbx.example.com"); // SIP URI
RuutCall:1234567call.accept(); call.reject(); call.disconnect(); // hang up call.mute(); / call.unmute(); call.hold(); / call.unhold(); call.sendDigits("123#"); call.transfer("+2348000000003");
1234device.on("incoming", async (call) => { const accepted = await call.accept(); if (accepted) console.log("Call connected"); });
client.agentExtensions.update(sid, { status: "online" }) so ring-group routing includes them.