ahs-cti 0.0.2-beta.9 β†’ 1.0.0-beta.10

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 CHANGED
@@ -1,12 +1,12 @@
1
1
  <div align="center">
2
2
 
3
- ## Call Control SDK
3
+ ## AHS CTI SDK
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/call-control-sdk.svg?color=blue&style=for-the-badge)](https://www.npmjs.com/package/call-control-sdk)
6
- [![npm downloads](https://img.shields.io/npm/dm/call-control-sdk.svg?color=green&style=for-the-badge)](https://www.npmjs.com/package/call-control-sdk)
7
- [![bundle size](https://img.shields.io/bundlephobia/minzip/call-control-sdk?color=orange&style=for-the-badge)](https://bundlephobia.com/package/call-control-sdk)
5
+ [![npm version](https://img.shields.io/npm/v/ahs-cti.svg?color=blue&style=for-the-badge)](https://www.npmjs.com/package/ahs-cti)
6
+ [![npm downloads](https://img.shields.io/npm/dm/ahs-cti.svg?color=green&style=for-the-badge)](https://www.npmjs.com/package/ahs-cti)
7
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/ahs-cti?color=orange&style=for-the-badge)](https://bundlephobia.com/package/ahs-cti)
8
8
 
9
- **A powerful, lightweight SDK for real-time call management**
9
+ **A powerful, lightweight SDK for real-time call management with dynamic configuration and permission-based access control**
10
10
 
11
11
  **πŸ”‘AUTHORIZED ACCESS REQUIRED - API Key & Tenant IDπŸ”‘**
12
12
 
@@ -16,6 +16,7 @@
16
16
 
17
17
  - **API Key Authentication** - Secure access through authorized API keys
18
18
  - **Tenant ID Management** - Multi-tenant support with isolated access
19
+ - **Permission-Based Access Control** - Entitlement-driven feature enablement
19
20
  - **Cross-Platform Support** - Use across web, mobile, desktop, and server platforms
20
21
  - **Usage Monitoring** - Real-time tracking and compliance monitoring
21
22
  - **Flexible Deployment** - Deploy on authorized platforms with proper credentials
@@ -36,12 +37,17 @@
36
37
  - [1️⃣ Initialize the SDK](#1️⃣-initialize-the-sdk)
37
38
  - [2️⃣ Add Call Control Panel](#2️⃣-add-call-control-panel)
38
39
  - [3️⃣ Use Call Management Hooks](#3️⃣-use-call-management-hooks)
39
- - [πŸ”§ Configuration Options](#-configuration-options)
40
+ - [βš™οΈ Dynamic Configuration](#️-dynamic-configuration)
41
+ - [πŸ”§ SDK Config](#-sdk-config)
42
+ - [🌐 URL Config](#-url-config)
43
+ - [πŸ” Permission-Based Controls](#-permission-based-controls)
44
+ - [πŸ“Š Configuration Merge Priority](#-configuration-merge-priority)
40
45
  - [πŸ“š API Reference](#-api-reference)
41
46
  - [πŸ”§ Core Functions](#-core-functions)
42
47
  - [πŸͺ React Hooks](#-react-hooks)
48
+ - [πŸ”’ Permissions System](#-permissions-system)
49
+ - [πŸ”Œ WebSocket Events](#-websocket-events)
43
50
  - [πŸ“¦ Data Types](#-data-types)
44
- - [πŸŽ› Control Features](#-control-features)
45
51
  - [🌍 Browser Support](#-browser-support)
46
52
  - [πŸ“„ License](#-license)
47
53
 
@@ -51,31 +57,40 @@
51
57
 
52
58
  ### 🎯 **Complete Call Control**
53
59
 
60
+ - Inbound and outbound call management
54
61
  - Hold/Resume calls
55
62
  - Mute/Unmute functionality
56
- - Agent status management
57
- - End call with disposition
63
+ - Blind, Attended, and Warm call transfers
64
+ - Multi-line conference calling (up to 5 lines)
65
+ - Agent status management (Ready, Break, Wrapup)
66
+ - End call with disposition tracking
67
+ - Ringtone support for incoming calls
68
+
69
+ ### βš™οΈ **Dynamic Configuration**
70
+
71
+ - **Three-layer config merging** - Backend defaults, permission-based controls, and explicit SDK config
72
+ - **Permission-based feature toggling** - Controls auto-disabled based on entitlements
73
+ - **Runtime URL configuration** - All endpoints dynamically resolved from config
74
+ - **Customizable UI** - Material-UI SxProps for button styling
58
75
 
59
76
  ### πŸ’Ύ **Smart State Management**
60
77
 
61
78
  - Real-time call timer
62
- - Persistent state storage
79
+ - Persistent state storage via `@react-solutions/vault`
63
80
  - Singleton state pattern
64
- - Cross-component sync
65
- - TypeScript support
81
+ - Cross-component sync via observer pattern
82
+ - Full TypeScript support
66
83
 
67
84
  ## πŸ“¦ Installation
68
85
 
69
86
  ```bash
70
- npm install call-control-sdk
87
+ npm install ahs-cti
71
88
  ```
72
89
 
73
- ### πŸ”‘ Required Dependencies
74
-
75
- Make sure you have these peer dependencies installed:
90
+ ### πŸ”‘ Required Peer Dependencies
76
91
 
77
92
  ```bash
78
- npm install react react-dom axios @mui/material @mui/icons-material @emotion/react @emotion/styled
93
+ npm install react react-dom axios @mui/material @mui/icons-material @emotion/react @emotion/styled @react-solutions/vault
79
94
  ```
80
95
 
81
96
  ---
@@ -84,27 +99,40 @@ npm install react react-dom axios @mui/material @mui/icons-material @emotion/rea
84
99
 
85
100
  ### 1️⃣ **Initialize the SDK**
86
101
 
87
- First, initialize the SDK at the root of your application:
102
+ Initialize the SDK at the root of your application with the required credentials and optional dynamic configuration:
88
103
 
89
104
  ```tsx
90
105
  import { useEffect } from "react";
91
- import { initSDK } from "call-control-sdk";
106
+ import { initSDK } from "ahs-cti";
92
107
 
93
108
  function App() {
94
- useEffect(() => {
95
- try {
96
- initSDK({
97
- apiKey: "your-api-key",
98
- tenantId: "your-tenant-id",
99
- agentId: "your-agent-id",
100
- });
101
- console.log("βœ… SDK initialized successfully");
102
- } catch (error) {
103
- console.error("❌ SDK initialization failed:", error);
104
- }
105
- }, []);
106
-
107
- return <YourAppContent />;
109
+ useEffect(() => {
110
+ const initialize = async () => {
111
+ try {
112
+ await initSDK({
113
+ // Required credentials
114
+ apiKey: "your-api-key",
115
+ tenantId: "your-tenant-id",
116
+ agentId: "your-agent-id",
117
+
118
+ // Optional: URL configuration for API endpoints
119
+ urlConfig: {
120
+ },
121
+
122
+ // Optional: Feature configuration overrides
123
+ sdkConfig: {
124
+ },
125
+ });
126
+ console.log("βœ… SDK initialized successfully");
127
+ } catch (error) {
128
+ console.error("❌ SDK initialization failed:", error);
129
+ }
130
+ };
131
+
132
+ initialize();
133
+ }, []);
134
+
135
+ return <YourAppContent />;
108
136
  }
109
137
  ```
110
138
 
@@ -113,246 +141,271 @@ function App() {
113
141
  Drop in the draggable call control panel anywhere in your app:
114
142
 
115
143
  ```tsx
116
- import { CallControlPanel } from "call-control-sdk";
144
+ import { CallControlPanel } from "ahs-cti";
117
145
 
118
146
  export default function AgentDashboard() {
119
- const handleCallDataChange = (data) => {
120
- console.log("πŸ“ž Call data updated:", data);
121
- // Handle call data changes (mobileNumber, callReferenceId, agentLoginId)
122
- };
123
-
124
- return (
125
- <div>
126
- <h1>Agent Dashboard</h1>
127
- <CallControlPanel onDataChange={handleCallDataChange} />
128
- </div>
129
- );
147
+ const handleCallDataChange = (data) => {
148
+ console.log("πŸ“ž Call data updated:", data);
149
+ };
150
+
151
+ return (
152
+ <div>
153
+ <h1>Agent Dashboard</h1>
154
+ <CallControlPanel onDataChange={handleCallDataChange} />
155
+ </div>
156
+ );
130
157
  }
131
158
  ```
132
159
 
133
- #### πŸ“ž **Get Caller Data (Alternative to onDataChange)**
160
+ ### 3️⃣ **Use Call Management Hooks**
134
161
 
135
- The `useGetCallerData` hook is an **independent alternative** to the `CallControlPanel`'s `onDataChange` prop. It provides the same call data but can be used anywhere in your application without depending on the `CallControlPanel` component.
162
+ #### πŸ”΄ **Start a Call**
136
163
 
137
- **Key Differences:**
164
+ ```tsx
165
+ import { useClickToCall } from "ahs-cti";
138
166
 
139
- - πŸ”„ **onDataChange**: Requires `CallControlPanel` component, callback-based
140
- - 🎯 **useGetCallerData**: Independent hook, reactive, can be used anywhere
167
+ export default function CallButton() {
168
+ const { handleStartCall, isLoading, isSuccess, isError, error } =
169
+ useClickToCall();
170
+
171
+ const startCall = () => {
172
+ handleStartCall({ mobileNumber: "1234567890" });
173
+ };
174
+
175
+ return (
176
+ <button onClick={startCall} disabled={isLoading}>
177
+ {isLoading ? "πŸ”„ Calling..." : "πŸ“ž Start Call"}
178
+ </button>
179
+ );
180
+ }
181
+ ```
141
182
 
142
- **When to use each:**
183
+ #### πŸ”š **End a Call**
143
184
 
144
- - Use `onDataChange` when you need the call control UI and want to handle data changes
145
- - Use `useGetCallerData` when you only need call data without the control panel UI
185
+ ```tsx
186
+ import { useEndCall } from "ahs-cti";
146
187
 
147
- The `useGetCallerData` hook provides reactive access to current call data. It automatically updates when call status changes, new calls arrive, or call information is modified.
188
+ export default function EndCallButton() {
189
+ const { handleEndCall, isLoading } = useEndCall();
148
190
 
149
- ```tsx
150
- import { useGetCallerData } from "call-control-sdk";
191
+ const endCall = () => {
192
+ handleEndCall({ disposition: "RES" });
193
+ };
151
194
 
152
- export default function AgentDashboard() {
153
- const callerData = useGetCallerData();
154
-
155
- // Sample data structure returned:
156
- // {
157
- // "phone_number": "1234567890",
158
- // "status": "ONCALL",
159
- // "callReferenceId": "convox_call_id_123",
160
- // "agent_id": "agent001",
161
- // "process_id": "proc001",
162
- // "process_name": "Sales Process"
163
- // }
164
-
165
- return (
166
- <div>
167
- <h1>Current Call Information</h1>
168
- <p>Phone Number: {callerData.phone_number}</p>
169
- <p>Call Status: {callerData.status}</p>
170
- <p>Call Reference ID: {callerData.callReferenceId}</p>
171
- <p>Agent ID: {callerData.agent_id}</p>
172
- <p>Process: {callerData.process_name}</p>
173
- </div>
174
- );
195
+ return (
196
+ <button onClick={endCall} disabled={isLoading}>
197
+ {isLoading ? "πŸ”„ Ending..." : "πŸ”š End Call"}
198
+ </button>
199
+ );
175
200
  }
176
201
  ```
177
202
 
178
- **Example: Using useGetCallerData independently (without CallControlPanel)**
203
+ #### πŸšͺ **Agent Logout**
179
204
 
180
205
  ```tsx
181
- import { useGetCallerData } from "call-control-sdk";
206
+ import { useLogout } from "ahs-cti";
182
207
 
183
- // This component can be used anywhere, even without CallControlPanel
184
- export default function CallStatusWidget() {
185
- const callerData = useGetCallerData();
186
-
187
- return (
188
- <div className="call-status-widget">
189
- <h3>Current Call Status</h3>
190
- {callerData.status === "ONCALL" ?
191
- <div>
192
- <p>πŸ“ž Active Call: {callerData.phone_number}</p>
193
- <p>Agent: {callerData.agent_id}</p>
194
- <p>Process: {callerData.process_name}</p>
195
- </div>
196
- : <p>No active call</p>}
197
- </div>
198
- );
199
- }
208
+ export default function LogoutButton() {
209
+ const { logout, isLoading } = useLogout();
200
210
 
201
- // You can use this widget anywhere in your app
202
- export default function MainApp() {
203
- return (
204
- <div>
205
- <h1>My Application</h1>
206
- <CallStatusWidget /> {/* Independent component */}
207
- {/* No CallControlPanel needed here */}
208
- </div>
209
- );
211
+ return (
212
+ <button onClick={logout} disabled={isLoading}>
213
+ {isLoading ? "πŸ”„ Logging out..." : "πŸšͺ Logout"}
214
+ </button>
215
+ );
210
216
  }
211
217
  ```
212
218
 
213
- **Key Features:**
214
-
215
- - βœ… **Reactive Updates**: Automatically re-renders when call data changes
216
- - βœ… **Real-time Data**: Reflects current call state from WebSocket updates
217
- - βœ… **Type Safety**: Fully typed with TypeScript interfaces
218
- - βœ… **Complete Data**: Returns all available call information
219
- - βœ… **Independent**: Works without `CallControlPanel` component
219
+ #### πŸ“ž **Get Caller Data**
220
220
 
221
- **Returned Data Fields:**
221
+ The `useGetCallerData` hook provides reactive access to current call data independently of `CallControlPanel`:
222
222
 
223
- - `phone_number`: The phone number involved in the call
224
- - `status`: Current call status (ONCALL, RINGING, WRAPUP, etc.)
225
- - `callReferenceId`: Unique identifier for the call
226
- - `agent_id`: ID of the agent handling the call
227
- - `process_id`: Process identifier for the call
228
- - `process_name`: Name of the process handling the call
223
+ ```tsx
224
+ import { useGetCallerData } from "ahs-cti";
229
225
 
230
- ### 3️⃣ **Use Call Management Hooks**
226
+ export default function CallStatusWidget() {
227
+ const callerData = useGetCallerData();
228
+
229
+ return (
230
+ <div>
231
+ <h3>Current Call Status</h3>
232
+ {callerData.status === "ONCALL" ? (
233
+ <div>
234
+ <p>Active Call: {callerData.phone_number}</p>
235
+ <p>Agent: {callerData.agent_id}</p>
236
+ <p>Process: {callerData.process_name}</p>
237
+ <p>Queue: {callerData.queue_name}</p>
238
+ </div>
239
+ ) : (
240
+ <p>No active call</p>
241
+ )}
242
+ </div>
243
+ );
244
+ }
245
+ ```
231
246
 
232
- #### πŸ”΄ **Start a Call**
247
+ #### πŸ”„ **Subscribe to SDK State**
233
248
 
234
249
  ```tsx
235
- import { useClickToCall } from "call-control-sdk";
236
-
237
- export default function CallButton() {
238
- const { handleStartCall, isLoading, isSuccess, isError, error } = useClickToCall();
239
-
240
- const startCall = () => {
241
- handleStartCall({
242
- mobileNumber: "1234567890",
243
- });
244
- };
245
-
246
- return (
247
- <button
248
- onClick={startCall}
249
- disabled={isLoading}
250
- >
251
- {isLoading ? "πŸ”„ Calling..." : "πŸ“ž Start Call"}
252
- </button>
253
- );
250
+ import { useSDKState } from "ahs-cti";
251
+
252
+ export default function AgentStatusDisplay() {
253
+ const state = useSDKState();
254
+
255
+ return (
256
+ <div>
257
+ <p>Agent: {state.agentId}</p>
258
+ <p>Status: {state.agentStatus}</p>
259
+ <p>Initialized: {state.isInitialized ? "Yes" : "No"}</p>
260
+ <p>Hold: {state.hold ? "On Hold" : "Active"}</p>
261
+ <p>Mute: {state.mute ? "Muted" : "Unmuted"}</p>
262
+ </div>
263
+ );
254
264
  }
255
265
  ```
256
266
 
257
- #### πŸ”š **End a Call**
267
+ #### πŸ” **Get Authorization Token**
268
+
269
+ Retrieve the access token for external API calls:
258
270
 
259
271
  ```tsx
260
- import { useEndCall } from "call-control-sdk";
272
+ import { useGetAuthorizationToken } from "ahs-cti";
261
273
 
262
- export default function EndCallButton() {
263
- const { handleEndCall, isLoading, isSuccess, isError, error } = useEndCall();
264
-
265
- const endCall = () => {
266
- handleEndCall({
267
- disposition: "RES", // Call disposition
268
- });
269
- };
270
-
271
- return (
272
- <button
273
- onClick={endCall}
274
- disabled={isLoading}
275
- >
276
- {isLoading ? "πŸ”„ Ending..." : "πŸ”š End Call"}
277
- </button>
278
- );
274
+ export default function ExternalAPICall() {
275
+ const token = useGetAuthorizationToken();
276
+
277
+ const fetchData = async () => {
278
+ const response = await fetch("https://api.example.com/data", {
279
+ headers: { Authorization: `Bearer ${token}` },
280
+ });
281
+ // handle response
282
+ };
283
+
284
+ return <button onClick={fetchData}>Fetch External Data</button>;
279
285
  }
280
286
  ```
281
287
 
282
- #### πŸšͺ **Agent Logout**
288
+ ---
283
289
 
284
- ```tsx
285
- import { useLogout } from "call-control-sdk";
290
+ ## βš™οΈ Dynamic Configuration
291
+
292
+ The SDK supports a three-layer dynamic configuration system that determines which call control features are enabled.
293
+
294
+ ### πŸ”§ SDK Config
295
+
296
+ Feature toggle options passed via `sdkConfig` in `initSDK()`:
297
+
298
+ ### 🎨 **Configuration Options**
299
+
300
+ | Option | Type | Default | Description |
301
+ | --------------------------- | --------- | ------- | --------------------------------------- |
302
+ | `disableEndCallButton` | `boolean` | `false` | Disable the end call button |
303
+ | `disabledDialButton` | `boolean` | `false` | Disable the dial/outbound call button |
304
+ | `disableCallTransferButton` | `boolean` | `false` | Disable the call transfer button |
305
+ | `disableBlindTransfer` | `boolean` | `false` | Disable blind transfer option |
306
+ | `disableAttendedTransfer` | `boolean` | `false` | Disable attended transfer option |
307
+ | `disableWarmTransfer` | `boolean` | `false` | Disable warm transfer option |
308
+ | `disableConferenceButton` | `boolean` | `false` | Disable the conference call button |
309
+ | `disableHoldButton` | `boolean` | `false` | Disable the hold functionality |
310
+ | `disableMuteButton` | `boolean` | `false` | Disable the mute functionality |
311
+ | `disabledMoreOptionsButton` | `boolean` | `false` | Disable the more options menu |
312
+ | `disableSoftPhone` | `boolean` | `false` | Disable the embedded soft phone iframe |
313
+ | `isDraggable` | `boolean` | `true` | Enable/disable panel dragging |
314
+ | `enableSmsServices` | `boolean` | `false` | Enable SMS services |
315
+ | `enableQueueName` | `boolean` | `false` | Show queue name in call data |
316
+ | `enableRingtone` | `boolean` | `false` | Enable ringtone for incoming calls |
317
+ | `auto_wrapup_time` | `number` | - | Auto wrapup time in seconds |
318
+ | `break_time` | `number` | - | Break duration in seconds |
319
+ | `disabled` | `SxProps` | - | Custom MUI styles for disabled states |
320
+ | `enabled` | `SxProps` | - | Custom MUI styles for enabled states |
321
+ | `outlined` | `SxProps` | - | Custom MUI styles for outlined states |
322
+
323
+ ### 🌐 URL Config
324
+
325
+ All API endpoints are dynamically resolved from the URL configuration:
326
+
327
+ ```typescript
328
+ interface URLConfig {
329
+ id: string; // Configuration identifier
330
+ baseURL: string; // Main API base URL
331
+ coreBaseURL: string; // Core API URL for call control actions
332
+ webSocketURL: string; // WebSocket URL for real-time events
333
+ iframeURL: string; // Soft phone iframe URL
334
+ iframeAPIURL: string; // Iframe API endpoint
335
+ password: string; // Agent password for authentication
336
+ accessToken?: string; // Pre-provided access token (optional)
337
+ }
338
+ ```
286
339
 
287
- export default function LogoutButton() {
288
- const { logout, isLoading, isSuccess, isError, error } = useLogout();
289
-
290
- return (
291
- <button
292
- onClick={logout}
293
- disabled={isLoading}
294
- >
295
- {isLoading ? "πŸ”„ Logging out..." : "πŸšͺ Logout"}
296
- </button>
297
- );
340
+ If `baseURL` is not provided, the SDK falls back to `window.location.origin`.
341
+
342
+ ### πŸ” Permission-Based Controls
343
+
344
+ The SDK implements a **fail-closed** permission model. After authentication, the backend returns entitlements that automatically determine which controls are enabled:
345
+
346
+ ```typescript
347
+ // Entitlements structure from login response
348
+ {
349
+ calls: {
350
+ enabled: boolean,
351
+ items: [
352
+ { code: "call_inbound", enabled: boolean },
353
+ { code: "call_outbound", enabled: boolean }
354
+ ]
355
+ },
356
+ call_transfer: {
357
+ enabled: boolean,
358
+ items: [
359
+ { code: "call_transfer_blind", enabled: boolean },
360
+ { code: "call_transfer_attended", enabled: boolean },
361
+ { code: "call_transfer_warm", enabled: boolean }
362
+ ]
363
+ },
364
+ call_conference: {
365
+ enabled: boolean,
366
+ items: [
367
+ { code: "call_conference", enabled: boolean }
368
+ ]
369
+ }
298
370
  }
299
371
  ```
300
372
 
301
- ### πŸ” Authorization Token
373
+ If permissions have not been loaded, **all controls are disabled by default**.
302
374
 
303
- get Authorization token for external API call
375
+ You can use the exported `SDK_PERMISSIONS` constants to reference permission codes:
304
376
 
305
- ```tsx
306
- import { useGetAuthorizationToken } from "call-control-sdk";
377
+ ```typescript
378
+ import { SDK_PERMISSIONS } from "ahs-cti";
307
379
 
308
- export default function axios() {
309
- const token = useGetAuthorizationToken();
380
+ // Permission categories
381
+ SDK_PERMISSIONS.CALLS; // "calls"
382
+ SDK_PERMISSIONS.CALL_TRANSFER; // "call_transfer"
383
+ SDK_PERMISSIONS.CALL_CONFERENCE; // "call_conference"
310
384
 
311
- console.log(token);
312
- }
385
+ // Permission codes
386
+ SDK_PERMISSIONS.CALL_INBOUND; // "call_inbound"
387
+ SDK_PERMISSIONS.CALL_OUTBOUND; // "call_outbound"
388
+ SDK_PERMISSIONS.TRANSFER_BLIND; // "call_transfer_blind"
389
+ SDK_PERMISSIONS.TRANSFER_ATTENDED; // "call_transfer_attended"
390
+ SDK_PERMISSIONS.TRANSFER_WARM; // "call_transfer_warm"
391
+ SDK_PERMISSIONS.CONFERENCE; // "call_conference"
313
392
  ```
314
393
 
315
- ---
316
-
317
- ## πŸ”§ Configuration Options
394
+ ### πŸ“Š Configuration Merge Priority
318
395
 
319
- Customize the SDK behavior to fit your needs:
396
+ The SDK merges configuration from three sources (highest priority wins):
320
397
 
321
- ```tsx
322
- initSDK({
323
- // Required configuration
324
- apiKey: "your-api-key",
325
- tenantId: "your-tenant-id",
326
- agentId: "your-agent-id",
327
-
328
- // Optional customization
329
- disableEndCallButton: false, // Hide end call button
330
- disabledDialButton: false, // Hide dial button
331
- disableCallTransferButton: false, // Hide transfer button
332
- disableConferenceButton: false, // Hide conference button
333
- disableSoftPhone: false, // Hide soft phone iframe
334
- isDraggable: true, // Enable/disable dragging
335
-
336
- // Custom styling (Material-UI SxProps)
337
- disabled: { opacity: 0.5 }, // Disabled button styles
338
- enabled: { color: "primary" }, // Enabled button styles
339
- outlined: { border: "1px solid" }, // Outlined button styles
340
- });
398
+ ```
399
+ 1. Explicit sdkConfig (passed to initSDK) <- Highest priority
400
+ 2. Permission-based controls (from entitlements) <- Medium priority
401
+ 3. Backend callControls (from login response) <- Lowest priority
341
402
  ```
342
403
 
343
- ### 🎨 **Styling Options**
404
+ This means:
344
405
 
345
- | Option | Type | Default | Description |
346
- | --------------------------- | --------- | ------- | --------------------------------- |
347
- | `disableEndCallButton` | `boolean` | `false` | Hide the "End Call" button |
348
- | `disabledDialButton` | `boolean` | `false` | Hide the "Dial" button |
349
- | `disableCallTransferButton` | `boolean` | `false` | Hide the "Call Transfer" button |
350
- | `disableConferenceButton` | `boolean` | `false` | Hide the "Conference" button |
351
- | `disableSoftPhone` | `boolean` | `false` | Hide the embedded soft phone |
352
- | `isDraggable` | `boolean` | `true` | Enable/disable panel dragging |
353
- | `disabled` | `SxProps` | - | Custom styles for disabled states |
354
- | `enabled` | `SxProps` | - | Custom styles for enabled states |
355
- | `outlined` | `SxProps` | - | Custom styles for outlined states |
406
+ - Backend defaults set the baseline configuration
407
+ - Entitlements override backend defaults based on the agent's permissions
408
+ - Explicit `sdkConfig` overrides everything, allowing host applications to force-enable or force-disable features
356
409
 
357
410
  ---
358
411
 
@@ -360,126 +413,204 @@ initSDK({
360
413
 
361
414
  ### πŸ”§ **Core Functions**
362
415
 
363
- #### `initSDK(config)`
416
+ #### `initSDK(params)`
364
417
 
365
- Initialize the SDK with your configuration. **Must be called before using any components or hooks.**
418
+ Initialize the SDK with credentials and configuration. **Must be called before using any components or hooks.** Returns a `Promise<void>`.
366
419
 
367
- ```tsx
368
- initSDK({
369
- apiKey: string, // βœ… Required - API key for authentication
370
- tenantId: string, // βœ… Required - Tenant ID for events/authentication
371
- agentId: string, // βœ… Required - Agent ID for call controls
372
- // ... plus optional configuration options
420
+ ```typescript
421
+ await initSDK({
422
+ apiKey: string, // βœ… Required - API key for authentication
423
+ tenantId: string, // βœ… Required - Tenant identifier
424
+ agentId: string, // βœ… Required - Agent identifier
425
+ sessionId?: string, // πŸ“Ž Optional - Session identifier
426
+ urlConfig?: URLConfig, // πŸ“Ž Optional - URL configuration for endpoints
427
+ sdkConfig?: SDKConfig, // πŸ“Ž Optional - Feature configuration overrides
373
428
  });
374
429
  ```
375
430
 
431
+ #### `isSDKInitialized()`
432
+
433
+ Check if the SDK has been successfully initialized.
434
+
435
+ ```typescript
436
+ const initialized: boolean = isSDKInitialized();
437
+ ```
438
+
439
+ #### `getSDKVersion()`
440
+
441
+ Get the current SDK version.
442
+
443
+ ```typescript
444
+ const version: string = getSDKVersion();
445
+ ```
446
+
376
447
  #### `CallControlPanel`
377
448
 
378
449
  Draggable control panel component for call management.
379
450
 
380
451
  ```tsx
381
452
  <CallControlPanel
382
- onDataChange={(data) => {
383
- console.log("Call data updated:", data);
384
- }}
453
+ onDataChange={(data: CallData) => {
454
+ // Called when call status, phone number, or any call data changes
455
+ }}
385
456
  />
386
457
  ```
387
458
 
388
459
  ### πŸͺ **React Hooks**
389
460
 
390
- #### `useLogout()`
461
+ | Hook | Description | Returns |
462
+ | --------------------------- | -------------------------------------------- | ----------------------------------------------------------- |
463
+ | `useClickToCall()` | Initiate outbound calls | `{ handleStartCall, isLoading, isSuccess, isError, error }` |
464
+ | `useEndCall()` | End active calls with disposition | `{ handleEndCall, isLoading, isSuccess, isError, error }` |
465
+ | `useLogout()` | Agent logout | `{ logout, isLoading, isSuccess, isError, error }` |
466
+ | `useGetCallerData()` | Reactive access to current call data | `CallData` |
467
+ | `useSDKState()` | Subscribe to full SDK state changes | `SDKState` |
468
+ | `useGetAuthorizationToken()`| Get the current access token | `string \| undefined` |
391
469
 
392
- Hook for agent logout functionality.
470
+ ---
393
471
 
394
- ```tsx
395
- const { logout, isLoading, isSuccess, isError, error } = useLogout();
472
+ ## πŸ”Œ WebSocket Events
396
473
 
397
- // Usage:
398
- logout();
474
+ The SDK connects to a WebSocket for real-time call events:
399
475
 
400
- // Returns:
401
- // - logout: () => void - Function to trigger logout
402
- // - isLoading: boolean - Loading state
403
- // - isSuccess: boolean - Success state
404
- // - isError: boolean - Error state
405
- // - error: any - Error object if failed
406
476
  ```
407
-
408
- #### `useClickToCall()`
409
-
410
- Hook for initiating calls to mobile numbers.
411
-
412
- ```tsx
413
- const { handleStartCall, isLoading, isSuccess, isError, error, data } = useClickToCall();
414
-
415
- // Usage:
416
- handleStartCall({ mobileNumber: "1234567890" });
417
-
418
- // Returns:
419
- // - handleStartCall: (payload: StartCallPayload) => void
420
- // - isLoading: boolean - Loading state
421
- // - isSuccess: boolean - Success state
422
- // - isError: boolean - Error state
423
- // - error: any - Error object if failed
424
- // - data: any - API response on success
477
+ WebSocket URL: {urlConfig.webSocketURL}/api/v1/ws/agent/events?token={accessToken}
425
478
  ```
426
479
 
427
- #### `useEndCall()`
480
+ **Connection behavior:**
481
+ - Auto-reconnects with exponential backoff (base: 2s, max: 30s, up to 60 attempts)
482
+ - Sends ping every 30 seconds to keep the connection alive
483
+
484
+ **Event data structure:**
485
+
486
+ ```typescript
487
+ {
488
+ agent_id: number;
489
+ status: CallStatus; // IDLE, READY, ONCALL, RINGING, DIALING, WRAPUP, etc.
490
+ type: string; // Call type
491
+ event_time: string;
492
+ phone_number: string;
493
+ convox_id: string;
494
+ process_id: number;
495
+ process_name: string;
496
+ hold: number; // 0 = not held, 1 = held
497
+ mute: number; // 0 = not muted, 1 = muted
498
+ mode: string; // 'manual' or automated
499
+ queue_name: string;
500
+ conferencestatus?: { // Present during conference calls
501
+ line_1_status: string;
502
+ line_1_phonenumber: string;
503
+ line_2_status: string;
504
+ line_2_phonenumber: string;
505
+ // ... up to line 5
506
+ }
507
+ }
508
+ ```
428
509
 
429
- Hook for ending active calls.
510
+ ---
430
511
 
431
- ```tsx
432
- const { handleEndCall, isLoading, isSuccess, isError, error, data } = useEndCall();
433
-
434
- // Usage:
435
- handleEndCall({ disposition: "RES" });
436
-
437
- // Returns:
438
- // - handleEndCall: (payload: EndCallPayload) => void
439
- // - isLoading: boolean - Loading state
440
- // - isSuccess: boolean - Success state
441
- // - isError: boolean - Error state
442
- // - error: any - Error object if failed
443
- // - data: any - API response on success
512
+ ## πŸ“¦ Data Types
513
+
514
+ ### `CallStatus` Enum
515
+
516
+ ```typescript
517
+ enum CallStatus {
518
+ IDLE = "IDLE",
519
+ READY = "READY",
520
+ BREAK = "BREAK",
521
+ ONCALL = "ONCALL",
522
+ WRAPUP = "WRAPUP",
523
+ RINGING = "RINGING",
524
+ DIALING = "DIALING",
525
+ MISSED = "MISSED",
526
+ HOLD = "HOLD",
527
+ UNHOLD = "UNHOLD",
528
+ MUTE = "MUTE",
529
+ UNMUTE = "UNMUTE",
530
+ DISCONNECTED = "DISCONNECTED",
531
+ CONFERENCE = "CONFERENCE",
532
+ }
444
533
  ```
445
534
 
446
- ---
535
+ ### `CallData`
536
+
537
+ ```typescript
538
+ interface CallData {
539
+ mobileNumber?: string;
540
+ callReferenceId?: string;
541
+ convoxId?: string;
542
+ type?: string;
543
+ status: string;
544
+ agent_id: number;
545
+ phone_number?: string;
546
+ event_time?: string;
547
+ convox_id?: string;
548
+ process_id?: string;
549
+ process_name?: string;
550
+ mode?: string;
551
+ queue_name?: string;
552
+ mute?: number; // 1 = muted, 0 = unmuted
553
+ hold?: number; // 1 = on hold, 0 = not on hold
554
+ }
555
+ ```
447
556
 
448
- ## πŸ“¦ **Data Types**
557
+ ### `ConferenceLineTypes`
558
+
559
+ ```typescript
560
+ type ConferenceLineTypes = {
561
+ line: number; // Line number (1-5)
562
+ status: string; // ONCALL, IDLE, LINE USED, etc.
563
+ type: "external" | "internal" | "";
564
+ phone: string;
565
+ isMute: boolean;
566
+ isHold: boolean;
567
+ isCallStart: boolean;
568
+ isMergeCall: boolean;
569
+ };
570
+ ```
449
571
 
450
572
  ### `StartCallPayload`
451
573
 
452
- ```tsx
574
+ ```typescript
453
575
  interface StartCallPayload {
454
- mobileNumber?: string; // Mobile number to call
576
+ mobileNumber?: string;
455
577
  }
456
578
  ```
457
579
 
458
580
  ### `EndCallPayload`
459
581
 
460
- ```tsx
582
+ ```typescript
461
583
  interface EndCallPayload {
462
- disposition?: string; // Call disposition (default: "RES")
584
+ disposition?: string; // Default: "RES"
463
585
  }
464
586
  ```
465
587
 
466
588
  ---
467
589
 
468
- ## πŸŽ› **Control Features**
590
+ ## πŸ“€ Exported Types
591
+
592
+ ```typescript
593
+ // Types
594
+ export type { CallData, CallControlPanelProps, SDKConfig, URLConfig };
595
+ export type { SDKPermissionState, ControlsFromPermissions, SDKPermissionContextValue };
596
+ export type { RequestResult, RequestOptions };
597
+ export type { UseGetRequest, UsePostRequest, UsePutRequest, UseDeleteRequest, UsePatchRequest };
469
598
 
470
- ### πŸ“ž **Call Management**
599
+ // Enum
600
+ export { CallStatus };
471
601
 
472
- - **Hold/Resume** - Pause and resume active calls
473
- - **Mute/Unmute** - Control audio during calls
474
- - **End Call** - Terminate calls with disposition tracking
475
- - **Agent Status** - Switch between Idle/Break states
602
+ // Constants
603
+ export { SDK_PERMISSIONS };
476
604
 
477
- ### πŸ’Ύ **State Persistence**
605
+ // Functions
606
+ export { initSDK, getSDKVersion, isSDKInitialized };
478
607
 
479
- - **Call Timer** - Real-time duration tracking
480
- - **Panel Position** - Remembers draggable panel location
481
- - **Agent Status** - Maintains current status across sessions
482
- - **Call State** - Preserves hold/mute states
608
+ // Hooks
609
+ export { useLogout, useEndCall, useClickToCall, useGetCallerData, useGetAuthorizationToken, useSDKState };
610
+
611
+ // Components
612
+ export { CallControlPanel };
613
+ ```
483
614
 
484
615
  ---
485
616
 
@@ -487,8 +618,8 @@ interface EndCallPayload {
487
618
 
488
619
  <div align="left">
489
620
 
490
- | Browser | Version | Status |
491
- | ----------------------------------------------------------------------------- | ------- | ------------ |
621
+ | Browser | Version | Status |
622
+ | ----------------------------------------------------------------------------- | ------- | ---------- |
492
623
  | ![Chrome](https://img.shields.io/badge/Chrome-60%2B-green?logo=google-chrome) | 60+ | βœ… Supported |
493
624
  | ![Firefox](https://img.shields.io/badge/Firefox-60%2B-green?logo=firefox) | 60+ | βœ… Supported |
494
625
  | ![Safari](https://img.shields.io/badge/Safari-12%2B-green?logo=safari) | 12+ | βœ… Supported |