call-control-sdk 5.3.0 → 5.3.3

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,265 +1,1179 @@
1
- ### Call Control SDK [![npm version](https://img.shields.io/npm/v/call-control-sdk.svg?color=blue)](https://www.npmjs.com/package/call-control-sdk) [![npm downloads](https://img.shields.io/npm/dm/call-control-sdk.svg?color=green)](https://www.npmjs.com/package/call-control-sdk)
1
+ # Call Control SDK - Comprehensive Documentation
2
+
3
+ ## Table of Contents
4
+ 1. [Overview](#overview)
5
+ 2. [Architecture](#architecture)
6
+ 3. [Installation & Setup](#installation--setup)
7
+ 4. [Core Components](#core-components)
8
+ 5. [Hooks & Utilities](#hooks--utilities)
9
+ 6. [Services & APIs](#services--apis)
10
+ 7. [TypeScript Types](#typescript-types)
11
+ 8. [Usage Examples](#usage-examples)
12
+ 9. [Best Practices](#best-practices)
13
+ 10. [API Reference](#api-reference)
14
+ 11. [Troubleshooting](#troubleshooting)
15
+ 12. [Productivity Features](#productivity-features)
2
16
 
3
- A lightweight SDK that provides a **draggable call control panel** and utility hooks for managing calls in real-time. Built with **TypeScript**, **Material-UI**, and designed for **agent productivity**.
17
+ ---
18
+
19
+ ## Overview
4
20
 
5
- ### Features
21
+ The **Call Control SDK** is a comprehensive TypeScript-based library designed for WebRTC call management in contact center environments. It provides a draggable call control panel with real-time call management capabilities, agent productivity tools, and seamless integration with existing applications.
6
22
 
23
+ ### Key Features
7
24
  - 🎯 **Complete Call Control** – Hold, Mute, Status management, and End Call
8
25
  - 🖱️ **Draggable Interface** – Movable panel with persisted position
9
- - 💾 **State Persistence** – Saves control states in `localStorage`
26
+ - 💾 **State Persistence** – Saves control states in localStorage
10
27
  - ⏱️ **Live Call Timer** – Real-time call duration tracking
11
28
  - 🎨 **Material-UI Design** – Responsive and accessible UI
12
29
  - 📱 **Touch Support** – Works seamlessly on desktop and mobile
13
30
  - 🔧 **TypeScript Support** – Full type safety and IntelliSense
14
31
  - 🎪 **Singleton State** – Consistent shared state across components
32
+ - 📊 **Event Tracking** – Comprehensive analytics and monitoring
33
+ - 🔄 **WebSocket Integration** – Real-time communication
34
+ - 📞 **Conference Calling** – Multi-line conference management
35
+ - 🔀 **Call Transfer** – Transfer to agents, processes, or queues
36
+
37
+ ---
38
+
39
+ ## Architecture
40
+
41
+ ### Core Architecture Components
42
+
43
+ ```
44
+ ┌─────────────────────────────────────────────────────────────┐
45
+ │ Call Control SDK │
46
+ ├─────────────────────────────────────────────────────────────┤
47
+ │ Components Layer │
48
+ │ ├── CallControlPanel (Main UI Component) │
49
+ │ ├── CallControls (Control Buttons & Logic) │
50
+ │ ├── Dialog Components (Transfer, Conference, etc.) │
51
+ │ └── SDKProvider (Context Provider) │
52
+ ├─────────────────────────────────────────────────────────────┤
53
+ │ Hooks Layer │
54
+ │ ├── useSDKState (State Management) │
55
+ │ ├── useClickToCall (Call Initiation) │
56
+ │ ├── useEndCall (Call Termination) │
57
+ │ ├── useLogout (Agent Logout) │
58
+ │ ├── useDraggable (Drag & Drop) │
59
+ │ └── eventsTracker (Analytics) │
60
+ ├─────────────────────────────────────────────────────────────┤
61
+ │ Services Layer │
62
+ │ ├── axios.ts (HTTP Client) │
63
+ │ ├── request.ts (API Hooks) │
64
+ │ ├── endPoint.ts (API Endpoints) │
65
+ │ └── websocketClient.ts (Real-time Communication) │
66
+ ├─────────────────────────────────────────────────────────────┤
67
+ │ State Management │
68
+ │ ├── sdk-state.ts (Singleton State Manager) │
69
+ │ └── types.ts (TypeScript Definitions) │
70
+ └─────────────────────────────────────────────────────────────┘
71
+ ```
15
72
 
73
+ ### State Management Flow
74
+
75
+ ```mermaid
76
+ graph TD
77
+ A[SDK Initialization] --> B[State Manager]
78
+ B --> C[localStorage Persistence]
79
+ B --> D[Component Updates]
80
+ D --> E[UI Rendering]
81
+ E --> F[User Interactions]
82
+ F --> G[API Calls]
83
+ G --> H[State Updates]
84
+ H --> B
85
+
86
+ I[WebSocket Events] --> J[Real-time Updates]
87
+ J --> B
88
+
89
+ K[Event Tracking] --> L[Analytics]
90
+ L --> M[Performance Monitoring]
91
+ ```
92
+
93
+ ---
16
94
 
95
+ ## Installation & Setup
17
96
 
18
- ### 📦 Installation [![bundle size](https://img.shields.io/bundlephobia/minzip/call-control-sdk?color=orange&fontSize=12px)](https://bundlephobia.com/package/call-control-sdk)
97
+ ### Prerequisites
98
+ - Node.js 16+
99
+ - React 16+
100
+ - TypeScript 5+
101
+
102
+ ### Installation
19
103
 
20
104
  ```bash
21
105
  npm install call-control-sdk
22
106
  ```
23
107
 
24
- ### 🔑 Peer Dependencies
108
+ ### Peer Dependencies
25
109
 
26
110
  ```bash
27
111
  npm install react react-dom axios @mui/material @mui/icons-material @emotion/react @emotion/styled
28
112
  ```
29
113
 
30
- ### 📚 Table of Contents
114
+ ### Basic Setup
115
+
116
+ ```tsx
117
+ import React, { useEffect } from 'react';
118
+ import { initSDK, CallControlPanel } from 'call-control-sdk';
119
+
120
+ function App() {
121
+ useEffect(() => {
122
+ // Initialize the SDK
123
+ initSDK({
124
+ apiKey: "your-api-key",
125
+ tenantId: "your-tenant-id",
126
+ agentId: "your-agent-id"
127
+ });
128
+ }, []);
129
+
130
+ return (
131
+ <div className="app">
132
+ <h1>Agent Dashboard</h1>
133
+ <CallControlPanel
134
+ onDataChange={(data) => {
135
+ console.log('Call data updated:', data);
136
+ }}
137
+ />
138
+ </div>
139
+ );
140
+ }
141
+
142
+ export default App;
143
+ ```
144
+
145
+ ---
31
146
 
32
- 1. [Getting Started](#-getting-started)
33
- 2. [Core API](#-core-api)
34
- - [initSDK](#initsdk)
35
- - [CallControlPanel](#callcontrolpanel)
36
- - [updateCallData](#updatecalldata)
37
- 3. [Hooks](#-hooks)
38
- - [useLogout](#uselogout)
39
- - [useClickToCall](#useClickToCall)
40
- - [useEndCall](#useendcall)
41
- 4. [Payloads](#-payloads)
42
- 5. [Control Features](#-control-features)
43
- 6. [Browser Support](#-browser-support)
44
- 7. [License](#-license)
147
+ ## Core Components
45
148
 
46
- ### 🚀 Getting Started
149
+ ### 1. CallControlPanel
47
150
 
48
- #### 1. Initialize the SDK
151
+ The main UI component that renders the draggable call control interface.
49
152
 
50
153
  ```tsx
51
- import { useEffect } from "react";
52
- import { initSDK } from "call-control-sdk";
154
+ interface CallControlPanelProps {
155
+ onDataChange?: (data: CallData) => void;
156
+ }
53
157
 
54
- // Initialize at the top level of your app
55
- function App() {
158
+ // Usage
159
+ <CallControlPanel
160
+ onDataChange={(callData) => {
161
+ // Handle call data changes
162
+ updateDashboard(callData);
163
+ }}
164
+ />
165
+ ```
166
+
167
+ **Features:**
168
+ - Draggable positioning with persistence
169
+ - Real-time call status display
170
+ - Agent status management
171
+ - Call duration timer
172
+ - Control buttons (Hold, Mute, Transfer, Conference, End Call)
173
+
174
+ ### 2. CallControls
175
+
176
+ The core control component containing all call management buttons and logic.
177
+
178
+ **Key Controls:**
179
+ - **Agent Ready**: Set agent status to ready
180
+ - **Hold/Resume**: Toggle call hold state
181
+ - **Mute/Unmute**: Toggle microphone state
182
+ - **Transfer**: Transfer call to another agent/queue/process
183
+ - **Conference**: Add participants to conference call
184
+ - **End Call**: Terminate call with disposition
185
+
186
+ ### 3. Dialog Components
187
+
188
+ #### ConferenceDialog
189
+ Manages multi-line conference calls with up to 5 lines.
190
+
191
+ ```tsx
192
+ // Conference line management
193
+ interface ConferenceLineTypes {
194
+ line: number;
195
+ status: string;
196
+ type: "external" | "internal" | "";
197
+ phone: string;
198
+ isMute: boolean;
199
+ isHold: boolean;
200
+ isCallStart: boolean;
201
+ isMergeCall: boolean;
202
+ }
203
+ ```
204
+
205
+ #### CallTransferDialog
206
+ Handles call transfers to:
207
+ - **Agents**: Transfer to specific agents
208
+ - **Processes**: Transfer to business processes
209
+ - **Queues**: Transfer to call queues
210
+
211
+ #### EndCallDispositionDialog
212
+ Captures call disposition and follow-up information:
213
+ - Disposition codes (Resolved, Not Interested)
214
+ - Follow-up requirements
215
+ - Callback scheduling
216
+
217
+ ---
218
+
219
+ ## Hooks & Utilities
220
+
221
+ ### 1. useSDKState
222
+
223
+ Provides reactive access to the SDK's global state.
224
+
225
+ ```tsx
226
+ import { useSDKState } from 'call-control-sdk';
227
+
228
+ function MyComponent() {
229
+ const state = useSDKState();
230
+
231
+ return (
232
+ <div>
233
+ <p>Agent Status: {state.status}</p>
234
+ <p>Call Duration: {state.callStartTime}</p>
235
+ <p>Is Muted: {state.isMuted ? 'Yes' : 'No'}</p>
236
+ </div>
237
+ );
238
+ }
239
+ ```
240
+
241
+ ### 2. useClickToCall
242
+
243
+ Initiates outbound calls to phone numbers.
244
+
245
+ ```tsx
246
+ import { useClickToCall } from 'call-control-sdk';
247
+
248
+ function DialerComponent() {
249
+ const { handleStartCall, isLoading, isSuccess, error } = useClickToCall();
250
+
251
+ const makeCall = () => {
252
+ handleStartCall({ mobileNumber: "1234567890" });
253
+ };
254
+
255
+ return (
256
+ <button onClick={makeCall} disabled={isLoading}>
257
+ {isLoading ? 'Calling...' : 'Call'}
258
+ </button>
259
+ );
260
+ }
261
+ ```
262
+
263
+ ### 3. useEndCall
264
+
265
+ Terminates active calls with disposition tracking.
266
+
267
+ ```tsx
268
+ import { useEndCall } from 'call-control-sdk';
269
+
270
+ function EndCallComponent() {
271
+ const { handleEndCall, isLoading } = useEndCall();
272
+
273
+ const endCall = () => {
274
+ handleEndCall({
275
+ disposition: "RES",
276
+ followUp: "N",
277
+ callbackDate: "",
278
+ callbackHrs: "",
279
+ callbackMins: ""
280
+ });
281
+ };
282
+
283
+ return (
284
+ <button onClick={endCall} disabled={isLoading}>
285
+ End Call
286
+ </button>
287
+ );
288
+ }
289
+ ```
290
+
291
+ ### 4. useLogout
292
+
293
+ Handles agent logout functionality.
294
+
295
+ ```tsx
296
+ import { useLogout } from 'call-control-sdk';
297
+
298
+ function LogoutComponent() {
299
+ const { logout, isLoading } = useLogout();
300
+
301
+ return (
302
+ <button onClick={logout} disabled={isLoading}>
303
+ {isLoading ? 'Logging out...' : 'Logout'}
304
+ </button>
305
+ );
306
+ }
307
+ ```
308
+
309
+ ### 5. useDraggable
310
+
311
+ Provides drag-and-drop functionality for UI elements.
312
+
313
+ ```tsx
314
+ import { useDraggable } from 'call-control-sdk';
315
+
316
+ function DraggablePanel() {
317
+ const { position, isDragging, dragRef, handleMouseDown, handleTouchStart } =
318
+ useDraggable({ x: 100, y: 100 }, (newPosition) => {
319
+ console.log('Moved to:', newPosition);
320
+ });
321
+
322
+ return (
323
+ <div
324
+ ref={dragRef}
325
+ onMouseDown={handleMouseDown}
326
+ onTouchStart={handleTouchStart}
327
+ style={{
328
+ position: 'fixed',
329
+ left: position.x,
330
+ top: position.y,
331
+ cursor: isDragging ? 'grabbing' : 'grab'
332
+ }}
333
+ >
334
+ Drag me
335
+ </div>
336
+ );
337
+ }
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Services & APIs
343
+
344
+ ### 1. HTTP Client (axios.ts)
345
+
346
+ Configured Axios instance with:
347
+ - Base URL configuration
348
+ - Authorization headers
349
+ - Request/response interceptors
350
+ - Error handling
351
+ - Retry logic for 401 errors
352
+
353
+ ```tsx
354
+ // Automatic token injection
355
+ axiosInstance.interceptors.request.use((config) => {
356
+ const token = getAuthToken();
357
+ if (token && config.headers) {
358
+ config.headers.Authorization = `Bearer ${token}`;
359
+ }
360
+ return config;
361
+ });
362
+ ```
363
+
364
+ ### 2. API Request Hooks (request.ts)
365
+
366
+ Custom hooks for different HTTP methods:
367
+
368
+ #### useGetRequest
369
+ ```tsx
370
+ const [getData, { isLoading, isSuccess, error, data }] = useGetRequest<User>({
371
+ onSuccess: (response) => console.log('Success:', response),
372
+ onError: (error) => console.error('Error:', error)
373
+ });
374
+
375
+ // Usage
376
+ getData('/api/users');
377
+ ```
378
+
379
+ #### usePostRequest
380
+ ```tsx
381
+ const [createUser, { isLoading, isSuccess, error }] = usePostRequest<User>({
382
+ onSuccess: (response) => console.log('User created:', response)
383
+ });
384
+
385
+ // Usage
386
+ createUser('/api/users', userData);
387
+ ```
388
+
389
+ ### 3. API Endpoints (endPoint.ts)
390
+
391
+ Centralized endpoint configuration:
392
+
393
+ ```tsx
394
+ export const END_POINT = {
395
+ LOGIN: `${BASE_URL}/api/v1/cti/login?provider=convox`,
396
+ READY_AGENT: `${BASE_URL}/api/v1/cti/ready-agent?provider=convox`,
397
+ CLICK_TO_CALL: `${BASE_URL}/api/v1/cti/calls?provider=convox`,
398
+ HOLD_CALL: `${BASE_URL}/api/v1/cti/calls/hold?provider=convox`,
399
+ MUTE_CALL: `${BASE_URL}/api/v1/cti/calls/mute?provider=convox`,
400
+ END_CALL: `${BASE_URL}/api/v1/cti/calls/end?provider=convox`,
401
+ CONFERENCE_CALL: `${BASE_URL}/api/v1/cti/calls/conference?provider=convox`,
402
+ TRANSFER_CALL: `${BASE_URL}/api/v1/cti/calls/transfer?provider=convox`,
403
+ // ... more endpoints
404
+ };
405
+ ```
406
+
407
+ ### 4. WebSocket Integration
408
+
409
+ Real-time communication for call events:
410
+
411
+ ```tsx
412
+ // WebSocket connection setup
413
+ useEffect(() => {
414
+ if (state.agentId) {
415
+ const ws = new WebSocket(`${WS_END_POINT.WS}?agent_id=${state.agentId}`);
416
+
417
+ ws.onmessage = (event) => {
418
+ const data = JSON.parse(event.data);
419
+ sdkStateManager.updateCallData(data);
420
+
421
+ if (data.status === "ONCALL") {
422
+ sdkStateManager.startCall();
423
+ }
424
+ if (data.status === "WRAPUP") {
425
+ sdkStateManager.endCall();
426
+ }
427
+ };
428
+
429
+ return () => ws.close();
430
+ }
431
+ }, [state.agentId]);
432
+ ```
433
+
434
+ ---
435
+
436
+ ## TypeScript Types
437
+
438
+ ### Core Types
439
+
440
+ ```tsx
441
+ // Call data structure
442
+ interface CallData {
443
+ mobileNumber?: string;
444
+ callReferenceId?: string;
445
+ convoxId?: string;
446
+ type?: string;
447
+ status?: string;
448
+ agent_id?: string;
449
+ phone_number?: string;
450
+ event_time?: string;
451
+ convox_id?: string;
452
+ process_id?: string;
453
+ process_name?: string;
454
+ }
455
+
456
+ // Agent status types
457
+ type CallStatus =
458
+ | "idle"
459
+ | "ready"
460
+ | "break"
461
+ | "on call"
462
+ | "wrap up"
463
+ | "dial"
464
+ | "hold"
465
+ | "mute";
466
+
467
+ // Conference line configuration
468
+ type ConferenceLineTypes = {
469
+ line: number;
470
+ status: string;
471
+ type: "external" | "internal" | "";
472
+ phone: string;
473
+ isMute: boolean;
474
+ isHold: boolean;
475
+ isCallStart: boolean;
476
+ isMergeCall: boolean;
477
+ };
478
+
479
+ // SDK state interface
480
+ interface SDKState {
481
+ apiKey: string | null;
482
+ process?: { process_id: number; process_name: string } | null;
483
+ agentId: string;
484
+ isInitialized: boolean;
485
+ isHolding: boolean;
486
+ isMuted: boolean;
487
+ status: CallStatus;
488
+ convox_id?: string;
489
+ process_id?: number;
490
+ callStartTime: number | null;
491
+ position?: { x: number; y: number };
492
+ controlPanelPosition: { x: number; y: number };
493
+ iframePosition: { x: number; y: number };
494
+ callData: CallData;
495
+ conferenceLine: ConferenceLineTypes[];
496
+ }
497
+ ```
498
+
499
+ ### API Request Types
500
+
501
+ ```tsx
502
+ // Request result interface
503
+ interface RequestResult<T> {
504
+ isLoading: boolean;
505
+ isSuccess: boolean;
506
+ isError: boolean;
507
+ error: AxiosError | null;
508
+ data: AxiosResponse<T> | null;
509
+ }
510
+
511
+ // Request options
512
+ interface RequestOptions {
513
+ onSuccess?: (response: AxiosResponse, request: any) => void;
514
+ onError?: (error: any, request: any) => void;
515
+ }
516
+
517
+ // Hook signatures
518
+ type UseGetRequest<T = UseApiRequest> = [
519
+ (url: string, config?: AxiosRequestConfig) => void,
520
+ RequestResult<T>
521
+ ];
522
+
523
+ type UsePostRequest<T = UseApiRequest> = [
524
+ (url: string, payload: T, config?: AxiosRequestConfig) => void,
525
+ RequestResult<T>
526
+ ];
527
+ ```
528
+
529
+ ---
530
+
531
+ ## Usage Examples
532
+
533
+ ### 1. Complete Agent Dashboard
534
+
535
+ ```tsx
536
+ import React, { useEffect, useState } from 'react';
537
+ import {
538
+ initSDK,
539
+ CallControlPanel,
540
+ useClickToCall,
541
+ useEndCall,
542
+ useLogout
543
+ } from 'call-control-sdk';
544
+
545
+ function AgentDashboard() {
546
+ const [callData, setCallData] = useState(null);
547
+
548
+ // Initialize SDK
56
549
  useEffect(() => {
57
- // Initialize the SDK.
58
- try {
59
- initSDK({
60
- apiKey: "your-api-key",
61
- tenantId: "your-tenant-id",
62
- agentId: "your-agent-id",
63
- });
64
- console.log("SDK initialized successfully");
65
- } catch (error) {
66
- console.error("SDK initialization failed:", error);
67
- }
550
+ initSDK({
551
+ apiKey: process.env.REACT_APP_API_KEY,
552
+ tenantId: process.env.REACT_APP_TENANT_ID,
553
+ agentId: process.env.REACT_APP_AGENT_ID
554
+ });
68
555
  }, []);
69
556
 
70
- return <h1>My App</h1>;
557
+ // Call management hooks
558
+ const { handleStartCall, isLoading: calling } = useClickToCall();
559
+ const { handleEndCall, isLoading: ending } = useEndCall();
560
+ const { logout, isLoading: loggingOut } = useLogout();
561
+
562
+ const handleCallDataChange = (data) => {
563
+ setCallData(data);
564
+ // Update dashboard metrics
565
+ updateDashboardMetrics(data);
566
+ };
567
+
568
+ return (
569
+ <div className="agent-dashboard">
570
+ <header className="dashboard-header">
571
+ <h1>Agent Dashboard</h1>
572
+ <button onClick={logout} disabled={loggingOut}>
573
+ {loggingOut ? 'Logging out...' : 'Logout'}
574
+ </button>
575
+ </header>
576
+
577
+ <main className="dashboard-content">
578
+ <div className="call-controls">
579
+ <CallControlPanel onDataChange={handleCallDataChange} />
580
+ </div>
581
+
582
+ <div className="dashboard-widgets">
583
+ <CallMetricsWidget data={callData} />
584
+ <CustomerInfoWidget data={callData} />
585
+ <CallHistoryWidget />
586
+ </div>
587
+ </main>
588
+ </div>
589
+ );
71
590
  }
72
591
  ```
73
592
 
74
- #### 2. Add the Call Control Panel
593
+ ### 2. Custom Call Controls
75
594
 
76
595
  ```tsx
77
- import { CallControlPanel } from "call-control-sdk";
596
+ import React from 'react';
597
+ import { useSDKState, useClickToCall, useEndCall } from 'call-control-sdk';
598
+
599
+ function CustomCallControls() {
600
+ const state = useSDKState();
601
+ const { handleStartCall } = useClickToCall();
602
+ const { handleEndCall } = useEndCall();
603
+
604
+ const isOnCall = state.callData?.status === "ONCALL";
605
+ const callDuration = state.callStartTime
606
+ ? Math.floor((Date.now() - state.callStartTime) / 1000)
607
+ : 0;
608
+
609
+ const formatDuration = (seconds) => {
610
+ const mins = Math.floor(seconds / 60);
611
+ const secs = seconds % 60;
612
+ return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
613
+ };
614
+
615
+ return (
616
+ <div className="custom-controls">
617
+ <div className="call-status">
618
+ <span className="status">{state.status}</span>
619
+ {isOnCall && (
620
+ <span className="duration">{formatDuration(callDuration)}</span>
621
+ )}
622
+ </div>
623
+
624
+ <div className="control-buttons">
625
+ {!isOnCall && (
626
+ <button onClick={() => handleStartCall({ mobileNumber: "1234567890" })}>
627
+ Start Call
628
+ </button>
629
+ )}
630
+
631
+ {isOnCall && (
632
+ <>
633
+ <button
634
+ onClick={() => handleEndCall({ disposition: "RES" })}
635
+ className="end-call"
636
+ >
637
+ End Call
638
+ </button>
639
+ </>
640
+ )}
641
+ </div>
642
+ </div>
643
+ );
644
+ }
645
+ ```
646
+
647
+ ### 3. Conference Call Management
78
648
 
79
- export default function App() {
80
- const handleDataChange = (data) => {
81
- console.log("Call data updated:", data);
649
+ ```tsx
650
+ import React, { useState } from 'react';
651
+ import { useSDKState } from 'call-control-sdk';
652
+
653
+ function ConferenceManager() {
654
+ const state = useSDKState();
655
+ const [showConference, setShowConference] = useState(false);
656
+
657
+ const addParticipant = (phoneNumber) => {
658
+ // Find available conference line
659
+ const availableLine = state.conferenceLine.find(
660
+ line => line.line !== 1 && line.status === "IDLE"
661
+ );
662
+
663
+ if (availableLine) {
664
+ // Initiate conference call
665
+ handleConferenceCall(availableLine.line, phoneNumber);
666
+ }
82
667
  };
83
668
 
84
669
  return (
85
- <div>
86
- <h1>Agent Dashboard</h1>
87
- <CallControlPanel onDataChange={handleDataChange} />
670
+ <div className="conference-manager">
671
+ <button onClick={() => setShowConference(true)}>
672
+ Manage Conference
673
+ </button>
674
+
675
+ {showConference && (
676
+ <div className="conference-dialog">
677
+ <h3>Conference Lines</h3>
678
+ {state.conferenceLine.map(line => (
679
+ <div key={line.line} className="conference-line">
680
+ <span>Line {line.line}: {line.status}</span>
681
+ {line.line !== 1 && (
682
+ <input
683
+ placeholder="Phone number"
684
+ onBlur={(e) => addParticipant(e.target.value)}
685
+ />
686
+ )}
687
+ </div>
688
+ ))}
689
+ </div>
690
+ )}
88
691
  </div>
89
692
  );
90
693
  }
91
694
  ```
92
695
 
93
- #### 3. Logout Agent
696
+ ---
697
+
698
+ ## Best Practices
699
+
700
+ ### 1. Initialization
94
701
 
95
702
  ```tsx
96
- import { useLogout } from "call-control-sdk";
703
+ // Good: Initialize SDK early in app lifecycle
704
+ function App() {
705
+ useEffect(() => {
706
+ try {
707
+ initSDK({
708
+ apiKey: process.env.REACT_APP_API_KEY,
709
+ tenantId: process.env.REACT_APP_TENANT_ID,
710
+ agentId: process.env.REACT_APP_AGENT_ID
711
+ });
712
+ } catch (error) {
713
+ console.error('SDK initialization failed:', error);
714
+ // Handle initialization error
715
+ }
716
+ }, []);
717
+
718
+ return <YourApp />;
719
+ }
97
720
 
98
- export default function LogoutButton() {
99
- const { logout, isLoading, isSuccess, isError, error } = useLogout();
100
- return <button onClick={logout}>Logout</button>;
721
+ // Bad: Initializing in component that might unmount
722
+ function SomeComponent() {
723
+ useEffect(() => {
724
+ initSDK(config); // This might be called multiple times
725
+ }, []);
101
726
  }
102
727
  ```
103
728
 
104
- #### 4. Start Call
729
+ ### 2. State Management
105
730
 
106
731
  ```tsx
107
- import { useClickToCall } from "call-control-sdk";
732
+ // Good: Use the provided state hook
733
+ function MyComponent() {
734
+ const state = useSDKState();
735
+
736
+ return (
737
+ <div>
738
+ <p>Status: {state.status}</p>
739
+ <p>Call Duration: {state.callStartTime}</p>
740
+ </div>
741
+ );
742
+ }
108
743
 
109
- export default function CallButton() {
110
- const { handleStartCall, isLoading, isSuccess, isError, error } = useClickToCall();
744
+ // Bad: Direct state access
745
+ function MyComponent() {
746
+ const state = sdkStateManager.getState(); // Won't trigger re-renders
747
+ return <div>{state.status}</div>;
748
+ }
749
+ ```
111
750
 
112
- const onStartCall = () => {
113
- handleStartCall({ mobileNumber: "1111111111" });
751
+ ### 3. Error Handling
752
+
753
+ ```tsx
754
+ // ✅ Good: Comprehensive error handling
755
+ function CallComponent() {
756
+ const { handleStartCall, isLoading, isError, error } = useClickToCall();
757
+
758
+ const makeCall = async () => {
759
+ try {
760
+ await handleStartCall({ mobileNumber: "1234567890" });
761
+ } catch (error) {
762
+ console.error('Call failed:', error);
763
+ // Show user-friendly error message
764
+ showNotification('Call failed. Please try again.');
765
+ }
114
766
  };
115
767
 
116
768
  return (
117
769
  <div>
118
- <button onClick={onStartCall} disabled={isLoading}>
119
- { "Call"}
770
+ <button onClick={makeCall} disabled={isLoading}>
771
+ {isLoading ? 'Calling...' : 'Call'}
120
772
  </button>
121
- {isSuccess && <p>✅ Call ended successfully</p>}
122
- {isError && <p>❌ Error: {error?.message}</p>}
773
+ {isError && <p className="error">Error: {error?.message}</p>}
123
774
  </div>
124
775
  );
125
776
  }
126
777
  ```
127
- #### 5. End Call
778
+
779
+ ### 4. Performance Optimization
128
780
 
129
781
  ```tsx
130
- import { useEndCall } from "call-control-sdk";
782
+ // Good: Memoize expensive operations
783
+ function CallMetrics({ callData }) {
784
+ const formattedDuration = useMemo(() => {
785
+ if (!callData?.startTime) return '00:00';
786
+ const duration = Date.now() - callData.startTime;
787
+ return formatDuration(duration);
788
+ }, [callData?.startTime]);
789
+
790
+ return <div>Duration: {formattedDuration}</div>;
791
+ }
131
792
 
132
- export default function EndCallButton() {
133
- const { handleEndCall, isLoading, isSuccess, isError, error } = useEndCall();
793
+ // Good: Debounce user input
794
+ function PhoneInput() {
795
+ const [phoneNumber, setPhoneNumber] = useState('');
796
+ const debouncedPhone = useDebounce(phoneNumber, 500);
797
+
798
+ useEffect(() => {
799
+ if (debouncedPhone.length === 10) {
800
+ validatePhoneNumber(debouncedPhone);
801
+ }
802
+ }, [debouncedPhone]);
803
+ }
804
+ ```
134
805
 
135
- const onEndCall = () => {
136
- handleEndCall({
137
- disposition: "RES", // Call disposition
138
- });
139
- };
806
+ ### 5. Accessibility
140
807
 
808
+ ```tsx
809
+ // ✅ Good: Accessible controls
810
+ function AccessibleCallControls() {
811
+ const state = useSDKState();
812
+
141
813
  return (
142
- <div>
143
- <button onClick={onEndCall} disabled={isLoading}>
144
- {isLoading ? "Ending Call..." : "End Call"}
814
+ <div role="toolbar" aria-label="Call controls">
815
+ <button
816
+ onClick={handleMute}
817
+ aria-pressed={state.isMuted}
818
+ aria-label={state.isMuted ? 'Unmute microphone' : 'Mute microphone'}
819
+ >
820
+ {state.isMuted ? <MicOffIcon /> : <MicIcon />}
821
+ </button>
822
+
823
+ <button
824
+ onClick={handleHold}
825
+ aria-pressed={state.isHolding}
826
+ aria-label={state.isHolding ? 'Resume call' : 'Hold call'}
827
+ >
828
+ {state.isHolding ? <PlayIcon /> : <PauseIcon />}
145
829
  </button>
146
- {isSuccess && <p>✅ Call ended successfully</p>}
147
- {isError && <p>❌ Error: {error?.message}</p>}
148
830
  </div>
149
831
  );
150
832
  }
151
833
  ```
152
834
 
153
- ### 🛠 Core API
835
+ ---
154
836
 
155
- #### `initSDK(config)`
837
+ ## API Reference
156
838
 
157
- Initializes the SDK. Must be called **before using any components or hooks**.
839
+ ### Core Functions
158
840
 
159
- **Parameters**:
841
+ #### `initSDK(config: InitSDKParams): void`
160
842
 
161
- | Name | Type | Required | Description |
162
- | ---------- | ------ | -------- | ----------------------------------- |
163
- | `apiKey` | string | ✅ | API key for authentication |
164
- | `tenantId` | string | ✅ | Tenant ID for events/authentication |
165
- | `agentId` | string | ✅ | Agent ID for call controls |
843
+ Initializes the Call Control SDK.
844
+
845
+ **Parameters:**
846
+ - `config.apiKey` (string, required): API key for authentication
847
+ - `config.tenantId` (string, required): Tenant ID for events/authentication
848
+ - `config.agentId` (string, required): Agent ID for call controls
849
+
850
+ **Example:**
851
+ ```tsx
852
+ initSDK({
853
+ apiKey: "your-api-key",
854
+ tenantId: "tenant-123",
855
+ agentId: "agent-456"
856
+ });
857
+ ```
166
858
 
167
859
  #### `CallControlPanel`
168
860
 
169
- Draggable control panel for call management.
861
+ React component that renders the draggable call control interface.
862
+
863
+ **Props:**
864
+ - `onDataChange?: (data: CallData) => void`: Callback fired when call data changes
865
+
866
+ **Example:**
867
+ ```tsx
868
+ <CallControlPanel
869
+ onDataChange={(data) => {
870
+ console.log('Call updated:', data);
871
+ }}
872
+ />
873
+ ```
874
+
875
+ ### Hooks
170
876
 
171
- **Props**:
877
+ #### `useSDKState(): SDKState`
172
878
 
173
- | Prop | Type | Required | Description |
174
- | --------------- | -------- | -------- | -------------------------------------------------------------------------------------------------- |
175
- | `onDataChange?` | function | ❌ | Callback fired when call data changes. Receives `{ mobileNumber, callReferenceId, agentLoginId }`. |
879
+ Returns the current SDK state with reactive updates.
176
880
 
177
- #### `updateCallData(data: Partial<CallData>)`
881
+ **Returns:** `SDKState` object containing:
882
+ - `isInitialized`: boolean
883
+ - `status`: CallStatus
884
+ - `isHolding`: boolean
885
+ - `isMuted`: boolean
886
+ - `callData`: CallData
887
+ - `conferenceLine`: ConferenceLineTypes[]
888
+ - And more...
178
889
 
179
- Update call data programmatically.
890
+ #### `useClickToCall()`
180
891
 
181
- **Parameters**:
892
+ Hook for initiating outbound calls.
182
893
 
183
- | Field | Type | Description |
184
- | ------------------ | ------ | ---------------------- |
185
- | `mobileNumber?` | string | Mobile phone number |
186
- | `callReferenceId?` | string | Unique call reference |
187
- | `agentLoginId?` | string | Agent login identifier |
894
+ **Returns:**
895
+ - `handleStartCall`: (payload: StartCallPayload) => Promise<void>
896
+ - `isLoading`: boolean
897
+ - `isSuccess`: boolean
898
+ - `isError`: boolean
899
+ - `error`: any
900
+ - `data`: any
901
+
902
+ #### `useEndCall()`
188
903
 
189
- ### 🪝 Hooks
904
+ Hook for ending active calls.
905
+
906
+ **Returns:**
907
+ - `handleEndCall`: (data: EndCallData) => Promise<void>
908
+ - `isLoading`: boolean
909
+ - `isSuccess`: boolean
910
+ - `isError`: boolean
911
+ - `error`: any
912
+ - `data`: any
190
913
 
191
914
  #### `useLogout()`
192
915
 
193
- Logs out the current agent.
916
+ Hook for agent logout functionality.
917
+
918
+ **Returns:**
919
+ - `logout`: () => Promise<void>
920
+ - `isLoading`: boolean
921
+ - `isSuccess`: boolean
922
+ - `isError`: boolean
923
+ - `error`: any
924
+ - `data`: any
925
+
926
+ ---
927
+
928
+ ## Troubleshooting
929
+
930
+ ### Common Issues
931
+
932
+ #### 1. SDK Not Initializing
194
933
 
934
+ **Problem:** SDK fails to initialize
935
+ **Solution:**
195
936
  ```tsx
196
- const { logOut } = useLogout();
197
- <button onClick={logOut}>Logout</button>;
937
+ // Check if all required parameters are provided
938
+ try {
939
+ initSDK({
940
+ apiKey: "valid-api-key", // Ensure this is not empty
941
+ tenantId: "valid-tenant-id", // Ensure this is not empty
942
+ agentId: "valid-agent-id" // Ensure this is not empty
943
+ });
944
+ } catch (error) {
945
+ console.error('SDK initialization failed:', error);
946
+ }
947
+ ```
948
+
949
+ #### 2. State Not Updating
950
+
951
+ **Problem:** Components not re-rendering when state changes
952
+ **Solution:**
953
+ ```tsx
954
+ // ✅ Use the hook, not direct state access
955
+ function MyComponent() {
956
+ const state = useSDKState(); // This will trigger re-renders
957
+
958
+ // ❌ Don't do this
959
+ // const state = sdkStateManager.getState();
960
+ }
198
961
  ```
199
962
 
200
- #### `useStartCall()`
963
+ #### 3. WebSocket Connection Issues
201
964
 
202
- Hook for call to mobile number.
965
+ **Problem:** Real-time updates not working
966
+ **Solution:**
967
+ ```tsx
968
+ // Check WebSocket connection
969
+ useEffect(() => {
970
+ if (state.agentId) {
971
+ const ws = new WebSocket(`${WS_END_POINT.WS}?agent_id=${state.agentId}`);
972
+
973
+ ws.onopen = () => console.log('WebSocket connected');
974
+ ws.onerror = (error) => console.error('WebSocket error:', error);
975
+ ws.onclose = () => console.log('WebSocket disconnected');
976
+
977
+ return () => ws.close();
978
+ }
979
+ }, [state.agentId]);
980
+ ```
203
981
 
204
- **Returns**:
982
+ #### 4. Call Controls Not Working
205
983
 
206
- | Key | Type | Description |
207
- | --------------- | -------- | --------------------------------------------------------------- |
208
- | `handleStartCall` | function | `(payload: StartCallPayload) => void` – triggers end-call request |
209
- | `isLoading` | boolean | True while request is pending |
210
- | `isSuccess` | boolean | True if request succeeded |
211
- | `isError` | boolean | True if request failed |
212
- | `error` | any | Error object if failed |
213
- | `data` | any | API response on success |
984
+ **Problem:** Buttons not responding or API calls failing
985
+ **Solution:**
986
+ ```tsx
987
+ // Check agent status and call state
988
+ function CallControls() {
989
+ const state = useSDKState();
990
+
991
+ // Ensure agent is ready before allowing calls
992
+ const canMakeCall = state.status === "idle" || state.status === "ready";
993
+
994
+ return (
995
+ <button
996
+ onClick={handleCall}
997
+ disabled={!canMakeCall || isLoading}
998
+ >
999
+ Call
1000
+ </button>
1001
+ );
1002
+ }
1003
+ ```
214
1004
 
215
- #### `useEndCall()`
1005
+ ### Debug Mode
1006
+
1007
+ Enable debug logging:
216
1008
 
217
- Hook for ending an active call.
1009
+ ```tsx
1010
+ // Add to your app initialization
1011
+ if (process.env.NODE_ENV === 'development') {
1012
+ // Enable SDK debug mode
1013
+ sdkStateManager.debugStorage();
1014
+
1015
+ // Log all state changes
1016
+ sdkStateManager.subscribe(() => {
1017
+ console.log('SDK State changed:', sdkStateManager.getState());
1018
+ });
1019
+ }
1020
+ ```
218
1021
 
219
- **Returns**:
1022
+ ---
220
1023
 
221
- | Key | Type | Description |
222
- | --------------- | -------- | --------------------------------------------------------------- |
223
- | `handleEndCall` | function | `(payload: EndCallPayload) => void` – triggers end-call request |
224
- | `isLoading` | boolean | True while request is pending |
225
- | `isSuccess` | boolean | True if request succeeded |
226
- | `isError` | boolean | True if request failed |
227
- | `error` | any | Error object if failed |
228
- | `data` | any | API response on success |
1024
+ ## Productivity Features
229
1025
 
230
- ### 📦 Payloads
1026
+ ### 1. Agent Productivity Metrics
231
1027
 
232
- #### `StartCallPayload`
1028
+ The SDK automatically tracks various productivity metrics:
233
1029
 
234
- ```ts
235
- interface EndCallPayload {
236
- mobileNumber?: string; // Mobile number
237
- }
1030
+ ```tsx
1031
+ // Event tracking for productivity analysis
1032
+ eventTracker.logEvent('callStarted', {
1033
+ agentId: state.agentId,
1034
+ phoneNumber: state.callData.phone_number,
1035
+ timestamp: new Date().toISOString(),
1036
+ processId: state.process?.process_id
1037
+ });
1038
+
1039
+ eventTracker.logEvent('callEnded', {
1040
+ agentId: state.agentId,
1041
+ duration: callDuration,
1042
+ disposition: disposition,
1043
+ timestamp: new Date().toISOString()
1044
+ });
1045
+ ```
1046
+
1047
+ ### 2. Real-time Status Updates
1048
+
1049
+ ```tsx
1050
+ // Automatic status synchronization
1051
+ useEffect(() => {
1052
+ const ws = new WebSocket(`${WS_END_POINT.WS}?agent_id=${state.agentId}`);
1053
+
1054
+ ws.onmessage = (event) => {
1055
+ const data = JSON.parse(event.data);
1056
+
1057
+ // Update call data
1058
+ sdkStateManager.updateCallData(data);
1059
+
1060
+ // Track status changes
1061
+ eventTracker.logEvent('statusChanged', {
1062
+ from: state.status,
1063
+ to: data.status,
1064
+ timestamp: new Date().toISOString()
1065
+ });
1066
+ };
1067
+ }, [state.agentId]);
238
1068
  ```
239
1069
 
240
- #### `EndCallPayload`
1070
+ ### 3. Call Quality Monitoring
241
1071
 
242
- ```ts
243
- interface EndCallPayload {
244
- disposition?: string; // Call disposition (default: "RES")
1072
+ ```tsx
1073
+ // Monitor call quality metrics
1074
+ function CallQualityMonitor() {
1075
+ const state = useSDKState();
1076
+
1077
+ useEffect(() => {
1078
+ if (state.callData?.status === "ONCALL") {
1079
+ const startTime = Date.now();
1080
+
1081
+ const interval = setInterval(() => {
1082
+ const duration = Date.now() - startTime;
1083
+
1084
+ // Log call quality metrics every 30 seconds
1085
+ if (duration % 30000 === 0) {
1086
+ eventTracker.logEvent('callQualityMetrics', {
1087
+ duration: duration,
1088
+ isHolding: state.isHolding,
1089
+ isMuted: state.isMuted,
1090
+ timestamp: new Date().toISOString()
1091
+ });
1092
+ }
1093
+ }, 1000);
1094
+
1095
+ return () => clearInterval(interval);
1096
+ }
1097
+ }, [state.callData?.status, state.isHolding, state.isMuted]);
245
1098
  }
246
1099
  ```
247
1100
 
248
- ### 🎛 Control Features
1101
+ ### 4. Performance Analytics
249
1102
 
250
- **Status Management**: Idle / Break
251
- **Call Controls**: Hold / Resume, Mute / Unmute, End Call, Agent Status
252
- **Persistent State**: Hold, mute, agent status, panel position, call timer
1103
+ ```tsx
1104
+ // Track UI performance
1105
+ function PerformanceTracker() {
1106
+ useEffect(() => {
1107
+ // Track component render times
1108
+ const startTime = performance.now();
1109
+
1110
+ return () => {
1111
+ const renderTime = performance.now() - startTime;
1112
+ eventTracker.logEvent('componentRender', {
1113
+ component: 'CallControlPanel',
1114
+ renderTime: renderTime,
1115
+ timestamp: new Date().toISOString()
1116
+ });
1117
+ };
1118
+ }, []);
1119
+ }
1120
+ ```
253
1121
 
254
- ### 🌍 Browser Support
1122
+ ### 5. User Experience Optimization
255
1123
 
256
- ✅ Chrome 60+
257
- Firefox 60+
258
- Safari 12+
259
- Edge 79+
1124
+ ```tsx
1125
+ // Optimize user interactions
1126
+ function OptimizedCallControls() {
1127
+ const state = useSDKState();
1128
+
1129
+ // Debounce rapid button clicks
1130
+ const debouncedHold = useDebounce(() => {
1131
+ handleHoldToggle();
1132
+ }, 300);
1133
+
1134
+ // Track user interaction patterns
1135
+ const trackInteraction = (action) => {
1136
+ eventTracker.logEvent('userInteraction', {
1137
+ action: action,
1138
+ agentId: state.agentId,
1139
+ timestamp: new Date().toISOString()
1140
+ });
1141
+ };
1142
+
1143
+ return (
1144
+ <div>
1145
+ <button
1146
+ onClick={() => {
1147
+ trackInteraction('holdToggle');
1148
+ debouncedHold();
1149
+ }}
1150
+ >
1151
+ Hold
1152
+ </button>
1153
+ </div>
1154
+ );
1155
+ }
1156
+ ```
260
1157
 
261
1158
  ---
262
1159
 
263
- ### 📄 License
1160
+ ## Conclusion
1161
+
1162
+ The Call Control SDK provides a comprehensive solution for WebRTC call management in contact center environments. With its draggable interface, real-time state management, extensive TypeScript support, and productivity features, it enables developers to build robust call center applications quickly and efficiently.
1163
+
1164
+ Key benefits:
1165
+ - **Rapid Development**: Pre-built components and hooks accelerate development
1166
+ - **Type Safety**: Full TypeScript support prevents runtime errors
1167
+ - **Real-time Updates**: WebSocket integration ensures live data synchronization
1168
+ - **Productivity Focus**: Built-in analytics and monitoring capabilities
1169
+ - **Accessibility**: Material-UI components with proper ARIA support
1170
+ - **Mobile Ready**: Touch support and responsive design
1171
+ - **Extensible**: Modular architecture allows for easy customization
1172
+
1173
+ For additional support or feature requests, please refer to the official documentation or contact the development team.
1174
+
1175
+ ---
264
1176
 
265
- MIT © 2025 [![license](https://img.shields.io/npm/l/call-control-sdk.svg)](#-license)
1177
+ *Documentation Version: 1.0*
1178
+ *Last Updated: 2025*
1179
+ *SDK Version: 5.3.0*