@webex/contact-center 3.11.0-next.21 → 3.11.0-next.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cc.js +71 -0
- package/dist/cc.js.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/metrics/behavioral-events.js +13 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +4 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/config/types.js +7 -1
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +92 -17
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/task/TaskManager.js +60 -3
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +16 -3
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +5 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +51 -0
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/types.js +15 -0
- package/dist/services/task/types.js.map +1 -1
- package/dist/types/cc.d.ts +31 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/config/types.d.ts +12 -0
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/aqm-reqs.d.ts +49 -0
- package/dist/types/services/task/TaskUtils.d.ts +8 -0
- package/dist/types/services/task/constants.d.ts +4 -0
- package/dist/types/services/task/dialer.d.ts +15 -0
- package/dist/types/services/task/types.d.ts +23 -1
- package/dist/types.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +2 -2
- package/src/cc.ts +99 -1
- package/src/constants.ts +1 -0
- package/src/metrics/behavioral-events.ts +14 -0
- package/src/metrics/constants.ts +4 -0
- package/src/services/config/types.ts +6 -0
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/aqm-reqs.ts +100 -22
- package/src/services/task/TaskManager.ts +75 -3
- package/src/services/task/TaskUtils.ts +12 -0
- package/src/services/task/constants.ts +4 -0
- package/src/services/task/dialer.ts +56 -1
- package/src/services/task/types.ts +24 -0
- package/src/types.ts +2 -1
- package/test/unit/spec/cc.ts +65 -0
- package/test/unit/spec/services/task/TaskManager.ts +281 -105
- package/test/unit/spec/services/task/dialer.ts +198 -112
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["HTTP_METHODS","exports","GET","POST","PATCH","PUT","DELETE","LOGGING_LEVEL","LoginOption","AGENT_DN","EXTENSION","BROWSER"],"sources":["types.ts"],"sourcesContent":["import {CallingClientConfig} from '@webex/calling';\nimport {\n SubmitBehavioralEvent,\n SubmitOperationalEvent,\n SubmitBusinessEvent,\n} from '@webex/internal-plugin-metrics/src/metrics.types';\nimport * as Agent from './services/agent/types';\nimport * as Contact from './services/task/types';\nimport {Profile} from './services/config/types';\nimport {PaginatedResponse, BaseSearchParams} from './utils/PageCache';\n\n/**\n * Generic type for converting a const enum object into a union type of its values.\n * @template T The enum object type\n * @internal\n * @ignore\n */\ntype Enum<T extends Record<string, unknown>> = T[keyof T];\n\n/**\n * HTTP methods supported by WebexRequest.\n * @enum {string}\n * @public\n * @example\n * const method: HTTP_METHODS = HTTP_METHODS.GET;\n * @ignore\n */\nexport const HTTP_METHODS = {\n /** HTTP GET method for retrieving data */\n GET: 'GET',\n /** HTTP POST method for creating resources */\n POST: 'POST',\n /** HTTP PATCH method for partial updates */\n PATCH: 'PATCH',\n /** HTTP PUT method for complete updates */\n PUT: 'PUT',\n /** HTTP DELETE method for removing resources */\n DELETE: 'DELETE',\n} as const;\n\n/**\n * Union type of HTTP methods.\n * @public\n * @example\n * function makeRequest(method: HTTP_METHODS) { ... }\n * @ignore\n */\nexport type HTTP_METHODS = Enum<typeof HTTP_METHODS>;\n\n/**\n * Payload for making requests to Webex APIs.\n * @public\n * @example\n * const payload: WebexRequestPayload = {\n * service: 'identity',\n * resource: '/users',\n * method: HTTP_METHODS.GET\n * };\n * @ignore\n */\nexport type WebexRequestPayload = {\n /** Service name to target */\n service?: string;\n /** Resource path within the service */\n resource?: string;\n /** HTTP method to use */\n method?: HTTP_METHODS;\n /** Full URI if not using service/resource pattern */\n uri?: string;\n /** Whether to add authorization header */\n addAuthHeader?: boolean;\n /** Custom headers to include in request */\n headers?: {\n [key: string]: string | null;\n };\n /** Request body data */\n body?: object;\n /** Expected response status code */\n statusCode?: number;\n /** Whether to parse response as JSON */\n json?: boolean;\n};\n\n/**\n * Event listener function type.\n * @internal\n * @ignore\n */\ntype Listener = (e: string, data?: unknown) => void;\n\n/**\n * Event listener removal function type.\n * @internal\n * @ignore\n */\ntype ListenerOff = (e: string) => void;\n\n/**\n * Service host configuration.\n * @internal\n * @ignore\n */\ntype ServiceHost = {\n /** Host URL/domain for the service */\n host: string;\n /** Time-to-live in seconds */\n ttl: number;\n /** Priority level for load balancing (lower is higher priority) */\n priority: number;\n /** Unique identifier for this host */\n id: string;\n /** Whether this is the home cluster for the user */\n homeCluster?: boolean;\n};\n\n/**\n * Configuration options for the Contact Center Plugin.\n * @interface CCPluginConfig\n * @public\n * @example\n * const config: CCPluginConfig = {\n * allowMultiLogin: true,\n * allowAutomatedRelogin: false,\n * clientType: 'browser',\n * isKeepAliveEnabled: true,\n * force: false,\n * metrics: { clientName: 'myClient', clientType: 'browser' },\n * logging: { enable: true, verboseEvents: false },\n * callingClientConfig: { ... }\n * };\n */\nexport interface CCPluginConfig {\n /** Whether to allow multiple logins from different devices */\n allowMultiLogin: boolean;\n /** Whether to automatically attempt relogin on connection loss */\n allowAutomatedRelogin: boolean;\n /** The type of client making the connection */\n clientType: string;\n /** Whether to enable keep-alive messages */\n isKeepAliveEnabled: boolean;\n /** Whether to force registration */\n force: boolean;\n /** Metrics configuration */\n metrics: {\n /** Name of the client for metrics */\n clientName: string;\n /** Type of client for metrics */\n clientType: string;\n };\n /** Logging configuration */\n logging: {\n /** Whether to enable logging */\n enable: boolean;\n /** Whether to log verbose events */\n verboseEvents: boolean;\n };\n /** Configuration for the calling client */\n callingClientConfig: CallingClientConfig;\n}\n\n/**\n * Logger interface for standardized logging throughout the plugin.\n * @public\n * @example\n * logger.log('This is a log message');\n * logger.error('This is an error message');\n * @ignore\n */\nexport type Logger = {\n /** Log general messages */\n log: (payload: string) => void;\n /** Log error messages */\n error: (payload: string) => void;\n /** Log warning messages */\n warn: (payload: string) => void;\n /** Log informational messages */\n info: (payload: string) => void;\n /** Log detailed trace messages */\n trace: (payload: string) => void;\n /** Log debug messages */\n debug: (payload: string) => void;\n};\n\n/**\n * Contextual information for log entries.\n * @public\n * @ignore\n */\nexport interface LogContext {\n /** Module name where the log originated */\n module?: string;\n /** Method name where the log originated */\n method?: string;\n interactionId?: string;\n trackingId?: string;\n /** Additional structured data to include in logs */\n data?: Record<string, any>;\n /** Error object to include in logs */\n error?: Error | unknown;\n}\n\n/**\n * Available logging severity levels.\n * @enum {string}\n * @public\n * @example\n * const level: LOGGING_LEVEL = LOGGING_LEVEL.error;\n * @ignore\n */\nexport enum LOGGING_LEVEL {\n /** Critical failures that require immediate attention */\n error = 'ERROR',\n /** Important issues that don't prevent the system from working */\n warn = 'WARN',\n /** General informational logs */\n log = 'LOG',\n /** Detailed information about system operation */\n info = 'INFO',\n /** Highly detailed diagnostic information */\n trace = 'TRACE',\n}\n\n/**\n * Metadata for log uploads.\n * @public\n * @example\n * const meta: LogsMetaData = { feedbackId: 'fb123', correlationId: 'corr456' };\n * @ignore\n */\nexport type LogsMetaData = {\n /** Optional feedback ID to associate with logs */\n feedbackId?: string;\n /** Optional correlation ID to track related operations */\n correlationId?: string;\n};\n\n/**\n * Response from uploading logs to the server.\n * @public\n * @example\n * const response: UploadLogsResponse = { trackingid: 'track123', url: 'https://...', userId: 'user1' };\n */\nexport type UploadLogsResponse = {\n /** Tracking ID for the upload request */\n trackingid?: string;\n /** URL where the logs can be accessed */\n url?: string;\n /** ID of the user who uploaded logs */\n userId?: string;\n /** Feedback ID associated with the logs */\n feedbackId?: string;\n /** Correlation ID for tracking related operations */\n correlationId?: string;\n};\n\n/**\n * Internal Webex SDK interfaces needed for plugin integration.\n * @internal\n * @ignore\n */\ninterface IWebexInternal {\n /** Mercury service for real-time messaging */\n mercury: {\n /** Register an event listener */\n on: Listener;\n /** Remove an event listener */\n off: ListenerOff;\n /** Establish a connection to the Mercury service */\n connect: () => Promise<void>;\n /** Disconnect from the Mercury service */\n disconnect: () => Promise<void>;\n /** Whether Mercury is currently connected */\n connected: boolean;\n /** Whether Mercury is in the process of connecting */\n connecting: boolean;\n };\n /** Device information */\n device: {\n /** Current WDM URL */\n url: string;\n /** Current user's ID */\n userId: string;\n /** Current organization ID */\n orgId: string;\n /** Device version */\n version: string;\n /** Calling behavior configuration */\n callingBehavior: string;\n };\n /** Presence service */\n presence: unknown;\n /** Services discovery and management */\n services: {\n /** Get a service URL by name */\n get: (service: string) => string;\n /** Wait for service catalog to be loaded */\n waitForCatalog: (service: string) => Promise<void>;\n /** Check if current environment is INT (integration) */\n isIntegrationEnvironment: () => boolean;\n /** Host catalog for service discovery */\n _hostCatalog: Record<string, ServiceHost[]>;\n /** Service URLs cache */\n _serviceUrls: {\n /** Mobius calling service */\n mobius: string;\n /** Identity service */\n identity: string;\n /** Janus media server */\n janus: string;\n /** WDM (WebEx Device Management) service */\n wdm: string;\n /** BroadWorks IDP proxy service */\n broadworksIdpProxy: string;\n /** Hydra API service */\n hydra: string;\n /** Mercury API service */\n mercuryApi: string;\n /** UC Management gateway service */\n 'ucmgmt-gateway': string;\n /** Contacts service */\n contactsService: string;\n };\n };\n /** Metrics collection services */\n newMetrics: {\n /** Submit behavioral events (user actions) */\n submitBehavioralEvent: SubmitBehavioralEvent;\n /** Submit operational events (system operations) */\n submitOperationalEvent: SubmitOperationalEvent;\n /** Submit business events (business outcomes) */\n submitBusinessEvent: SubmitBusinessEvent;\n };\n /** Support functionality */\n support: {\n /** Submit logs to server */\n submitLogs: (\n metaData: LogsMetaData,\n logs: string,\n options: {\n /** Whether to submit full logs or just differences */\n type: 'diff' | 'full';\n }\n ) => Promise<UploadLogsResponse>;\n };\n}\n\n/**\n * Interface representing the WebexSDK core functionality.\n * @interface WebexSDK\n * @public\n * @example\n * const sdk: WebexSDK = ...;\n * sdk.request({ service: 'identity', resource: '/users', method: HTTP_METHODS.GET });\n * @ignore\n */\nexport interface WebexSDK {\n /** Version of the WebexSDK */\n version: string;\n /** Whether the SDK can authorize requests */\n canAuthorize: boolean;\n /** Credentials management */\n credentials: {\n /** Get the user token for authentication */\n getUserToken: () => Promise<string>;\n /** Get the organization ID */\n getOrgId: () => string;\n };\n /** Whether the SDK is ready for use */\n ready: boolean;\n /** Make a request to the Webex APIs */\n request: <T>(payload: WebexRequestPayload) => Promise<T>;\n /** Register a one-time event handler */\n once: (event: string, callBack: () => void) => void;\n /** Internal plugins and services */\n internal: IWebexInternal;\n /** Logger instance */\n logger: Logger;\n}\n\n/**\n * An interface for the `ContactCenter` class.\n * The `ContactCenter` package is designed to provide a set of APIs to perform various operations for the Agent flow within Webex Contact Center.\n * @public\n * @example\n * const cc: IContactCenter = ...;\n * cc.register().then(profile => { ... });\n * @ignore\n */\nexport interface IContactCenter {\n /**\n * Initialize the CC SDK by setting up the contact center mercury connection.\n * This establishes WebSocket connectivity for real-time communication.\n *\n * @returns A Promise that resolves to the agent's profile upon successful registration\n * @public\n * @example\n * cc.register().then(profile => { ... });\n */\n register(): Promise<Profile>;\n}\n\n/**\n * Generic HTTP response structure.\n * @public\n * @example\n * const response: IHttpResponse = { body: {}, statusCode: 200, method: 'GET', headers: {}, url: '...' };\n * @ignore\n */\nexport interface IHttpResponse {\n /** Response body content */\n body: any;\n /** HTTP status code */\n statusCode: number;\n /** HTTP method used for the request */\n method: string;\n /** Response headers */\n headers: Headers;\n /** Request URL */\n url: string;\n}\n\n/**\n * Supported login options for agent authentication.\n * @public\n * @example\n * const option: LoginOption = LoginOption.AGENT_DN;\n * @ignore\n */\nexport const LoginOption = {\n /** Login using agent's direct number */\n AGENT_DN: 'AGENT_DN',\n /** Login using an extension number */\n EXTENSION: 'EXTENSION',\n /** Login using browser WebRTC capabilities */\n BROWSER: 'BROWSER',\n} as const;\n\n/**\n * Union type of login options.\n * @public\n * @example\n * function login(option: LoginOption) { ... }\n * @ignore\n */\nexport type LoginOption = Enum<typeof LoginOption>;\n\n/**\n * Request payload for subscribing to the contact center websocket.\n * @public\n * @example\n * const req: SubscribeRequest = { force: true, isKeepAliveEnabled: true, clientType: 'browser', allowMultiLogin: false };\n * @ignore\n */\nexport type SubscribeRequest = {\n /** Whether to force connection even if another exists */\n force: boolean;\n /** Whether to send keepalive messages */\n isKeepAliveEnabled: boolean;\n /** Type of client connecting */\n clientType: string;\n /** Whether to allow login from multiple devices */\n allowMultiLogin: boolean;\n};\n\n/**\n * Represents the response from getListOfTeams method.\n * Teams are groups of agents that can be managed together.\n * @public\n * @example\n * const team: Team = { id: 'team1', name: 'Support', desktopLayoutId: 'layout1' };\n * @ignore\n */\nexport type Team = {\n /**\n * Unique identifier of the team.\n */\n id: string;\n\n /**\n * Display name of the team.\n */\n name: string;\n\n /**\n * Associated desktop layout ID for the team.\n * Controls how the agent desktop is displayed for team members.\n */\n desktopLayoutId?: string;\n};\n\n/**\n * Represents the request to perform agent login.\n * @public\n * @example\n * const login: AgentLogin = { dialNumber: '1234', teamId: 'team1', loginOption: LoginOption.AGENT_DN };\n */\nexport type AgentLogin = {\n /**\n * A dialNumber field contains the number to dial such as a route point or extension.\n * Required for AGENT_DN and EXTENSION login options.\n */\n dialNumber?: string;\n\n /**\n * The unique ID representing a team of users.\n * The agent must belong to this team.\n */\n teamId: string;\n\n /**\n * The loginOption field specifies the type of login method.\n * Controls how calls are delivered to the agent.\n */\n loginOption: LoginOption;\n};\n\n/**\n * Represents the request to update agent profile settings.\n * @public\n * @example\n * const update: AgentProfileUpdate = { loginOption: LoginOption.BROWSER, dialNumber: '5678' };\n */\nexport type AgentProfileUpdate = Pick<AgentLogin, 'loginOption' | 'dialNumber' | 'teamId'>;\n\n/**\n * Union type for all possible request body types.\n * @internal\n * @ignore\n */\nexport type RequestBody =\n | SubscribeRequest\n | Agent.Logout\n | Agent.UserStationLogin\n | Agent.StateChange\n | Agent.BuddyAgents\n | Contact.HoldResumePayload\n | Contact.ResumeRecordingPayload\n | Contact.ConsultPayload\n | Contact.ConsultEndAPIPayload // API Payload accepts only QueueId wheres SDK API allows more params\n | Contact.TransferPayLoad\n | Contact.ConsultTransferPayLoad\n | Contact.cancelCtq\n | Contact.WrapupPayLoad\n | Contact.DialerPayload;\n\n/**\n * Represents the options to fetch buddy agents for the logged in agent.\n * Buddy agents are other agents who can be consulted or transfered to.\n * @public\n * @example\n * const opts: BuddyAgents = { mediaType: 'telephony', state: 'Available' };\n * @ignore\n */\nexport type BuddyAgents = {\n /**\n * The media type channel to filter buddy agents.\n * Determines which channel capability the returned agents must have.\n */\n mediaType: 'telephony' | 'chat' | 'social' | 'email';\n\n /**\n * Optional filter for agent state.\n * If specified, returns only agents in that state.\n * If omitted, returns both available and idle agents.\n */\n state?: 'Available' | 'Idle';\n};\n\n/**\n * Generic error structure for Contact Center SDK errors.\n * Contains detailed information about the error context.\n * @public\n * @example\n * const err: GenericError = new Error('Failed');\n * err.details = { type: 'ERR', orgId: 'org1', trackingId: 'track1', data: {} };\n * @ignore\n */\nexport interface GenericError extends Error {\n /** Structured details about the error */\n details: {\n /** Error type identifier */\n type: string;\n /** Organization ID where the error occurred */\n orgId: string;\n /** Unique tracking ID for the error */\n trackingId: string;\n /** Additional error context data */\n data: Record<string, any>;\n };\n}\n\n/**\n * Response type for station login operations.\n * Either a success response with agent details or an error.\n * @public\n * @example\n * function handleLogin(resp: StationLoginResponse) { ... }\n */\nexport type StationLoginResponse = Agent.StationLoginSuccessResponse | Error;\n\n/**\n * Response type for station logout operations.\n * Either a success response with logout details or an error.\n * @public\n * @example\n * function handleLogout(resp: StationLogoutResponse) { ... }\n */\nexport type StationLogoutResponse = Agent.LogoutSuccess | Error;\n\n/**\n * Response type for station relogin operations.\n * Either a success response with relogin details or an error.\n * @public\n * @example\n * function handleReLogin(resp: StationReLoginResponse) { ... }\n * @ignore\n */\nexport type StationReLoginResponse = Agent.ReloginSuccess | Error;\n\n/**\n * Response type for agent state change operations.\n * Either a success response with state change details or an error.\n * @public\n * @example\n * function handleStateChange(resp: SetStateResponse) { ... }\n * @ignore\n */\nexport type SetStateResponse = Agent.StateChangeSuccess | Error;\n\n/**\n * AddressBook types\n */\nexport interface AddressBookEntry {\n id: string;\n organizationId?: string;\n version?: number;\n name: string;\n number: string;\n createdTime?: number;\n lastUpdatedTime?: number;\n}\n\nexport type AddressBookEntriesResponse = PaginatedResponse<AddressBookEntry>;\n\nexport interface AddressBookEntrySearchParams extends BaseSearchParams {\n addressBookId?: string;\n}\n\n/**\n * EntryPointRecord types\n */\nexport interface EntryPointRecord {\n id: string;\n name: string;\n description?: string;\n type: string;\n isActive: boolean;\n orgId: string;\n createdAt?: string;\n updatedAt?: string;\n settings?: Record<string, any>;\n}\n\nexport type EntryPointListResponse = PaginatedResponse<EntryPointRecord>;\nexport type EntryPointSearchParams = BaseSearchParams;\n\n/**\n * Queue types\n */\nexport interface QueueSkillRequirement {\n organizationId?: string;\n id?: string;\n version?: number;\n skillId: string;\n skillName?: string;\n skillType?: string;\n condition: string;\n skillValue: string;\n createdTime?: number;\n lastUpdatedTime?: number;\n}\n\nexport interface QueueAgent {\n id: string;\n ciUserId?: string;\n}\n\nexport interface AgentGroup {\n teamId: string;\n}\n\nexport interface CallDistributionGroup {\n agentGroups: AgentGroup[];\n order: number;\n duration?: number;\n}\n\nexport interface AssistantSkillMapping {\n assistantSkillId?: string;\n assistantSkillUpdatedTime?: number;\n}\n\n/**\n * Configuration for a contact service queue\n * @public\n */\nexport interface ContactServiceQueue {\n /** Organization ID */\n organizationId?: string;\n /** Unique identifier for the queue */\n id?: string;\n /** Version of the queue */\n version?: number;\n /** Name of the Contact Service Queue */\n name: string;\n /** Description of the queue */\n description?: string;\n /** Queue type (INBOUND, OUTBOUND) */\n queueType: 'INBOUND' | 'OUTBOUND';\n /** Whether to check agent availability */\n checkAgentAvailability: boolean;\n /** Channel type (TELEPHONY, EMAIL, SOCIAL_CHANNEL, CHAT, etc.) */\n channelType: 'TELEPHONY' | 'EMAIL' | 'FAX' | 'CHAT' | 'VIDEO' | 'OTHERS' | 'SOCIAL_CHANNEL';\n /** Social channel type for SOCIAL_CHANNEL channelType */\n socialChannelType?:\n | 'MESSAGEBIRD'\n | 'MESSENGER'\n | 'WHATSAPP'\n | 'APPLE_BUSINESS_CHAT'\n | 'GOOGLE_BUSINESS_MESSAGES';\n /** Service level threshold in seconds */\n serviceLevelThreshold: number;\n /** Maximum number of simultaneous contacts */\n maxActiveContacts: number;\n /** Maximum time in queue in seconds */\n maxTimeInQueue: number;\n /** Default music in queue media file ID */\n defaultMusicInQueueMediaFileId: string;\n /** Timezone for routing strategies */\n timezone?: string;\n /** Whether the queue is active */\n active: boolean;\n /** Whether outdial campaign is enabled */\n outdialCampaignEnabled?: boolean;\n /** Whether monitoring is permitted */\n monitoringPermitted: boolean;\n /** Whether parking is permitted */\n parkingPermitted: boolean;\n /** Whether recording is permitted */\n recordingPermitted: boolean;\n /** Whether recording all calls is permitted */\n recordingAllCallsPermitted: boolean;\n /** Whether pausing recording is permitted */\n pauseRecordingPermitted: boolean;\n /** Recording pause duration in seconds */\n recordingPauseDuration?: number;\n /** Control flow script URL */\n controlFlowScriptUrl: string;\n /** IVR requeue URL */\n ivrRequeueUrl: string;\n /** Overflow number for telephony */\n overflowNumber?: string;\n /** Vendor ID */\n vendorId?: string;\n /** Routing type */\n routingType: 'LONGEST_AVAILABLE_AGENT' | 'SKILLS_BASED' | 'CIRCULAR' | 'LINEAR';\n /** Skills-based routing type */\n skillBasedRoutingType?: 'LONGEST_AVAILABLE_AGENT' | 'BEST_AVAILABLE_AGENT';\n /** Queue routing type */\n queueRoutingType: 'TEAM_BASED' | 'SKILL_BASED' | 'AGENT_BASED';\n /** Queue skill requirements */\n queueSkillRequirements?: QueueSkillRequirement[];\n /** List of agents for agent-based queue */\n agents?: QueueAgent[];\n /** Call distribution groups */\n callDistributionGroups: CallDistributionGroup[];\n /** XSP version */\n xspVersion?: string;\n /** Subscription ID */\n subscriptionId?: string;\n /** Assistant skill mapping */\n assistantSkill?: AssistantSkillMapping;\n /** Whether this is a system default queue */\n systemDefault?: boolean;\n /** User who last updated agents list */\n agentsLastUpdatedByUserName?: string;\n /** Email of user who last updated agents list */\n agentsLastUpdatedByUserEmailPrefix?: string;\n /** When agents list was last updated */\n agentsLastUpdatedTime?: number;\n /** Creation timestamp in epoch millis */\n createdTime?: number;\n /** Last updated timestamp in epoch millis */\n lastUpdatedTime?: number;\n}\n\nexport type ContactServiceQueuesResponse = PaginatedResponse<ContactServiceQueue>;\n\nexport interface ContactServiceQueueSearchParams extends BaseSearchParams {\n desktopProfileFilter?: boolean;\n provisioningView?: boolean;\n singleObjectResponse?: boolean;\n}\n\n/**\n * Response type for buddy agents query operations.\n * Either a success response with list of buddy agents or an error.\n * @public\n * @example\n * function handleBuddyAgents(resp: BuddyAgentsResponse) { ... }\n */\nexport type BuddyAgentsResponse = Agent.BuddyAgentsSuccess | Error;\n\n/**\n * Response type for device type update operations.\n * Either a success response with update confirmation or an error.\n * @public\n * @example\n * function handleUpdateDeviceType(resp: UpdateDeviceTypeResponse) { ... }\n */\nexport type UpdateDeviceTypeResponse = Agent.DeviceTypeUpdateSuccess | Error;\n"],"mappings":";;;;;;AAWA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,YAAY,GAAAC,OAAA,CAAAD,YAAA,GAAG;EAC1B;EACAE,GAAG,EAAE,KAAK;EACV;EACAC,IAAI,EAAE,MAAM;EACZ;EACAC,KAAK,EAAE,OAAO;EACd;EACAC,GAAG,EAAE,KAAK;EACV;EACAC,MAAM,EAAE;AACV,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAwBA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA8BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA,IAQYC,aAAa,GAAAN,OAAA,CAAAM,aAAA,0BAAbA,aAAa;EACvB;EADUA,aAAa;EAGvB;EAHUA,aAAa;EAKvB;EALUA,aAAa;EAOvB;EAPUA,aAAa;EASvB;EATUA,aAAa;EAAA,OAAbA,aAAa;AAAA;AAazB;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AAuFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,WAAW,GAAAP,OAAA,CAAAO,WAAA,GAAG;EACzB;EACAC,QAAQ,EAAE,UAAU;EACpB;EACAC,SAAS,EAAE,WAAW;EACtB;EACAC,OAAO,EAAE;AACX,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmBA;AACA;AACA;AACA;AACA;AACA;;AAqBA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAiBA;AACA;AACA;;AAgBA;AACA;AACA;;AAkCA;AACA;AACA;AACA;;AAmGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["HTTP_METHODS","exports","GET","POST","PATCH","PUT","DELETE","LOGGING_LEVEL","LoginOption","AGENT_DN","EXTENSION","BROWSER"],"sources":["types.ts"],"sourcesContent":["import {CallingClientConfig} from '@webex/calling';\nimport {\n SubmitBehavioralEvent,\n SubmitOperationalEvent,\n SubmitBusinessEvent,\n} from '@webex/internal-plugin-metrics/src/metrics.types';\nimport * as Agent from './services/agent/types';\nimport * as Contact from './services/task/types';\nimport {Profile} from './services/config/types';\nimport {PaginatedResponse, BaseSearchParams} from './utils/PageCache';\n\n/**\n * Generic type for converting a const enum object into a union type of its values.\n * @template T The enum object type\n * @internal\n * @ignore\n */\ntype Enum<T extends Record<string, unknown>> = T[keyof T];\n\n/**\n * HTTP methods supported by WebexRequest.\n * @enum {string}\n * @public\n * @example\n * const method: HTTP_METHODS = HTTP_METHODS.GET;\n * @ignore\n */\nexport const HTTP_METHODS = {\n /** HTTP GET method for retrieving data */\n GET: 'GET',\n /** HTTP POST method for creating resources */\n POST: 'POST',\n /** HTTP PATCH method for partial updates */\n PATCH: 'PATCH',\n /** HTTP PUT method for complete updates */\n PUT: 'PUT',\n /** HTTP DELETE method for removing resources */\n DELETE: 'DELETE',\n} as const;\n\n/**\n * Union type of HTTP methods.\n * @public\n * @example\n * function makeRequest(method: HTTP_METHODS) { ... }\n * @ignore\n */\nexport type HTTP_METHODS = Enum<typeof HTTP_METHODS>;\n\n/**\n * Payload for making requests to Webex APIs.\n * @public\n * @example\n * const payload: WebexRequestPayload = {\n * service: 'identity',\n * resource: '/users',\n * method: HTTP_METHODS.GET\n * };\n * @ignore\n */\nexport type WebexRequestPayload = {\n /** Service name to target */\n service?: string;\n /** Resource path within the service */\n resource?: string;\n /** HTTP method to use */\n method?: HTTP_METHODS;\n /** Full URI if not using service/resource pattern */\n uri?: string;\n /** Whether to add authorization header */\n addAuthHeader?: boolean;\n /** Custom headers to include in request */\n headers?: {\n [key: string]: string | null;\n };\n /** Request body data */\n body?: object;\n /** Expected response status code */\n statusCode?: number;\n /** Whether to parse response as JSON */\n json?: boolean;\n};\n\n/**\n * Event listener function type.\n * @internal\n * @ignore\n */\ntype Listener = (e: string, data?: unknown) => void;\n\n/**\n * Event listener removal function type.\n * @internal\n * @ignore\n */\ntype ListenerOff = (e: string) => void;\n\n/**\n * Service host configuration.\n * @internal\n * @ignore\n */\ntype ServiceHost = {\n /** Host URL/domain for the service */\n host: string;\n /** Time-to-live in seconds */\n ttl: number;\n /** Priority level for load balancing (lower is higher priority) */\n priority: number;\n /** Unique identifier for this host */\n id: string;\n /** Whether this is the home cluster for the user */\n homeCluster?: boolean;\n};\n\n/**\n * Configuration options for the Contact Center Plugin.\n * @interface CCPluginConfig\n * @public\n * @example\n * const config: CCPluginConfig = {\n * allowMultiLogin: true,\n * allowAutomatedRelogin: false,\n * clientType: 'browser',\n * isKeepAliveEnabled: true,\n * force: false,\n * metrics: { clientName: 'myClient', clientType: 'browser' },\n * logging: { enable: true, verboseEvents: false },\n * callingClientConfig: { ... }\n * };\n */\nexport interface CCPluginConfig {\n /** Whether to allow multiple logins from different devices */\n allowMultiLogin: boolean;\n /** Whether to automatically attempt relogin on connection loss */\n allowAutomatedRelogin: boolean;\n /** The type of client making the connection */\n clientType: string;\n /** Whether to enable keep-alive messages */\n isKeepAliveEnabled: boolean;\n /** Whether to force registration */\n force: boolean;\n /** Metrics configuration */\n metrics: {\n /** Name of the client for metrics */\n clientName: string;\n /** Type of client for metrics */\n clientType: string;\n };\n /** Logging configuration */\n logging: {\n /** Whether to enable logging */\n enable: boolean;\n /** Whether to log verbose events */\n verboseEvents: boolean;\n };\n /** Configuration for the calling client */\n callingClientConfig: CallingClientConfig;\n}\n\n/**\n * Logger interface for standardized logging throughout the plugin.\n * @public\n * @example\n * logger.log('This is a log message');\n * logger.error('This is an error message');\n * @ignore\n */\nexport type Logger = {\n /** Log general messages */\n log: (payload: string) => void;\n /** Log error messages */\n error: (payload: string) => void;\n /** Log warning messages */\n warn: (payload: string) => void;\n /** Log informational messages */\n info: (payload: string) => void;\n /** Log detailed trace messages */\n trace: (payload: string) => void;\n /** Log debug messages */\n debug: (payload: string) => void;\n};\n\n/**\n * Contextual information for log entries.\n * @public\n * @ignore\n */\nexport interface LogContext {\n /** Module name where the log originated */\n module?: string;\n /** Method name where the log originated */\n method?: string;\n interactionId?: string;\n trackingId?: string;\n /** Additional structured data to include in logs */\n data?: Record<string, any>;\n /** Error object to include in logs */\n error?: Error | unknown;\n}\n\n/**\n * Available logging severity levels.\n * @enum {string}\n * @public\n * @example\n * const level: LOGGING_LEVEL = LOGGING_LEVEL.error;\n * @ignore\n */\nexport enum LOGGING_LEVEL {\n /** Critical failures that require immediate attention */\n error = 'ERROR',\n /** Important issues that don't prevent the system from working */\n warn = 'WARN',\n /** General informational logs */\n log = 'LOG',\n /** Detailed information about system operation */\n info = 'INFO',\n /** Highly detailed diagnostic information */\n trace = 'TRACE',\n}\n\n/**\n * Metadata for log uploads.\n * @public\n * @example\n * const meta: LogsMetaData = { feedbackId: 'fb123', correlationId: 'corr456' };\n * @ignore\n */\nexport type LogsMetaData = {\n /** Optional feedback ID to associate with logs */\n feedbackId?: string;\n /** Optional correlation ID to track related operations */\n correlationId?: string;\n};\n\n/**\n * Response from uploading logs to the server.\n * @public\n * @example\n * const response: UploadLogsResponse = { trackingid: 'track123', url: 'https://...', userId: 'user1' };\n */\nexport type UploadLogsResponse = {\n /** Tracking ID for the upload request */\n trackingid?: string;\n /** URL where the logs can be accessed */\n url?: string;\n /** ID of the user who uploaded logs */\n userId?: string;\n /** Feedback ID associated with the logs */\n feedbackId?: string;\n /** Correlation ID for tracking related operations */\n correlationId?: string;\n};\n\n/**\n * Internal Webex SDK interfaces needed for plugin integration.\n * @internal\n * @ignore\n */\ninterface IWebexInternal {\n /** Mercury service for real-time messaging */\n mercury: {\n /** Register an event listener */\n on: Listener;\n /** Remove an event listener */\n off: ListenerOff;\n /** Establish a connection to the Mercury service */\n connect: () => Promise<void>;\n /** Disconnect from the Mercury service */\n disconnect: () => Promise<void>;\n /** Whether Mercury is currently connected */\n connected: boolean;\n /** Whether Mercury is in the process of connecting */\n connecting: boolean;\n };\n /** Device information */\n device: {\n /** Current WDM URL */\n url: string;\n /** Current user's ID */\n userId: string;\n /** Current organization ID */\n orgId: string;\n /** Device version */\n version: string;\n /** Calling behavior configuration */\n callingBehavior: string;\n };\n /** Presence service */\n presence: unknown;\n /** Services discovery and management */\n services: {\n /** Get a service URL by name */\n get: (service: string) => string;\n /** Wait for service catalog to be loaded */\n waitForCatalog: (service: string) => Promise<void>;\n /** Check if current environment is INT (integration) */\n isIntegrationEnvironment: () => boolean;\n /** Host catalog for service discovery */\n _hostCatalog: Record<string, ServiceHost[]>;\n /** Service URLs cache */\n _serviceUrls: {\n /** Mobius calling service */\n mobius: string;\n /** Identity service */\n identity: string;\n /** Janus media server */\n janus: string;\n /** WDM (WebEx Device Management) service */\n wdm: string;\n /** BroadWorks IDP proxy service */\n broadworksIdpProxy: string;\n /** Hydra API service */\n hydra: string;\n /** Mercury API service */\n mercuryApi: string;\n /** UC Management gateway service */\n 'ucmgmt-gateway': string;\n /** Contacts service */\n contactsService: string;\n };\n };\n /** Metrics collection services */\n newMetrics: {\n /** Submit behavioral events (user actions) */\n submitBehavioralEvent: SubmitBehavioralEvent;\n /** Submit operational events (system operations) */\n submitOperationalEvent: SubmitOperationalEvent;\n /** Submit business events (business outcomes) */\n submitBusinessEvent: SubmitBusinessEvent;\n };\n /** Support functionality */\n support: {\n /** Submit logs to server */\n submitLogs: (\n metaData: LogsMetaData,\n logs: string,\n options: {\n /** Whether to submit full logs or just differences */\n type: 'diff' | 'full';\n }\n ) => Promise<UploadLogsResponse>;\n };\n}\n\n/**\n * Interface representing the WebexSDK core functionality.\n * @interface WebexSDK\n * @public\n * @example\n * const sdk: WebexSDK = ...;\n * sdk.request({ service: 'identity', resource: '/users', method: HTTP_METHODS.GET });\n * @ignore\n */\nexport interface WebexSDK {\n /** Version of the WebexSDK */\n version: string;\n /** Whether the SDK can authorize requests */\n canAuthorize: boolean;\n /** Credentials management */\n credentials: {\n /** Get the user token for authentication */\n getUserToken: () => Promise<string>;\n /** Get the organization ID */\n getOrgId: () => string;\n };\n /** Whether the SDK is ready for use */\n ready: boolean;\n /** Make a request to the Webex APIs */\n request: <T>(payload: WebexRequestPayload) => Promise<T>;\n /** Register a one-time event handler */\n once: (event: string, callBack: () => void) => void;\n /** Internal plugins and services */\n internal: IWebexInternal;\n /** Logger instance */\n logger: Logger;\n}\n\n/**\n * An interface for the `ContactCenter` class.\n * The `ContactCenter` package is designed to provide a set of APIs to perform various operations for the Agent flow within Webex Contact Center.\n * @public\n * @example\n * const cc: IContactCenter = ...;\n * cc.register().then(profile => { ... });\n * @ignore\n */\nexport interface IContactCenter {\n /**\n * Initialize the CC SDK by setting up the contact center mercury connection.\n * This establishes WebSocket connectivity for real-time communication.\n *\n * @returns A Promise that resolves to the agent's profile upon successful registration\n * @public\n * @example\n * cc.register().then(profile => { ... });\n */\n register(): Promise<Profile>;\n}\n\n/**\n * Generic HTTP response structure.\n * @public\n * @example\n * const response: IHttpResponse = { body: {}, statusCode: 200, method: 'GET', headers: {}, url: '...' };\n * @ignore\n */\nexport interface IHttpResponse {\n /** Response body content */\n body: any;\n /** HTTP status code */\n statusCode: number;\n /** HTTP method used for the request */\n method: string;\n /** Response headers */\n headers: Headers;\n /** Request URL */\n url: string;\n}\n\n/**\n * Supported login options for agent authentication.\n * @public\n * @example\n * const option: LoginOption = LoginOption.AGENT_DN;\n * @ignore\n */\nexport const LoginOption = {\n /** Login using agent's direct number */\n AGENT_DN: 'AGENT_DN',\n /** Login using an extension number */\n EXTENSION: 'EXTENSION',\n /** Login using browser WebRTC capabilities */\n BROWSER: 'BROWSER',\n} as const;\n\n/**\n * Union type of login options.\n * @public\n * @example\n * function login(option: LoginOption) { ... }\n * @ignore\n */\nexport type LoginOption = Enum<typeof LoginOption>;\n\n/**\n * Request payload for subscribing to the contact center websocket.\n * @public\n * @example\n * const req: SubscribeRequest = { force: true, isKeepAliveEnabled: true, clientType: 'browser', allowMultiLogin: false };\n * @ignore\n */\nexport type SubscribeRequest = {\n /** Whether to force connection even if another exists */\n force: boolean;\n /** Whether to send keepalive messages */\n isKeepAliveEnabled: boolean;\n /** Type of client connecting */\n clientType: string;\n /** Whether to allow login from multiple devices */\n allowMultiLogin: boolean;\n};\n\n/**\n * Represents the response from getListOfTeams method.\n * Teams are groups of agents that can be managed together.\n * @public\n * @example\n * const team: Team = { id: 'team1', name: 'Support', desktopLayoutId: 'layout1' };\n * @ignore\n */\nexport type Team = {\n /**\n * Unique identifier of the team.\n */\n id: string;\n\n /**\n * Display name of the team.\n */\n name: string;\n\n /**\n * Associated desktop layout ID for the team.\n * Controls how the agent desktop is displayed for team members.\n */\n desktopLayoutId?: string;\n};\n\n/**\n * Represents the request to perform agent login.\n * @public\n * @example\n * const login: AgentLogin = { dialNumber: '1234', teamId: 'team1', loginOption: LoginOption.AGENT_DN };\n */\nexport type AgentLogin = {\n /**\n * A dialNumber field contains the number to dial such as a route point or extension.\n * Required for AGENT_DN and EXTENSION login options.\n */\n dialNumber?: string;\n\n /**\n * The unique ID representing a team of users.\n * The agent must belong to this team.\n */\n teamId: string;\n\n /**\n * The loginOption field specifies the type of login method.\n * Controls how calls are delivered to the agent.\n */\n loginOption: LoginOption;\n};\n\n/**\n * Represents the request to update agent profile settings.\n * @public\n * @example\n * const update: AgentProfileUpdate = { loginOption: LoginOption.BROWSER, dialNumber: '5678' };\n */\nexport type AgentProfileUpdate = Pick<AgentLogin, 'loginOption' | 'dialNumber' | 'teamId'>;\n\n/**\n * Union type for all possible request body types.\n * @internal\n * @ignore\n */\nexport type RequestBody =\n | SubscribeRequest\n | Agent.Logout\n | Agent.UserStationLogin\n | Agent.StateChange\n | Agent.BuddyAgents\n | Contact.HoldResumePayload\n | Contact.ResumeRecordingPayload\n | Contact.ConsultPayload\n | Contact.ConsultEndAPIPayload // API Payload accepts only QueueId wheres SDK API allows more params\n | Contact.TransferPayLoad\n | Contact.ConsultTransferPayLoad\n | Contact.cancelCtq\n | Contact.WrapupPayLoad\n | Contact.DialerPayload\n | Contact.PreviewContactPayload;\n\n/**\n * Represents the options to fetch buddy agents for the logged in agent.\n * Buddy agents are other agents who can be consulted or transfered to.\n * @public\n * @example\n * const opts: BuddyAgents = { mediaType: 'telephony', state: 'Available' };\n * @ignore\n */\nexport type BuddyAgents = {\n /**\n * The media type channel to filter buddy agents.\n * Determines which channel capability the returned agents must have.\n */\n mediaType: 'telephony' | 'chat' | 'social' | 'email';\n\n /**\n * Optional filter for agent state.\n * If specified, returns only agents in that state.\n * If omitted, returns both available and idle agents.\n */\n state?: 'Available' | 'Idle';\n};\n\n/**\n * Generic error structure for Contact Center SDK errors.\n * Contains detailed information about the error context.\n * @public\n * @example\n * const err: GenericError = new Error('Failed');\n * err.details = { type: 'ERR', orgId: 'org1', trackingId: 'track1', data: {} };\n * @ignore\n */\nexport interface GenericError extends Error {\n /** Structured details about the error */\n details: {\n /** Error type identifier */\n type: string;\n /** Organization ID where the error occurred */\n orgId: string;\n /** Unique tracking ID for the error */\n trackingId: string;\n /** Additional error context data */\n data: Record<string, any>;\n };\n}\n\n/**\n * Response type for station login operations.\n * Either a success response with agent details or an error.\n * @public\n * @example\n * function handleLogin(resp: StationLoginResponse) { ... }\n */\nexport type StationLoginResponse = Agent.StationLoginSuccessResponse | Error;\n\n/**\n * Response type for station logout operations.\n * Either a success response with logout details or an error.\n * @public\n * @example\n * function handleLogout(resp: StationLogoutResponse) { ... }\n */\nexport type StationLogoutResponse = Agent.LogoutSuccess | Error;\n\n/**\n * Response type for station relogin operations.\n * Either a success response with relogin details or an error.\n * @public\n * @example\n * function handleReLogin(resp: StationReLoginResponse) { ... }\n * @ignore\n */\nexport type StationReLoginResponse = Agent.ReloginSuccess | Error;\n\n/**\n * Response type for agent state change operations.\n * Either a success response with state change details or an error.\n * @public\n * @example\n * function handleStateChange(resp: SetStateResponse) { ... }\n * @ignore\n */\nexport type SetStateResponse = Agent.StateChangeSuccess | Error;\n\n/**\n * AddressBook types\n */\nexport interface AddressBookEntry {\n id: string;\n organizationId?: string;\n version?: number;\n name: string;\n number: string;\n createdTime?: number;\n lastUpdatedTime?: number;\n}\n\nexport type AddressBookEntriesResponse = PaginatedResponse<AddressBookEntry>;\n\nexport interface AddressBookEntrySearchParams extends BaseSearchParams {\n addressBookId?: string;\n}\n\n/**\n * EntryPointRecord types\n */\nexport interface EntryPointRecord {\n id: string;\n name: string;\n description?: string;\n type: string;\n isActive: boolean;\n orgId: string;\n createdAt?: string;\n updatedAt?: string;\n settings?: Record<string, any>;\n}\n\nexport type EntryPointListResponse = PaginatedResponse<EntryPointRecord>;\nexport type EntryPointSearchParams = BaseSearchParams;\n\n/**\n * Queue types\n */\nexport interface QueueSkillRequirement {\n organizationId?: string;\n id?: string;\n version?: number;\n skillId: string;\n skillName?: string;\n skillType?: string;\n condition: string;\n skillValue: string;\n createdTime?: number;\n lastUpdatedTime?: number;\n}\n\nexport interface QueueAgent {\n id: string;\n ciUserId?: string;\n}\n\nexport interface AgentGroup {\n teamId: string;\n}\n\nexport interface CallDistributionGroup {\n agentGroups: AgentGroup[];\n order: number;\n duration?: number;\n}\n\nexport interface AssistantSkillMapping {\n assistantSkillId?: string;\n assistantSkillUpdatedTime?: number;\n}\n\n/**\n * Configuration for a contact service queue\n * @public\n */\nexport interface ContactServiceQueue {\n /** Organization ID */\n organizationId?: string;\n /** Unique identifier for the queue */\n id?: string;\n /** Version of the queue */\n version?: number;\n /** Name of the Contact Service Queue */\n name: string;\n /** Description of the queue */\n description?: string;\n /** Queue type (INBOUND, OUTBOUND) */\n queueType: 'INBOUND' | 'OUTBOUND';\n /** Whether to check agent availability */\n checkAgentAvailability: boolean;\n /** Channel type (TELEPHONY, EMAIL, SOCIAL_CHANNEL, CHAT, etc.) */\n channelType: 'TELEPHONY' | 'EMAIL' | 'FAX' | 'CHAT' | 'VIDEO' | 'OTHERS' | 'SOCIAL_CHANNEL';\n /** Social channel type for SOCIAL_CHANNEL channelType */\n socialChannelType?:\n | 'MESSAGEBIRD'\n | 'MESSENGER'\n | 'WHATSAPP'\n | 'APPLE_BUSINESS_CHAT'\n | 'GOOGLE_BUSINESS_MESSAGES';\n /** Service level threshold in seconds */\n serviceLevelThreshold: number;\n /** Maximum number of simultaneous contacts */\n maxActiveContacts: number;\n /** Maximum time in queue in seconds */\n maxTimeInQueue: number;\n /** Default music in queue media file ID */\n defaultMusicInQueueMediaFileId: string;\n /** Timezone for routing strategies */\n timezone?: string;\n /** Whether the queue is active */\n active: boolean;\n /** Whether outdial campaign is enabled */\n outdialCampaignEnabled?: boolean;\n /** Whether monitoring is permitted */\n monitoringPermitted: boolean;\n /** Whether parking is permitted */\n parkingPermitted: boolean;\n /** Whether recording is permitted */\n recordingPermitted: boolean;\n /** Whether recording all calls is permitted */\n recordingAllCallsPermitted: boolean;\n /** Whether pausing recording is permitted */\n pauseRecordingPermitted: boolean;\n /** Recording pause duration in seconds */\n recordingPauseDuration?: number;\n /** Control flow script URL */\n controlFlowScriptUrl: string;\n /** IVR requeue URL */\n ivrRequeueUrl: string;\n /** Overflow number for telephony */\n overflowNumber?: string;\n /** Vendor ID */\n vendorId?: string;\n /** Routing type */\n routingType: 'LONGEST_AVAILABLE_AGENT' | 'SKILLS_BASED' | 'CIRCULAR' | 'LINEAR';\n /** Skills-based routing type */\n skillBasedRoutingType?: 'LONGEST_AVAILABLE_AGENT' | 'BEST_AVAILABLE_AGENT';\n /** Queue routing type */\n queueRoutingType: 'TEAM_BASED' | 'SKILL_BASED' | 'AGENT_BASED';\n /** Queue skill requirements */\n queueSkillRequirements?: QueueSkillRequirement[];\n /** List of agents for agent-based queue */\n agents?: QueueAgent[];\n /** Call distribution groups */\n callDistributionGroups: CallDistributionGroup[];\n /** XSP version */\n xspVersion?: string;\n /** Subscription ID */\n subscriptionId?: string;\n /** Assistant skill mapping */\n assistantSkill?: AssistantSkillMapping;\n /** Whether this is a system default queue */\n systemDefault?: boolean;\n /** User who last updated agents list */\n agentsLastUpdatedByUserName?: string;\n /** Email of user who last updated agents list */\n agentsLastUpdatedByUserEmailPrefix?: string;\n /** When agents list was last updated */\n agentsLastUpdatedTime?: number;\n /** Creation timestamp in epoch millis */\n createdTime?: number;\n /** Last updated timestamp in epoch millis */\n lastUpdatedTime?: number;\n}\n\nexport type ContactServiceQueuesResponse = PaginatedResponse<ContactServiceQueue>;\n\nexport interface ContactServiceQueueSearchParams extends BaseSearchParams {\n desktopProfileFilter?: boolean;\n provisioningView?: boolean;\n singleObjectResponse?: boolean;\n}\n\n/**\n * Response type for buddy agents query operations.\n * Either a success response with list of buddy agents or an error.\n * @public\n * @example\n * function handleBuddyAgents(resp: BuddyAgentsResponse) { ... }\n */\nexport type BuddyAgentsResponse = Agent.BuddyAgentsSuccess | Error;\n\n/**\n * Response type for device type update operations.\n * Either a success response with update confirmation or an error.\n * @public\n * @example\n * function handleUpdateDeviceType(resp: UpdateDeviceTypeResponse) { ... }\n */\nexport type UpdateDeviceTypeResponse = Agent.DeviceTypeUpdateSuccess | Error;\n"],"mappings":";;;;;;AAWA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,YAAY,GAAAC,OAAA,CAAAD,YAAA,GAAG;EAC1B;EACAE,GAAG,EAAE,KAAK;EACV;EACAC,IAAI,EAAE,MAAM;EACZ;EACAC,KAAK,EAAE,OAAO;EACd;EACAC,GAAG,EAAE,KAAK;EACV;EACAC,MAAM,EAAE;AACV,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAwBA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA8BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA,IAQYC,aAAa,GAAAN,OAAA,CAAAM,aAAA,0BAAbA,aAAa;EACvB;EADUA,aAAa;EAGvB;EAHUA,aAAa;EAKvB;EALUA,aAAa;EAOvB;EAPUA,aAAa;EASvB;EATUA,aAAa;EAAA,OAAbA,aAAa;AAAA;AAazB;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AAuFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,WAAW,GAAAP,OAAA,CAAAO,WAAA,GAAG;EACzB;EACAC,QAAQ,EAAE,UAAU;EACpB;EACAC,SAAS,EAAE,WAAW;EACtB;EACAC,OAAO,EAAE;AACX,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmBA;AACA;AACA;AACA;AACA;AACA;;AAqBA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAiBA;AACA;AACA;;AAgBA;AACA;AACA;;AAkCA;AACA;AACA;AACA;;AAmGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
|
package/dist/webex.js
CHANGED
package/package.json
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@webex/calling": "3.11.0-next.13",
|
|
49
49
|
"@webex/internal-plugin-mercury": "3.11.0-next.9",
|
|
50
50
|
"@webex/internal-plugin-metrics": "3.11.0-next.7",
|
|
51
|
-
"@webex/internal-plugin-support": "3.11.0-next.
|
|
51
|
+
"@webex/internal-plugin-support": "3.11.0-next.10",
|
|
52
52
|
"@webex/plugin-authorization": "3.11.0-next.7",
|
|
53
53
|
"@webex/plugin-logger": "3.11.0-next.7",
|
|
54
54
|
"@webex/webex-core": "3.11.0-next.7",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"typedoc": "^0.25.0",
|
|
81
81
|
"typescript": "4.9.5"
|
|
82
82
|
},
|
|
83
|
-
"version": "3.11.0-next.
|
|
83
|
+
"version": "3.11.0-next.23"
|
|
84
84
|
}
|
package/src/cc.ts
CHANGED
|
@@ -55,7 +55,13 @@ import {
|
|
|
55
55
|
import {ConnectionLostDetails} from './services/core/websocket/types';
|
|
56
56
|
import TaskManager from './services/task/TaskManager';
|
|
57
57
|
import WebCallingService from './services/WebCallingService';
|
|
58
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
ITask,
|
|
60
|
+
TASK_EVENTS,
|
|
61
|
+
TaskResponse,
|
|
62
|
+
DialerPayload,
|
|
63
|
+
PreviewContactPayload,
|
|
64
|
+
} from './services/task/types';
|
|
59
65
|
import MetricsManager from './metrics/MetricsManager';
|
|
60
66
|
import {METRIC_EVENT_NAMES} from './metrics/constants';
|
|
61
67
|
import {Failure} from './services/core/GlobalTypes';
|
|
@@ -119,6 +125,7 @@ import type {
|
|
|
119
125
|
* - `task:established` - Task/call has been connected
|
|
120
126
|
* - `task:ended` - Task/call has ended
|
|
121
127
|
* - `task:error` - An error occurred during task handling
|
|
128
|
+
* - `task:campaignPreviewReservation` - Campaign preview contact offered to agent
|
|
122
129
|
*
|
|
123
130
|
* @public
|
|
124
131
|
*
|
|
@@ -406,6 +413,16 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
|
|
|
406
413
|
this.trigger(TASK_EVENTS.TASK_MERGED, task);
|
|
407
414
|
};
|
|
408
415
|
|
|
416
|
+
/**
|
|
417
|
+
* Handles campaign preview reservation events when a contact is offered to the agent
|
|
418
|
+
* @private
|
|
419
|
+
* @param {ITask} task The campaign reservation task
|
|
420
|
+
*/
|
|
421
|
+
private handleCampaignPreviewReservation = (task: ITask) => {
|
|
422
|
+
// @ts-ignore
|
|
423
|
+
this.trigger(TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, task);
|
|
424
|
+
};
|
|
425
|
+
|
|
409
426
|
/**
|
|
410
427
|
* Sets up event listeners for incoming tasks and task hydration
|
|
411
428
|
* Subscribes to task events from the task manager
|
|
@@ -415,6 +432,10 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
|
|
|
415
432
|
this.taskManager.on(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
416
433
|
this.taskManager.on(TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
417
434
|
this.taskManager.on(TASK_EVENTS.TASK_MERGED, this.handleTaskMerged);
|
|
435
|
+
this.taskManager.on(
|
|
436
|
+
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION,
|
|
437
|
+
this.handleCampaignPreviewReservation
|
|
438
|
+
);
|
|
418
439
|
}
|
|
419
440
|
|
|
420
441
|
/**
|
|
@@ -543,6 +564,10 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
|
|
|
543
564
|
|
|
544
565
|
this.taskManager.off(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
545
566
|
this.taskManager.off(TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
567
|
+
this.taskManager.off(
|
|
568
|
+
TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION,
|
|
569
|
+
this.handleCampaignPreviewReservation
|
|
570
|
+
);
|
|
546
571
|
this.taskManager.unregisterIncomingCallEvent();
|
|
547
572
|
|
|
548
573
|
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
|
|
@@ -1513,6 +1538,79 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
|
|
|
1513
1538
|
}
|
|
1514
1539
|
}
|
|
1515
1540
|
|
|
1541
|
+
/**
|
|
1542
|
+
* Accepts a campaign preview contact, initiating the outbound call.
|
|
1543
|
+
*
|
|
1544
|
+
* When a campaign manager reserves a contact for an agent, the agent receives an
|
|
1545
|
+
* `AgentOfferCampaignReservation` event. The agent can then accept the preview contact
|
|
1546
|
+
* to initiate the outbound call.
|
|
1547
|
+
*
|
|
1548
|
+
* @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
|
|
1549
|
+
* @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
|
|
1550
|
+
* @throws {Error} If the operation fails (network error, customer unavailable, etc.)
|
|
1551
|
+
*
|
|
1552
|
+
* @example
|
|
1553
|
+
* ```typescript
|
|
1554
|
+
* webex.cc.on('task:campaignPreviewReservation', async (task) => {
|
|
1555
|
+
* const { interactionId } = task.data;
|
|
1556
|
+
* // campaignId is the campaign name (e.g. "MyCampaign"), not a UUID
|
|
1557
|
+
* const campaignId = task.data.interaction.callProcessingDetails.campaignId;
|
|
1558
|
+
*
|
|
1559
|
+
* const result = await webex.cc.acceptPreviewContact({ interactionId, campaignId });
|
|
1560
|
+
* });
|
|
1561
|
+
* ```
|
|
1562
|
+
*/
|
|
1563
|
+
public async acceptPreviewContact(payload: PreviewContactPayload): Promise<TaskResponse> {
|
|
1564
|
+
LoggerProxy.info('Accepting campaign preview contact', {
|
|
1565
|
+
module: CC_FILE,
|
|
1566
|
+
method: METHODS.ACCEPT_PREVIEW_CONTACT,
|
|
1567
|
+
});
|
|
1568
|
+
try {
|
|
1569
|
+
this.metricsManager.timeEvent([
|
|
1570
|
+
METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS,
|
|
1571
|
+
METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED,
|
|
1572
|
+
]);
|
|
1573
|
+
|
|
1574
|
+
const result = await this.services.dialer.acceptPreviewContact({data: payload});
|
|
1575
|
+
|
|
1576
|
+
this.metricsManager.trackEvent(
|
|
1577
|
+
METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS,
|
|
1578
|
+
{
|
|
1579
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(result),
|
|
1580
|
+
interactionId: payload.interactionId,
|
|
1581
|
+
campaignId: payload.campaignId,
|
|
1582
|
+
},
|
|
1583
|
+
['behavioral', 'business', 'operational']
|
|
1584
|
+
);
|
|
1585
|
+
|
|
1586
|
+
LoggerProxy.log('Campaign preview contact accepted successfully', {
|
|
1587
|
+
module: CC_FILE,
|
|
1588
|
+
method: METHODS.ACCEPT_PREVIEW_CONTACT,
|
|
1589
|
+
trackingId: result.trackingId,
|
|
1590
|
+
interactionId: payload.interactionId,
|
|
1591
|
+
});
|
|
1592
|
+
|
|
1593
|
+
return result;
|
|
1594
|
+
} catch (error) {
|
|
1595
|
+
const failure = error.details as Failure;
|
|
1596
|
+
this.metricsManager.trackEvent(
|
|
1597
|
+
METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED,
|
|
1598
|
+
{
|
|
1599
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
1600
|
+
interactionId: payload.interactionId,
|
|
1601
|
+
campaignId: payload.campaignId,
|
|
1602
|
+
},
|
|
1603
|
+
['behavioral', 'business', 'operational']
|
|
1604
|
+
);
|
|
1605
|
+
const {error: detailedError} = getErrorDetails(
|
|
1606
|
+
error,
|
|
1607
|
+
METHODS.ACCEPT_PREVIEW_CONTACT,
|
|
1608
|
+
CC_FILE
|
|
1609
|
+
);
|
|
1610
|
+
throw detailedError;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1516
1614
|
/**
|
|
1517
1615
|
* Fetches outdial ANI (Automatic Number Identification) entries for an outdial ANI ID.
|
|
1518
1616
|
*
|
package/src/constants.ts
CHANGED
|
@@ -435,6 +435,20 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
|
|
|
435
435
|
target: 'outdial_ani_ep_fetch',
|
|
436
436
|
verb: 'fail',
|
|
437
437
|
},
|
|
438
|
+
|
|
439
|
+
// Campaign Preview API Events
|
|
440
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS]: {
|
|
441
|
+
product,
|
|
442
|
+
agent: 'user',
|
|
443
|
+
target: 'campaign_preview_accept',
|
|
444
|
+
verb: 'complete',
|
|
445
|
+
},
|
|
446
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED]: {
|
|
447
|
+
product,
|
|
448
|
+
agent: 'user',
|
|
449
|
+
target: 'campaign_preview_accept',
|
|
450
|
+
verb: 'fail',
|
|
451
|
+
},
|
|
438
452
|
};
|
|
439
453
|
|
|
440
454
|
/**
|
package/src/metrics/constants.ts
CHANGED
|
@@ -159,6 +159,10 @@ export const METRIC_EVENT_NAMES = {
|
|
|
159
159
|
// Outdial ANI Entries API Events
|
|
160
160
|
OUTDIAL_ANI_EP_FETCH_SUCCESS: 'Outdial ANI Entries Fetch Success',
|
|
161
161
|
OUTDIAL_ANI_EP_FETCH_FAILED: 'Outdial ANI Entries Fetch Failed',
|
|
162
|
+
|
|
163
|
+
// Campaign Preview API Events
|
|
164
|
+
CAMPAIGN_PREVIEW_ACCEPT_SUCCESS: 'Campaign Preview Accept Success',
|
|
165
|
+
CAMPAIGN_PREVIEW_ACCEPT_FAILED: 'Campaign Preview Accept Failed',
|
|
162
166
|
} as const;
|
|
163
167
|
|
|
164
168
|
/**
|
|
@@ -111,6 +111,12 @@ export const CC_TASK_EVENTS = {
|
|
|
111
111
|
AGENT_CONTACT_UNASSIGNED: 'AgentContactUnassigned',
|
|
112
112
|
/** Event emitted when inviting agent fails */
|
|
113
113
|
AGENT_INVITE_FAILED: 'AgentInviteFailed',
|
|
114
|
+
/** Event emitted when a campaign preview contact is offered to the agent */
|
|
115
|
+
AGENT_OFFER_CAMPAIGN_RESERVATION: 'AgentOfferCampaignReservation',
|
|
116
|
+
/** Event emitted when campaign contact is updated */
|
|
117
|
+
CAMPAIGN_CONTACT_UPDATED: 'CampaignContactUpdated',
|
|
118
|
+
/** Event emitted when accepting a campaign preview contact fails */
|
|
119
|
+
CAMPAIGN_PREVIEW_ACCEPT_FAILED: 'CampaignPreviewAcceptFailed',
|
|
114
120
|
} as const;
|
|
115
121
|
|
|
116
122
|
/**
|
package/src/services/core/Err.ts
CHANGED
|
@@ -38,6 +38,7 @@ export type TaskErrorIds =
|
|
|
38
38
|
| {'Service.aqm.task.pauseRecording': Failure}
|
|
39
39
|
| {'Service.aqm.task.resumeRecording': Failure}
|
|
40
40
|
| {'Service.aqm.dialer.startOutdial': Failure}
|
|
41
|
+
| {'Service.aqm.dialer.acceptPreviewContact': Failure}
|
|
41
42
|
| {'Service.reqs.generic.failure': {trackingId: string}};
|
|
42
43
|
|
|
43
44
|
export type ReqError =
|
|
@@ -20,18 +20,40 @@ export default class AqmReqs {
|
|
|
20
20
|
this.webSocketManager.on('message', this.onMessage.bind(this));
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Creates a request function for an API call with parameters
|
|
25
|
+
* @param c - The configuration for the request
|
|
26
|
+
* @returns A function that makes the API request
|
|
27
|
+
*/
|
|
23
28
|
req<TRes, TErr, TReq>(c: Conf<TRes, TErr, TReq>): Res<TRes, TReq> {
|
|
24
29
|
return (p: TReq, cbRes?: CbRes<TRes>) => this.makeAPIRequest(c(p), cbRes);
|
|
25
30
|
}
|
|
26
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Creates a request function for an API call with no parameters
|
|
34
|
+
* @param c - The configuration for the request
|
|
35
|
+
* @returns A function that makes the API request
|
|
36
|
+
*/
|
|
27
37
|
reqEmpty<TRes, TErr>(c: ConfEmpty<TRes, TErr>): ResEmpty<TRes> {
|
|
28
38
|
return (cbRes?: CbRes<TRes>) => this.makeAPIRequest(c(), cbRes);
|
|
29
39
|
}
|
|
30
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Makes an API request
|
|
43
|
+
* @param c - The request configuration
|
|
44
|
+
* @param cbRes - The callback for the response
|
|
45
|
+
* @returns A promise that resolves with the response or rejects with an error
|
|
46
|
+
*/
|
|
31
47
|
private async makeAPIRequest<TRes, TErr>(c: Req<TRes, TErr>, cbRes?: CbRes<TRes>): Promise<TRes> {
|
|
32
48
|
return this.createPromise(c, cbRes);
|
|
33
49
|
}
|
|
34
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Creates a promise for an API request
|
|
53
|
+
* @param c - The request configuration
|
|
54
|
+
* @param cbRes - The callback for the response
|
|
55
|
+
* @returns A promise that resolves with the response or rejects with an error
|
|
56
|
+
*/
|
|
35
57
|
private createPromise<TRes, TErr>(c: Req<TRes, TErr>, cbRes?: CbRes<TRes>) {
|
|
36
58
|
return new Promise<TRes>((resolve, reject) => {
|
|
37
59
|
const keySuccess = this.bindPrint(c.notifSuccess.bind);
|
|
@@ -154,10 +176,13 @@ export default class AqmReqs {
|
|
|
154
176
|
if (response?.headers) {
|
|
155
177
|
response.headers.Authorization = '*';
|
|
156
178
|
}
|
|
157
|
-
LoggerProxy.error(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
179
|
+
LoggerProxy.error(
|
|
180
|
+
`Routing request timeout${keySuccess}${JSON.stringify(response)}${c.url}`,
|
|
181
|
+
{
|
|
182
|
+
module: AQM_REQS_FILE,
|
|
183
|
+
method: METHODS.CREATE_PROMISE,
|
|
184
|
+
}
|
|
185
|
+
);
|
|
161
186
|
reject(
|
|
162
187
|
new Err.Details('Service.aqm.reqs.Timeout', {
|
|
163
188
|
key: keySuccess,
|
|
@@ -171,39 +196,60 @@ export default class AqmReqs {
|
|
|
171
196
|
});
|
|
172
197
|
}
|
|
173
198
|
|
|
174
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Converts a bind object to a string representation
|
|
201
|
+
* @param bind - The bind object to convert
|
|
202
|
+
* @returns A string representation of the bind object
|
|
203
|
+
*/
|
|
204
|
+
private bindPrint(bind: any): string {
|
|
175
205
|
let result = '';
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
for (const key of Object.keys(bind).filter((prop) => prop !== '__typeMap')) {
|
|
207
|
+
const value = bind[key];
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(value)) {
|
|
210
|
+
result += `${key}=[${value.join(',')}],`;
|
|
211
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
212
|
+
result += `${key}=(${this.bindPrint(value)}),`;
|
|
182
213
|
} else {
|
|
183
|
-
result += `${
|
|
214
|
+
result += `${key}=${value},`;
|
|
184
215
|
}
|
|
185
216
|
}
|
|
186
217
|
|
|
187
218
|
return result ? result.slice(0, -1) : result;
|
|
188
219
|
}
|
|
189
220
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Checks if a message matches a bind object
|
|
223
|
+
* @param bind - The bind object to check against
|
|
224
|
+
* @param msg - The message to check
|
|
225
|
+
* @returns True if the message matches the bind object, false otherwise
|
|
226
|
+
*/
|
|
227
|
+
private bindCheck(bind: any, msg: any): boolean {
|
|
228
|
+
// Handle type-dependent field matching if __typeMap is present
|
|
229
|
+
if (bind.__typeMap && typeof bind.__typeMap === 'object') {
|
|
230
|
+
if (!AqmReqs.typeMapCheck(bind.__typeMap, msg)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
for (const key of Object.keys(bind).filter((prop) => prop !== '__typeMap')) {
|
|
236
|
+
const bindValue = bind[key];
|
|
237
|
+
const msgValue = msg[key];
|
|
238
|
+
|
|
239
|
+
if (Array.isArray(bindValue)) {
|
|
194
240
|
// Check if the message value matches any of the values in the array
|
|
195
|
-
if (!
|
|
241
|
+
if (!bindValue.includes(msgValue)) {
|
|
196
242
|
return false;
|
|
197
243
|
}
|
|
198
|
-
} else if (typeof
|
|
199
|
-
if (typeof
|
|
200
|
-
if (!this.bindCheck(
|
|
244
|
+
} else if (typeof bindValue === 'object' && bindValue !== null) {
|
|
245
|
+
if (typeof msgValue === 'object' && msgValue !== null) {
|
|
246
|
+
if (!this.bindCheck(bindValue, msgValue)) {
|
|
201
247
|
return false;
|
|
202
248
|
}
|
|
203
249
|
} else {
|
|
204
250
|
return false;
|
|
205
251
|
}
|
|
206
|
-
} else if (!
|
|
252
|
+
} else if (!msgValue || msgValue !== bindValue) {
|
|
207
253
|
return false;
|
|
208
254
|
}
|
|
209
255
|
}
|
|
@@ -211,7 +257,39 @@ export default class AqmReqs {
|
|
|
211
257
|
return true;
|
|
212
258
|
}
|
|
213
259
|
|
|
214
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Checks type-dependent field conditions defined in __typeMap.
|
|
262
|
+
* @param typeMap - The type map to check against
|
|
263
|
+
* @param msg - The message to check
|
|
264
|
+
* @returns True if the message matches the type map, false otherwise
|
|
265
|
+
* The typeMap has the shape:
|
|
266
|
+
* { typeField: "type", conditions: { EventA: { field: value }, EventB: { field: value } } }
|
|
267
|
+
* It reads msg[typeField] to determine which condition set to apply,
|
|
268
|
+
* then verifies all fields in that condition match the message.
|
|
269
|
+
*/
|
|
270
|
+
private static typeMapCheck(typeMap: any, msg: any): boolean {
|
|
271
|
+
const typeField = typeMap.typeField || 'type';
|
|
272
|
+
const msgType = msg[typeField];
|
|
273
|
+
|
|
274
|
+
if (typeMap.conditions && typeMap.conditions[msgType]) {
|
|
275
|
+
const condition = typeMap.conditions[msgType];
|
|
276
|
+
for (const field of Object.keys(condition)) {
|
|
277
|
+
if (!msg[field] || msg[field] !== condition[field]) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Handles incoming messages from the WebSocket (must be a lambda fn)
|
|
290
|
+
* @param msg - The message to handle
|
|
291
|
+
* @returns
|
|
292
|
+
*/
|
|
215
293
|
private readonly onMessage = (msg: any) => {
|
|
216
294
|
const event = JSON.parse(msg);
|
|
217
295
|
if (event.type === 'Welcome') {
|