@koi-design/callkit 2.0.0-beta.1 → 2.0.0-beta.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../package/index.ts","../package/axios.ts","../package/api.ts","../package/const.ts","../package/call.ts","../package/config.ts","../package/logger.ts","../package/connect.ts","../package/socket.ts"],"sourcesContent":["import md5 from 'blueimp-md5';\nimport { Api } from './api';\nimport { Call } from './call';\nimport type { IConfig, WebrtcConstranis } from './config';\nimport { Config } from './config';\nimport type { LoggerLevel } from './logger';\nimport { Logger } from './logger';\nimport { Connect } from './connect';\nimport {\n constrainsDefault,\n KitEvent,\n EncryptionMethod,\n CallSourceType,\n ErrorCode\n} from './const';\nimport { Socket } from './socket';\n\nexport interface CallKitConfig {\n host: string;\n audioRef: HTMLAudioElement | (() => HTMLAudioElement);\n socket: string;\n constrains?: WebrtcConstranis;\n log?: LoggerLevel;\n}\n\nexport type ConfigEntity = CallKitConfig & Partial<IConfig>;\n\nexport type kitEventType = (typeof KitEvent)[keyof typeof KitEvent];\n\ninterface Listener {\n event: kitEventType;\n callback: (...args: any[]) => void;\n}\ninterface CallOptions {\n sourceType: (typeof CallSourceType)[keyof typeof CallSourceType];\n phoneNum?: string;\n workOrderId?: string;\n}\n\nexport class CallKit {\n api: Api;\n config: Config;\n logger: Logger;\n callCenter: Call;\n connect: Connect;\n socket: Socket;\n\n listener: Listener[] = [];\n\n constructor(options: ConfigEntity) {\n this.config = new Config(this);\n this.api = new Api(this);\n this.connect = new Connect(this);\n this.callCenter = new Call(this);\n this.socket = new Socket(this);\n this.config.setConfig('log', options.log);\n this.config.setConfig('trackLogs', options.trackLogs);\n this.config.setConfig('audioRef', options.audioRef);\n this.config.setConfig('host', options.host);\n this.config.setConfig(\n 'constrains',\n options.constrains || constrainsDefault\n );\n this.config.setConfig('socket', options.socket);\n this.config.setConfig('reconnect', options.reconnect);\n this.logger = new Logger(this, options.log);\n\n this.logger.info('callKit init', {\n caller: 'CallKit.init',\n content: options\n });\n }\n\n async login(\n username: string,\n password: string,\n extra: { [key: string]: any } = {\n encryptionMethod: EncryptionMethod.INTERNAL\n }\n ) {\n if (this.config.isLogin()) {\n this.logger.warn('already login', {\n caller: 'CallKit.login',\n content: { username, password, extra }\n });\n return;\n }\n\n let encryptionPassword = '';\n const { encryptionMethod = EncryptionMethod.INTERNAL } = extra;\n switch (encryptionMethod) {\n case EncryptionMethod.NONE:\n encryptionPassword = password;\n break;\n case EncryptionMethod.INTERNAL:\n encryptionPassword = md5(username + md5(password));\n break;\n default:\n encryptionPassword = md5(username + md5(password));\n break;\n }\n\n this.logger.info('login info:', {\n caller: 'CallKit.login',\n content: {\n username,\n password,\n encryptionMethod,\n encryptionPassword\n }\n });\n\n try {\n const user = await this.api.login({\n userName: username,\n password: encryptionPassword\n });\n\n if (user) {\n this.config.setConfig('userInfo', {\n wsUrl: `wss://${user.wsUrl}`,\n sessionId: user.sessionId,\n username,\n password: encryptionPassword,\n encryptionPassword,\n agentId: user.agentId,\n fsUserId: user.fsUserId,\n userPart: user.userPart,\n fsPassword: user.fsPassword,\n fsIp: user.fsIp,\n fsPort: user.fsPort,\n iceInfo: user.iceInfo,\n iceGatheringTimeout: user.iceGatheringTimeout,\n logGather: user.logGather,\n // encryptionType is in extra\n ...extra\n });\n this.socket.init();\n this.trigger(KitEvent.KIT_LOGIN_CHANGE, true);\n }\n } catch (error) {\n this.logger.error(error, {\n caller: 'CallKit.login',\n content: {\n errCode: ErrorCode.API_USER_LOGIN_ERROR\n }\n });\n }\n }\n\n async logout() {\n if (!this.config.check()) return;\n const { userInfo } = this.config.getConfig();\n this.logger.info('logout', {\n caller: 'CallKit.logout',\n content: {\n sessionId: userInfo.sessionId\n }\n });\n if (this.config.isLogin()) {\n const { sessionId } = userInfo;\n try {\n await this.api.loginOut({ sessionId });\n } catch (error) {\n this.logger.error(error, {\n caller: 'CallKit.logout',\n content: {\n errCode: ErrorCode.API_USER_LOGOUT_ERROR\n }\n });\n }\n }\n\n await this.hangup();\n this.socket.reset(false);\n this.connect.reset();\n this.config.reset();\n this.trigger(KitEvent.KIT_LOGIN_CHANGE, false);\n }\n\n async call(\n extno: string | number = '',\n options: CallOptions = {\n sourceType: CallSourceType.phoneNum,\n workOrderId: ''\n }\n ) {\n if (!this.config.check()) return;\n if (!this.connect.isRegistered) {\n this.logger.warn('Currently not registered', {\n caller: 'CallKit.call',\n content: { extno, options }\n });\n return;\n }\n\n const { sourceType, workOrderId } = options;\n this.config.setUserInfo('sourceType', sourceType);\n if (sourceType === CallSourceType.phoneNum) {\n if (extno) {\n this.config.setUserInfo('extno', extno);\n }\n } else if (sourceType === CallSourceType.workOrderId) {\n if (workOrderId) {\n this.config.setUserInfo('workOrderId', workOrderId);\n }\n }\n\n this.logger.info('call', {\n caller: 'CallKit.call',\n content: {\n extno,\n options\n }\n });\n this.callCenter.callStart();\n }\n\n async refer(uri: string, options?: any) {\n if (!this.config.check()) return;\n this.logger.info('refer', {\n caller: 'CallKit.refer',\n content: {\n uri,\n options\n }\n });\n this.callCenter.callRefer(uri, options);\n }\n\n async register() {\n if (!this.config.check()) return;\n this.logger.info('register', {\n caller: 'CallKit.register',\n content: {}\n });\n this.connect.register();\n }\n\n async unregister() {\n if (!this.config.check()) return;\n this.logger.info('unregister', {\n caller: 'CallKit.unregister',\n content: {}\n });\n this.connect.unregister();\n }\n\n async stop() {\n await this.connect.stop();\n }\n\n async hangup() {\n if (!this.config.check()) return;\n this.logger.info('hangup', {\n caller: 'CallKit.hangup',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n if (\n !this.connect.isConnecting() &&\n !this.connect.isRinging() &&\n !this.connect.isCalling() &&\n !this.connect.isHolding()\n ) {\n this.logger.warn('Currently not in a call', {\n caller: 'CallKit.hangup',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n return;\n }\n await this.callCenter.callEnd(true);\n }\n\n hold() {\n if (!this.config.check()) return;\n this.logger.info('hold', {\n caller: 'CallKit.hold',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.callCenter.callHold();\n }\n\n unhold() {\n if (!this.config.check()) return;\n this.logger.info('unhold', {\n caller: 'CallKit.unhold',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.callCenter.callUnhold();\n }\n\n /**\n * set userstatus\n * @param status\n */\n setUserStatus(status: number) {\n const { agentId } = this.config.getConfig().userInfo;\n this.api.updateUserStatus({\n agentId,\n status\n });\n }\n\n async reset() {\n this.logger.info('reset', {\n caller: 'CallKit.reset',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.connect.reset();\n }\n\n on(event: kitEventType, callback: (...args: any[]) => void) {\n this.listener.push({\n event,\n callback\n });\n }\n\n off(event: kitEventType, callback?: (...args: any[]) => void) {\n this.logger.info(`off ${event}`, {\n caller: 'CallKit.off',\n content: {\n event\n }\n });\n if (callback) {\n this.listener = this.listener.filter(\n (item) => !(item.event === event && item.callback === callback)\n );\n } else {\n this.listener = this.listener.filter((item) => item.event !== event);\n }\n }\n\n removeAllListeners() {\n this.listener = this.listener.splice(0, this.listener.length);\n this.logger.info('removeAllListeners', {\n caller: 'CallKit.removeAllListeners',\n content: {\n listener: this.listener\n }\n });\n }\n\n trigger(event: kitEventType, data?: any) {\n this.listener.forEach((item) => {\n if (item.event === event) {\n try {\n item.callback(data);\n } catch (err) {\n this.logger.error('Event callback error:', err);\n }\n }\n });\n }\n}\n","import type { AxiosRequestConfig } from 'axios';\nimport axios from 'axios';\nimport axiosRetry from 'axios-retry';\n\nconst instance = axios.create({\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n }\n});\n\ninstance.interceptors.request.use((config) => config);\n\ninstance.interceptors.response.use(\n (response) => response.data,\n (error) => Promise.reject(error)\n);\n\naxiosRetry(instance, {\n retries: 3, // Maximum number of retries, default is 3\n retryDelay: (retryCount, error) => {\n // Delay between each retry (ms)\n console.log(\n `AJAX Retrying attempt ${retryCount}, error: ${error?.message}`\n );\n return retryCount * 1000; // Incremental wait: 1s, 2s, 3s...\n },\n retryCondition: (error) => {\n // Determines if a retry is needed, returns true to retry\n if (!error.response) return true; // Network error\n return error.response.status < 200 || error.response.status >= 300; // Retry on non-2xx errors\n },\n shouldResetTimeout: true // Whether to reset axios timeout on retry\n});\n\nconst request = (config: AxiosRequestConfig): Promise<any> =>\n instance.request(config);\n\nexport default request;\n","import type { AxiosRequestConfig } from 'axios';\nimport request from './axios';\nimport type { CallKit } from '.';\n\nexport class Api {\n private callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n async login(params: { userName: string; password: string }) {\n return this.post({\n url: '/auth/agentUser/login',\n method: 'post',\n data: params\n });\n }\n\n async loginOut(params: { sessionId: string }) {\n return this.post({\n url: '/auth/agentUser/loginOut',\n method: 'post',\n data: params\n });\n }\n\n async trackLogs(log: string) {\n return this.post(\n { url: '/agent/user/sdkLog', method: 'post', data: { content: [log] } },\n {\n useFormData: true\n }\n );\n }\n\n /**\n *\n * @param params agentId status\n * @returns\n */\n async updateUserStatus(params: any) {\n return this.post({\n url: '/agent/user/changeStatus',\n method: 'post',\n data: params\n });\n }\n\n private async post(config: AxiosRequestConfig, extra: any = {}) {\n const { userInfo, host } = this.callKit.config.getConfig();\n const { sessionId } = userInfo;\n config.url = `${host}${config.url}`;\n config.headers = {\n 'Content-Type': 'application/x-www-form-urlencoded',\n ...config.headers\n };\n\n if (\n config.headers['Content-Type'] === 'application/x-www-form-urlencoded' &&\n extra.useFormData\n ) {\n const formData = new FormData();\n const data = config.data || {};\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n formData.append(key, data[key]);\n }\n }\n config.data = formData;\n } else {\n config.data = new URLSearchParams(config.data).toString();\n }\n\n if (sessionId) {\n config.headers.sessionId = sessionId;\n }\n const res = await request(config).catch(() => {\n // Network error\n this.callKit.config.reset();\n });\n if (!res) {\n this.callKit.config.reset();\n throw new Error('Network error');\n }\n const { code, data, message } = res;\n if (code === '000000') {\n return data;\n }\n\n // Authentication failed, need to re-login\n if (code === '100013') {\n this.callKit.config.reset();\n }\n throw new Error(message ?? 'Request failed');\n }\n}\n","import type { WebrtcConstranis } from './config';\n\nexport const CallStatus = {\n /**\n * Initial state/Hang up\n */\n init: 0,\n // /**\n // * @deprecated Deprecated\n // * Registered\n // */\n // registered: 1,\n /**\n * Connecting\n */\n connecting: 2,\n /**\n * Call on hold\n */\n holding: 3,\n /**\n * Ringing\n */\n ringing: 4,\n /**\n * In call\n */\n calling: 5\n};\n\nexport const KitEvent = {\n /**\n * Log\n */\n KIT_LOG: 'log',\n /**\n * User status change\n */\n KIT_USER_STATUS_CHANGE: 'userStatusChange',\n /**\n * User login status change\n */\n KIT_LOGIN_CHANGE: 'loginChange',\n /**\n * Registration status change\n */\n KIT_REGISTER_CHANGE: 'registerChange',\n /**\n * Call status change\n */\n KIT_CALL_STATUS_CHANGE: 'callStatusChange',\n /**\n * Hold status change\n */\n KIT_SET_HOLD: 'holdChange',\n /**\n * Mute status change\n */\n KIT_SET_MUTE: 'muteChange',\n /**\n * Error\n */\n KIT_ERROR: 'error',\n /**\n * Server initiated call\n */\n KIT_INVITE: 'invite',\n /**\n * Server outgoing initiated call\n */\n KIT_OUTGOING_INVITE: 'outgoingInvite',\n // /**\n // * Referral\n // */\n // KIT_REFER: 'refer',\n /**\n * Connecting\n */\n CALL_CONNECTING: 'connecting',\n /**\n * Customer ringing\n */\n CALL_RINGING: 'ringing',\n\n /**\n * Agent pick up\n */\n AGENT_PICK_UP: 'agentPickUp',\n /**\n * Customer answer\n */\n CALL_PICK_UP: 'pickUp',\n /**\n * Customer no response\n */\n CALL_NO_ANSWER: 'noAnswer',\n\n /**\n * Customer hang up\n */\n CALL_HANG_UP: 'hangUp',\n\n /**\n * Call end\n */\n CALL_END: 'callEnd',\n /**\n * Call detail record push\n */\n CALL_CDR: 'callCdr',\n\n /**\n * Forward all socket events\n */\n SERVER_SOCKET_EVENT: 'socketEvent',\n\n /**\n * User status change\n */\n USER_STATUS_CHANGE: 'userStatusChange',\n\n CONNECT_EVENT: 'CONNECT_EVENT',\n\n SIP_REGISTERER_EVENT: 'sipRegistererEvent',\n SIP_SESSION_EVENT: 'sipSessionEvent'\n};\n\nexport const ErrorCode = {\n /**\n * Unknown error\n */\n UNKNOWN_ERROR: -1,\n /**\n * API user login failed\n */\n API_USER_LOGIN_ERROR: 1000001,\n /**\n * API user status update failed\n */\n API_USER_STATUS_UPDATE_ERROR: 1000002,\n\n /**\n * API user logout failed\n */\n API_USER_LOGOUT_ERROR: 1000003,\n\n /**\n * connectStatus call status error\n */\n CONNECT_CALL_STATUS_ERROR: 2000001,\n /**\n * User not logged in\n */\n USER_NOT_LOGIN: 2000002,\n /**\n * Browser version too low, does not support webrtc getUserMedia\n */\n WEBRTC_USER_MEDIA_ERROR: 2000003,\n /**\n * Call hold failed\n */\n WEBRTC_HOLE_STATUS_ERROR: 2000004,\n /**\n * Audio player does not exist\n */\n WEBRTC_AUDIO_PLAYER_ERROR: 2000005,\n /**\n * Audio playback failed\n */\n WEBRTC_AUDIO_PLAY_ERROR: 2000006,\n /**\n * User agent startup failed\n */\n WEBRTC_USER_AGENT_ERROR: 2000007,\n /**\n * Call request failed\n */\n WEBRTC_CALL_INVITE_ERROR: 2000008,\n /**\n * Register request failed\n */\n WEBRTC_REGISTER_ERROR: 2000009,\n /**\n * Mute failed\n */\n WEBRTC_MUTE_STATUS_ERROR: 2000010,\n /**\n * Unregister failed\n */\n WEBRTC_CANCEL_REGISTER_ERROR: 2000011,\n\n /**\n * Mute failed\n */\n WEBRTC_MUTE_ERROR: 2000012,\n\n /**\n * Socket connection error\n */\n SOCKET_CONNECT_ERROR: 3000001,\n /**\n * Ping timeout\n */\n SOCKET_PING_TIMEOUT: 3000002,\n /**\n * Server error\n */\n SOKET_SERVER_ERROR: 3000003,\n /**\n * API call failed\n */\n SOCKET_CALL_ERROR: 3000004,\n /**\n * Reconnection limit exceeded\n */\n SOCKET_RECONNECT_FAILED: 3000005\n};\n\nexport const LoggerLevelMap = {\n info: 9,\n success: 4,\n warn: 3,\n error: 2,\n silent: 1\n};\n\n// Send events\nexport const SocketSendEvent = {\n /**\n * ping\n */\n PING: 'PING',\n /**\n * Start\n */\n START: 'START',\n /**\n * Hang up\n */\n AGENT_HANGUP: 'AGENT_HANG_UP',\n /**\n * Cancel\n */\n CALL_CANCEL: 'AGENT_CANCEL',\n /**\n * Hold\n */\n HOLD: 'AGENT_HOLD',\n /**\n * Unhold\n */\n UNHOLD: 'AGENT_UN_HOLD',\n /**\n * Call\n */\n CALL: 'CALL',\n /**\n * End\n */\n END: 'STOP',\n /**\n * AGENT_TRANSFER\n */\n AGENT_TRANSFER: 'AGENT_TRANSFER',\n /**\n * AGENT_TRANSFER\n */\n HANG_UP_REASON: 'HANG_UP_REASON',\n\n ACK: 'ACK'\n};\n\n// Receive events\nexport const SocketReceiveEvent = {\n /**\n * Response\n */\n PONG: 'PONG',\n /**\n * Start confirmation\n */\n START_CONFIRM: 'START_CONFIRM',\n /**\n * Call success\n */\n CALL_SUCCESS: 'CALL_SUCCESS',\n /**\n * Call failed\n */\n CALL_FAILED: 'CALL_FAILED',\n /**\n * Customer ringing\n */\n CUSTOMER_RINGING: 'CUSTOMER_RINGING',\n\n /**\n * Agent pick up\n */\n AGENT_PICK_UP: 'AGENT_PICK_UP',\n /**\n * Customer pick up\n */\n CUSTOMER_PICK_UP: 'CUSTOMER_PICK_UP',\n /**\n * Customer no answer\n */\n CUSTOMER_NO_ANSWER: 'CUSTOMER_NO_ANSWER',\n /**\n * Customer hang up\n */\n CUSTOMER_HANG_UP: 'CUSTOMER_HANG_UP',\n /**\n * Agent no answer\n */\n AGENT_NO_ANSWER: 'AGENT_NO_ANSWER',\n /**\n * Call detail record push\n */\n CALL_CDR: 'CALL_CDR',\n /**\n * Stop confirmation\n */\n STOP_CONFIRM: 'STOP_CONFIRM',\n /**\n * Close\n */\n CLOSE: 'CLOSE',\n /**\n * Error\n */\n ERROR: 'ERROR'\n};\n\nexport const EncryptionMethod = {\n NONE: 'NONE',\n INTERNAL: 'INTERNAL'\n};\nexport type EncryptionMethodType =\n (typeof EncryptionMethod)[keyof typeof EncryptionMethod];\n\nexport const constrainsDefault: WebrtcConstranis = {\n audio: {\n autoGainControl: true,\n // Noise suppression\n noiseSuppression: true,\n // Set echo cancellation\n echoCancellation: true\n },\n video: false\n};\n\nexport const CallSourceType = {\n phoneNum: 1,\n workOrderId: 2\n};\n","import { CallStatus, SocketSendEvent, CallSourceType } from './const';\nimport { type CallKit } from './index';\n\nexport class Call {\n private callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n async callStart() {\n if (!this.callKit.config.check()) return;\n this.callKit.logger.info('callStart', {\n caller: 'Call.callStart',\n content: {\n startConfirm: this.callKit.socket.satrtConfirm\n }\n });\n if (!this.callKit.socket.satrtConfirm) {\n this.callKit.logger.warn('server not confirm start', {\n caller: 'Call.callStart',\n content: {\n startConfirm: this.callKit.socket.satrtConfirm\n }\n });\n return;\n }\n this.callKit.connect.call(async (user) => {\n let queryTrain = {};\n if (user.sourceType === CallSourceType.phoneNum) {\n queryTrain = {\n agentId: user.agentId,\n phoneNum: user.extno,\n sourceType: user.sourceType\n };\n } else if (user.sourceType === CallSourceType.workOrderId) {\n queryTrain = {\n agentId: user.agentId,\n workOrderId: user.workOrderId,\n sourceType: user.sourceType\n };\n }\n this.callKit.socket.send(SocketSendEvent.CALL, queryTrain);\n });\n }\n\n /**\n * Refer\n * @param referTo - The referral target. If a `Session`, a REFER w/Replaces is sent.\n * @returns\n */\n async callRefer(referTo: string, options?: any) {\n if (!this.callKit.config.check()) return;\n this.callKit.logger.info('callRefer', {\n caller: 'Call.callRefer',\n content: {\n referTo,\n options\n }\n });\n this.callKit.connect.refer(referTo, options);\n }\n\n /**\n * Hang up\n * @param isUnprompted Whether to actively hang up\n * @param isError Whether an error occurred\n * @returns\n */\n async callEnd(isUnprompted = false, isError = false) {\n if (this.callKit.connect.connectStatus === CallStatus.init) return;\n if (!this.callKit.config.check()) return;\n this.callKit.connect.hangup(isUnprompted, isError);\n }\n\n async callHold() {\n if (!this.callKit.config.check()) return;\n if (!this.callKit.connect.isCalling()) {\n this.callKit.logger.warn('Current state cannot be held', {\n caller: 'Call.callHold',\n content: {\n isCalling: this.callKit.connect.isCalling()\n }\n });\n return;\n }\n this.callKit.socket.send(SocketSendEvent.HOLD);\n this.callKit.connect.setConnectStatus(CallStatus.holding);\n }\n\n async callUnhold() {\n if (!this.callKit.config.check()) return;\n if (!this.callKit.connect.isHolding()) {\n this.callKit.logger.warn('Current state cannot unhold', {\n caller: 'Call.callUnhold',\n content: {\n isHolding: this.callKit.connect.isHolding()\n }\n });\n return;\n }\n this.callKit.socket.send(SocketSendEvent.UNHOLD);\n this.callKit.connect.setConnectStatus(CallStatus.calling);\n }\n}\n","import type { CallKit } from '.';\nimport type { EncryptionMethodType } from './const';\nimport {\n constrainsDefault,\n ErrorCode,\n KitEvent,\n EncryptionMethod,\n CallSourceType\n} from './const';\nimport { type LoggerLevel } from './logger';\nimport type { SocketConfig } from './socket';\n\nexport interface WebrtcConstranis {\n audio: {\n autoGainControl?: boolean;\n noiseSuppression?: boolean;\n echoCancellation?: boolean;\n };\n video: false;\n}\n\nexport interface IConfig {\n version: string;\n host: string;\n log: LoggerLevel;\n trackLogs: boolean;\n audioRef?: HTMLAudioElement | (() => HTMLAudioElement);\n constrains: WebrtcConstranis;\n socket: string;\n reconnect?: SocketConfig;\n userInfo: {\n wsUrl: string;\n sessionId: string;\n username: string;\n password: string;\n encryptionPassword: string;\n sourceType: (typeof CallSourceType)[keyof typeof CallSourceType];\n extno: string;\n workOrderId: string;\n userPart: string;\n agentId: string;\n fsUserId: string;\n fsPassword: string;\n fsIp: string;\n fsPort: string;\n iceInfo: string[];\n iceGatheringTimeout: number;\n encryptionMethod: EncryptionMethodType;\n };\n}\n\nexport class Config {\n callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n config: IConfig = {\n version: '1.0.27',\n host: '',\n log: 'info',\n trackLogs: false,\n audioRef: undefined,\n constrains: constrainsDefault,\n socket: '',\n userInfo: {\n wsUrl: '',\n\n sessionId: '',\n // User\n username: '',\n // Password\n password: '',\n encryptionPassword: EncryptionMethod.INTERNAL,\n\n sourceType: CallSourceType.phoneNum,\n // Extension number\n extno: '',\n workOrderId: '',\n\n userPart: '',\n\n agentId: '',\n\n fsUserId: '',\n\n fsPassword: '',\n fsIp: '',\n fsPort: '',\n iceInfo: [],\n iceGatheringTimeout: 0,\n encryptionMethod: EncryptionMethod.INTERNAL\n }\n };\n\n getConfig = () => this.config;\n\n setConfig = async (key: string, value: any) => {\n this.config[key] = value;\n };\n\n setUserInfo = async (key: string, value: any) => {\n this.config.userInfo[key] = value;\n this.callKit.logger.info('setUserInfo', {\n caller: 'Config.setUserInfo',\n content: {\n key,\n value\n }\n });\n };\n\n reset = () => {\n if (this.isLogin()) {\n this.config.userInfo = {\n wsUrl: '',\n sessionId: '',\n username: '',\n password: '',\n encryptionPassword: '',\n userPart: '',\n sourceType: CallSourceType.phoneNum,\n extno: '',\n workOrderId: '',\n agentId: '',\n fsUserId: '',\n fsPassword: '',\n fsIp: '',\n fsPort: '',\n iceInfo: [],\n iceGatheringTimeout: this.config.userInfo.iceGatheringTimeout,\n encryptionMethod: EncryptionMethod.INTERNAL\n };\n this.callKit.trigger(KitEvent.KIT_LOGIN_CHANGE, false);\n }\n };\n\n validate = () => {\n const { userPart, fsIp, fsPassword, fsPort } = this.config.userInfo;\n if (!userPart || !fsIp || !fsPort || !fsPassword) {\n return false;\n }\n return true;\n };\n\n isLogin = () => this.validate();\n\n check() {\n if (!this.isLogin()) {\n this.callKit.logger.warn('User not logged in', {\n caller: 'Config.check',\n content: {\n errCode: ErrorCode.USER_NOT_LOGIN\n }\n });\n return false;\n }\n return true;\n }\n}\n","import stringify from 'json-stringify-safe';\nimport type { CallKit } from '.';\nimport { ErrorCode, KitEvent, LoggerLevelMap } from './const';\n\nexport type LoggerLevel = 'info' | 'success' | 'warn' | 'error' | 'silent';\n\nexport interface Log {\n timestamp: string;\n level: LoggerLevel;\n type?: 'INCALL' | 'SIP' | 'API' | 'OTHER';\n message: string;\n caller: string;\n content: Record<string, any>;\n}\n\ntype LogEntity = Omit<Log, 'timestamp' | 'level' | 'message'>;\n\nfunction getLevel(level: LoggerLevel) {\n return LoggerLevelMap[level];\n}\n\nfunction transformLog(log: Log): string {\n const { timestamp, level, type = 'OTHER', message, caller, content } = log;\n const logLevel = String(level).toUpperCase();\n return `${timestamp} [${logLevel}] [${type}] [${\n caller ?? 'unknown'\n }] [${message}] ${stringify(content)}`.trim();\n}\n\nconst MAX_SIZE = 8192;\nconst FLUSH_INTERVAL = 5000;\n\nfunction getByteSize(str: string): number {\n return new Blob([str]).size;\n}\n\nexport class Logger {\n prefix = 'CallKit';\n level: LoggerLevel = 'info';\n private pendingTrackLogs: string[] = [];\n private trackLogsTimer: number | null = null;\n\n private callKit: CallKit;\n constructor(callKit: CallKit, level?: LoggerLevel) {\n this.callKit = callKit;\n this.level = level || 'info';\n this.startTrackLogsTimer();\n }\n\n private startTrackLogsTimer() {\n if (this.trackLogsTimer) {\n return;\n }\n this.trackLogsTimer = setInterval(() => {\n this.flushTrackLogs();\n }, FLUSH_INTERVAL);\n }\n\n private flushTrackLogs() {\n if (this.pendingTrackLogs.length === 0) {\n return;\n }\n const { trackLogs } = this.callKit.config.getConfig();\n if (trackLogs) {\n try {\n const chunks: string[] = [];\n let currentChunk: string[] = [];\n let currentSize = 0;\n\n for (const log of this.pendingTrackLogs) {\n const logSize = getByteSize(log);\n const separator = currentChunk.length > 0 ? '\\n' : '';\n const separatorSize = getByteSize(separator);\n\n if (\n currentSize + logSize + separatorSize > MAX_SIZE &&\n currentChunk.length > 0\n ) {\n chunks.push(currentChunk.join('\\n'));\n currentChunk = [log];\n currentSize = logSize;\n } else {\n currentChunk.push(log);\n currentSize += logSize + separatorSize;\n }\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk.join('\\n'));\n }\n\n for (const chunk of chunks) {\n this.callKit.api.trackLogs(chunk);\n }\n\n this.pendingTrackLogs = [];\n } catch (error) {\n console.error(error);\n }\n }\n }\n\n destroy() {\n if (this.trackLogsTimer) {\n clearInterval(this.trackLogsTimer);\n this.trackLogsTimer = null;\n }\n this.flushTrackLogs();\n }\n\n setLevel(level: LoggerLevel) {\n this.level = level;\n }\n\n info(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'info');\n if (getLevel(this.level) >= getLevel('info')) {\n console.log(`%c${logString}`, `color: gray;`);\n }\n }\n\n success(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'success');\n if (getLevel(this.level) >= getLevel('success')) {\n console.log(`%c${logString}`, `color: green;`);\n }\n }\n\n warn(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'warn');\n if (getLevel(this.level) >= getLevel('warn')) {\n console.log(`%c${logString}`, `color: orange;`);\n }\n }\n\n error(msg: string | Error, extra: LogEntity) {\n const errorMsg = msg instanceof Error ? msg.message : msg;\n const logString = this.catchLog(errorMsg, extra, 'error');\n if (getLevel(this.level) >= getLevel('error')) {\n console.log(`%c${logString}`, `color: red;`);\n }\n const { errCode, ...rest } = extra?.content ?? {};\n const errorCode = errCode ?? ErrorCode.UNKNOWN_ERROR;\n\n this.callKit.trigger(KitEvent.KIT_ERROR, {\n code: errorCode,\n msg: errorMsg,\n data: rest\n });\n const error = new Error(errorMsg);\n error.name = 'CallKitError';\n (error as any).code = errorCode;\n (error as any).data = rest;\n throw error;\n }\n\n private catchLog(msg: string, extra: LogEntity, level: LoggerLevel): string {\n const now = new Date();\n const log: Log = {\n timestamp: now.toLocaleString().replace('T', ' ').replace('.000Z', ''),\n level,\n message: msg,\n caller: extra?.caller,\n type: extra?.type,\n content: extra?.content ?? {}\n };\n const logString = transformLog(log);\n const { trackLogs } = this.callKit.config.getConfig();\n if (trackLogs) {\n this.pendingTrackLogs.push(logString);\n }\n this.callKit.trigger(KitEvent.KIT_LOG, logString);\n return logString;\n }\n}\n","import type { Invitation, UserAgentOptions } from 'sip.js';\n\nimport {\n UserAgent,\n Web,\n Registerer,\n SessionState,\n RegistererState\n} from 'sip.js';\n\nimport type { CallKit } from '.';\nimport { CallStatus, ErrorCode, KitEvent, SocketSendEvent } from './const';\nimport type { IConfig } from './config';\n\nexport interface ConnectReconnectConfig {\n maxAttempts: number;\n delay: number;\n}\n\nconst DEFAULT_RECONNECT_CONFIG: ConnectReconnectConfig = {\n maxAttempts: 3,\n delay: 500\n};\n\nconst MAX_HEARTBEAT_COUNT = 6;\n\nfunction convertObjectStringToJSON(input) {\n // Use regular expressions to add double quotes to keys and values\n const corrected = input\n .replace(/(\\w+):\\s*'(.*?)'/g, '\"$1\": \"$2\"')\n .replace(/'/g, '\"');\n\n return corrected;\n}\n\nconst closeStream = (stream) => {\n if (stream) stream.getTracks().forEach((track) => track.stop());\n};\n\nconst initUserMedia = (): void => {\n if (typeof navigator.mediaDevices === 'undefined') {\n (navigator as any).mediaDevices = {} as MediaDevices;\n }\n if (typeof navigator.mediaDevices.getUserMedia === 'undefined') {\n navigator.mediaDevices.getUserMedia = (\n constraints: MediaStreamConstraints\n ): Promise<MediaStream> => {\n const getUserMedia =\n (navigator as any).getUserMedia ||\n (navigator as any).webkitGetUserMedia ||\n (navigator as any).mozGetUserMedia;\n if (!getUserMedia) {\n return Promise.reject(\n new Error(\n 'Unable to obtain device permissions. Please check your browser settings or device permissions.'\n )\n );\n }\n return new Promise((resolve, reject) => {\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n };\n }\n};\n\n// const enableSenderTracks = (session, enable) => {\n// const { sessionDescriptionHandler } = session;\n// sessionDescriptionHandler.enableSenderTracks(enable);\n// };\n\n// const enableReceiverTracks = (session, enable) => {\n// const { sessionDescriptionHandler } = session;\n// sessionDescriptionHandler.enableReceiverTracks(enable);\n// };\n\nexport type CallStatusType = (typeof CallStatus)[keyof typeof CallStatus];\n\nexport class Connect {\n callKit: CallKit;\n\n /**\n * connectStatus: init registered connecting calling\n */\n connectStatus = CallStatus.init;\n currentSession?: Invitation;\n mediaStream?: MediaStream;\n userAgent?: UserAgent;\n registerer?: Registerer;\n\n // current call id for invite data\n currentCallId?: string;\n\n /**\n * Whether it's a re-connected\n */\n isReConnected = false;\n\n observeOptionsHeartbeatHandler: ReturnType<typeof setTimeout> | null = null;\n\n // sipConnected = false;\n /**\n * Whether it's an outgoing call\n */\n isOutgoing = false;\n\n /**\n * Whether it's an active hangup\n */\n isUnprompted = false;\n isCurrentSessionInvited = false;\n\n private reconnectConfig: ConnectReconnectConfig;\n\n /**\n * Whether muted\n */\n isMute = false;\n\n /**\n * Whether registered\n */\n isRegistered = false;\n\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n const { reconnect = {} } = this.callKit.config.getConfig();\n this.reconnectConfig = {\n ...DEFAULT_RECONNECT_CONFIG,\n ...reconnect\n };\n }\n\n reset() {\n if (this.isHolding()) {\n this.setHoldStatus(false);\n }\n if (this.connectStatus !== CallStatus.init) {\n this.setConnectStatus(CallStatus.init);\n }\n if (this.isRegistered) {\n this.unregister();\n }\n\n this.currentSession = undefined;\n this.mediaStream = undefined;\n this.userAgent = undefined;\n this.registerer = undefined;\n this.isOutgoing = false;\n this.isUnprompted = false;\n if (this.mediaStream) {\n try {\n closeStream(this.mediaStream);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.pause();\n audioRef.srcObject = null;\n }\n } catch (error) {\n this.callKit.logger.error(error, {\n caller: 'Connect.reset',\n content: {}\n });\n }\n }\n\n this.setConnectStatus(CallStatus.init);\n this.clearObserveOptionsHeartbeatInterval();\n }\n\n private getAduioReference() {\n const { audioRef } = this.callKit.config.getConfig();\n if (typeof audioRef === 'function') {\n return audioRef();\n }\n return audioRef;\n }\n\n async permission() {\n this.callKit.logger.info('permission', {\n caller: 'Connect.permission',\n content: {\n permission: true\n }\n });\n initUserMedia();\n const _stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n closeStream(_stream);\n }\n\n /**\n * Making connection\n * @returns\n */\n isConnecting() {\n return this.connectStatus === CallStatus.connecting;\n }\n\n /**\n * In call\n * @returns\n */\n isCalling() {\n return this.connectStatus === CallStatus.calling;\n }\n\n /**\n * Ringing\n */\n isRinging() {\n return this.connectStatus === CallStatus.ringing;\n }\n\n /**\n *\n */\n isHolding() {\n return this.connectStatus === CallStatus.holding;\n }\n\n /**\n * Call ended, call not started\n * @returns\n */\n isInit() {\n return this.connectStatus === CallStatus.init;\n }\n\n clearObserveOptionsHeartbeatInterval() {\n if (this.observeOptionsHeartbeatHandler !== null) {\n clearInterval(this.observeOptionsHeartbeatHandler);\n this.observeOptionsHeartbeatHandler = null;\n }\n }\n\n heartbeatFlag = MAX_HEARTBEAT_COUNT;\n startHeartbeat() {\n this.heartbeatFlag = MAX_HEARTBEAT_COUNT;\n setTimeout(() => {\n this.heartbeatFlag -= 1;\n if (this.heartbeatFlag <= 0) {\n this.heartbeatFlag = MAX_HEARTBEAT_COUNT;\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'OPTIONS_HEARTBEAT_EXPIRED'\n });\n }\n }, 1000);\n }\n\n async register() {\n if (this.connectStatus !== CallStatus.init) {\n if (this.isRegistered) {\n this.callKit.logger.warn('connectStatus is registered', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.CONNECT_CALL_STATUS_ERROR\n }\n });\n return;\n }\n this.callKit.logger.error('connectStatus is not init', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.CONNECT_CALL_STATUS_ERROR\n }\n });\n this.callKit.reset();\n return;\n }\n\n this.callKit.logger.info('connect register', {\n caller: 'Connect.register',\n content: {\n connectStatus: this.connectStatus\n }\n });\n\n await this.permission().catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.WEBRTC_USER_MEDIA_ERROR\n }\n });\n this.callKit.reset();\n });\n\n const { userInfo, constrains } = this.callKit.config.getConfig();\n\n const localStreamFactory = async () => {\n this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);\n return this.mediaStream;\n };\n\n const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;\n\n const connectConfig: UserAgentOptions = {\n uri: UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),\n displayName: userPart,\n transportOptions: {\n wsServers: [wsUrl],\n traceSip: true\n },\n logLevel: 'error',\n allowLegacyNotifications: true,\n contactName: userPart,\n sessionDescriptionHandlerFactory:\n Web.defaultSessionDescriptionHandlerFactory(localStreamFactory),\n sessionDescriptionHandlerFactoryOptions: {\n constraints: constrains,\n iceGatheringTimeout: userInfo.iceGatheringTimeout,\n peerConnectionConfiguration: {\n iceServers: JSON.parse(convertObjectStringToJSON(iceInfo))\n }\n }\n };\n\n this.callKit.logger.info('connect connectConfig', {\n caller: 'Connect.register',\n content: connectConfig\n });\n\n this.userAgent = new UserAgent(connectConfig);\n\n const remoteStream = new MediaStream();\n\n const setupRemoteMedia = (session) => {\n const audioRef = this.getAduioReference();\n this.callKit.logger.info('connect setupRemoteMedia', {\n caller: 'Connect.register.setupRemoteMedia',\n content: audioRef\n });\n session.sessionDescriptionHandler.peerConnection\n .getReceivers()\n .forEach((receiver) => {\n if (receiver.track) {\n remoteStream.addTrack(receiver.track);\n }\n });\n\n if (audioRef) {\n audioRef.srcObject = remoteStream;\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.register.setupRemoteMedia',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n } else {\n this.callKit.logger.error('video is not exist', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAYER_ERROR\n }\n });\n }\n };\n\n const observeSocketStatus = (userAgent: UserAgent, extra?: any) => {\n const { that = this } = extra;\n // Get userAgentCore\n const core: any = (userAgent as any).userAgentCore;\n // Save the original receiveRequest method\n const originalReceiveRequest = core.receiveRequest.bind(core);\n // Proxy receiveRequest\n core.receiveRequest = (request: any) => {\n if (request.method === 'OPTIONS') {\n that.startHeartbeat();\n }\n that.callKit.logger.info(`SIP Receive Request: ${request.method}`, {\n caller: 'Connect.register.observeSocketStatus',\n type: 'SIP',\n content: {\n request\n }\n });\n // Other requests are handled by the original method\n return originalReceiveRequest(request);\n };\n\n // Get transport layer to intercept outgoing messages\n const { transport } = userAgent as any;\n if (transport) {\n // Save the original send method\n const originalSend = transport.send.bind(transport);\n // Proxy transport send to capture outgoing messages\n transport.send = (message: any) => {\n that.callKit.logger.info(`SIP send message`, {\n caller: 'Connect.register.observeSocketStatus',\n type: 'SIP',\n content: {\n message: message.toString()\n }\n });\n // Send the message using the original method\n return originalSend(message);\n };\n }\n };\n\n const registererOptions = {};\n this.registerer = new Registerer(this.userAgent, registererOptions);\n\n this.registerer.stateChange.addListener((state) => {\n switch (state) {\n // No registration relationship established with the SIP server yet\n case RegistererState.Initial:\n this.callKit.logger.info('registerer stateChange Initial', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n registererState: state,\n isRegistered: this.isRegistered\n });\n break;\n // REGISTER request was successful, the User Agent has completed registration on the server.\n case RegistererState.Registered:\n this.callKit.logger.info('registerer stateChange Registered', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(true);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n registererState: state,\n isRegistered: this.isRegistered\n });\n break;\n // Just unregistered, can call register() to re-register\n case RegistererState.Terminated:\n this.callKit.logger.info('registerer stateChange Terminated', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n isRegistered: this.isRegistered,\n registererState: state\n });\n break;\n // Just unregistered, can register() again to re-register\n case RegistererState.Unregistered:\n this.callKit.logger.info('registerer stateChange Unregistered', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n isRegistered: this.isRegistered,\n registererState: state\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n isRegistered: this.isRegistered,\n registererState: state\n });\n break;\n default:\n break;\n }\n });\n\n this.userAgent.delegate = {\n onInvite: (invite) => {\n this.callKit.logger.info('connect onInvite', {\n type: 'SIP',\n caller: 'Connect.register.onInvite',\n content: {\n invite,\n isRegistered: this.isRegistered\n }\n });\n this.currentSession = invite;\n if (this.isOutgoing) {\n this.isCurrentSessionInvited = false;\n }\n this.currentSession.stateChange.addListener((state) => {\n switch (state) {\n case SessionState.Establishing:\n this.callKit.logger.info('connect Establishing', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n this.setConnectStatus(CallStatus.ringing);\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n case SessionState.Established:\n this.callKit.logger.info('connect Established', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n this.callKit.connect.setConnectStatus(CallStatus.calling);\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n setupRemoteMedia(this.currentSession);\n break;\n case SessionState.Terminating:\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n case SessionState.Terminated:\n this.callKit.logger.info('connect Terminated', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n if (this.isUnprompted) {\n if (this.isCurrentSessionInvited) {\n this.currentSession.reject();\n }\n } else {\n this.callKit.callCenter.callEnd();\n }\n this.isUnprompted = false;\n\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n default:\n break;\n }\n });\n\n const options = {\n sessionDescriptionHandlerOptions: {\n constraints: constrains,\n alwaysAcquireMediaFirst: true\n }\n };\n // Active dialing, automatically answer when connecting\n if (this.isOutgoing) {\n this.currentSession.accept(options);\n this.setConnectStatus(CallStatus.connecting);\n this.callKit.trigger(KitEvent.KIT_OUTGOING_INVITE, {\n getInviteData: () => {\n const { request } = this.currentSession;\n const headerNames = Object.keys(request.headers);\n const xHeaders = {};\n headerNames\n .filter((name) =>\n name.toLocaleLowerCase().startsWith('x-antaios')\n )\n .forEach((name) => {\n xHeaders[name.toLocaleLowerCase()] = request.getHeader(name);\n });\n this.callKit.logger.info('get invite data', {\n caller: 'Connect.register.onInvite',\n content: xHeaders\n });\n return xHeaders;\n }\n });\n } else {\n const reject = () => {\n this.currentSession.reject();\n this.callKit.callCenter.callEnd(true, false);\n };\n\n this.callKit.trigger(KitEvent.KIT_INVITE, {\n accept: () => {\n this.isCurrentSessionInvited = true;\n this.callKit.trigger(KitEvent.CALL_CONNECTING, new Date());\n this.currentSession.accept(options);\n },\n reject,\n getInviteData: () => {\n const { request } = this.currentSession;\n const headerNames = Object.keys(request.headers);\n const xHeaders = {};\n headerNames\n .filter((name) =>\n name.toLocaleLowerCase().startsWith('x-antaios')\n )\n .forEach((name) => {\n xHeaders[name.toLocaleLowerCase()] = request.getHeader(name);\n });\n this.callKit.logger.info('get invite data', {\n caller: 'Connect.register',\n content: xHeaders\n });\n return xHeaders;\n }\n });\n }\n },\n onConnect: async () => {\n this.reconnectAttempts = 0;\n this.reconnectTimer = null;\n this.callKit.logger.info('connect onConnect', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n version: `V${this.callKit.config.getConfig().version}`\n }\n });\n const version = `V${this.callKit.config.getConfig().version}`;\n await this.registerer\n .register()\n .then(() => {\n this.callKit.socket.send(SocketSendEvent.START, {\n version\n });\n })\n .catch(async (err) => {\n this.callKit.logger.error(err?.message, {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_REGISTER_ERROR\n }\n });\n this.callKit.reset();\n });\n },\n onDisconnect: (error?: Error) => {\n console.log('onDisconnect', error);\n if (error) {\n this.startReconnectTimer();\n } else {\n this.callKit.logger.info('SIP User Agent Disconnected', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n err: error.message,\n errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR\n }\n });\n }\n },\n onRegister: () => {\n this.callKit.logger.info('connect onRegister', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n version: `V${this.callKit.config.getConfig().version}`\n }\n });\n }\n };\n\n observeSocketStatus(this.userAgent, {\n that: this\n });\n\n await this.userAgent.start().catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR\n }\n });\n this.callKit.reset();\n });\n }\n\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private reconnectAttempts = 0;\n\n private startReconnectTimer() {\n if (this.reconnectAttempts >= this.reconnectConfig.maxAttempts) {\n this.callKit.logger.error('Reconnect failed max attempts', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n errCode: ErrorCode.SOCKET_RECONNECT_FAILED,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n this.callKit.reset();\n return;\n }\n\n this.callKit.logger.info('Reconnect timer started', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n\n this.reconnectAttempts += 1;\n this.reconnectTimer = setTimeout(() => {\n if (this.reconnectTimer) {\n this.userAgent.reconnect();\n this.callKit.logger.info('Reconnect attempt', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n } else {\n this.callKit.logger.info('Reconnect timer already expired', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n }\n }, this.reconnectConfig.delay);\n }\n\n async stop() {\n await this.userAgent.stop();\n }\n\n async unregister() {\n this.callKit.logger.info('connect unregister', {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n isRegistered: this.isRegistered,\n registerer: this.registerer\n }\n });\n if (!this.isRegistered || !this.registerer) {\n this.callKit.logger.warn('No registerer to unregister.', {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_CANCEL_REGISTER_ERROR\n }\n });\n return;\n }\n await this.registerer.unregister({ all: true }).catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_CANCEL_REGISTER_ERROR\n }\n });\n this.callKit.reset();\n });\n }\n\n async call(callback: (userInfo: IConfig['userInfo']) => void) {\n this.callKit.logger.info('connect call', {\n caller: 'Connect.call',\n type: 'SIP',\n content: {\n callback\n }\n });\n this.isOutgoing = true;\n if (!this.isRegistered) {\n await this.register();\n }\n this.setConnectStatus(CallStatus.connecting);\n this.callKit.trigger(KitEvent.CALL_CONNECTING, new Date());\n const { userInfo } = this.callKit.config.getConfig();\n callback(userInfo);\n }\n\n /**\n * Update registration status\n * @param register\n */\n setRegister(register: boolean) {\n this.callKit.logger.info('connect setRegister', {\n caller: 'Connect.setRegister',\n type: 'SIP',\n content: {\n register\n }\n });\n this.isRegistered = register;\n this.callKit.trigger(KitEvent.KIT_REGISTER_CHANGE, register);\n }\n\n /**\n * Set call status\n * @param status\n */\n setConnectStatus(status: CallStatusType) {\n this.callKit.logger.info('connect setConnectStatus', {\n caller: 'Connect.setConnectStatus',\n type: 'SIP',\n content: {\n status\n }\n });\n this.connectStatus = status;\n this.callKit.trigger(KitEvent.KIT_CALL_STATUS_CHANGE, status);\n }\n\n /**\n * Hang up\n * @param isUnprompted Whether actively hanging up\n * @param isError Whether an error occurred\n * @returns\n */\n async hangup(isUnprompted = false, isError = false) {\n this.callKit.logger.info('connect hangup', {\n caller: 'Connect.hangup',\n type: 'SIP',\n content: {\n isUnprompted,\n isError,\n connectStatus: this.connectStatus\n }\n });\n if (this.connectStatus === CallStatus.init) return;\n this.isOutgoing = false;\n this.isUnprompted = isUnprompted;\n\n try {\n // 1. First handle Socket signaling\n if (isUnprompted) {\n // this.callKit.socket.send(SocketSendEvent.AGENT_HANGUP);\n\n const shouldSendBye =\n // this.sipConnected ||\n this.isRinging() || this.isCalling() || this.isHolding();\n\n if (shouldSendBye) {\n await this.currentSession?.bye();\n }\n }\n\n // 2. Clean up media resources\n // this.sipConnected = false;\n closeStream(this.mediaStream);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.pause();\n audioRef.srcObject = null;\n }\n\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.CALL_END, new Date());\n } catch (err) {\n this.callKit.logger.error(err, {\n caller: 'Connect.hangup',\n type: 'SIP',\n content: {\n connectStatus: this.connectStatus,\n isError,\n isUnprompted\n }\n });\n this.callKit.trigger(KitEvent.CALL_END, new Date());\n this.callKit.reset();\n }\n }\n\n /**\n * The remote media stream. Undefined if call not answered.\n * @param session - Session to get the media stream from.\n */\n getRemoteMediaStream(session) {\n this.callKit.logger.info('connect getRemoteMediaStream', {\n caller: 'Connect.getRemoteMediaStream',\n type: 'SIP',\n content: {\n session\n }\n });\n const sdh = session.sessionDescriptionHandler;\n if (!sdh) {\n return undefined;\n }\n return sdh.remoteMediaStream;\n }\n\n setupRemoteMedia(session) {\n this.callKit.logger.info('connect setupRemoteMedia', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n session\n }\n });\n const remoteStream = this.getRemoteMediaStream(session);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.autoplay = true;\n audioRef.srcObject = remoteStream;\n\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n\n remoteStream.onaddtrack = () => {\n this.callKit.logger.info('Remote media onaddtrack', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n session\n }\n });\n audioRef.load();\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n };\n } else {\n this.callKit.logger.error('video is not exist', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAYER_ERROR\n }\n });\n }\n }\n\n /**\n * Update hold\n * @param hold\n */\n setHoldStatus(hold: boolean) {\n this.callKit.logger.info('connect setHold', {\n caller: 'Connect.setHoldStatus',\n type: 'SIP',\n content: {\n hold\n }\n });\n this.callKit.trigger(KitEvent.KIT_SET_HOLD, hold);\n }\n\n async setHold(hold: boolean) {\n this.setHoldStatus(hold);\n // Hold goes through socket, not sip\n\n // const options = {\n // requestDelegate: {\n // onAccept: () => {\n // this.callKit.logger.info('setHold onAccept', hold);\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.setupRemoteMedia(this.currentSession);\n // },\n // onReject: () => {\n // this.callKit.logger.info('setHold onReject');\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.setupRemoteMedia(this.currentSession);\n // }\n // }\n // };\n\n // const sessionDescriptionHandlerOptions = this.currentSession.sessionDescriptionHandlerOptionsReInvite;\n\n // (sessionDescriptionHandlerOptions as any).hold = hold;\n // this.currentSession.sessionDescriptionHandlerOptionsReInvite = sessionDescriptionHandlerOptions;\n\n // return this.currentSession\n // .invite(options)\n // .then(() => {\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.callKit.logger.info('setHold success');\n // })\n // .catch((err) => {\n // this.callKit.logger.error(err?.message, {\n // errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR\n // });\n // });\n }\n\n async hold() {\n this.callKit.logger.info('connect hold', {\n caller: 'Connect.hold',\n type: 'SIP',\n content: {\n hold: true\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.error('Current status is not in call', {\n caller: 'Connect.hold',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_HOLE_STATUS_ERROR\n }\n });\n }\n }\n\n async unhold() {\n this.callKit.logger.info('connect unhold', {\n caller: 'Connect.unhold',\n type: 'SIP',\n content: {\n hold: false\n }\n });\n }\n\n async setMute(mute: boolean) {\n this.callKit.logger.info('connect setMute', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n mute\n }\n });\n\n if (!this.currentSession) {\n this.callKit.logger.error('No active session', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n this.callKit.reset();\n return;\n }\n\n try {\n // Get SessionDescriptionHandler\n const sdh = this.currentSession.sessionDescriptionHandler;\n if (!sdh || !('peerConnection' in sdh)) {\n throw new Error('Invalid session description handler');\n }\n\n // Get PeerConnection\n const pc = (sdh as any).peerConnection as RTCPeerConnection;\n\n // Get local audio track and set status\n const audioSender = pc\n .getSenders()\n .find((sender) => sender.track?.kind === 'audio');\n\n if (audioSender && audioSender.track) {\n audioSender.track.enabled = !mute;\n // Update status and trigger event\n this.isMute = mute;\n this.callKit.trigger(KitEvent.KIT_SET_MUTE, mute);\n } else {\n throw new Error('No audio track found');\n }\n } catch (error) {\n this.callKit.logger.error('Failed to set mute state', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n err: error.message,\n errCode: ErrorCode.WEBRTC_MUTE_ERROR\n }\n });\n }\n }\n\n async mute() {\n this.callKit.logger.info('connect mute', {\n caller: 'Connect.mute',\n type: 'SIP',\n content: {\n mute: true\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.warn('Current status is not in call', {\n caller: 'Connect.mute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n return;\n }\n await this.setMute(true);\n }\n\n async unmute() {\n this.callKit.logger.info('connect unmute', {\n caller: 'Connect.unmute',\n type: 'SIP',\n content: {\n mute: false\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.warn('Current status is not in call', {\n caller: 'Connect.unmute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n return;\n }\n await this.setMute(false);\n }\n\n async refer(referTo: string, extra?: any) {\n this.callKit.logger.info('connect refer', {\n caller: 'Connect.refer',\n type: 'SIP',\n content: {\n referTo,\n extra\n }\n });\n let target;\n if (referTo) {\n target = UserAgent.makeURI(referTo);\n }\n this.currentSession.refer(target, extra?.sessionReferOptions);\n }\n}\n","import type { CallKit } from '.';\nimport {\n SocketSendEvent,\n ErrorCode,\n KitEvent,\n SocketReceiveEvent,\n CallSourceType\n} from './const';\n\nexport type SocketReceiveEventType =\n (typeof SocketReceiveEvent)[keyof typeof SocketReceiveEvent];\nexport type SocketSendEventType =\n (typeof SocketSendEvent)[keyof typeof SocketSendEvent];\n\nexport interface SocketMessage {\n event: SocketReceiveEventType;\n msg: string;\n data: object;\n}\n\nexport interface SocketConfig {\n enabled: boolean;\n maxAttempts: number;\n delay: number;\n backoffMultiplier: number; // Reconnection delay time multiplier growth factor\n pingInterval: number;\n pingTimeout: number;\n}\n\n/**\n * Default configuration\n */\nconst RECONNECT_CONFIG: SocketConfig = {\n enabled: true,\n maxAttempts: 1,\n delay: 500,\n backoffMultiplier: 1.5,\n pingInterval: 30000,\n pingTimeout: 5000\n};\n\nexport class Socket {\n private callKit: CallKit;\n private ws?: WebSocket;\n\n private socketConfig: SocketConfig;\n\n lastPingTime = undefined;\n isConnected = false;\n pingTimer?: number;\n\n // Whether received start confirmation\n satrtConfirm = false;\n private reconnectTimer?: any;\n private isReconnecting = false;\n private reconnectAttempts = 0;\n\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n const { reconnect } = this.callKit.config.getConfig();\n this.socketConfig = {\n ...RECONNECT_CONFIG,\n ...reconnect\n };\n }\n\n init() {\n const { socket } = this.callKit.config.getConfig();\n this.callKit.logger.info(`socket init: ${socket}`, {\n caller: 'Socket.init',\n type: 'INCALL',\n content: {\n socket\n }\n });\n this.connect(socket);\n }\n\n private handleDisconnect() {\n this.isConnected = false;\n\n if (!this.callKit.config.isLogin() || !this.socketConfig.enabled) {\n this.reset();\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n return;\n }\n\n this.attemptReconnect();\n }\n\n private connect(socketUrl: string) {\n this.ws = new WebSocket(socketUrl);\n this.ws.onopen = (ev: Event) => this.onOpen(ev);\n this.ws.onclose = (ev: CloseEvent) => this.onClose(ev);\n this.ws.onerror = (ev: Event) => this.onError(ev);\n this.ws.onmessage = (ev: MessageEvent) => this.onMessage(ev);\n }\n\n private onOpen(ev: Event) {\n this.callKit.logger.info('socket onOpen', {\n caller: 'Socket.onOpen',\n type: 'INCALL',\n content: { ev }\n });\n\n this.isConnected = true;\n this.lastPingTime = Date.now();\n this.checkPing();\n\n if (this.isReconnecting) {\n this.callKit.logger.info('reconnect success', {\n caller: 'Socket.onOpen',\n type: 'INCALL',\n content: {\n event: 'INCALL_RECONNECT_SUCCESS',\n reconnectAttempts: this.reconnectAttempts\n }\n });\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_SUCCESS'\n });\n }\n\n this.resetReconnectState();\n }\n\n private resetReconnectState() {\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n private onClose(ev: CloseEvent) {\n this.callKit.logger.info('socket onClose', {\n caller: 'Socket.onClose',\n type: 'INCALL',\n content: { ev }\n });\n\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_CONNECT_ERROR',\n err: ev\n });\n\n this.handleDisconnect();\n }\n\n private onError(ev: Event) {\n this.callKit.logger.error('socket onError', {\n caller: 'Socket.onError',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR,\n data: ev\n }\n });\n }\n\n private confirmAck(data: any) {\n const { ack, messageId } = data;\n if (ack) {\n this.send(SocketSendEvent.ACK, {\n messageId\n });\n }\n }\n\n private onMessage(ev: MessageEvent<string>) {\n const data = JSON.parse(ev.data);\n this.callKit.logger.info('socket onMessage', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: data.event\n }\n });\n\n this.confirmAck(data);\n\n if (data.event === SocketReceiveEvent.PONG) {\n this.lastPingTime = Date.now();\n return;\n }\n\n if (data.event === SocketReceiveEvent.START_CONFIRM) {\n this.callKit.logger.info('start confirm success', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.START_CONFIRM\n }\n });\n this.satrtConfirm = true;\n }\n\n if (data.event === SocketReceiveEvent.CALL_SUCCESS) {\n this.callKit.logger.info('call success', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CALL_SUCCESS\n }\n });\n }\n\n if (data.event === SocketReceiveEvent.CALL_FAILED) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n errCode: ErrorCode.SOCKET_CALL_ERROR\n }\n });\n }\n\n if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {\n this.callKit.trigger(KitEvent.CALL_RINGING, new Date());\n }\n if (data.event === SocketReceiveEvent.CUSTOMER_PICK_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_PICK_UP\n }\n });\n this.callKit.trigger(KitEvent.CALL_PICK_UP, new Date());\n }\n\n if (data.event === SocketReceiveEvent.AGENT_PICK_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.AGENT_PICK_UP\n }\n });\n this.callKit.trigger(KitEvent.AGENT_PICK_UP, new Date());\n }\n\n if (data.event === SocketReceiveEvent.CUSTOMER_HANG_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_HANG_UP\n }\n });\n this.callKit.trigger(KitEvent.CALL_HANG_UP, new Date());\n }\n if (data.event === SocketReceiveEvent.CUSTOMER_NO_ANSWER) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_NO_ANSWER\n }\n });\n this.callKit.trigger(KitEvent.CALL_NO_ANSWER);\n }\n if (data.event === SocketReceiveEvent.CALL_CDR) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CALL_CDR\n }\n });\n this.callKit.trigger(KitEvent.CALL_CDR, data.data);\n }\n if (data.event === SocketReceiveEvent.STOP_CONFIRM) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.STOP_CONFIRM\n }\n });\n }\n if (data.event === SocketReceiveEvent.CLOSE) {\n const { userInfo } = this.callKit.config.getConfig();\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CLOSE\n }\n });\n this.send(SocketSendEvent.END, {\n agentId: userInfo.agentId\n });\n }\n if (data.event === SocketReceiveEvent.ERROR) {\n this.callKit.logger.error(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n errCode: ErrorCode.SOKET_SERVER_ERROR,\n data: data.data\n }\n });\n this.callKit.reset();\n }\n\n if (data.event === SocketReceiveEvent.AGENT_NO_ANSWER) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.AGENT_NO_ANSWER\n }\n });\n }\n\n this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);\n }\n\n send(event: SocketSendEventType, message?: any) {\n if (!this.isConnected) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n this.callKit.logger.error('socket not connected', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n this.callKit.config.reset();\n this.callKit.reset();\n return;\n }\n const { userInfo } = this.callKit.config.getConfig();\n const { sessionId, extno, agentId } = userInfo;\n if (!sessionId) {\n this.callKit.logger.error('sessionId is empty', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n return;\n }\n const msg = {\n event,\n sessionId,\n ...message\n };\n\n if (SocketSendEvent.CALL === event) {\n msg.phoneNum = extno;\n msg.agentId = agentId;\n if (message?.sourceType === CallSourceType.phoneNum) {\n delete msg.workOrderId;\n } else if (message?.sourceType === CallSourceType.workOrderId) {\n delete msg.phoneNum;\n }\n }\n\n this.callKit.logger.info('socket send', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n event,\n message\n }\n });\n switch (event) {\n case SocketSendEvent.PING:\n this.lastPingTime = Date.now();\n this.ws?.send(JSON.stringify({ event, ...msg }));\n break;\n default:\n this.ws?.send(JSON.stringify({ event, ...msg }));\n break;\n }\n }\n\n async sendMessage(event: SocketSendEventType, message?: any) {\n if (!this.isConnected) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n this.callKit.logger.error('socket not connected', {\n caller: 'Socket.sendMessage',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n return;\n }\n const { userInfo } = this.callKit.config.getConfig();\n const { sessionId } = userInfo;\n\n this.ws?.send(JSON.stringify({ event, sessionId, ...message }));\n }\n\n private ping() {\n if (!this.isConnected) return;\n this.send(SocketSendEvent.PING);\n this.callKit.logger.info(`socket ping`, {\n caller: 'Socket.ping',\n type: 'INCALL',\n content: {\n lastPingTime: this.lastPingTime\n }\n });\n // 5s is considered timeout\n const now = Date.now();\n const { pingInterval, pingTimeout } = this.socketConfig;\n if (now - this.lastPingTime > pingInterval + pingTimeout) {\n this.callKit.logger.error('socket ping timeout', {\n caller: 'Socket.ping',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_PING_TIMEOUT\n }\n });\n if (this.ws && this.isConnected) {\n this.ws.close(4001, 'ping timeout');\n } else {\n this.reset();\n }\n }\n }\n\n private checkPing() {\n if (this.pingTimer) {\n clearInterval(this.pingTimer);\n }\n this.ping();\n this.pingTimer = setInterval(() => {\n this.ping();\n }, this.socketConfig.pingInterval);\n }\n\n /**\n * 重置 socket 连接和所有状态\n * @param isWaitConfirm Whether need to wait for close confirmation\n */\n async reset(isWaitConfirm = true) {\n // 清理定时器\n if (this.pingTimer) {\n clearInterval(this.pingTimer);\n this.pingTimer = undefined;\n }\n\n // 重置重连状态\n this.resetReconnectState();\n\n // 重置其他状态\n this.lastPingTime = undefined;\n this.satrtConfirm = false;\n\n // 关闭 WebSocket 连接\n if (this.ws && this.isConnected) {\n this.callKit.logger.info('Closing socket connection', {\n caller: 'Socket.reset',\n type: 'INCALL',\n content: {\n isWaitConfirm\n }\n });\n this.ws.close();\n this.isConnected = false;\n }\n }\n\n private attemptReconnect() {\n // 检查是否已达到最大重连次数\n if (this.reconnectAttempts >= this.socketConfig.maxAttempts) {\n this.callKit.logger.error('Maximum reconnection attempts reached', {\n caller: 'Socket.attemptReconnect',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_RECONNECT_FAILED,\n reconnectAttempts: this.reconnectAttempts\n }\n });\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_ERROR'\n });\n this.reset();\n return;\n }\n\n // 首次重连时触发开始事件\n if (this.reconnectAttempts === 0) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_START'\n });\n }\n\n this.isReconnecting = true;\n this.reconnectAttempts += 1;\n\n const { delay } = this.socketConfig;\n\n this.callKit.logger.info(\n `Preparing reconnection attempt ${this.reconnectAttempts}/${this.socketConfig.maxAttempts}, delay: ${delay}ms`,\n {\n caller: 'Socket.attemptReconnect',\n type: 'INCALL',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.socketConfig.maxAttempts,\n delay\n }\n }\n );\n\n this.reconnectTimer = setTimeout(() => {\n const { socket } = this.callKit.config.getConfig();\n this.connect(socket);\n }, delay);\n }\n}\n"],"mappings":"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","names":["data","request"]}
1
+ {"version":3,"sources":["../package/index.ts","../package/axios.ts","../package/api.ts","../package/const.ts","../package/call.ts","../package/config.ts","../package/logger.ts","../package/connect.ts","../package/socket.ts"],"sourcesContent":["import md5 from 'blueimp-md5';\nimport { Api } from './api';\nimport { Call } from './call';\nimport type { IConfig, WebrtcConstranis } from './config';\nimport { Config } from './config';\nimport type { LoggerLevel } from './logger';\nimport { Logger } from './logger';\nimport { Connect } from './connect';\nimport {\n constrainsDefault,\n KitEvent,\n EncryptionMethod,\n CallSourceType,\n ErrorCode\n} from './const';\nimport { Socket } from './socket';\n\nexport interface CallKitConfig {\n host: string;\n audioRef: HTMLAudioElement | (() => HTMLAudioElement);\n socket: string;\n constrains?: WebrtcConstranis;\n log?: LoggerLevel;\n}\n\nexport type ConfigEntity = CallKitConfig & Partial<IConfig>;\n\nexport type kitEventType = (typeof KitEvent)[keyof typeof KitEvent];\n\ninterface Listener {\n event: kitEventType;\n callback: (...args: any[]) => void;\n}\ninterface CallOptions {\n sourceType: (typeof CallSourceType)[keyof typeof CallSourceType];\n phoneNum?: string;\n workOrderId?: string;\n}\n\nexport class CallKit {\n api: Api;\n config: Config;\n logger: Logger;\n callCenter: Call;\n connect: Connect;\n socket: Socket;\n\n listener: Listener[] = [];\n\n constructor(options: ConfigEntity) {\n this.config = new Config(this);\n this.api = new Api(this);\n this.connect = new Connect(this);\n this.callCenter = new Call(this);\n this.socket = new Socket(this);\n this.config.setConfig('log', options.log);\n this.config.setConfig('trackLogs', options.trackLogs);\n this.config.setConfig('audioRef', options.audioRef);\n this.config.setConfig('host', options.host);\n this.config.setConfig(\n 'constrains',\n options.constrains || constrainsDefault\n );\n this.config.setConfig('socket', options.socket);\n this.config.setConfig('reconnect', options.reconnect);\n this.logger = new Logger(this, options.log);\n\n this.logger.info('callKit init', {\n caller: 'CallKit.init',\n content: options\n });\n }\n\n async login(\n username: string,\n password: string,\n extra: { [key: string]: any } = {\n encryptionMethod: EncryptionMethod.INTERNAL\n }\n ) {\n if (this.config.isLogin()) {\n this.logger.warn('already login', {\n caller: 'CallKit.login',\n content: { username, password, extra }\n });\n return;\n }\n\n let encryptionPassword = '';\n const { encryptionMethod = EncryptionMethod.INTERNAL } = extra;\n switch (encryptionMethod) {\n case EncryptionMethod.NONE:\n encryptionPassword = password;\n break;\n case EncryptionMethod.INTERNAL:\n encryptionPassword = md5(username + md5(password));\n break;\n default:\n encryptionPassword = md5(username + md5(password));\n break;\n }\n\n this.logger.info('login info:', {\n caller: 'CallKit.login',\n content: {\n username,\n password,\n encryptionMethod,\n encryptionPassword\n }\n });\n\n try {\n const user = await this.api.login({\n userName: username,\n password: encryptionPassword\n });\n\n if (user) {\n this.config.setConfig('userInfo', {\n wsUrl: `wss://${user.wsUrl}`,\n sessionId: user.sessionId,\n username,\n password: encryptionPassword,\n encryptionPassword,\n agentId: user.agentId,\n fsUserId: user.fsUserId,\n userPart: user.userPart,\n fsPassword: user.fsPassword,\n fsIp: user.fsIp,\n fsPort: user.fsPort,\n iceInfo: user.iceInfo,\n iceGatheringTimeout: user.iceGatheringTimeout,\n logGather: user.logGather,\n // encryptionType is in extra\n ...extra\n });\n this.socket.init();\n this.trigger(KitEvent.KIT_LOGIN_CHANGE, true);\n }\n } catch (error) {\n this.logger.error(error, {\n caller: 'CallKit.login',\n content: {\n errCode: ErrorCode.API_USER_LOGIN_ERROR\n }\n });\n }\n }\n\n async logout() {\n if (!this.config.check()) return;\n const { userInfo } = this.config.getConfig();\n this.logger.info('logout', {\n caller: 'CallKit.logout',\n content: {\n sessionId: userInfo.sessionId\n }\n });\n if (this.config.isLogin()) {\n const { sessionId } = userInfo;\n try {\n await this.api.loginOut({ sessionId });\n } catch (error) {\n this.logger.error(error, {\n caller: 'CallKit.logout',\n content: {\n errCode: ErrorCode.API_USER_LOGOUT_ERROR\n }\n });\n }\n }\n\n await this.hangup();\n this.socket.reset(false);\n this.connect.reset();\n this.config.reset();\n this.trigger(KitEvent.KIT_LOGIN_CHANGE, false);\n }\n\n async call(\n extno: string | number = '',\n options: CallOptions = {\n sourceType: CallSourceType.phoneNum,\n workOrderId: ''\n }\n ) {\n if (!this.config.check()) return;\n if (!this.connect.isRegistered) {\n this.logger.warn('Currently not registered', {\n caller: 'CallKit.call',\n content: { extno, options }\n });\n return;\n }\n\n const { sourceType, workOrderId } = options;\n this.config.setUserInfo('sourceType', sourceType);\n if (sourceType === CallSourceType.phoneNum) {\n if (extno) {\n this.config.setUserInfo('extno', extno);\n }\n } else if (sourceType === CallSourceType.workOrderId) {\n if (workOrderId) {\n this.config.setUserInfo('workOrderId', workOrderId);\n }\n }\n\n this.logger.info('call', {\n caller: 'CallKit.call',\n content: {\n extno,\n options\n }\n });\n this.callCenter.callStart();\n }\n\n async refer(uri: string, options?: any) {\n if (!this.config.check()) return;\n this.logger.info('refer', {\n caller: 'CallKit.refer',\n content: {\n uri,\n options\n }\n });\n this.callCenter.callRefer(uri, options);\n }\n\n async register() {\n if (!this.config.check()) return;\n this.logger.info('register', {\n caller: 'CallKit.register',\n content: {}\n });\n this.connect.register();\n }\n\n async unregister() {\n if (!this.config.check()) return;\n this.logger.info('unregister', {\n caller: 'CallKit.unregister',\n content: {}\n });\n this.connect.unregister();\n }\n\n async stop() {\n await this.connect.stop();\n }\n\n async hangup() {\n if (!this.config.check()) return;\n this.logger.info('hangup', {\n caller: 'CallKit.hangup',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n if (\n !this.connect.isConnecting() &&\n !this.connect.isRinging() &&\n !this.connect.isCalling() &&\n !this.connect.isHolding()\n ) {\n this.logger.warn('Currently not in a call', {\n caller: 'CallKit.hangup',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n return;\n }\n await this.callCenter.callEnd(true);\n }\n\n hold() {\n if (!this.config.check()) return;\n this.logger.info('hold', {\n caller: 'CallKit.hold',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.callCenter.callHold();\n }\n\n unhold() {\n if (!this.config.check()) return;\n this.logger.info('unhold', {\n caller: 'CallKit.unhold',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.callCenter.callUnhold();\n }\n\n /**\n * set userstatus\n * @param status\n */\n async setUserStatus(status: number) {\n const { agentId } = this.config.getConfig().userInfo;\n await this.api.updateUserStatus({\n agentId,\n status\n });\n }\n\n async reset() {\n this.logger.info('reset', {\n caller: 'CallKit.reset',\n content: {\n connectStatus: this.connect.connectStatus\n }\n });\n this.connect.reset();\n }\n\n on(event: kitEventType, callback: (...args: any[]) => void) {\n this.listener.push({\n event,\n callback\n });\n }\n\n off(event: kitEventType, callback?: (...args: any[]) => void) {\n this.logger.info(`off ${event}`, {\n caller: 'CallKit.off',\n content: {\n event\n }\n });\n if (callback) {\n this.listener = this.listener.filter(\n (item) => !(item.event === event && item.callback === callback)\n );\n } else {\n this.listener = this.listener.filter((item) => item.event !== event);\n }\n }\n\n removeAllListeners() {\n this.listener = this.listener.splice(0, this.listener.length);\n this.logger.info('removeAllListeners', {\n caller: 'CallKit.removeAllListeners',\n content: {\n listener: this.listener\n }\n });\n }\n\n trigger(event: kitEventType, data?: any) {\n this.listener.forEach((item) => {\n if (item.event === event) {\n try {\n item.callback(data);\n } catch (err) {\n this.logger.error('Event callback error:', err);\n }\n }\n });\n }\n}\n","import type { AxiosRequestConfig } from 'axios';\nimport axios from 'axios';\n\nconst instance = axios.create({\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n }\n});\n\ninstance.interceptors.request.use((config) => config);\n\ninstance.interceptors.response.use(\n (response) => response.data,\n (error) => Promise.reject(error)\n);\n\nconst request = (config: AxiosRequestConfig): Promise<any> =>\n instance.request(config);\n\nexport default request;\n","import type { AxiosRequestConfig } from 'axios';\nimport request from './axios';\nimport type { CallKit } from '.';\n\nexport class Api {\n private callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n async login(params: { userName: string; password: string }) {\n return this.post({\n url: '/auth/agentUser/login',\n method: 'post',\n data: params\n });\n }\n\n async loginOut(params: { sessionId: string }) {\n return this.post({\n url: '/auth/agentUser/loginOut',\n method: 'post',\n data: params\n });\n }\n\n async trackLogs(log: string) {\n return this.post(\n { url: '/agent/user/sdkLog', method: 'post', data: { content: [log] } },\n {\n useFormData: true\n }\n );\n }\n\n /**\n *\n * @param params agentId status\n * @returns\n */\n async updateUserStatus(params: any) {\n return this.post({\n url: '/agent/user/changeStatus',\n method: 'post',\n data: params\n });\n }\n\n private async post(config: AxiosRequestConfig, extra: any = {}) {\n const { userInfo, host } = this.callKit.config.getConfig();\n const { sessionId } = userInfo;\n config.url = `${host}${config.url}`;\n config.headers = {\n 'Content-Type': 'application/x-www-form-urlencoded',\n ...config.headers\n };\n\n if (\n config.headers['Content-Type'] === 'application/x-www-form-urlencoded' &&\n extra.useFormData\n ) {\n const formData = new FormData();\n const data = config.data || {};\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n formData.append(key, data[key]);\n }\n }\n config.data = formData;\n } else {\n config.data = new URLSearchParams(config.data).toString();\n }\n\n if (sessionId) {\n config.headers.sessionId = sessionId;\n }\n const res = await request(config).catch(() => {\n // Network error\n this.callKit.config.reset();\n });\n if (!res) {\n this.callKit.config.reset();\n throw new Error('Network error');\n }\n const { code, data, message } = res;\n if (code === '000000') {\n return data;\n }\n\n // Authentication failed, need to re-login\n if (code === '100013') {\n this.callKit.config.reset();\n }\n throw new Error(message ?? 'Request failed');\n }\n}\n","import type { WebrtcConstranis } from './config';\n\nexport const CallStatus = {\n /**\n * Initial state/Hang up\n */\n init: 0,\n // /**\n // * @deprecated Deprecated\n // * Registered\n // */\n // registered: 1,\n /**\n * Connecting\n */\n connecting: 2,\n /**\n * Call on hold\n */\n holding: 3,\n /**\n * Ringing\n */\n ringing: 4,\n /**\n * In call\n */\n calling: 5\n};\n\nexport const KitEvent = {\n /**\n * Log\n */\n KIT_LOG: 'log',\n /**\n * User status change\n */\n KIT_USER_STATUS_CHANGE: 'userStatusChange',\n /**\n * User login status change\n */\n KIT_LOGIN_CHANGE: 'loginChange',\n /**\n * Registration status change\n */\n KIT_REGISTER_CHANGE: 'registerChange',\n /**\n * Call status change\n */\n KIT_CALL_STATUS_CHANGE: 'callStatusChange',\n /**\n * Hold status change\n */\n KIT_SET_HOLD: 'holdChange',\n /**\n * Mute status change\n */\n KIT_SET_MUTE: 'muteChange',\n /**\n * Error\n */\n KIT_ERROR: 'error',\n /**\n * Server initiated call\n */\n KIT_INVITE: 'invite',\n /**\n * Server outgoing initiated call\n */\n KIT_OUTGOING_INVITE: 'outgoingInvite',\n // /**\n // * Referral\n // */\n // KIT_REFER: 'refer',\n /**\n * Connecting\n */\n CALL_CONNECTING: 'connecting',\n /**\n * Customer ringing\n */\n CALL_RINGING: 'ringing',\n\n /**\n * Agent pick up\n */\n AGENT_PICK_UP: 'agentPickUp',\n /**\n * Customer answer\n */\n CALL_PICK_UP: 'pickUp',\n /**\n * Customer no response\n */\n CALL_NO_ANSWER: 'noAnswer',\n\n /**\n * Customer hang up\n */\n CALL_HANG_UP: 'hangUp',\n\n /**\n * Call end\n */\n CALL_END: 'callEnd',\n /**\n * Call detail record push\n */\n CALL_CDR: 'callCdr',\n\n /**\n * Forward all socket events\n */\n SERVER_SOCKET_EVENT: 'socketEvent',\n\n /**\n * User status change\n */\n USER_STATUS_CHANGE: 'userStatusChange',\n\n CONNECT_EVENT: 'CONNECT_EVENT',\n\n SIP_REGISTERER_EVENT: 'sipRegistererEvent',\n SIP_SESSION_EVENT: 'sipSessionEvent'\n};\n\nexport const ErrorCode = {\n /**\n * Unknown error\n */\n UNKNOWN_ERROR: -1,\n /**\n * API user login failed\n */\n API_USER_LOGIN_ERROR: 1000001,\n /**\n * API user status update failed\n */\n API_USER_STATUS_UPDATE_ERROR: 1000002,\n\n /**\n * API user logout failed\n */\n API_USER_LOGOUT_ERROR: 1000003,\n\n /**\n * connectStatus call status error\n */\n CONNECT_CALL_STATUS_ERROR: 2000001,\n /**\n * User not logged in\n */\n USER_NOT_LOGIN: 2000002,\n /**\n * Browser version too low, does not support webrtc getUserMedia\n */\n WEBRTC_USER_MEDIA_ERROR: 2000003,\n /**\n * Call hold failed\n */\n WEBRTC_HOLE_STATUS_ERROR: 2000004,\n /**\n * Audio player does not exist\n */\n WEBRTC_AUDIO_PLAYER_ERROR: 2000005,\n /**\n * Audio playback failed\n */\n WEBRTC_AUDIO_PLAY_ERROR: 2000006,\n /**\n * User agent startup failed\n */\n WEBRTC_USER_AGENT_ERROR: 2000007,\n /**\n * Call request failed\n */\n WEBRTC_CALL_INVITE_ERROR: 2000008,\n /**\n * Register request failed\n */\n WEBRTC_REGISTER_ERROR: 2000009,\n /**\n * Mute failed\n */\n WEBRTC_MUTE_STATUS_ERROR: 2000010,\n /**\n * Unregister failed\n */\n WEBRTC_CANCEL_REGISTER_ERROR: 2000011,\n\n /**\n * Mute failed\n */\n WEBRTC_MUTE_ERROR: 2000012,\n\n /**\n * Socket connection error\n */\n SOCKET_CONNECT_ERROR: 3000001,\n /**\n * Ping timeout\n */\n SOCKET_PING_TIMEOUT: 3000002,\n /**\n * Server error\n */\n SOKET_SERVER_ERROR: 3000003,\n /**\n * API call failed\n */\n SOCKET_CALL_ERROR: 3000004,\n /**\n * Reconnection limit exceeded\n */\n SOCKET_RECONNECT_FAILED: 3000005\n};\n\nexport const LoggerLevelMap = {\n info: 9,\n success: 4,\n warn: 3,\n error: 2,\n silent: 1\n};\n\n// Send events\nexport const SocketSendEvent = {\n /**\n * ping\n */\n PING: 'PING',\n /**\n * Start\n */\n START: 'START',\n /**\n * Hang up\n */\n AGENT_HANGUP: 'AGENT_HANG_UP',\n /**\n * Cancel\n */\n CALL_CANCEL: 'AGENT_CANCEL',\n /**\n * Hold\n */\n HOLD: 'AGENT_HOLD',\n /**\n * Unhold\n */\n UNHOLD: 'AGENT_UN_HOLD',\n /**\n * Call\n */\n CALL: 'CALL',\n /**\n * End\n */\n END: 'STOP',\n /**\n * AGENT_TRANSFER\n */\n AGENT_TRANSFER: 'AGENT_TRANSFER',\n /**\n * AGENT_TRANSFER\n */\n HANG_UP_REASON: 'HANG_UP_REASON',\n\n ACK: 'ACK'\n};\n\n// Receive events\nexport const SocketReceiveEvent = {\n /**\n * Response\n */\n PONG: 'PONG',\n /**\n * Start confirmation\n */\n START_CONFIRM: 'START_CONFIRM',\n /**\n * Call success\n */\n CALL_SUCCESS: 'CALL_SUCCESS',\n /**\n * Call failed\n */\n CALL_FAILED: 'CALL_FAILED',\n /**\n * Customer ringing\n */\n CUSTOMER_RINGING: 'CUSTOMER_RINGING',\n\n /**\n * Agent pick up\n */\n AGENT_PICK_UP: 'AGENT_PICK_UP',\n /**\n * Customer pick up\n */\n CUSTOMER_PICK_UP: 'CUSTOMER_PICK_UP',\n /**\n * Customer no answer\n */\n CUSTOMER_NO_ANSWER: 'CUSTOMER_NO_ANSWER',\n /**\n * Customer hang up\n */\n CUSTOMER_HANG_UP: 'CUSTOMER_HANG_UP',\n /**\n * Agent no answer\n */\n AGENT_NO_ANSWER: 'AGENT_NO_ANSWER',\n /**\n * Call detail record push\n */\n CALL_CDR: 'CALL_CDR',\n /**\n * Stop confirmation\n */\n STOP_CONFIRM: 'STOP_CONFIRM',\n /**\n * Close\n */\n CLOSE: 'CLOSE',\n /**\n * Error\n */\n ERROR: 'ERROR'\n};\n\nexport const EncryptionMethod = {\n NONE: 'NONE',\n INTERNAL: 'INTERNAL'\n};\nexport type EncryptionMethodType =\n (typeof EncryptionMethod)[keyof typeof EncryptionMethod];\n\nexport const constrainsDefault: WebrtcConstranis = {\n audio: {\n autoGainControl: true,\n // Noise suppression\n noiseSuppression: true,\n // Set echo cancellation\n echoCancellation: true\n },\n video: false\n};\n\nexport const CallSourceType = {\n phoneNum: 1,\n workOrderId: 2\n};\n","import { CallStatus, SocketSendEvent, CallSourceType } from './const';\nimport { type CallKit } from './index';\n\nexport class Call {\n private callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n async callStart() {\n if (!this.callKit.config.check()) return;\n this.callKit.logger.info('callStart', {\n caller: 'Call.callStart',\n content: {\n startConfirm: this.callKit.socket.satrtConfirm\n }\n });\n if (!this.callKit.socket.satrtConfirm) {\n this.callKit.logger.warn('server not confirm start', {\n caller: 'Call.callStart',\n content: {\n startConfirm: this.callKit.socket.satrtConfirm\n }\n });\n return;\n }\n this.callKit.connect.call(async (user) => {\n let queryTrain = {};\n if (user.sourceType === CallSourceType.phoneNum) {\n queryTrain = {\n agentId: user.agentId,\n phoneNum: user.extno,\n sourceType: user.sourceType\n };\n } else if (user.sourceType === CallSourceType.workOrderId) {\n queryTrain = {\n agentId: user.agentId,\n workOrderId: user.workOrderId,\n sourceType: user.sourceType\n };\n }\n this.callKit.socket.send(SocketSendEvent.CALL, queryTrain);\n });\n }\n\n /**\n * Refer\n * @param referTo - The referral target. If a `Session`, a REFER w/Replaces is sent.\n * @returns\n */\n async callRefer(referTo: string, options?: any) {\n if (!this.callKit.config.check()) return;\n this.callKit.logger.info('callRefer', {\n caller: 'Call.callRefer',\n content: {\n referTo,\n options\n }\n });\n this.callKit.connect.refer(referTo, options);\n }\n\n /**\n * Hang up\n * @param isUnprompted Whether to actively hang up\n * @param isError Whether an error occurred\n * @returns\n */\n async callEnd(isUnprompted = false, isError = false) {\n if (this.callKit.connect.connectStatus === CallStatus.init) return;\n if (!this.callKit.config.check()) return;\n this.callKit.connect.hangup(isUnprompted, isError);\n }\n\n async callHold() {\n if (!this.callKit.config.check()) return;\n if (!this.callKit.connect.isCalling()) {\n this.callKit.logger.warn('Current state cannot be held', {\n caller: 'Call.callHold',\n content: {\n isCalling: this.callKit.connect.isCalling()\n }\n });\n return;\n }\n this.callKit.socket.send(SocketSendEvent.HOLD);\n this.callKit.connect.setConnectStatus(CallStatus.holding);\n }\n\n async callUnhold() {\n if (!this.callKit.config.check()) return;\n if (!this.callKit.connect.isHolding()) {\n this.callKit.logger.warn('Current state cannot unhold', {\n caller: 'Call.callUnhold',\n content: {\n isHolding: this.callKit.connect.isHolding()\n }\n });\n return;\n }\n this.callKit.socket.send(SocketSendEvent.UNHOLD);\n this.callKit.connect.setConnectStatus(CallStatus.calling);\n }\n}\n","import type { CallKit } from '.';\nimport type { EncryptionMethodType } from './const';\nimport {\n constrainsDefault,\n ErrorCode,\n KitEvent,\n EncryptionMethod,\n CallSourceType\n} from './const';\nimport { type LoggerLevel } from './logger';\nimport type { SocketConfig } from './socket';\n\nexport interface WebrtcConstranis {\n audio: {\n autoGainControl?: boolean;\n noiseSuppression?: boolean;\n echoCancellation?: boolean;\n };\n video: false;\n}\n\nexport interface IConfig {\n version: string;\n host: string;\n log: LoggerLevel;\n trackLogs: boolean;\n audioRef?: HTMLAudioElement | (() => HTMLAudioElement);\n constrains: WebrtcConstranis;\n socket: string;\n reconnect?: SocketConfig;\n userInfo: {\n wsUrl: string;\n sessionId: string;\n username: string;\n password: string;\n encryptionPassword: string;\n sourceType: (typeof CallSourceType)[keyof typeof CallSourceType];\n extno: string;\n workOrderId: string;\n userPart: string;\n agentId: string;\n fsUserId: string;\n fsPassword: string;\n fsIp: string;\n fsPort: string;\n iceInfo: string[];\n iceGatheringTimeout: number;\n encryptionMethod: EncryptionMethodType;\n };\n}\n\nexport class Config {\n callKit: CallKit;\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n }\n\n config: IConfig = {\n version: '1.0.27',\n host: '',\n log: 'info',\n trackLogs: false,\n audioRef: undefined,\n constrains: constrainsDefault,\n socket: '',\n userInfo: {\n wsUrl: '',\n\n sessionId: '',\n // User\n username: '',\n // Password\n password: '',\n encryptionPassword: EncryptionMethod.INTERNAL,\n\n sourceType: CallSourceType.phoneNum,\n // Extension number\n extno: '',\n workOrderId: '',\n\n userPart: '',\n\n agentId: '',\n\n fsUserId: '',\n\n fsPassword: '',\n fsIp: '',\n fsPort: '',\n iceInfo: [],\n iceGatheringTimeout: 0,\n encryptionMethod: EncryptionMethod.INTERNAL\n }\n };\n\n getConfig = () => this.config;\n\n setConfig = async (key: string, value: any) => {\n this.config[key] = value;\n };\n\n setUserInfo = async (key: string, value: any) => {\n this.config.userInfo[key] = value;\n this.callKit.logger.info('setUserInfo', {\n caller: 'Config.setUserInfo',\n content: {\n key,\n value\n }\n });\n };\n\n reset = () => {\n if (this.isLogin()) {\n this.config.userInfo = {\n wsUrl: '',\n sessionId: '',\n username: '',\n password: '',\n encryptionPassword: '',\n userPart: '',\n sourceType: CallSourceType.phoneNum,\n extno: '',\n workOrderId: '',\n agentId: '',\n fsUserId: '',\n fsPassword: '',\n fsIp: '',\n fsPort: '',\n iceInfo: [],\n iceGatheringTimeout: this.config.userInfo.iceGatheringTimeout,\n encryptionMethod: EncryptionMethod.INTERNAL\n };\n this.callKit.trigger(KitEvent.KIT_LOGIN_CHANGE, false);\n }\n };\n\n validate = () => {\n const { userPart, fsIp, fsPassword, fsPort } = this.config.userInfo;\n if (!userPart || !fsIp || !fsPort || !fsPassword) {\n return false;\n }\n return true;\n };\n\n isLogin = () => this.validate();\n\n check() {\n if (!this.isLogin()) {\n this.callKit.logger.warn('User not logged in', {\n caller: 'Config.check',\n content: {\n errCode: ErrorCode.USER_NOT_LOGIN\n }\n });\n return false;\n }\n return true;\n }\n}\n","import stringify from 'json-stringify-safe';\nimport type { CallKit } from '.';\nimport { ErrorCode, KitEvent, LoggerLevelMap } from './const';\n\nexport type LoggerLevel = 'info' | 'success' | 'warn' | 'error' | 'silent';\n\nexport interface Log {\n timestamp: string;\n level: LoggerLevel;\n type?: 'INCALL' | 'SIP' | 'API' | 'OTHER';\n message: string;\n caller: string;\n content: Record<string, any>;\n}\n\ntype LogEntity = Omit<Log, 'timestamp' | 'level' | 'message'>;\n\nfunction getLevel(level: LoggerLevel) {\n return LoggerLevelMap[level];\n}\n\nfunction transformLog(log: Log): string {\n const { timestamp, level, type = 'OTHER', message, caller, content } = log;\n const logLevel = String(level).toUpperCase();\n return `${timestamp} [${logLevel}] [${type}] [${\n caller ?? 'unknown'\n }] [${message}] ${stringify(content)}`.trim();\n}\n\nconst MAX_SIZE = 8192;\nconst FLUSH_INTERVAL = 5000;\n\nfunction getByteSize(str: string): number {\n return new Blob([str]).size;\n}\n\nexport class Logger {\n prefix = 'CallKit';\n level: LoggerLevel = 'info';\n private pendingTrackLogs: string[] = [];\n private trackLogsTimer: number | null = null;\n\n private callKit: CallKit;\n constructor(callKit: CallKit, level?: LoggerLevel) {\n this.callKit = callKit;\n this.level = level || 'info';\n this.startTrackLogsTimer();\n }\n\n private startTrackLogsTimer() {\n if (this.trackLogsTimer) {\n return;\n }\n this.trackLogsTimer = setInterval(() => {\n this.flushTrackLogs();\n }, FLUSH_INTERVAL);\n }\n\n private flushTrackLogs() {\n if (this.pendingTrackLogs.length === 0) {\n return;\n }\n const { trackLogs } = this.callKit.config.getConfig();\n if (trackLogs) {\n try {\n const chunks: string[] = [];\n let currentChunk: string[] = [];\n let currentSize = 0;\n\n for (const log of this.pendingTrackLogs) {\n const logSize = getByteSize(log);\n const separator = currentChunk.length > 0 ? '\\n' : '';\n const separatorSize = getByteSize(separator);\n\n if (\n currentSize + logSize + separatorSize > MAX_SIZE &&\n currentChunk.length > 0\n ) {\n chunks.push(currentChunk.join('\\n'));\n currentChunk = [log];\n currentSize = logSize;\n } else {\n currentChunk.push(log);\n currentSize += logSize + separatorSize;\n }\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk.join('\\n'));\n }\n\n for (const chunk of chunks) {\n this.callKit.api.trackLogs(chunk);\n }\n\n this.pendingTrackLogs = [];\n } catch (error) {\n console.error(error);\n }\n }\n }\n\n destroy() {\n if (this.trackLogsTimer) {\n clearInterval(this.trackLogsTimer);\n this.trackLogsTimer = null;\n }\n this.flushTrackLogs();\n }\n\n setLevel(level: LoggerLevel) {\n this.level = level;\n }\n\n info(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'info');\n if (getLevel(this.level) >= getLevel('info')) {\n console.log(`%c${logString}`, `color: gray;`);\n }\n }\n\n success(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'success');\n if (getLevel(this.level) >= getLevel('success')) {\n console.log(`%c${logString}`, `color: green;`);\n }\n }\n\n warn(msg: string, extra: LogEntity) {\n const logString = this.catchLog(msg, extra, 'warn');\n if (getLevel(this.level) >= getLevel('warn')) {\n console.log(`%c${logString}`, `color: orange;`);\n }\n }\n\n error(msg: string | Error, extra: LogEntity) {\n const errorMsg = msg instanceof Error ? msg.message : msg;\n const logString = this.catchLog(errorMsg, extra, 'error');\n if (getLevel(this.level) >= getLevel('error')) {\n console.log(`%c${logString}`, `color: red;`);\n }\n const { errCode, ...rest } = extra?.content ?? {};\n const errorCode = errCode ?? ErrorCode.UNKNOWN_ERROR;\n\n this.callKit.trigger(KitEvent.KIT_ERROR, {\n code: errorCode,\n msg: errorMsg,\n data: rest\n });\n const error = new Error(errorMsg);\n error.name = 'CallKitError';\n (error as any).code = errorCode;\n (error as any).data = rest;\n throw error;\n }\n\n private catchLog(msg: string, extra: LogEntity, level: LoggerLevel): string {\n const now = new Date();\n const log: Log = {\n timestamp: now.toLocaleString().replace('T', ' ').replace('.000Z', ''),\n level,\n message: msg,\n caller: extra?.caller,\n type: extra?.type,\n content: extra?.content ?? {}\n };\n const logString = transformLog(log);\n const { trackLogs } = this.callKit.config.getConfig();\n if (trackLogs) {\n this.pendingTrackLogs.push(logString);\n }\n this.callKit.trigger(KitEvent.KIT_LOG, logString);\n return logString;\n }\n}\n","import type { Invitation, UserAgentOptions } from 'sip.js';\n\nimport {\n UserAgent,\n Web,\n Registerer,\n SessionState,\n RegistererState\n} from 'sip.js';\n\nimport type { CallKit } from '.';\nimport { CallStatus, ErrorCode, KitEvent, SocketSendEvent } from './const';\nimport type { IConfig } from './config';\n\nexport interface ConnectReconnectConfig {\n maxAttempts: number;\n delay: number;\n}\n\nconst DEFAULT_RECONNECT_CONFIG: ConnectReconnectConfig = {\n maxAttempts: 3,\n delay: 500\n};\n\nconst MAX_HEARTBEAT_COUNT = 6;\n\nfunction convertObjectStringToJSON(input) {\n // Use regular expressions to add double quotes to keys and values\n const corrected = input\n .replace(/(\\w+):\\s*'(.*?)'/g, '\"$1\": \"$2\"')\n .replace(/'/g, '\"');\n\n return corrected;\n}\n\nconst closeStream = (stream) => {\n if (stream) stream.getTracks().forEach((track) => track.stop());\n};\n\nconst initUserMedia = (): void => {\n if (typeof navigator.mediaDevices === 'undefined') {\n (navigator as any).mediaDevices = {} as MediaDevices;\n }\n if (typeof navigator.mediaDevices.getUserMedia === 'undefined') {\n navigator.mediaDevices.getUserMedia = (\n constraints: MediaStreamConstraints\n ): Promise<MediaStream> => {\n const getUserMedia =\n (navigator as any).getUserMedia ||\n (navigator as any).webkitGetUserMedia ||\n (navigator as any).mozGetUserMedia;\n if (!getUserMedia) {\n return Promise.reject(\n new Error(\n 'Unable to obtain device permissions. Please check your browser settings or device permissions.'\n )\n );\n }\n return new Promise((resolve, reject) => {\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n };\n }\n};\n\n// const enableSenderTracks = (session, enable) => {\n// const { sessionDescriptionHandler } = session;\n// sessionDescriptionHandler.enableSenderTracks(enable);\n// };\n\n// const enableReceiverTracks = (session, enable) => {\n// const { sessionDescriptionHandler } = session;\n// sessionDescriptionHandler.enableReceiverTracks(enable);\n// };\n\nexport type CallStatusType = (typeof CallStatus)[keyof typeof CallStatus];\n\nexport class Connect {\n callKit: CallKit;\n\n /**\n * connectStatus: init registered connecting calling\n */\n connectStatus = CallStatus.init;\n currentSession?: Invitation;\n mediaStream?: MediaStream;\n userAgent?: UserAgent;\n registerer?: Registerer;\n\n // current call id for invite data\n currentCallId?: string;\n\n /**\n * Whether it's a re-connected\n */\n isReConnected = false;\n\n observeOptionsHeartbeatHandler: ReturnType<typeof setTimeout> | null = null;\n\n // sipConnected = false;\n /**\n * Whether it's an outgoing call\n */\n isOutgoing = false;\n\n /**\n * Whether it's an active hangup\n */\n isUnprompted = false;\n isCurrentSessionInvited = false;\n\n private reconnectConfig: ConnectReconnectConfig;\n\n /**\n * Whether muted\n */\n isMute = false;\n\n /**\n * Whether registered\n */\n isRegistered = false;\n\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n const { reconnect = {} } = this.callKit.config.getConfig();\n this.reconnectConfig = {\n ...DEFAULT_RECONNECT_CONFIG,\n ...reconnect\n };\n }\n\n reset() {\n if (this.isHolding()) {\n this.setHoldStatus(false);\n }\n if (this.connectStatus !== CallStatus.init) {\n this.setConnectStatus(CallStatus.init);\n }\n if (this.isRegistered) {\n this.unregister();\n }\n\n this.currentSession = undefined;\n this.mediaStream = undefined;\n this.userAgent = undefined;\n this.registerer = undefined;\n this.isOutgoing = false;\n this.isUnprompted = false;\n if (this.mediaStream) {\n try {\n closeStream(this.mediaStream);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.pause();\n audioRef.srcObject = null;\n }\n } catch (error) {\n this.callKit.logger.error(error, {\n caller: 'Connect.reset',\n content: {}\n });\n }\n }\n\n this.setConnectStatus(CallStatus.init);\n this.clearObserveOptionsHeartbeatInterval();\n }\n\n private getAduioReference() {\n const { audioRef } = this.callKit.config.getConfig();\n if (typeof audioRef === 'function') {\n return audioRef();\n }\n return audioRef;\n }\n\n async permission() {\n this.callKit.logger.info('permission', {\n caller: 'Connect.permission',\n content: {\n permission: true\n }\n });\n initUserMedia();\n const _stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n closeStream(_stream);\n }\n\n /**\n * Making connection\n * @returns\n */\n isConnecting() {\n return this.connectStatus === CallStatus.connecting;\n }\n\n /**\n * In call\n * @returns\n */\n isCalling() {\n return this.connectStatus === CallStatus.calling;\n }\n\n /**\n * Ringing\n */\n isRinging() {\n return this.connectStatus === CallStatus.ringing;\n }\n\n /**\n *\n */\n isHolding() {\n return this.connectStatus === CallStatus.holding;\n }\n\n /**\n * Call ended, call not started\n * @returns\n */\n isInit() {\n return this.connectStatus === CallStatus.init;\n }\n\n clearObserveOptionsHeartbeatInterval() {\n if (this.observeOptionsHeartbeatHandler !== null) {\n clearInterval(this.observeOptionsHeartbeatHandler);\n this.observeOptionsHeartbeatHandler = null;\n }\n }\n\n heartbeatFlag = MAX_HEARTBEAT_COUNT;\n startHeartbeat() {\n this.heartbeatFlag = MAX_HEARTBEAT_COUNT;\n setTimeout(() => {\n this.heartbeatFlag -= 1;\n if (this.heartbeatFlag <= 0) {\n this.heartbeatFlag = MAX_HEARTBEAT_COUNT;\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'OPTIONS_HEARTBEAT_EXPIRED'\n });\n }\n }, 1000);\n }\n\n async register() {\n if (this.connectStatus !== CallStatus.init) {\n if (this.isRegistered) {\n this.callKit.logger.warn('connectStatus is registered', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.CONNECT_CALL_STATUS_ERROR\n }\n });\n return;\n }\n this.callKit.logger.error('connectStatus is not init', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.CONNECT_CALL_STATUS_ERROR\n }\n });\n this.callKit.reset();\n return;\n }\n\n this.callKit.logger.info('connect register', {\n caller: 'Connect.register',\n content: {\n connectStatus: this.connectStatus\n }\n });\n\n await this.permission().catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.WEBRTC_USER_MEDIA_ERROR\n }\n });\n this.callKit.reset();\n });\n\n const { userInfo, constrains } = this.callKit.config.getConfig();\n\n const localStreamFactory = async () => {\n this.mediaStream = await navigator.mediaDevices.getUserMedia(constrains);\n return this.mediaStream;\n };\n\n const { userPart, fsIp, fsPort, iceInfo, wsUrl } = userInfo;\n\n const connectConfig: UserAgentOptions = {\n uri: UserAgent.makeURI(`sip:${userPart}@${fsIp}:${fsPort}`),\n displayName: userPart,\n transportOptions: {\n wsServers: [wsUrl],\n traceSip: true\n },\n logLevel: 'error',\n allowLegacyNotifications: true,\n contactName: userPart,\n sessionDescriptionHandlerFactory:\n Web.defaultSessionDescriptionHandlerFactory(localStreamFactory),\n sessionDescriptionHandlerFactoryOptions: {\n constraints: constrains,\n iceGatheringTimeout: userInfo.iceGatheringTimeout,\n peerConnectionConfiguration: {\n iceServers: JSON.parse(convertObjectStringToJSON(iceInfo))\n }\n }\n };\n\n this.callKit.logger.info('connect connectConfig', {\n caller: 'Connect.register',\n content: connectConfig\n });\n\n this.userAgent = new UserAgent(connectConfig);\n\n const remoteStream = new MediaStream();\n\n const setupRemoteMedia = (session) => {\n const audioRef = this.getAduioReference();\n this.callKit.logger.info('connect setupRemoteMedia', {\n caller: 'Connect.register.setupRemoteMedia',\n content: audioRef\n });\n session.sessionDescriptionHandler.peerConnection\n .getReceivers()\n .forEach((receiver) => {\n if (receiver.track) {\n remoteStream.addTrack(receiver.track);\n }\n });\n\n if (audioRef) {\n audioRef.srcObject = remoteStream;\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.register.setupRemoteMedia',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n } else {\n this.callKit.logger.error('video is not exist', {\n caller: 'Connect.register',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAYER_ERROR\n }\n });\n }\n };\n\n const observeSocketStatus = (userAgent: UserAgent, extra?: any) => {\n const { that = this } = extra;\n // Get userAgentCore\n const core: any = (userAgent as any).userAgentCore;\n // Save the original receiveRequest method\n const originalReceiveRequest = core.receiveRequest.bind(core);\n // Proxy receiveRequest\n core.receiveRequest = (request: any) => {\n if (request.method === 'OPTIONS') {\n that.startHeartbeat();\n }\n that.callKit.logger.info(`SIP Receive Request: ${request.method}`, {\n caller: 'Connect.register.observeSocketStatus',\n type: 'SIP',\n content: {\n request\n }\n });\n // Other requests are handled by the original method\n return originalReceiveRequest(request);\n };\n\n // Get transport layer to intercept outgoing messages\n const { transport } = userAgent as any;\n if (transport) {\n // Save the original send method\n const originalSend = transport.send.bind(transport);\n // Proxy transport send to capture outgoing messages\n transport.send = (message: any) => {\n that.callKit.logger.info(`SIP send message`, {\n caller: 'Connect.register.observeSocketStatus',\n type: 'SIP',\n content: {\n message: message.toString()\n }\n });\n // Send the message using the original method\n return originalSend(message);\n };\n }\n };\n\n const registererOptions = {};\n this.registerer = new Registerer(this.userAgent, registererOptions);\n\n this.registerer.stateChange.addListener((state) => {\n switch (state) {\n // No registration relationship established with the SIP server yet\n case RegistererState.Initial:\n this.callKit.logger.info('registerer stateChange Initial', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n registererState: state,\n isRegistered: this.isRegistered\n });\n break;\n // REGISTER request was successful, the User Agent has completed registration on the server.\n case RegistererState.Registered:\n this.callKit.logger.info('registerer stateChange Registered', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(true);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n registererState: state,\n isRegistered: this.isRegistered\n });\n break;\n // Just unregistered, can call register() to re-register\n case RegistererState.Terminated:\n this.callKit.logger.info('registerer stateChange Terminated', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n registererState: state,\n isRegistered: this.isRegistered\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n isRegistered: this.isRegistered,\n registererState: state\n });\n break;\n // Just unregistered, can register() again to re-register\n case RegistererState.Unregistered:\n this.callKit.logger.info('registerer stateChange Unregistered', {\n caller: 'Connect.register.registererStateChange',\n type: 'SIP',\n content: {\n isRegistered: this.isRegistered,\n registererState: state\n }\n });\n this.setRegister(false);\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.SIP_REGISTERER_EVENT, {\n isRegistered: this.isRegistered,\n registererState: state\n });\n break;\n default:\n break;\n }\n });\n\n this.userAgent.delegate = {\n onInvite: (invite) => {\n this.callKit.logger.info('connect onInvite', {\n type: 'SIP',\n caller: 'Connect.register.onInvite',\n content: {\n invite,\n isRegistered: this.isRegistered\n }\n });\n this.currentSession = invite;\n if (this.isOutgoing) {\n this.isCurrentSessionInvited = false;\n }\n this.currentSession.stateChange.addListener((state) => {\n switch (state) {\n case SessionState.Establishing:\n this.callKit.logger.info('connect Establishing', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n this.setConnectStatus(CallStatus.ringing);\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n case SessionState.Established:\n this.callKit.logger.info('connect Established', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n this.callKit.connect.setConnectStatus(CallStatus.calling);\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n setupRemoteMedia(this.currentSession);\n break;\n case SessionState.Terminating:\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n case SessionState.Terminated:\n this.callKit.logger.info('connect Terminated', {\n caller: 'Connect.register.onInvite',\n type: 'SIP',\n content: {\n sessionState: state\n }\n });\n if (this.isUnprompted) {\n if (this.isCurrentSessionInvited) {\n this.currentSession.reject();\n }\n } else {\n this.callKit.callCenter.callEnd();\n }\n this.isUnprompted = false;\n\n this.callKit.trigger(KitEvent.SIP_SESSION_EVENT, {\n sessionState: state,\n isRegistered: this.isRegistered\n });\n break;\n default:\n break;\n }\n });\n\n const options = {\n sessionDescriptionHandlerOptions: {\n constraints: constrains,\n alwaysAcquireMediaFirst: true\n }\n };\n // Active dialing, automatically answer when connecting\n if (this.isOutgoing) {\n this.currentSession.accept(options);\n this.setConnectStatus(CallStatus.connecting);\n this.callKit.trigger(KitEvent.KIT_OUTGOING_INVITE, {\n getInviteData: () => {\n const { request } = this.currentSession;\n const headerNames = Object.keys(request.headers);\n const xHeaders = {};\n headerNames\n .filter((name) =>\n name.toLocaleLowerCase().startsWith('x-antaios')\n )\n .forEach((name) => {\n xHeaders[name.toLocaleLowerCase()] = request.getHeader(name);\n });\n this.callKit.logger.info('get invite data', {\n caller: 'Connect.register.onInvite',\n content: xHeaders\n });\n return xHeaders;\n }\n });\n } else {\n const reject = () => {\n this.currentSession.reject();\n this.callKit.callCenter.callEnd(true, false);\n };\n\n this.callKit.trigger(KitEvent.KIT_INVITE, {\n accept: () => {\n this.isCurrentSessionInvited = true;\n this.callKit.trigger(KitEvent.CALL_CONNECTING, new Date());\n this.currentSession.accept(options);\n },\n reject,\n getInviteData: () => {\n const { request } = this.currentSession;\n const headerNames = Object.keys(request.headers);\n const xHeaders = {};\n headerNames\n .filter((name) =>\n name.toLocaleLowerCase().startsWith('x-antaios')\n )\n .forEach((name) => {\n xHeaders[name.toLocaleLowerCase()] = request.getHeader(name);\n });\n this.callKit.logger.info('get invite data', {\n caller: 'Connect.register',\n content: xHeaders\n });\n return xHeaders;\n }\n });\n }\n },\n onConnect: async () => {\n this.reconnectAttempts = 0;\n this.reconnectTimer = null;\n this.callKit.logger.info('connect onConnect', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n version: `V${this.callKit.config.getConfig().version}`\n }\n });\n const version = `V${this.callKit.config.getConfig().version}`;\n await this.registerer\n .register()\n .then(() => {\n this.callKit.socket.send(SocketSendEvent.START, {\n version\n });\n })\n .catch(async (err) => {\n this.callKit.logger.error(err?.message, {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_REGISTER_ERROR\n }\n });\n this.callKit.reset();\n });\n },\n onDisconnect: (error?: Error) => {\n console.log('onDisconnect', error);\n if (error) {\n this.startReconnectTimer();\n } else {\n this.callKit.logger.info('SIP User Agent Disconnected', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n err: error.message,\n errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR\n }\n });\n }\n },\n onRegister: () => {\n this.callKit.logger.info('connect onRegister', {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n version: `V${this.callKit.config.getConfig().version}`\n }\n });\n }\n };\n\n observeSocketStatus(this.userAgent, {\n that: this\n });\n\n await this.userAgent.start().catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.register',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_USER_AGENT_ERROR\n }\n });\n this.callKit.reset();\n });\n }\n\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private reconnectAttempts = 0;\n\n private startReconnectTimer() {\n if (this.reconnectAttempts >= this.reconnectConfig.maxAttempts) {\n this.callKit.logger.error('Reconnect failed max attempts', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n errCode: ErrorCode.SOCKET_RECONNECT_FAILED,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n this.callKit.reset();\n return;\n }\n\n this.callKit.logger.info('Reconnect timer started', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n\n this.reconnectAttempts += 1;\n this.reconnectTimer = setTimeout(() => {\n if (this.reconnectTimer) {\n this.userAgent.reconnect();\n this.callKit.logger.info('Reconnect attempt', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n } else {\n this.callKit.logger.info('Reconnect timer already expired', {\n caller: 'Connect.startReconnectTimer',\n type: 'SIP',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts,\n delay: this.reconnectConfig.delay\n }\n });\n }\n }, this.reconnectConfig.delay);\n }\n\n async stop() {\n await this.userAgent.stop();\n }\n\n async unregister() {\n this.callKit.logger.info('connect unregister', {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n isRegistered: this.isRegistered,\n registerer: this.registerer\n }\n });\n if (!this.isRegistered || !this.registerer) {\n this.callKit.logger.warn('No registerer to unregister.', {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_CANCEL_REGISTER_ERROR\n }\n });\n return;\n }\n await this.registerer.unregister({ all: true }).catch((err) => {\n this.callKit.logger.error(err, {\n caller: 'Connect.unregister',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_CANCEL_REGISTER_ERROR\n }\n });\n this.callKit.reset();\n });\n }\n\n async call(callback: (userInfo: IConfig['userInfo']) => void) {\n this.callKit.logger.info('connect call', {\n caller: 'Connect.call',\n type: 'SIP',\n content: {\n callback\n }\n });\n this.isOutgoing = true;\n if (!this.isRegistered) {\n await this.register();\n }\n this.setConnectStatus(CallStatus.connecting);\n this.callKit.trigger(KitEvent.CALL_CONNECTING, new Date());\n const { userInfo } = this.callKit.config.getConfig();\n callback(userInfo);\n }\n\n /**\n * Update registration status\n * @param register\n */\n setRegister(register: boolean) {\n this.callKit.logger.info('connect setRegister', {\n caller: 'Connect.setRegister',\n type: 'SIP',\n content: {\n register\n }\n });\n this.isRegistered = register;\n this.callKit.trigger(KitEvent.KIT_REGISTER_CHANGE, register);\n }\n\n /**\n * Set call status\n * @param status\n */\n setConnectStatus(status: CallStatusType) {\n this.callKit.logger.info('connect setConnectStatus', {\n caller: 'Connect.setConnectStatus',\n type: 'SIP',\n content: {\n status\n }\n });\n this.connectStatus = status;\n this.callKit.trigger(KitEvent.KIT_CALL_STATUS_CHANGE, status);\n }\n\n /**\n * Hang up\n * @param isUnprompted Whether actively hanging up\n * @param isError Whether an error occurred\n * @returns\n */\n async hangup(isUnprompted = false, isError = false) {\n this.callKit.logger.info('connect hangup', {\n caller: 'Connect.hangup',\n type: 'SIP',\n content: {\n isUnprompted,\n isError,\n connectStatus: this.connectStatus\n }\n });\n if (this.connectStatus === CallStatus.init) return;\n this.isOutgoing = false;\n this.isUnprompted = isUnprompted;\n\n try {\n // 1. First handle Socket signaling\n if (isUnprompted) {\n // this.callKit.socket.send(SocketSendEvent.AGENT_HANGUP);\n\n const shouldSendBye =\n // this.sipConnected ||\n this.isRinging() || this.isCalling() || this.isHolding();\n\n if (shouldSendBye) {\n await this.currentSession?.bye();\n }\n }\n\n // 2. Clean up media resources\n // this.sipConnected = false;\n closeStream(this.mediaStream);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.pause();\n audioRef.srcObject = null;\n }\n\n this.setConnectStatus(CallStatus.init);\n this.callKit.trigger(KitEvent.CALL_END, new Date());\n } catch (err) {\n this.callKit.logger.error(err, {\n caller: 'Connect.hangup',\n type: 'SIP',\n content: {\n connectStatus: this.connectStatus,\n isError,\n isUnprompted\n }\n });\n this.callKit.trigger(KitEvent.CALL_END, new Date());\n this.callKit.reset();\n }\n }\n\n /**\n * The remote media stream. Undefined if call not answered.\n * @param session - Session to get the media stream from.\n */\n getRemoteMediaStream(session) {\n this.callKit.logger.info('connect getRemoteMediaStream', {\n caller: 'Connect.getRemoteMediaStream',\n type: 'SIP',\n content: {\n session\n }\n });\n const sdh = session.sessionDescriptionHandler;\n if (!sdh) {\n return undefined;\n }\n return sdh.remoteMediaStream;\n }\n\n setupRemoteMedia(session) {\n this.callKit.logger.info('connect setupRemoteMedia', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n session\n }\n });\n const remoteStream = this.getRemoteMediaStream(session);\n const audioRef = this.getAduioReference();\n if (audioRef) {\n audioRef.autoplay = true;\n audioRef.srcObject = remoteStream;\n\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n\n remoteStream.onaddtrack = () => {\n this.callKit.logger.info('Remote media onaddtrack', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n session\n }\n });\n audioRef.load();\n audioRef.play().catch((error) => {\n this.callKit.logger.error(error.message, {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAY_ERROR\n }\n });\n });\n };\n } else {\n this.callKit.logger.error('video is not exist', {\n caller: 'Connect.setupRemoteMedia',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_AUDIO_PLAYER_ERROR\n }\n });\n }\n }\n\n /**\n * Update hold\n * @param hold\n */\n setHoldStatus(hold: boolean) {\n this.callKit.logger.info('connect setHold', {\n caller: 'Connect.setHoldStatus',\n type: 'SIP',\n content: {\n hold\n }\n });\n this.callKit.trigger(KitEvent.KIT_SET_HOLD, hold);\n }\n\n async setHold(hold: boolean) {\n this.setHoldStatus(hold);\n // Hold goes through socket, not sip\n\n // const options = {\n // requestDelegate: {\n // onAccept: () => {\n // this.callKit.logger.info('setHold onAccept', hold);\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.setupRemoteMedia(this.currentSession);\n // },\n // onReject: () => {\n // this.callKit.logger.info('setHold onReject');\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.setupRemoteMedia(this.currentSession);\n // }\n // }\n // };\n\n // const sessionDescriptionHandlerOptions = this.currentSession.sessionDescriptionHandlerOptionsReInvite;\n\n // (sessionDescriptionHandlerOptions as any).hold = hold;\n // this.currentSession.sessionDescriptionHandlerOptionsReInvite = sessionDescriptionHandlerOptions;\n\n // return this.currentSession\n // .invite(options)\n // .then(() => {\n // enableReceiverTracks(this.currentSession, !hold);\n // enableSenderTracks(this.currentSession, !hold);\n // this.callKit.logger.info('setHold success');\n // })\n // .catch((err) => {\n // this.callKit.logger.error(err?.message, {\n // errCode: ErrorCode.WEBRTC_CALL_INVITE_ERROR\n // });\n // });\n }\n\n async hold() {\n this.callKit.logger.info('connect hold', {\n caller: 'Connect.hold',\n type: 'SIP',\n content: {\n hold: true\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.error('Current status is not in call', {\n caller: 'Connect.hold',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_HOLE_STATUS_ERROR\n }\n });\n }\n }\n\n async unhold() {\n this.callKit.logger.info('connect unhold', {\n caller: 'Connect.unhold',\n type: 'SIP',\n content: {\n hold: false\n }\n });\n }\n\n async setMute(mute: boolean) {\n this.callKit.logger.info('connect setMute', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n mute\n }\n });\n\n if (!this.currentSession) {\n this.callKit.logger.error('No active session', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n this.callKit.reset();\n return;\n }\n\n try {\n // Get SessionDescriptionHandler\n const sdh = this.currentSession.sessionDescriptionHandler;\n if (!sdh || !('peerConnection' in sdh)) {\n throw new Error('Invalid session description handler');\n }\n\n // Get PeerConnection\n const pc = (sdh as any).peerConnection as RTCPeerConnection;\n\n // Get local audio track and set status\n const audioSender = pc\n .getSenders()\n .find((sender) => sender.track?.kind === 'audio');\n\n if (audioSender && audioSender.track) {\n audioSender.track.enabled = !mute;\n // Update status and trigger event\n this.isMute = mute;\n this.callKit.trigger(KitEvent.KIT_SET_MUTE, mute);\n } else {\n throw new Error('No audio track found');\n }\n } catch (error) {\n this.callKit.logger.error('Failed to set mute state', {\n caller: 'Connect.setMute',\n type: 'SIP',\n content: {\n err: error.message,\n errCode: ErrorCode.WEBRTC_MUTE_ERROR\n }\n });\n }\n }\n\n async mute() {\n this.callKit.logger.info('connect mute', {\n caller: 'Connect.mute',\n type: 'SIP',\n content: {\n mute: true\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.warn('Current status is not in call', {\n caller: 'Connect.mute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n return;\n }\n await this.setMute(true);\n }\n\n async unmute() {\n this.callKit.logger.info('connect unmute', {\n caller: 'Connect.unmute',\n type: 'SIP',\n content: {\n mute: false\n }\n });\n if (this.connectStatus !== CallStatus.calling || !this.currentSession) {\n this.callKit.logger.warn('Current status is not in call', {\n caller: 'Connect.unmute',\n type: 'SIP',\n content: {\n errCode: ErrorCode.WEBRTC_MUTE_STATUS_ERROR\n }\n });\n return;\n }\n await this.setMute(false);\n }\n\n async refer(referTo: string, extra?: any) {\n this.callKit.logger.info('connect refer', {\n caller: 'Connect.refer',\n type: 'SIP',\n content: {\n referTo,\n extra\n }\n });\n let target;\n if (referTo) {\n target = UserAgent.makeURI(referTo);\n }\n this.currentSession.refer(target, extra?.sessionReferOptions);\n }\n}\n","import type { CallKit } from '.';\nimport {\n SocketSendEvent,\n ErrorCode,\n KitEvent,\n SocketReceiveEvent,\n CallSourceType\n} from './const';\n\nexport type SocketReceiveEventType =\n (typeof SocketReceiveEvent)[keyof typeof SocketReceiveEvent];\nexport type SocketSendEventType =\n (typeof SocketSendEvent)[keyof typeof SocketSendEvent];\n\nexport interface SocketMessage {\n event: SocketReceiveEventType;\n msg: string;\n data: object;\n}\n\nexport interface SocketConfig {\n enabled: boolean;\n maxAttempts: number;\n delay: number;\n backoffMultiplier: number; // Reconnection delay time multiplier growth factor\n pingInterval: number;\n pingTimeout: number;\n}\n\n/**\n * Default configuration\n */\nconst RECONNECT_CONFIG: SocketConfig = {\n enabled: true,\n maxAttempts: 1,\n delay: 500,\n backoffMultiplier: 1.5,\n pingInterval: 30000,\n pingTimeout: 5000\n};\n\nexport class Socket {\n private callKit: CallKit;\n private ws?: WebSocket;\n\n private socketConfig: SocketConfig;\n\n lastPingTime = undefined;\n isConnected = false;\n pingTimer?: number;\n\n // Whether received start confirmation\n satrtConfirm = false;\n private reconnectTimer?: any;\n private isReconnecting = false;\n private reconnectAttempts = 0;\n\n constructor(callKit: CallKit) {\n this.callKit = callKit;\n const { reconnect } = this.callKit.config.getConfig();\n this.socketConfig = {\n ...RECONNECT_CONFIG,\n ...reconnect\n };\n }\n\n init() {\n const { socket } = this.callKit.config.getConfig();\n this.callKit.logger.info(`socket init: ${socket}`, {\n caller: 'Socket.init',\n type: 'INCALL',\n content: {\n socket\n }\n });\n this.connect(socket);\n }\n\n private handleDisconnect() {\n this.isConnected = false;\n\n if (!this.callKit.config.isLogin() || !this.socketConfig.enabled) {\n this.reset();\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n return;\n }\n\n this.attemptReconnect();\n }\n\n private connect(socketUrl: string) {\n this.ws = new WebSocket(socketUrl);\n this.ws.onopen = (ev: Event) => this.onOpen(ev);\n this.ws.onclose = (ev: CloseEvent) => this.onClose(ev);\n this.ws.onerror = (ev: Event) => this.onError(ev);\n this.ws.onmessage = (ev: MessageEvent) => this.onMessage(ev);\n }\n\n private onOpen(ev: Event) {\n this.callKit.logger.info('socket onOpen', {\n caller: 'Socket.onOpen',\n type: 'INCALL',\n content: { ev }\n });\n\n this.isConnected = true;\n this.lastPingTime = Date.now();\n this.checkPing();\n\n if (this.isReconnecting) {\n this.callKit.logger.info('reconnect success', {\n caller: 'Socket.onOpen',\n type: 'INCALL',\n content: {\n event: 'INCALL_RECONNECT_SUCCESS',\n reconnectAttempts: this.reconnectAttempts\n }\n });\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_SUCCESS'\n });\n }\n\n this.resetReconnectState();\n }\n\n private resetReconnectState() {\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n private onClose(ev: CloseEvent) {\n this.callKit.logger.info('socket onClose', {\n caller: 'Socket.onClose',\n type: 'INCALL',\n content: { ev }\n });\n\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_CONNECT_ERROR',\n err: ev\n });\n\n this.handleDisconnect();\n }\n\n private onError(ev: Event) {\n this.callKit.logger.error('socket onError', {\n caller: 'Socket.onError',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR,\n data: ev\n }\n });\n }\n\n private confirmAck(data: any) {\n const { ack, messageId } = data;\n if (ack) {\n this.send(SocketSendEvent.ACK, {\n messageId\n });\n }\n }\n\n private onMessage(ev: MessageEvent<string>) {\n const data = JSON.parse(ev.data);\n this.callKit.logger.info('socket onMessage', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: data.event\n }\n });\n\n this.confirmAck(data);\n\n if (data.event === SocketReceiveEvent.PONG) {\n this.lastPingTime = Date.now();\n return;\n }\n\n if (data.event === SocketReceiveEvent.START_CONFIRM) {\n this.callKit.logger.info('start confirm success', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.START_CONFIRM\n }\n });\n this.satrtConfirm = true;\n }\n\n if (data.event === SocketReceiveEvent.CALL_SUCCESS) {\n this.callKit.logger.info('call success', {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CALL_SUCCESS\n }\n });\n }\n\n if (data.event === SocketReceiveEvent.CALL_FAILED) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n errCode: ErrorCode.SOCKET_CALL_ERROR\n }\n });\n }\n\n if (data.event === SocketReceiveEvent.CUSTOMER_RINGING) {\n this.callKit.trigger(KitEvent.CALL_RINGING, new Date());\n }\n if (data.event === SocketReceiveEvent.CUSTOMER_PICK_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_PICK_UP\n }\n });\n this.callKit.trigger(KitEvent.CALL_PICK_UP, new Date());\n }\n\n if (data.event === SocketReceiveEvent.AGENT_PICK_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.AGENT_PICK_UP\n }\n });\n this.callKit.trigger(KitEvent.AGENT_PICK_UP, new Date());\n }\n\n if (data.event === SocketReceiveEvent.CUSTOMER_HANG_UP) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_HANG_UP\n }\n });\n this.callKit.trigger(KitEvent.CALL_HANG_UP, new Date());\n }\n if (data.event === SocketReceiveEvent.CUSTOMER_NO_ANSWER) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n type: 'INCALL',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CUSTOMER_NO_ANSWER\n }\n });\n this.callKit.trigger(KitEvent.CALL_NO_ANSWER);\n }\n if (data.event === SocketReceiveEvent.CALL_CDR) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CALL_CDR\n }\n });\n this.callKit.trigger(KitEvent.CALL_CDR, data.data);\n }\n if (data.event === SocketReceiveEvent.STOP_CONFIRM) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.STOP_CONFIRM\n }\n });\n }\n if (data.event === SocketReceiveEvent.CLOSE) {\n const { userInfo } = this.callKit.config.getConfig();\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.CLOSE\n }\n });\n this.send(SocketSendEvent.END, {\n agentId: userInfo.agentId\n });\n }\n if (data.event === SocketReceiveEvent.ERROR) {\n this.callKit.logger.error(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n errCode: ErrorCode.SOKET_SERVER_ERROR,\n data: data.data\n }\n });\n this.callKit.reset();\n }\n\n if (data.event === SocketReceiveEvent.AGENT_NO_ANSWER) {\n this.callKit.logger.info(data.msg, {\n caller: 'Socket.onMessage',\n content: {\n data: data.data,\n event: SocketReceiveEvent.AGENT_NO_ANSWER\n }\n });\n }\n\n this.callKit.trigger(KitEvent.SERVER_SOCKET_EVENT, data);\n }\n\n send(event: SocketSendEventType, message?: any) {\n if (!this.isConnected) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n this.callKit.logger.error('socket not connected', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n this.callKit.config.reset();\n this.callKit.reset();\n return;\n }\n const { userInfo } = this.callKit.config.getConfig();\n const { sessionId, extno, agentId } = userInfo;\n if (!sessionId) {\n this.callKit.logger.error('sessionId is empty', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n return;\n }\n const msg = {\n event,\n sessionId,\n ...message\n };\n\n if (SocketSendEvent.CALL === event) {\n msg.phoneNum = extno;\n msg.agentId = agentId;\n if (message?.sourceType === CallSourceType.phoneNum) {\n delete msg.workOrderId;\n } else if (message?.sourceType === CallSourceType.workOrderId) {\n delete msg.phoneNum;\n }\n }\n\n this.callKit.logger.info('socket send', {\n caller: 'Socket.send',\n type: 'INCALL',\n content: {\n event,\n message\n }\n });\n switch (event) {\n case SocketSendEvent.PING:\n this.lastPingTime = Date.now();\n this.ws?.send(JSON.stringify({ event, ...msg }));\n break;\n default:\n this.ws?.send(JSON.stringify({ event, ...msg }));\n break;\n }\n }\n\n async sendMessage(event: SocketSendEventType, message?: any) {\n if (!this.isConnected) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_NOT_CONNECTED'\n });\n this.callKit.logger.error('socket not connected', {\n caller: 'Socket.sendMessage',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_CONNECT_ERROR\n }\n });\n return;\n }\n const { userInfo } = this.callKit.config.getConfig();\n const { sessionId } = userInfo;\n\n this.ws?.send(JSON.stringify({ event, sessionId, ...message }));\n }\n\n private ping() {\n if (!this.isConnected) return;\n this.send(SocketSendEvent.PING);\n this.callKit.logger.info(`socket ping`, {\n caller: 'Socket.ping',\n type: 'INCALL',\n content: {\n lastPingTime: this.lastPingTime\n }\n });\n // 5s is considered timeout\n const now = Date.now();\n const { pingInterval, pingTimeout } = this.socketConfig;\n if (now - this.lastPingTime > pingInterval + pingTimeout) {\n this.callKit.logger.error('socket ping timeout', {\n caller: 'Socket.ping',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_PING_TIMEOUT\n }\n });\n if (this.ws && this.isConnected) {\n this.ws.close(4001, 'ping timeout');\n } else {\n this.reset();\n }\n }\n }\n\n private checkPing() {\n if (this.pingTimer) {\n clearInterval(this.pingTimer);\n }\n this.ping();\n this.pingTimer = setInterval(() => {\n this.ping();\n }, this.socketConfig.pingInterval);\n }\n\n /**\n * 重置 socket 连接和所有状态\n * @param isWaitConfirm Whether need to wait for close confirmation\n */\n async reset(isWaitConfirm = true) {\n // 清理定时器\n if (this.pingTimer) {\n clearInterval(this.pingTimer);\n this.pingTimer = undefined;\n }\n\n // 重置重连状态\n this.resetReconnectState();\n\n // 重置其他状态\n this.lastPingTime = undefined;\n this.satrtConfirm = false;\n\n // 关闭 WebSocket 连接\n if (this.ws && this.isConnected) {\n this.callKit.logger.info('Closing socket connection', {\n caller: 'Socket.reset',\n type: 'INCALL',\n content: {\n isWaitConfirm\n }\n });\n this.ws.close();\n this.isConnected = false;\n }\n }\n\n private attemptReconnect() {\n // 检查是否已达到最大重连次数\n if (this.reconnectAttempts >= this.socketConfig.maxAttempts) {\n this.callKit.logger.error('Maximum reconnection attempts reached', {\n caller: 'Socket.attemptReconnect',\n type: 'INCALL',\n content: {\n errCode: ErrorCode.SOCKET_RECONNECT_FAILED,\n reconnectAttempts: this.reconnectAttempts\n }\n });\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_ERROR'\n });\n this.reset();\n return;\n }\n\n // 首次重连时触发开始事件\n if (this.reconnectAttempts === 0) {\n this.callKit.trigger(KitEvent.CONNECT_EVENT, {\n event: 'INCALL_RECONNECT_START'\n });\n }\n\n this.isReconnecting = true;\n this.reconnectAttempts += 1;\n\n const { delay } = this.socketConfig;\n\n this.callKit.logger.info(\n `Preparing reconnection attempt ${this.reconnectAttempts}/${this.socketConfig.maxAttempts}, delay: ${delay}ms`,\n {\n caller: 'Socket.attemptReconnect',\n type: 'INCALL',\n content: {\n reconnectAttempts: this.reconnectAttempts,\n maxAttempts: this.socketConfig.maxAttempts,\n delay\n }\n }\n );\n\n this.reconnectTimer = setTimeout(() => {\n const { socket } = this.callKit.config.getConfig();\n this.connect(socket);\n }, delay);\n }\n}\n"],"mappings":"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","names":["data","request"]}