@wizai/agent-sip-sdk 0.1.17-alpha → 0.2.0

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,4 +1,5 @@
1
- import type { IApiProps, IRespones, IAgentStatusListResponse, IAgentStatusResponse, IGetAgentSettingParams, IGetAgentSettingResponse, IUpdateAgentTicketParams, IRegisterSSEParams, ICloseSSEParams, ISwitchAgentStatusParams, IOutboundCallParams, IOutboundCallResponse, IAgentResponseTimeParams, IAgentAbnormalCloseParams, IGetCallTaskInfoParams, IGetCallTaskInfoResponse, ISendBeaconParams } from './types';
1
+ import type { ISdkTraceEvent, ISdkTraceConfig, ITrackOpts } from '../tracker/types';
2
+ import type { IApiProps, IRespones, IAgentStatusListResponse, IAgentStatusResponse, IGetAgentSettingParams, IGetAgentSettingResponse, IUpdateAgentTicketParams, IRegisterSSEParams, ICloseSSEParams, ISwitchAgentStatusParams, IOutboundCallParams, IOutboundCallResponse, IAgentResponseTimeParams, IAgentAbnormalCloseParams, IGetCallTaskInfoParams, IGetCallTaskInfoResponse, ISendBeaconParams, IReportPDSTimeline } from './types';
2
3
  import { EApiCode } from '../enums/common';
3
4
  declare class Api {
4
5
  private baseUrl;
@@ -10,6 +11,8 @@ declare class Api {
10
11
  private token;
11
12
  private getSystemToken;
12
13
  private resetSSE;
14
+ private track;
15
+ setTrack(fn: (event: string, opts?: ITrackOpts) => void): void;
13
16
  constructor(props: IApiProps);
14
17
  validateToken(id: string, token: string): Promise<IRespones<boolean>>;
15
18
  initToken(): Promise<{
@@ -23,13 +26,26 @@ declare class Api {
23
26
  getAgentSetting(params: IGetAgentSettingParams): Promise<IGetAgentSettingResponse>;
24
27
  updateAgentHangup(agentId: number): Promise<IGetAgentSettingResponse>;
25
28
  updateAgentTicket(data: IUpdateAgentTicketParams): Promise<IRespones<any>>;
26
- sendSSEACK(agentId: number): Promise<any>;
29
+ sendSSEACK(agentId: number): Promise<boolean>;
27
30
  registerSSE(data: IRegisterSSEParams): Promise<unknown>;
28
31
  closeClientSSE(): void;
29
32
  closeSSE(data: ICloseSSEParams): Promise<IRespones<any> | undefined>;
33
+ sendHeartbeat(agentId: number): Promise<boolean>;
30
34
  switchAgentStatus(data: ISwitchAgentStatusParams): Promise<IRespones<IAgentStatusResponse>>;
31
35
  outboundCall(data: IOutboundCallParams): Promise<IRespones<IOutboundCallResponse>>;
32
36
  saveAgentResponseTime(data: IAgentResponseTimeParams): Promise<IRespones<any>>;
37
+ reportPDSTimeline(data: IReportPDSTimeline): Promise<boolean>;
38
+ /**
39
+ * 埋点上报专用发送:不复用 request()(避开 waitToken/initToken)。
40
+ * 尽力带 token(非强制,取不到也照发),只看 res.ok 判成功,不强解 body。
41
+ * keepalive:卸载时用;useBeacon:keepalive 不支持时降级 FormData + sendBeacon。
42
+ */
43
+ reportSdkTrace(event: ISdkTraceEvent, opts?: {
44
+ keepalive?: boolean;
45
+ useBeacon?: boolean;
46
+ }): Promise<boolean>;
47
+ /** 采集开关:全局、不带 token、不校验。失败返回 null(调用方用缓存兜底)。 */
48
+ getSdkTraceConfig(): Promise<ISdkTraceConfig | null>;
33
49
  getCallTaskInfo(data: IGetCallTaskInfoParams): Promise<IGetCallTaskInfoResponse>;
34
50
  getAfterCallProcessTime(data: IGetCallTaskInfoParams): Promise<IRespones<number>>;
35
51
  formatFormData<T = Record<string, any>>(params: T): FormData;
@@ -47,6 +63,5 @@ declare class Api {
47
63
  private request;
48
64
  private executePeriodically;
49
65
  static getInstance(options?: IApiProps): Api;
50
- heartbeat(): Promise<IRespones<boolean>>;
51
66
  }
52
67
  export default Api;
@@ -9,7 +9,7 @@ export interface IRequestOptionsType<T = any> {
9
9
  export interface IApiProps {
10
10
  id: string;
11
11
  getSystemToken: () => Promise<string>;
12
- resetSSE: () => Promise<void>;
12
+ resetSSE?: () => Promise<void>;
13
13
  baseUrl?: string;
14
14
  retryCount?: number;
15
15
  }
@@ -150,4 +150,9 @@ export interface ISendBeaconParams {
150
150
  Authentication?: string;
151
151
  trace?: string;
152
152
  }
153
+ export interface IReportPDSTimeline {
154
+ callId?: string;
155
+ eventType: number;
156
+ timestamp?: number;
157
+ }
153
158
  export {};
@@ -7,3 +7,7 @@ export declare enum EAgentAction {
7
7
  ANSWER = 1,
8
8
  HANGUP = 2
9
9
  }
10
+ export declare enum EReportPDSTimeEventType {
11
+ INCOMMING = 1,
12
+ ACW = 2
13
+ }
@@ -13,21 +13,20 @@ declare class AgentSipSDK {
13
13
  private agentResponseTime;
14
14
  private timer;
15
15
  private callDetails;
16
- private unloadingHandled;
17
16
  private baseUrl;
18
17
  private autoFinishACWTimer;
18
+ private _acwAutoTriggered;
19
19
  private heartbeatTimer;
20
20
  private heartbeatFailCount;
21
21
  private isHeartbeatRunning;
22
+ private tracker;
22
23
  constructor(props: IAgentSipSDKOptions);
23
24
  private init;
24
25
  getAgentStatusList(): Promise<IGetAgentStatusList>;
25
26
  private getTicket;
26
27
  private getHostName;
27
- private processSSEMessage;
28
- private resetSSE;
29
- private createSSEAndOpensips;
30
- private closeSSEAndOpensips;
28
+ private createOpensips;
29
+ private closeSip;
31
30
  private waitSIPRegistered;
32
31
  private getAgentInfo;
33
32
  getAgentStatus(): Promise<IGetAgentStatus>;
@@ -46,12 +45,10 @@ declare class AgentSipSDK {
46
45
  }>;
47
46
  private sessionEnded;
48
47
  private sessionFailed;
49
- private openOnunload;
50
- private cancelOnunload;
51
- private doForceOfflineCleanup;
52
48
  private saveAgentResponseTime;
53
49
  hangup(): void;
54
50
  private timingResTime;
51
+ private trackIncomingCall;
55
52
  private incomingCall;
56
53
  answer(): void;
57
54
  ignore(): void;
@@ -65,6 +62,8 @@ declare class AgentSipSDK {
65
62
  private emitAgentEvent;
66
63
  attachAnswerEvent(listener: IAnswerFnType): void;
67
64
  removeAnswerEvent(listener: IAnswerFnType): void;
65
+ attachAutoAnswerEvent(listener: IAnswerFnType): void;
66
+ removeAutoAnswerEvent(listener: IAnswerFnType): void;
68
67
  attachNewMessageEvent(listener: INewMessageFnType): void;
69
68
  removeNewMessageEvent(listener: INewMessageFnType): void;
70
69
  attchSessionEvent<T extends ISessionType>(type: T, listener: ISessionEventListener<T>): void;
@@ -1,6 +1,7 @@
1
1
  import type { UAEventMap, IncomingRTCSessionEvent } from 'jssip/lib/UA.d.ts';
2
2
  import type { RTCSession, RTCSessionEventMap } from 'jssip/lib/RTCSession.d.ts';
3
3
  import type { IAnswerFnType, IAnswerEventPayload, INewMessageFnType, INewMessageEventPayload, ISessionType, ISessionEventListener, ISessionEventPayload } from './types';
4
+ import type { ITrackOpts } from '../tracker/types';
4
5
  declare class SIP {
5
6
  private callType;
6
7
  private ua;
@@ -14,15 +15,22 @@ declare class SIP {
14
15
  private audio;
15
16
  private ringAudio;
16
17
  private answerEvent;
18
+ private autoAnswerEvent;
17
19
  private newMessageEvent;
18
20
  private sessionEvent;
19
21
  private callDetails;
20
22
  private cancelCallId;
21
23
  private readonly incomingCallCallback;
24
+ private readonly trackIncomingCallCallback?;
22
25
  private readonly getMediaStream;
26
+ private readonly applyAnswer?;
27
+ private readonly track;
23
28
  constructor(props: {
24
29
  incomingCallCallback: (_e: IncomingRTCSessionEvent) => Promise<IAnswerEventPayload>;
30
+ trackIncomingCallCallback?: (_callId: string) => void | undefined;
25
31
  getMediaStream?: () => Promise<MediaStream>;
32
+ applyAnswer?: () => void;
33
+ track?: (event: string, opts?: ITrackOpts) => void;
26
34
  });
27
35
  /**
28
36
  *
@@ -57,6 +65,9 @@ declare class SIP {
57
65
  attachAnswerEvent(listener: IAnswerFnType): void;
58
66
  removeAnswerEvent(listener: IAnswerFnType): void;
59
67
  emitAnswerEvent(data: IAnswerEventPayload): void;
68
+ attachAutoAnswerEvent(listener: IAnswerFnType): void;
69
+ removeAutoAnswerEvent(listener: IAnswerFnType): void;
70
+ emitAutoAnswerEvent(data: IAnswerEventPayload): void;
60
71
  attachNewMessageEvent(listener: INewMessageFnType): void;
61
72
  removeNewMessageEvent(listener: INewMessageFnType): void;
62
73
  emitNewMessageEvent(data: INewMessageEventPayload): void;
@@ -21,7 +21,9 @@ export type INewMessageEventPayload = IResponse<{
21
21
  } | null>;
22
22
  export type INewMessageFnType = (_data: INewMessageEventPayload) => void;
23
23
  export type ISessionType = 'success' | 'failed' | 'ended';
24
- export type ISessionEventPayload<T extends ISessionType> = IResponse<ICallDetails | null>;
24
+ export type ISessionEventPayload<T extends ISessionType> = IResponse<ICallDetails | null> & {
25
+ _type?: T;
26
+ };
25
27
  export type ISessionEventListener<T extends ISessionType> = (_data: ISessionEventPayload<T>) => void;
26
28
  export type ISessionEventType<T extends ISessionType> = {
27
29
  [K in T]: Array<ISessionEventListener<K>>;
@@ -0,0 +1,5 @@
1
+ type Storage = Pick<globalThis.Storage, 'getItem' | 'setItem' | 'removeItem'>;
2
+ /** 返回上次缓存的 collect;无缓存或损坏 → null */
3
+ export declare const readCachedCollect: (storage: Storage) => boolean | null;
4
+ export declare const writeCachedCollect: (storage: Storage, collect: boolean) => void;
5
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { ITrackOpts, ITrackerDeps } from './types';
2
+ export declare class Tracker {
3
+ private enabled;
4
+ private traceId;
5
+ private agentId;
6
+ private readonly version;
7
+ private readonly now;
8
+ private readonly genId;
9
+ private readonly report;
10
+ private readonly queue;
11
+ private lastSent;
12
+ private bucket;
13
+ private bucketTs;
14
+ constructor(deps: ITrackerDeps);
15
+ /** init 拉到 config 后调;也用于乐观套缓存 */
16
+ applyConfig(collect: boolean): void;
17
+ setAgentId(id: string | number): void;
18
+ resetTraceId(): void;
19
+ /** 唯一对外入口。全程 try/catch,任何情况不抛、不返回错误。 */
20
+ track(event: string, opts?: ITrackOpts): void;
21
+ /** 卸载/重连时把队列残留发出(keepalive 优先,降级 beacon)。 */
22
+ flush(): void;
23
+ private isDeduped;
24
+ private takeToken;
25
+ }
@@ -0,0 +1,18 @@
1
+ import type { ISdkTraceEvent } from './types';
2
+ export interface TraceQueueOpts {
3
+ cap: number;
4
+ ttlMs: number;
5
+ now: () => number;
6
+ }
7
+ type Storage = Pick<globalThis.Storage, 'getItem' | 'setItem' | 'removeItem'>;
8
+ export declare class TraceQueue {
9
+ private storage;
10
+ private opts;
11
+ constructor(storage: Storage, opts: TraceQueueOpts);
12
+ private read;
13
+ /** 入队:追加 + 超容量丢最旧。任何异常吞掉(不影响业务)。 */
14
+ enqueue(event: ISdkTraceEvent): void;
15
+ /** 取出全部(过滤超 TTL)并清空。异常吞掉返回空。 */
16
+ drain(): ISdkTraceEvent[];
17
+ }
18
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * message 统一脱敏兜底(PII 第二道防线):
3
+ * - url:去 query、把纯数字路径段替成 {id}
4
+ * - 7 位以上连续数字(手机号/卡号)→ 保留前 3 后 2,中间掩码
5
+ * - 限长 1024(顺带兜 keepalive/beacon ~64KB)
6
+ */
7
+ export declare const scrubMessage: (input: string) => string;
@@ -0,0 +1,41 @@
1
+ /** extra 白名单值类型:只允许标量,杜绝嵌套对象(FormData 装不下,且防 PII 后门) */
2
+ export type TraceExtra = Record<string, string | number | boolean>;
3
+ /** 单条埋点事件(上报 body / 入队单元) */
4
+ export interface ISdkTraceEvent {
5
+ timestamp: number;
6
+ traceId: string;
7
+ agentId: string;
8
+ sdkVersion: string;
9
+ callId: string;
10
+ callRecordId: string;
11
+ event: string;
12
+ message: string;
13
+ extra?: TraceExtra;
14
+ }
15
+ /** getSdkTraceConfig 响应 */
16
+ export interface ISdkTraceConfig {
17
+ collect: boolean;
18
+ }
19
+ /** track() 的可选入参(agentId/sdkVersion/timestamp/traceId 由 Tracker 补齐) */
20
+ export interface ITrackOpts {
21
+ callId?: string;
22
+ callRecordId?: string;
23
+ message?: string;
24
+ extra?: TraceExtra;
25
+ }
26
+ /** Tracker 的注入依赖——便于单测,不直接耦合 Api/全局 */
27
+ export interface ITrackerDeps {
28
+ /** 传输:返回是否送达(res.ok)。keepalive/beacon 由 opts 控制 */
29
+ report: (event: ISdkTraceEvent, opts?: {
30
+ keepalive?: boolean;
31
+ useBeacon?: boolean;
32
+ }) => Promise<boolean>;
33
+ /** localStorage(默认注入 window.localStorage;测试可注 mock) */
34
+ storage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
35
+ /** 版本常量 */
36
+ version: string;
37
+ /** 取当前毫秒(默认 Date.now;测试可注 mock) */
38
+ now?: () => number;
39
+ /** 生成 traceId(默认 nanoid;测试可注 mock) */
40
+ genId?: () => string;
41
+ }
@@ -25,6 +25,7 @@ export type IAgentEventPayload = IResponse<IAgentStatusParams>;
25
25
  export type IAgentFnType = (_data: IAgentEventPayload) => void;
26
26
  export interface ICallDetails {
27
27
  callId: string;
28
+ originCallId: string;
28
29
  callType: string;
29
30
  taskName: string;
30
31
  afterCallProcessTime: string;
@@ -0,0 +1 @@
1
+ export declare const SDK_VERSION: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wizai/agent-sip-sdk",
3
- "version": "0.1.17-alpha",
3
+ "version": "0.2.0",
4
4
  "description": "Manages SIP clients and agent status, simplifying calls and events.",
5
5
  "main": "lib/agent-sip-sdk-cjs.js",
6
6
  "module": "lib/agent-sip-sdk-es.js",