@knmholdings/phone-sdk v0.1.18
KNM Phone SDK (React)
A reusable React-based SIP softphone SDK for web applications, built with SIP.js, React, TypeScript, and Tailwind CSS.
This SDK provides a floating button and a modal interface for making and receiving SIP calls via WebRTC, designed to be easily embeddable into existing web pages or modern JavaScript applications.
Features:
- SIP Registration (Username/Password Authentication)
- Outgoing Calls via Dialpad
- Incoming Call Notifications (In-Modal and OS-level Web Notifications)
- Call Transfer (Blind Transfer)
- Mute/Unhold Call Functionality
- Call History & Recording Playback (requires backend API integration)
- Basic In-Call UI (Caller ID, Timer, Hangup)
- Configurable Server Settings & Customer Info Fetching
- Style isolation using Shadow DOM
- Built with modern web technologies: React, TypeScript, SIP.js, Tailwind CSS.
- Real-time audio stream monitoring via
phone:localAudioandphone:remoteAudioevents
Installation
You can integrate the KNM Phone SDK into your project in two main ways:
1. Using npm/pnpm/yarn (Recommended for Modern JavaScript/TypeScript Projects)
This method is best for projects using module bundlers like Vite, Next.js, Create React App, etc. It allows for better tree-shaking and version management.
# Using npm
npm install @knmholdings/phone-sdk
# Using pnpm
pnpm add @knmholdings/phone-sdk
# Using yarn
yarn add @knmholdings/phone-sdkSee the ES Module (ESM) Integration section below for usage details.
2. Using UMD Build via CDN (For simple HTML pages)
This method is suitable for static HTML pages or projects not using a JavaScript module bundler.
See the UMD / CDN Integration section below for usage details.
ES Module (ESM) Integration (Recommended for Frameworks)
This is the preferred method for integrating with modern JavaScript frameworks like Next.js, React (Vite/CRA), Vue, Angular, etc.
Install the package (as shown in the Installation section above).
Import and Initialize in your application: It's crucial to initialize the SDK in a client-side environment, typically within a
useEffecthook in a React component. For Next.js, ensure this is done within a Client Component ("use client";).// Example: In a React component (e.g., your main App component or a specific layout) import React, { useEffect } from 'react'; import KnmPhoneSDK, { type PhoneSDKConfig, // Import types for configuration type CustomerInfo // Import types for data structures } from '@knmholdings/phone-sdk'; function MyAppComponent() { useEffect(() => { // Ensure this runs only once and on the client side if (typeof window !== "undefined") { console.log('Initializing KNM Phone SDK (ESM)...'); const myGetCustomerInfo = async (callerId: string): Promise<CustomerInfo | null> => { console.log("Host App: Fetching info for caller:", callerId); // Replace with your actual API call or logic if (callerId === '1003') { return { name: 'ESM Customer', avatarUrl: 'https://via.placeholder.com/100/000/fff?text=EC' }; } return null; }; const sdkConfig: PhoneSDKConfig = { // --- REQUIRED --- sipHost: 'your-sip-provider.com', // *** REPLACE THIS *** // --- OPTIONAL BUT RECOMMENDED FOR SHADOW DOM CSS --- // The SDK needs to fetch its CSS for Shadow DOM. // Point to the style.css file on a CDN like unpkg. // For production, pin to a specific SDK version for stability. cssBuildPath: 'https://unpkg.com/@knmholdings/phone-sdk/dist/style.css', // --- OTHER OPTIONAL CONFIG --- webSocketUrl: 'wss://your-sip-provider.com:8089/ws', renderButton: true, getCustomerInfo: myGetCustomerInfo, onCallStop: () => { console.log('Call stopped'); }, onCallModalOpenChange: (isOpen) => { console.log('Call modal open state changed:', isOpen); }, // containerId: 'my-custom-phone-container' }; KnmPhoneSDK.init(sdkConfig); } // Cleanup function when the component unmounts return () => { if (typeof window !== "undefined" && window.KnmPhoneSDK) { console.log('Unmounting KNM Phone SDK (ESM)...'); KnmPhoneSDK.unmount(); } }; }, []); // Empty dependency array ensures init runs only once on mount const openPhone = () => KnmPhoneSDK.open(); const closePhone = () => KnmPhoneSDK.close(); // Get call ID const callId = KnmPhoneSDK.getCallId(); return ( <div> <h1>My Application (ESM Integration)</h1> <button onClick={openPhone}>Open Phone</button> <button onClick={closePhone}>Close Phone</button> {/* Optional: <div id="my-custom-phone-container"></div> */} {/* Rest of your app */} </div> ); } export default MyAppComponent;- Replace placeholders like
'your-sip-provider.com'. - CSS Path: The
cssBuildPathshould point to thestyle.cssfrom the SDK version you installed, typically hosted on unpkg. For production, it's highly recommended to use a specific version in the URL (e.g.,https://unpkg.com/@knmholdings/phone-sdk@0.1.5/dist/style.css) instead of relying on@latest.
- Replace placeholders like
UMD / CDN Integration
This method is suitable for static HTML pages or projects not using a JavaScript module bundler.
Include Scripts in HTML: Add the following to the
<head>of your HTML file:<head> <!-- ... other head elements ... --> <title>My Page with KNM Phone SDK</title> <!-- 1. React & ReactDOM Dependencies (from CDN) --> <script crossorigin src="https://unpkg.com/react@18.2.0/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js" ></script> <!-- 2. SDK's UMD JavaScript Build (from unpkg) --> <!-- This will fetch the latest version. Pin to a specific version for production. --> <script src="https://unpkg.com/@knmholdings/phone-sdk/dist/knm-phone.umd.js"></script> <!-- 3. SDK's CSS is fetched internally by the SDK when using Shadow DOM --> <!-- No separate <link> tag is needed here if cssBuildPath is configured correctly during init --> </head>Initialize the SDK: Add a
<script>block to initialize:<body> <!-- ... your page content ... --> <script> document.addEventListener('DOMContentLoaded', () => { if (window.KnmPhoneSDK) { window.KnmPhoneSDK.init({ sipHost: 'your-sip-provider.com', // *** REPLACE THIS *** // For production, pin to a specific SDK version for stability. cssBuildPath: 'https://unpkg.com/@knmholdings/phone-sdk/dist/style.css', // ... other config ... }); } }); </script> </body>- Replace placeholders and consider pinning to a specific SDK version in the unpkg URLs for production stability (e.g.,
https://unpkg.com/@knmholdings/phone-sdk@0.1.5/dist/...).
- Replace placeholders and consider pinning to a specific SDK version in the unpkg URLs for production stability (e.g.,
Configuration
The SDK is configured via an options object passed to KnmPhoneSDK.init().
sipHost: string(Required): SIP server domain or IP.webSocketUrl?: string: Full WebSocket URL. Defaults towss://{sipHost}:8089/ws.cssBuildPath?: string: Absolute URL to the SDK'sstyle.cssfile. Required if using Shadow DOM (default for style isolation) to allow the SDK to inject its styles. Example:'https://unpkg.com/@knmholdings/phone-sdk/dist/style.css'.renderButton?: boolean: Show the floating phone button. Defaults totrue.buttonColor?: string: Floating button background color (hex code).buttonTextColor?: string: Floating button icon color (hex code).containerId?: string: ID of an HTML element to render the SDK into. Defaults to a new div inbody.getCustomerInfo?: (callerId: string) => Promise<CustomerInfo | null | undefined>: Callback to fetch info for the incoming caller. See Typing & API Reference forCustomerInfotype.onCallStop?: (params: CallStopParams) => void: Callback triggered when a call ends.onCallModalOpenChange?: (isOpen: boolean) => void: Callback triggered when the call modal opens or closes.
Events & Callbacks
phone:localAudio & phone:remoteAudio
These events provide access to live audio streams:
window.addEventListener('phone:remoteAudio', (event) => {
const stream = event.detail.stream; // Remote audio MediaStream
// Visualize or process stream
});
window.addEventListener('phone:localAudio', (event) => {
const stream = event.detail.stream; // Local microphone MediaStream
// Monitor input levels
});onCallStop Callback
Triggered when a call ends:
// In config:
{
onCallStop: () => {
// Handle call cleanup
console.log(`Call ended. Clean up the process.`);
};
}API
The SDK exposes methods on the imported KnmPhoneSDK object (for ESM) or the global window.KnmPhoneSDK object (for UMD):
init(config: PhoneSDKConfig): void: Initializes the SDK.open(): void: Opens the phone modal.close(): void: Closes the phone modal.unmount(): void: Unmounts the SDK and cleans up resources.callAgentFirst(customerNumber: string): Promise<boolean>: Initiates a two-legged call (agent first, then customer). Requires backend API integration.
Typing & API Reference (for TypeScript Users)
The SDK includes TypeScript declaration files for a better development experience.
Installation (for Type Support): If using the UMD build, you can still install the package as a dev dependency to get type information in your editor:
npm install --save-dev @knmholdings/phone-sdkIf using ESM, types are automatically available after installation.
Using Types: Import types in your TypeScript files or use JSDoc for type hinting in JavaScript.
TypeScript Example (when SDK is installed):
import KnmPhoneSDK, { type PhoneSDKConfig, type CustomerInfo } from '@knmholdings/phone-sdk'; const sdkConfig: PhoneSDKConfig = { /* ... */ }; // KnmPhoneSDK.init(sdkConfig); // If using ESM import // For UMD, you might declare window.KnmPhoneSDK typeKey Exported Types:
PhoneSDKConfig: Interface for theinit()configuration object.CustomerInfo: Interface for the object expected fromgetCustomerInfo.
Refer to the
dist/types/PhoneSDK.d.tsfile within the installed package for full type details.
Styling
The SDK uses Tailwind CSS and renders its UI inside a Shadow DOM for style isolation. The necessary CSS is loaded from the style.css file (via the cssBuildPath configuration) and injected into the Shadow DOM.
Development (Contributing)
- Clone:
git clone <repository-url> - Install:
pnpm install - Configure Dev SIP: Modify
src/main.tsxwith test SIP details. - Run Dev Server:
pnpm dev - Build Library:
pnpm build(outputs todist/)- To publish: Increment version in
package.json, create a GitHub Release (triggers npm publish workflow).
- To publish: Increment version in
License
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago