@koi-design/callkit 1.0.22

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 ADDED
@@ -0,0 +1,272 @@
1
+ # CallKit-1.0.21
2
+
3
+ SIP-based Web Phone Call Toolkit
4
+
5
+ ## Installation
6
+
7
+ ### Method 1: Full Import
8
+
9
+ ```html
10
+ <script src="callkit/index.global.js"></script>
11
+ ```
12
+
13
+ ### Method 2: ESM/CJS Import
14
+
15
+ Install the following dependencies:
16
+
17
+ ```json
18
+ {
19
+ "dependencies": {
20
+ "axios": "~0.26.1",
21
+ "blueimp-md5": "^2.12.0",
22
+ "sip.js": "^0.21.2"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ### Full Import Usage
30
+
31
+ ```html
32
+ <script src="callkit/index.global.js"></script>
33
+ <script>
34
+ const callKit = new WebCall.CallKit({
35
+ host: 'https://example.com',
36
+ log: 'debug',
37
+ audioRef: () => document.querySelector('#audioRef'),
38
+ socket: 'wss://example.com/ws/in-call',
39
+ });
40
+ </script>
41
+ ```
42
+
43
+ ### ESM Import Usage
44
+
45
+ ```js
46
+ import { CallKit } from 'CallKit';
47
+
48
+ const callKit = new CallKit({
49
+ host: 'https://example.com',
50
+ log: 'debug',
51
+ audioRef: () => document.querySelector('#audioRef'),
52
+ socket: 'wss://example.com/ws/in-call',
53
+ });
54
+ ```
55
+
56
+ ## API Documentation
57
+
58
+ ### Configuration Options
59
+
60
+ ```ts
61
+ interface CallKitConfig {
62
+ // Request host address
63
+ host: string;
64
+
65
+ // Audio element object
66
+ audioRef: HTMLAudioElement | (() => HTMLAudioElement);
67
+
68
+ // WebSocket address
69
+ socket: string;
70
+
71
+ // WebRTC constraint configuration
72
+ constrains?: WebrtcConstranis;
73
+
74
+ // Log level
75
+ log?: 'debug' | 'log' | 'warn' | 'error' | 'silent';
76
+
77
+ // User manually maintains sending user status requests
78
+ isAutoUpdateUserStatus: boolean;
79
+ }
80
+ ```
81
+
82
+ ### Instance Methods
83
+
84
+ ```ts
85
+ interface CallKit {
86
+ // User login
87
+ login(username: string, password: string): Promise<void>;
88
+
89
+ // User logout
90
+ logout(): Promise<void>;
91
+
92
+ // Initiate call
93
+ call(): Promise<void>;
94
+
95
+ // SIP registration
96
+ register(): Promise<void>;
97
+
98
+ // SIP unregistration
99
+ unregister(): Promise<void>;
100
+
101
+ // Hang up call
102
+ hangup(): Promise<void>;
103
+
104
+ // Call hold
105
+ hold(): void;
106
+
107
+ // Release hold
108
+ unhold(): void;
109
+
110
+ // Set free status
111
+ setFree(): Promise<void>;
112
+
113
+ // Set nap status
114
+ setSleep(): Promise<void>;
115
+
116
+ // Set busy status
117
+ setBusy(): Promise<void>;
118
+
119
+ // Reset all states
120
+ reset(): Promise<void>;
121
+
122
+ // Event listener
123
+ on(event: string, callback: Function): void;
124
+ }
125
+ ```
126
+
127
+ ### Event List
128
+
129
+ #### Status Events
130
+
131
+ - `userStatusChange` - User status change
132
+ - `loginChange` - Login status change
133
+ - `registerChange` - Registration status change
134
+ - `callStatusChange` - Call status change
135
+ - `holdChange` - Hold status change
136
+ - `muteChange` - Mute status change
137
+
138
+ #### Call Events
139
+
140
+ - `invite` - Received call invitation (with accept, reject, getInviteData callback functions)
141
+ - `connecting` - Connecting (with timestamp parameter)
142
+ - `ringing` - Remote party ringing (with timestamp parameter)
143
+ - `pickUp` - Remote party answered (with timestamp parameter)
144
+ - `agentPickUp` - Agent connected
145
+ - `noAnswer` - No answer
146
+ - `callEnd` - Call ended
147
+ - `callCdr` - Call record push
148
+
149
+ #### Error Events
150
+
151
+ - `error` - Error occurred
152
+
153
+ #### Server Socket Events
154
+
155
+ - `socketEvent` Forward all socket events
156
+
157
+ ## Status Codes
158
+
159
+ ### Call Status
160
+
161
+ ```js
162
+ const CallStatus = {
163
+ init: 0, // Initial state/hung up
164
+ registered: 1, // Registered
165
+ connecting: 2, // Connecting
166
+ holding: 3, // Call hold
167
+ ringing: 4, // Ringing
168
+ calling: 5, // In call
169
+ };
170
+ ```
171
+
172
+ ### User Status
173
+
174
+ ```js
175
+ const UserStatus = {
176
+ offline: 1, // Offline
177
+ online: 2, // Online & Free
178
+ catNap: 3, // Cat Nap
179
+ busy: 4, // Busy
180
+ training: 5, // Training
181
+ processing: 6, // Processing
182
+ };
183
+ ```
184
+
185
+ ### Error Codes
186
+
187
+ ```js
188
+ const ErrorCode = {
189
+ // API errors (1000xxx)
190
+ API_USER_LOGIN_ERROR: 1000001, // User login failed
191
+ API_USER_STATUS_UPDATE_ERROR: 1000002, // Update user status failed
192
+ API_USER_LOGOUT_ERROR: 1000003, // User logout failed
193
+
194
+ // WebRTC errors (2000xxx)
195
+ CONNECT_CALL_STATUS_ERROR: 2000001, // Call status exception
196
+ USER_NOT_LOGIN: 2000002, // User not logged in
197
+ WEBRTC_USER_MEDIA_ERROR: 2000003, // WebRTC not supported
198
+ WEBRTC_HOLE_STATUS_ERROR: 2000004, // Call hold failed
199
+ WEBRTC_AUDIO_PLAYER_ERROR: 2000005, // Audio player does not exist
200
+ WEBRTC_AUDIO_PLAY_ERROR: 2000006, // Audio playback failed
201
+
202
+ // WebSocket errors (3000xxx)
203
+ SOCKET_CONNECT_ERROR: 3000001, // Connection exception
204
+ SOCKET_PING_TIMEOUT: 3000002, // Ping timeout
205
+ SOKET_SERVER_ERROR: 3000003, // Server exception
206
+ SOCKET_CALL_ERROR: 3000004, // Call failed
207
+
208
+ UNKNOWN_ERROR: -1, // Unknown error
209
+ };
210
+ ```
211
+
212
+ ## FAQ
213
+
214
+ ### Q1: How to listen for call status changes?
215
+
216
+ ```js
217
+ callKit.on('callStatusChange', (status) => {
218
+ const statusMap = {
219
+ 0: 'Initial state',
220
+ 1: 'Registered',
221
+ 2: 'Connecting',
222
+ 3: 'Call on hold',
223
+ 4: 'Ringing',
224
+ 5: 'In call',
225
+ };
226
+ console.log('Current status:', statusMap[status]);
227
+ });
228
+ ```
229
+
230
+ ### Q2: How to get call duration?
231
+
232
+ ```js
233
+ let startTime;
234
+
235
+ callKit.on('pickUp', (date) => {
236
+ startTime = date;
237
+ });
238
+
239
+ callKit.on('callEnd', (date) => {
240
+ const duration = date - startTime;
241
+ console.log('Call duration (ms):', duration);
242
+ });
243
+ ```
244
+
245
+ ### Q3: How to handle errors?
246
+
247
+ ```js
248
+ callKit.on('error', (error) => {
249
+ console.error('Error code:', error.code);
250
+ console.error('Error message:', error.message);
251
+
252
+ switch (error.code) {
253
+ case 1000001:
254
+ // Handle login failure
255
+ break;
256
+ case 2000002:
257
+ // Handle not logged in error
258
+ break;
259
+ // Remove CALL_FAILED default handling, at this stage, users need to handle it actively
260
+ // ...other error handling
261
+ }
262
+ });
263
+ ```
264
+
265
+ ## More Information
266
+
267
+ For complete TypeScript type definitions, please refer to [index.d.ts](./dist/index.d.ts)
268
+
269
+ ## License
270
+
271
+ MIT
272
+
@@ -0,0 +1,436 @@
1
+ import { Invitation, UserAgent, Registerer } from 'sip.js';
2
+
3
+ declare class Api {
4
+ private callKit;
5
+ constructor(callKit: CallKit);
6
+ login(params: {
7
+ userName: string;
8
+ password: string;
9
+ }): Promise<any>;
10
+ loginOut(params: {
11
+ sessionId: string;
12
+ }): Promise<any>;
13
+ /**
14
+ *
15
+ * @param params agentId userStatus
16
+ * @description userStatus: Logout(1, "unregistered"), Free(2, "free"), Break(3, "nap"), Busy(4, "busy")
17
+ * @returns
18
+ */
19
+ setUserStatus(params: any): Promise<any>;
20
+ private post;
21
+ }
22
+
23
+ declare class Call {
24
+ private callKit;
25
+ constructor(callKit: CallKit);
26
+ callStart(): Promise<void>;
27
+ /**
28
+ * Hang up
29
+ * @param isUnprompted Whether to actively hang up
30
+ * @param isError Whether an error occurred
31
+ * @returns
32
+ */
33
+ callEnd(isUnprompted?: boolean, isError?: boolean): Promise<void>;
34
+ callHold(): Promise<void>;
35
+ callUnhold(): Promise<void>;
36
+ }
37
+
38
+ type LoggerLevel = 'debug' | 'log' | 'warn' | 'error' | 'silent';
39
+ declare class Logger {
40
+ prefix: string;
41
+ level: LoggerLevel;
42
+ private callKit;
43
+ constructor(callKit: CallKit, level?: LoggerLevel);
44
+ setLevel(level: LoggerLevel): void;
45
+ debug(msg: any, extra?: Object): void;
46
+ log(msg: any, extra?: Object): void;
47
+ warn(msg: any, extra?: Object): void;
48
+ error(msg: any, extra?: any): void;
49
+ output(color: string): (msg: any, extra?: Object) => void;
50
+ }
51
+
52
+ declare const CallStatus: {
53
+ /**
54
+ * Initial state/Hang up
55
+ */
56
+ init: number;
57
+ /**
58
+ * Registered
59
+ */
60
+ registered: number;
61
+ /**
62
+ * Connecting
63
+ */
64
+ connecting: number;
65
+ /**
66
+ * Call on hold
67
+ */
68
+ holding: number;
69
+ /**
70
+ * Ringing
71
+ */
72
+ ringing: number;
73
+ /**
74
+ * In call
75
+ */
76
+ calling: number;
77
+ };
78
+ declare const KitEvent: {
79
+ /**
80
+ * User status change
81
+ */
82
+ KIT_USER_STATUS_CHANGE: string;
83
+ /**
84
+ * User login status change
85
+ */
86
+ KIT_LOGIN_CHANGE: string;
87
+ /**
88
+ * Registration status change
89
+ */
90
+ KIT_REGISTER_CHANGE: string;
91
+ /**
92
+ * Call status change
93
+ */
94
+ KIT_CALL_STATUS_CHANGE: string;
95
+ /**
96
+ * Hold status change
97
+ */
98
+ KIT_SET_HOLD: string;
99
+ /**
100
+ * Mute status change
101
+ */
102
+ KIT_SET_MUTE: string;
103
+ /**
104
+ * Error
105
+ */
106
+ KIT_ERROR: string;
107
+ /**
108
+ * Server initiated call
109
+ */
110
+ KIT_INVITE: string;
111
+ /**
112
+ * Connecting
113
+ */
114
+ CALL_CONNECTING: string;
115
+ /**
116
+ * Customer ringing
117
+ */
118
+ CALL_RINGING: string;
119
+ /**
120
+ * Agent pick up
121
+ */
122
+ AGENT_PICK_UP: string;
123
+ /**
124
+ * Customer answer
125
+ */
126
+ CALL_PICK_UP: string;
127
+ /**
128
+ * Customer no response
129
+ */
130
+ CALL_NO_ANSWER: string;
131
+ /**
132
+ * Customer hang up
133
+ */
134
+ CALL_HANG_UP: string;
135
+ /**
136
+ * Call end
137
+ */
138
+ CALL_END: string;
139
+ /**
140
+ * Call detail record push
141
+ */
142
+ CALL_CDR: string;
143
+ /**
144
+ * Forward all socket events
145
+ */
146
+ SERVER_SOCKET_EVENT: string;
147
+ /**
148
+ * User status change
149
+ */
150
+ USER_STATUS_CHANGE: string;
151
+ };
152
+ declare const SocketSendEvent: {
153
+ /**
154
+ * ping
155
+ */
156
+ PING: string;
157
+ /**
158
+ * Start
159
+ */
160
+ START: string;
161
+ /**
162
+ * Hang up
163
+ */
164
+ AGENT_HANGUP: string;
165
+ /**
166
+ * Cancel
167
+ */
168
+ CALL_CANCEL: string;
169
+ /**
170
+ * Hold
171
+ */
172
+ HOLD: string;
173
+ /**
174
+ * Unhold
175
+ */
176
+ UNHOLD: string;
177
+ /**
178
+ * Call
179
+ */
180
+ CALL: string;
181
+ /**
182
+ * End
183
+ */
184
+ END: string;
185
+ };
186
+
187
+ type SocketSendEventType = (typeof SocketSendEvent)[keyof typeof SocketSendEvent];
188
+ interface SocketConfig {
189
+ enabled: boolean;
190
+ maxAttempts: number;
191
+ delay: number;
192
+ backoffMultiplier: number;
193
+ pingInterval: number;
194
+ pingTimeout: number;
195
+ }
196
+ declare class Socket {
197
+ private callKit;
198
+ private ws?;
199
+ private socketConfig;
200
+ lastPingTime: any;
201
+ isConnected: boolean;
202
+ pingTimer?: number;
203
+ recivedClose: boolean;
204
+ satrtConfirm: boolean;
205
+ private reconnectTimer?;
206
+ private isReconnecting;
207
+ private reconnectAttempts;
208
+ constructor(callKit: CallKit);
209
+ init(): void;
210
+ private connect;
211
+ private onOpen;
212
+ private onClose;
213
+ private onError;
214
+ private onMessage;
215
+ send(event: SocketSendEventType, message?: any): void;
216
+ /**
217
+ * Attempt to close socket, need to wait for server confirmation
218
+ * @returns
219
+ */
220
+ requestClose(): Promise<boolean>;
221
+ private ping;
222
+ private checkPing;
223
+ /**
224
+ *
225
+ * @param isWaitConfirm Whether need to wait for close confirmation
226
+ */
227
+ reset(isWaitConfirm?: boolean): Promise<void>;
228
+ private attemptReconnect;
229
+ }
230
+
231
+ interface WebrtcConstranis {
232
+ audio: {
233
+ autoGainControl?: boolean;
234
+ noiseSuppression?: boolean;
235
+ echoCancellation?: boolean;
236
+ };
237
+ video: false;
238
+ }
239
+ interface IConfig {
240
+ version: string;
241
+ host: string;
242
+ log: LoggerLevel;
243
+ audioRef?: HTMLAudioElement | (() => HTMLAudioElement);
244
+ constrains: WebrtcConstranis;
245
+ socket: string;
246
+ reconnect?: SocketConfig;
247
+ userInfo: {
248
+ wsUrl: string;
249
+ sessionId: string;
250
+ username: string;
251
+ password: string;
252
+ extno: string;
253
+ userPart: string;
254
+ agentId: string;
255
+ fsUserId: string;
256
+ fsPassword: string;
257
+ fsIp: string;
258
+ fsPort: string;
259
+ iceInfo: string[];
260
+ iceGatheringTimeout: number;
261
+ };
262
+ isAutoUpdateUserStatus: boolean;
263
+ }
264
+ declare class Config {
265
+ callKit: CallKit;
266
+ constructor(callKit: CallKit);
267
+ config: IConfig;
268
+ getConfig: () => IConfig;
269
+ setConfig: (key: string, value: any) => Promise<void>;
270
+ setUserInfo: (key: string, value: any) => Promise<void>;
271
+ reset: () => void;
272
+ validate: () => boolean;
273
+ isLogin: () => boolean;
274
+ check(): boolean;
275
+ }
276
+
277
+ type CallStatusType = (typeof CallStatus)[keyof typeof CallStatus];
278
+ declare class Connect {
279
+ callKit: CallKit;
280
+ /**
281
+ * connectStatus: init registered connecting calling
282
+ */
283
+ connectStatus: number;
284
+ currentSession?: Invitation;
285
+ mediaStream?: MediaStream;
286
+ userAgent?: UserAgent;
287
+ registerer?: Registerer;
288
+ sipConnected: boolean;
289
+ /**
290
+ * Whether it's an outgoing call
291
+ */
292
+ isOutgoing: boolean;
293
+ /**
294
+ * Whether it's an active hangup
295
+ */
296
+ isUnprompted: boolean;
297
+ /**
298
+ * Whether registered
299
+ * @param
300
+ * @deprecated Deprecated, please use isRegistered method
301
+ */
302
+ get isRegister(): boolean;
303
+ /**
304
+ * Call hold
305
+ * @param isHold
306
+ */
307
+ isHold: boolean;
308
+ /**
309
+ * Whether muted
310
+ */
311
+ isMute: boolean;
312
+ constructor(callKit: CallKit);
313
+ reset(): void;
314
+ private getAduioReference;
315
+ permission(): Promise<void>;
316
+ isRegistered(): boolean;
317
+ /**
318
+ * Making connection
319
+ * @returns
320
+ */
321
+ isConnecting(): boolean;
322
+ /**
323
+ * In call
324
+ * @returns
325
+ */
326
+ isCalling(): boolean;
327
+ /**
328
+ * Ringing
329
+ */
330
+ isRinging(): boolean;
331
+ /**
332
+ *
333
+ */
334
+ isHolding(): boolean;
335
+ /**
336
+ * Call ended, call not started
337
+ * @returns
338
+ */
339
+ isInit(): boolean;
340
+ register(): Promise<void>;
341
+ unregister(): Promise<void>;
342
+ call(callback: Function): Promise<void>;
343
+ /**
344
+ * Update registration status
345
+ * @param register
346
+ */
347
+ setRegister(register: boolean): void;
348
+ /**
349
+ * Set call status
350
+ * @param status
351
+ */
352
+ setConnectStatus(status: CallStatusType): void;
353
+ /**
354
+ * Hang up
355
+ * @param isUnprompted Whether actively hanging up
356
+ * @param isError Whether an error occurred
357
+ * @returns
358
+ */
359
+ hangup(isUnprompted?: boolean, isError?: boolean): Promise<void>;
360
+ /**
361
+ * The remote media stream. Undefined if call not answered.
362
+ * @param session - Session to get the media stream from.
363
+ */
364
+ getRemoteMediaStream(session: any): any;
365
+ setupRemoteMedia(session: any): void;
366
+ /**
367
+ * Update hold
368
+ * @param hold
369
+ */
370
+ setHoldStatus(hold: boolean): void;
371
+ setHold(hold: boolean): Promise<void>;
372
+ hold(): Promise<void>;
373
+ unhold(): Promise<void>;
374
+ setMute(mute: boolean): Promise<void>;
375
+ mute(): Promise<void>;
376
+ unmute(): Promise<void>;
377
+ }
378
+
379
+ declare class User {
380
+ private callKit;
381
+ userStatus: number;
382
+ constructor(callKit: CallKit);
383
+ /**
384
+ *
385
+ * @param status logout(1, "unregistered"), idle(2, "free"), break(3, "nap"), busy(4, "busy")
386
+ */
387
+ setUserStatus(status: number): Promise<void>;
388
+ /**
389
+ * Update user status
390
+ * @param status
391
+ */
392
+ updateUserStatus(status: number): Promise<void>;
393
+ }
394
+
395
+ interface CallKitConfig {
396
+ host: string;
397
+ audioRef: HTMLAudioElement | (() => HTMLAudioElement);
398
+ socket: string;
399
+ constrains?: WebrtcConstranis;
400
+ log?: LoggerLevel;
401
+ }
402
+ type ConfigEntity = CallKitConfig & Partial<IConfig>;
403
+ type kitEventType = (typeof KitEvent)[keyof typeof KitEvent];
404
+ interface Listener {
405
+ event: kitEventType;
406
+ callback: (...args: any[]) => void;
407
+ }
408
+ declare class CallKit {
409
+ api: Api;
410
+ config: Config;
411
+ logger: Logger;
412
+ callCenter: Call;
413
+ connect: Connect;
414
+ socket: Socket;
415
+ user: User;
416
+ listener: Listener[];
417
+ constructor(options: ConfigEntity);
418
+ login(username: string, password: string, extra?: object): Promise<void>;
419
+ logout(): Promise<void>;
420
+ call(extno?: string | number): Promise<void>;
421
+ register(): Promise<void>;
422
+ unregister(): Promise<void>;
423
+ hangup(): Promise<void>;
424
+ hold(): void;
425
+ unhold(): void;
426
+ setFree(): Promise<void>;
427
+ setSleep(): Promise<void>;
428
+ setBusy(): Promise<void>;
429
+ reset(): Promise<void>;
430
+ on(event: kitEventType, callback: (...args: any[]) => void): void;
431
+ off(event: kitEventType, callback?: (...args: any[]) => void): void;
432
+ removeAllListeners(): void;
433
+ trigger(event: kitEventType, data?: any): void;
434
+ }
435
+
436
+ export { CallKit, CallKitConfig, ConfigEntity, kitEventType };