@webex/contact-center 3.10.0-next.9 → 3.10.0-wxc-disconnect.1

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.
Files changed (46) hide show
  1. package/dist/cc.js +1 -12
  2. package/dist/cc.js.map +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/services/config/types.js +2 -2
  5. package/dist/services/config/types.js.map +1 -1
  6. package/dist/services/core/Utils.js +71 -90
  7. package/dist/services/core/Utils.js.map +1 -1
  8. package/dist/services/core/constants.js +1 -17
  9. package/dist/services/core/constants.js.map +1 -1
  10. package/dist/services/task/TaskManager.js +17 -89
  11. package/dist/services/task/TaskManager.js.map +1 -1
  12. package/dist/services/task/constants.js +1 -20
  13. package/dist/services/task/constants.js.map +1 -1
  14. package/dist/services/task/index.js +98 -123
  15. package/dist/services/task/index.js.map +1 -1
  16. package/dist/services/task/types.js +4 -2
  17. package/dist/services/task/types.js.map +1 -1
  18. package/dist/types/cc.d.ts +0 -6
  19. package/dist/types/index.d.ts +1 -1
  20. package/dist/types/services/config/types.d.ts +4 -4
  21. package/dist/types/services/core/Utils.d.ts +17 -32
  22. package/dist/types/services/core/constants.d.ts +0 -14
  23. package/dist/types/services/task/constants.d.ts +0 -17
  24. package/dist/types/services/task/index.d.ts +2 -41
  25. package/dist/types/services/task/types.d.ts +33 -133
  26. package/dist/webex.js +1 -1
  27. package/package.json +9 -9
  28. package/src/cc.ts +1 -12
  29. package/src/index.ts +0 -1
  30. package/src/services/config/types.ts +2 -2
  31. package/src/services/core/Utils.ts +85 -101
  32. package/src/services/core/constants.ts +0 -16
  33. package/src/services/task/TaskManager.ts +15 -112
  34. package/src/services/task/constants.ts +0 -19
  35. package/src/services/task/index.ts +82 -108
  36. package/src/services/task/types.ts +33 -142
  37. package/test/unit/spec/services/core/Utils.ts +31 -262
  38. package/test/unit/spec/services/task/TaskManager.ts +6 -620
  39. package/test/unit/spec/services/task/index.ts +79 -502
  40. package/umd/contact-center.min.js +2 -2
  41. package/umd/contact-center.min.js.map +1 -1
  42. package/dist/services/task/TaskUtils.js +0 -104
  43. package/dist/services/task/TaskUtils.js.map +0 -1
  44. package/dist/types/services/task/TaskUtils.d.ts +0 -42
  45. package/src/services/task/TaskUtils.ts +0 -113
  46. package/test/unit/spec/services/task/TaskUtils.ts +0 -131
@@ -444,29 +444,7 @@ export declare enum TASK_EVENTS {
444
444
  * });
445
445
  * ```
446
446
  */
447
- TASK_PARTICIPANT_LEFT_FAILED = "task:participantLeftFailed",
448
- /**
449
- * Triggered when a contact is merged
450
- * @example
451
- * ```typescript
452
- * task.on(TASK_EVENTS.TASK_MERGED, (task: ITask) => {
453
- * console.log('Contact merged:', task.data.interactionId);
454
- * // Handle contact merge
455
- * });
456
- * ```
457
- */
458
- TASK_MERGED = "task:merged",
459
- /**
460
- * Triggered when a participant enters post-call activity state
461
- * @example
462
- * ```typescript
463
- * task.on(TASK_EVENTS.TASK_POST_CALL_ACTIVITY, (task: ITask) => {
464
- * console.log('Participant in post-call activity:', task.data.interactionId);
465
- * // Handle post-call activity
466
- * });
467
- * ```
468
- */
469
- TASK_POST_CALL_ACTIVITY = "task:postCallActivity"
447
+ TASK_PARTICIPANT_LEFT_FAILED = "task:participantLeftFailed"
470
448
  }
471
449
  /**
472
450
  * Represents a customer interaction within the contact center system
@@ -704,8 +682,6 @@ export type TaskData = {
704
682
  isConsulted?: boolean;
705
683
  /** Indicates if the task is in conference state */
706
684
  isConferencing: boolean;
707
- /** Indicates if a conference is currently in progress (2+ active agents) */
708
- isConferenceInProgress?: boolean;
709
685
  /** Identifier of agent who last updated the task */
710
686
  updatedBy?: string;
711
687
  /** Type of destination for transfer/consult */
@@ -728,8 +704,6 @@ export type TaskData = {
728
704
  isWebCallMute?: boolean;
729
705
  /** Identifier for reservation interaction */
730
706
  reservationInteractionId?: string;
731
- /** Identifier for the reserved agent channel (used for campaign tasks) */
732
- reservedAgentChannelId?: string;
733
707
  /** Indicates if wrap-up is required for this task */
734
708
  wrapUpRequired?: boolean;
735
709
  };
@@ -964,6 +938,18 @@ export type ConsultConferenceData = {
964
938
  /** Type of destination (e.g., 'agent', 'queue') */
965
939
  destinationType: string;
966
940
  };
941
+ /**
942
+ * Legacy consultation conference data type matching Agent Desktop
943
+ * @public
944
+ */
945
+ export type consultConferencePayloadData = {
946
+ /** Identifier of the agent initiating consult/conference */
947
+ agentId: string;
948
+ /** Type of destination (e.g., 'agent', 'queue') */
949
+ destinationType: string;
950
+ /** Identifier of the destination agent */
951
+ destAgentId: string;
952
+ };
967
953
  /**
968
954
  * Parameters required for cancelling a consult to queue operation
969
955
  * @public
@@ -1076,15 +1062,15 @@ export interface ITask extends EventEmitter {
1076
1062
  */
1077
1063
  autoWrapup?: AutoWrapup;
1078
1064
  /**
1079
- * Cancels the auto-wrapup timer for the task.
1080
- * This method stops the auto-wrapup process if it is currently active.
1065
+ * cancels the auto-wrapup timer for the task
1066
+ * This method stops the auto-wrapup process if it is currently active
1081
1067
  * Note: This is supported only in single session mode. Not supported in multi-session mode.
1082
1068
  * @returns void
1083
1069
  */
1084
1070
  cancelAutoWrapupTimer(): void;
1085
1071
  /**
1086
- * Deregisters all web call event listeners.
1087
- * Used when cleaning up task resources.
1072
+ * Deregisters all web call event listeners
1073
+ * Used when cleaning up task resources
1088
1074
  * @ignore
1089
1075
  */
1090
1076
  unregisterWebCallListeners(): void;
@@ -1102,7 +1088,7 @@ export interface ITask extends EventEmitter {
1102
1088
  * @returns Promise<TaskResponse>
1103
1089
  * @example
1104
1090
  * ```typescript
1105
- * await task.accept();
1091
+ * task.accept();
1106
1092
  * ```
1107
1093
  */
1108
1094
  accept(): Promise<TaskResponse>;
@@ -1111,54 +1097,44 @@ export interface ITask extends EventEmitter {
1111
1097
  * @returns Promise<TaskResponse>
1112
1098
  * @example
1113
1099
  * ```typescript
1114
- * await task.decline();
1100
+ * task.decline();
1115
1101
  * ```
1116
1102
  */
1117
1103
  decline(): Promise<TaskResponse>;
1118
1104
  /**
1119
- * Places the current task on hold.
1120
- * @param mediaResourceId - Optional media resource ID to use for the hold operation. If not provided, uses the task's current mediaResourceId
1105
+ * Places the current task on hold
1121
1106
  * @returns Promise<TaskResponse>
1122
1107
  * @example
1123
1108
  * ```typescript
1124
- * // Hold with default mediaResourceId
1125
- * await task.hold();
1126
- *
1127
- * // Hold with custom mediaResourceId
1128
- * await task.hold('custom-media-resource-id');
1109
+ * task.hold();
1129
1110
  * ```
1130
1111
  */
1131
- hold(mediaResourceId?: string): Promise<TaskResponse>;
1112
+ hold(): Promise<TaskResponse>;
1132
1113
  /**
1133
- * Resumes a task that was previously on hold.
1134
- * @param mediaResourceId - Optional media resource ID to use for the resume operation. If not provided, uses the task's current mediaResourceId from interaction media
1114
+ * Resumes a task that was previously on hold
1135
1115
  * @returns Promise<TaskResponse>
1136
1116
  * @example
1137
1117
  * ```typescript
1138
- * // Resume with default mediaResourceId
1139
- * await task.resume();
1140
- *
1141
- * // Resume with custom mediaResourceId
1142
- * await task.resume('custom-media-resource-id');
1118
+ * task.resume();
1143
1119
  * ```
1144
1120
  */
1145
- resume(mediaResourceId?: string): Promise<TaskResponse>;
1121
+ resume(): Promise<TaskResponse>;
1146
1122
  /**
1147
- * Ends/terminates the current task.
1123
+ * Ends/terminates the current task
1148
1124
  * @returns Promise<TaskResponse>
1149
1125
  * @example
1150
1126
  * ```typescript
1151
- * await task.end();
1127
+ * task.end();
1152
1128
  * ```
1153
1129
  */
1154
1130
  end(): Promise<TaskResponse>;
1155
1131
  /**
1156
- * Initiates wrap-up process for the task with specified details.
1132
+ * Initiates wrap-up process for the task with specified details
1157
1133
  * @param wrapupPayload - Wrap-up details including reason and auxiliary code
1158
1134
  * @returns Promise<TaskResponse>
1159
1135
  * @example
1160
1136
  * ```typescript
1161
- * await task.wrapup({
1137
+ * task.wrapup({
1162
1138
  * wrapUpReason: "Customer issue resolved",
1163
1139
  * auxCodeId: "RESOLVED"
1164
1140
  * });
@@ -1166,100 +1142,24 @@ export interface ITask extends EventEmitter {
1166
1142
  */
1167
1143
  wrapup(wrapupPayload: WrapupPayLoad): Promise<TaskResponse>;
1168
1144
  /**
1169
- * Pauses the recording for current task.
1145
+ * Pauses the recording for current task
1170
1146
  * @returns Promise<TaskResponse>
1171
1147
  * @example
1172
1148
  * ```typescript
1173
- * await task.pauseRecording();
1149
+ * task.pauseRecording();
1174
1150
  * ```
1175
1151
  */
1176
1152
  pauseRecording(): Promise<TaskResponse>;
1177
1153
  /**
1178
- * Resumes a previously paused recording.
1154
+ * Resumes a previously paused recording
1179
1155
  * @param resumeRecordingPayload - Parameters for resuming the recording
1180
1156
  * @returns Promise<TaskResponse>
1181
1157
  * @example
1182
1158
  * ```typescript
1183
- * await task.resumeRecording({
1159
+ * task.resumeRecording({
1184
1160
  * autoResumed: false
1185
1161
  * });
1186
1162
  * ```
1187
1163
  */
1188
1164
  resumeRecording(resumeRecordingPayload: ResumeRecordingPayload): Promise<TaskResponse>;
1189
- /**
1190
- * Initiates a consultation with another agent or queue.
1191
- * @param consultPayload - Consultation details including destination and type
1192
- * @returns Promise<TaskResponse>
1193
- * @example
1194
- * ```typescript
1195
- * await task.consult({ to: "agentId", destinationType: "agent" });
1196
- * ```
1197
- */
1198
- consult(consultPayload: ConsultPayload): Promise<TaskResponse>;
1199
- /**
1200
- * Ends an ongoing consultation.
1201
- * @param consultEndPayload - Details for ending the consultation
1202
- * @returns Promise<TaskResponse>
1203
- * @example
1204
- * ```typescript
1205
- * await task.endConsult({ isConsult: true, taskId: "taskId" });
1206
- * ```
1207
- */
1208
- endConsult(consultEndPayload: ConsultEndPayload): Promise<TaskResponse>;
1209
- /**
1210
- * Transfers the task to another agent or queue.
1211
- * @param transferPayload - Transfer details including destination and type
1212
- * @returns Promise<TaskResponse>
1213
- * @example
1214
- * ```typescript
1215
- * await task.transfer({ to: "queueId", destinationType: "queue" });
1216
- * ```
1217
- */
1218
- transfer(transferPayload: TransferPayLoad): Promise<TaskResponse>;
1219
- /**
1220
- * Transfers the task after consultation.
1221
- * @param consultTransferPayload - Details for consult transfer (optional)
1222
- * @returns Promise<TaskResponse>
1223
- * @example
1224
- * ```typescript
1225
- * await task.consultTransfer({ to: "agentId", destinationType: "agent" });
1226
- * ```
1227
- */
1228
- consultTransfer(consultTransferPayload?: ConsultTransferPayLoad): Promise<TaskResponse>;
1229
- /**
1230
- * Initiates a consult conference (merge consult call with main call).
1231
- * @returns Promise<TaskResponse>
1232
- * @example
1233
- * ```typescript
1234
- * await task.consultConference();
1235
- * ```
1236
- */
1237
- consultConference(): Promise<TaskResponse>;
1238
- /**
1239
- * Exits from an ongoing conference.
1240
- * @returns Promise<TaskResponse>
1241
- * @example
1242
- * ```typescript
1243
- * await task.exitConference();
1244
- * ```
1245
- */
1246
- exitConference(): Promise<TaskResponse>;
1247
- /**
1248
- * Transfers the conference to another participant.
1249
- * @returns Promise<TaskResponse>
1250
- * @example
1251
- * ```typescript
1252
- * await task.transferConference();
1253
- * ```
1254
- */
1255
- transferConference(): Promise<TaskResponse>;
1256
- /**
1257
- * Toggles mute/unmute for the local audio stream during a WebRTC task.
1258
- * @returns Promise<void>
1259
- * @example
1260
- * ```typescript
1261
- * await task.toggleMute();
1262
- * ```
1263
- */
1264
- toggleMute(): Promise<void>;
1265
1165
  }
package/dist/webex.js CHANGED
@@ -29,7 +29,7 @@ if (!global.Buffer) {
29
29
  */
30
30
  const Webex = _webexCore.default.extend({
31
31
  webex: true,
32
- version: `3.10.0-next.9`
32
+ version: `3.10.0-wxc-disconnect.1`
33
33
  });
34
34
 
35
35
  /**
package/package.json CHANGED
@@ -45,13 +45,13 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@types/platform": "1.3.4",
48
- "@webex/calling": "3.10.0-next.6",
49
- "@webex/internal-plugin-mercury": "3.10.0-next.2",
50
- "@webex/internal-plugin-metrics": "3.10.0-next.2",
51
- "@webex/internal-plugin-support": "3.10.0-next.2",
52
- "@webex/plugin-authorization": "3.10.0-next.2",
53
- "@webex/plugin-logger": "3.10.0-next.2",
54
- "@webex/webex-core": "3.10.0-next.2",
48
+ "@webex/calling": "3.10.0-wxc-disconnect.1",
49
+ "@webex/internal-plugin-mercury": "3.10.0-wxc-disconnect.1",
50
+ "@webex/internal-plugin-metrics": "3.10.0-wxc-disconnect.1",
51
+ "@webex/internal-plugin-support": "3.10.0-wxc-disconnect.1",
52
+ "@webex/plugin-authorization": "3.10.0-wxc-disconnect.1",
53
+ "@webex/plugin-logger": "3.10.0-wxc-disconnect.1",
54
+ "@webex/webex-core": "3.10.0-wxc-disconnect.1",
55
55
  "jest-html-reporters": "3.0.11",
56
56
  "lodash": "^4.17.21"
57
57
  },
@@ -65,7 +65,7 @@
65
65
  "@webex/eslint-config-legacy": "0.0.0",
66
66
  "@webex/jest-config-legacy": "0.0.0",
67
67
  "@webex/legacy-tools": "0.0.0",
68
- "@webex/test-helper-mock-webex": "3.8.1-next.11",
68
+ "@webex/test-helper-mock-webex": "3.10.0-wxc-disconnect.1",
69
69
  "eslint": "^8.24.0",
70
70
  "eslint-config-airbnb-base": "15.0.0",
71
71
  "eslint-config-prettier": "8.3.0",
@@ -80,5 +80,5 @@
80
80
  "typedoc": "^0.25.0",
81
81
  "typescript": "4.9.5"
82
82
  },
83
- "version": "3.10.0-next.9"
83
+ "version": "3.10.0-wxc-disconnect.1"
84
84
  }
package/src/cc.ts CHANGED
@@ -396,16 +396,6 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
396
396
  this.trigger(TASK_EVENTS.TASK_HYDRATE, task);
397
397
  };
398
398
 
399
- /**
400
- * Handles task merged events when tasks are combined eg: EPDN merge/transfer
401
- * @private
402
- * @param {ITask} task The task object that has been merged
403
- */
404
- private handleTaskMerged = (task: ITask) => {
405
- // @ts-ignore
406
- this.trigger(TASK_EVENTS.TASK_MERGED, task);
407
- };
408
-
409
399
  /**
410
400
  * Sets up event listeners for incoming tasks and task hydration
411
401
  * Subscribes to task events from the task manager
@@ -414,7 +404,6 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
414
404
  private incomingTaskListener() {
415
405
  this.taskManager.on(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
416
406
  this.taskManager.on(TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
417
- this.taskManager.on(TASK_EVENTS.TASK_MERGED, this.handleTaskMerged);
418
407
  }
419
408
 
420
409
  /**
@@ -795,7 +784,7 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
795
784
  throw error;
796
785
  }
797
786
 
798
- const loginResponse = await this.services.agent.stationLogin({
787
+ const loginResponse = this.services.agent.stationLogin({
799
788
  data: {
800
789
  dialNumber:
801
790
  data.loginOption === LoginOption.BROWSER ? this.agentConfig.agentId : data.dialNumber,
package/src/index.ts CHANGED
@@ -126,7 +126,6 @@ export type {
126
126
  AgentContact,
127
127
  /** Task interface */
128
128
  ITask,
129
- Interaction,
130
129
  TaskData,
131
130
  /** Task response */
132
131
  TaskResponse,
@@ -63,6 +63,8 @@ export const CC_TASK_EVENTS = {
63
63
  AGENT_CONFERENCE_TRANSFERRED: 'AgentConferenceTransferred',
64
64
  /** Event emitted when conference transfer fails */
65
65
  AGENT_CONFERENCE_TRANSFER_FAILED: 'AgentConferenceTransferFailed',
66
+ /** Event emitted when consulted participant is moving/being transferred */
67
+ CONSULTED_PARTICIPANT_MOVING: 'ConsultedParticipantMoving',
66
68
  /** Event emitted for post-call activity by participant */
67
69
  PARTICIPANT_POST_CALL_ACTIVITY: 'ParticipantPostCallActivity',
68
70
  /** Event emitted when contact is blind transferred */
@@ -89,8 +91,6 @@ export const CC_TASK_EVENTS = {
89
91
  CONTACT_RECORDING_RESUME_FAILED: 'ContactRecordingResumeFailed',
90
92
  /** Event emitted when contact ends */
91
93
  CONTACT_ENDED: 'ContactEnded',
92
- /** Event emitted when contact is merged */
93
- CONTACT_MERGED: 'ContactMerged',
94
94
  /** Event emitted when ending contact fails */
95
95
  AGENT_CONTACT_END_FAILED: 'AgentContactEndFailed',
96
96
  /** Event emitted when agent enters wrap-up state */
@@ -6,10 +6,11 @@ import WebexRequest from './WebexRequest';
6
6
  import {
7
7
  TaskData,
8
8
  ConsultTransferPayLoad,
9
+ ConsultConferenceData,
10
+ consultConferencePayloadData,
9
11
  CONSULT_TRANSFER_DESTINATION_TYPE,
10
12
  Interaction,
11
13
  } from '../task/types';
12
- import {PARTICIPANT_TYPES, STATE_CONSULT} from './constants';
13
14
 
14
15
  /**
15
16
  * Extracts common error details from a Webex request payload.
@@ -217,118 +218,59 @@ export const createErrDetailsObject = (errObj: WebexRequestPayload) => {
217
218
  };
218
219
 
219
220
  /**
220
- * Gets the consulted agent ID from the media object by finding the agent
221
- * in the consult media participants (excluding the current agent).
221
+ * Derives the consult transfer destination type based on the provided task data.
222
222
  *
223
- * @param media - The media object from the interaction
224
- * @param agentId - The current agent's ID to exclude from the search
225
- * @returns The consulted agent ID, or empty string if none found
226
- */
227
- export const getConsultedAgentId = (media: Interaction['media'], agentId: string): string => {
228
- let consultParticipants: string[] = [];
229
- let consultedParticipantId = '';
230
-
231
- Object.keys(media).forEach((key) => {
232
- if (media[key].mType === STATE_CONSULT) {
233
- consultParticipants = media[key].participants;
234
- }
235
- });
236
-
237
- if (consultParticipants.includes(agentId)) {
238
- const id = consultParticipants.find((participant) => participant !== agentId);
239
- consultedParticipantId = id || consultedParticipantId;
240
- }
241
-
242
- return consultedParticipantId;
243
- };
244
-
245
- /**
246
- * Gets the destination agent ID for CBT (Capacity Based Team) scenarios.
247
- * CBT refers to teams created in Control Hub with capacity-based routing
248
- * (as opposed to agent-based routing). This handles cases where the consulted
249
- * participant is not directly in participants but can be found by matching
250
- * the dial number (dn).
223
+ * Logic parity with desktop behavior:
224
+ * - If agent action is dialing a number (DN/EPDN/ENTRYPOINT):
225
+ * - ENTRYPOINT/EPDN map to ENTRYPOINT
226
+ * - DN maps to DIALNUMBER
227
+ * - Otherwise defaults to AGENT
251
228
  *
252
- * @param interaction - The interaction object
253
- * @param consultingAgent - The consulting agent identifier
254
- * @returns The destination agent ID for CBT scenarios, or empty string if none found
229
+ * @param taskData - The task data used to infer the agent action and destination type
230
+ * @returns The normalized destination type to be used for consult transfer
255
231
  */
256
- export const getDestAgentIdForCBT = (interaction: Interaction, consultingAgent: string): string => {
257
- const participants = interaction.participants;
258
- let destAgentIdForCBT = '';
259
-
260
- // Check if this is a CBT scenario (consultingAgent exists but not directly in participants)
261
- if (consultingAgent && !participants[consultingAgent]) {
262
- const foundEntry = Object.entries(participants).find(
263
- ([, participant]: [string, Interaction['participants'][string]]) => {
264
- return (
265
- participant.pType.toLowerCase() === PARTICIPANT_TYPES.DN &&
266
- participant.type === PARTICIPANT_TYPES.AGENT &&
267
- participant.dn === consultingAgent
268
- );
269
- }
270
- );
271
-
272
- if (foundEntry) {
273
- destAgentIdForCBT = foundEntry[0];
274
- }
275
- }
276
-
277
- return destAgentIdForCBT;
278
- };
279
-
280
232
  /**
281
- * Calculates the destination agent ID for consult operations.
282
- *
283
- * @param interaction - The interaction object
284
- * @param agentId - The current agent's ID
285
- * @returns The destination agent ID
233
+ * Checks if a participant type represents a non-customer participant.
234
+ * Non-customer participants include agents, dial numbers, entry point dial numbers,
235
+ * and entry points.
286
236
  */
287
- export const calculateDestAgentId = (interaction: Interaction, agentId: string): string => {
288
- const consultingAgent = getConsultedAgentId(interaction.media, agentId);
289
-
290
- // Check if this is a CBT (Capacity Based Team) scenario
291
- // If not CBT, the function will return empty string and we'll use the normal flow
292
- const destAgentIdCBT = getDestAgentIdForCBT(interaction, consultingAgent);
293
- if (destAgentIdCBT) {
294
- return destAgentIdCBT;
295
- }
296
-
297
- return interaction.participants[consultingAgent]?.type === PARTICIPANT_TYPES.EP_DN
298
- ? interaction.participants[consultingAgent]?.epId
299
- : interaction.participants[consultingAgent]?.id;
237
+ const isNonCustomerParticipant = (participantType: string): boolean => {
238
+ return (
239
+ participantType === 'Agent' ||
240
+ participantType === 'DN' ||
241
+ participantType === 'EpDn' ||
242
+ participantType === 'entryPoint'
243
+ );
300
244
  };
301
245
 
302
246
  /**
303
- * Calculates the destination agent ID for fetching destination type.
247
+ * Gets the destination agent ID from participants data by finding the first
248
+ * non-customer participant that is not the current agent and is not in wrap-up state.
304
249
  *
305
- * @param interaction - The interaction object
306
- * @param agentId - The current agent's ID
307
- * @returns The destination agent ID for determining destination type
250
+ * @param participants - The participants data from the interaction
251
+ * @param agentId - The current agent's ID to exclude from the search
252
+ * @returns The destination agent ID, or empty string if none found
308
253
  */
309
- export const calculateDestType = (interaction: Interaction, agentId: string): string => {
310
- const consultingAgent = getConsultedAgentId(interaction.media, agentId);
311
-
312
- // Check if this is a CBT (Capacity Based Team) scenario, otherwise use consultingAgent
313
- const destAgentIdCBT = getDestAgentIdForCBT(interaction, consultingAgent);
314
- const destinationaegntId = destAgentIdCBT || consultingAgent;
315
- const destAgentType = destinationaegntId
316
- ? interaction.participants[destinationaegntId]?.pType
317
- : undefined;
318
- if (destAgentType) {
319
- if (destAgentType === 'DN') {
320
- return CONSULT_TRANSFER_DESTINATION_TYPE.DIALNUMBER;
321
- }
322
- if (destAgentType === 'EP-DN') {
323
- return CONSULT_TRANSFER_DESTINATION_TYPE.ENTRYPOINT;
324
- }
325
- // Keep the existing destinationType if it's something else (like "agent" or "Agent")
326
- // Convert "Agent" to lowercase for consistency
327
-
328
- return destAgentType.toLowerCase();
254
+ export const getDestinationAgentId = (
255
+ participants: Interaction['participants'],
256
+ agentId: string
257
+ ): string => {
258
+ let id = '';
259
+
260
+ if (participants) {
261
+ Object.keys(participants).forEach((participant) => {
262
+ const participantData = participants[participant];
263
+ if (
264
+ isNonCustomerParticipant(participantData.type) &&
265
+ participantData.id !== agentId &&
266
+ !participantData.isWrapUp
267
+ ) {
268
+ id = participantData.id;
269
+ }
270
+ });
329
271
  }
330
272
 
331
- return CONSULT_TRANSFER_DESTINATION_TYPE.AGENT;
273
+ return id;
332
274
  };
333
275
 
334
276
  export const deriveConsultTransferDestinationType = (
@@ -344,3 +286,45 @@ export const deriveConsultTransferDestinationType = (
344
286
 
345
287
  return CONSULT_TRANSFER_DESTINATION_TYPE.AGENT;
346
288
  };
289
+
290
+ /**
291
+ * Builds consult conference parameter data using EXACT Agent Desktop logic.
292
+ * This matches the Agent Desktop's consultConference implementation exactly.
293
+ *
294
+ * @param dataPassed - Original consultation data from Agent Desktop format
295
+ * @param interactionIdPassed - The interaction ID for the task
296
+ * @returns Object with interactionId and ConsultConferenceData matching Agent Desktop format
297
+ * @public
298
+ */
299
+ export const buildConsultConferenceParamData = (
300
+ dataPassed: consultConferencePayloadData,
301
+ interactionIdPassed: string
302
+ ): {interactionId: string; data: ConsultConferenceData} => {
303
+ const data: ConsultConferenceData = {
304
+ // Include agentId if present in input data
305
+ ...('agentId' in dataPassed && {agentId: dataPassed.agentId}),
306
+ // Handle destAgentId from consultation data
307
+ to: dataPassed.destAgentId,
308
+ destinationType: '',
309
+ };
310
+
311
+ // Agent Desktop destination type logic
312
+ if ('destinationType' in dataPassed) {
313
+ if (dataPassed.destinationType === 'DN') {
314
+ data.destinationType = CONSULT_TRANSFER_DESTINATION_TYPE.DIALNUMBER;
315
+ } else if (dataPassed.destinationType === 'EP_DN') {
316
+ data.destinationType = CONSULT_TRANSFER_DESTINATION_TYPE.ENTRYPOINT;
317
+ } else {
318
+ // Keep the existing destinationType if it's something else (like "agent" or "Agent")
319
+ // Convert "Agent" to lowercase for consistency
320
+ data.destinationType = dataPassed.destinationType.toLowerCase();
321
+ }
322
+ } else {
323
+ data.destinationType = CONSULT_TRANSFER_DESTINATION_TYPE.AGENT;
324
+ }
325
+
326
+ return {
327
+ interactionId: interactionIdPassed,
328
+ data,
329
+ };
330
+ };
@@ -64,22 +64,6 @@ export const CONNECTIVITY_CHECK_INTERVAL = 5000;
64
64
  */
65
65
  export const CLOSE_SOCKET_TIMEOUT = 16000;
66
66
 
67
- /**
68
- * Constants for participant types, destination types, and interaction states
69
- * @ignore
70
- */
71
- export const PARTICIPANT_TYPES = {
72
- /** Participant type for Entry Point Dial Number */
73
- EP_DN: 'EpDn',
74
- /** Participant type for dial number */
75
- DN: 'dn',
76
- /** Participant type for Agent */
77
- AGENT: 'Agent',
78
- };
79
-
80
- /** Interaction state for consultation */
81
- export const STATE_CONSULT = 'consult';
82
-
83
67
  // Method names for core services
84
68
  export const METHODS = {
85
69
  // WebexRequest methods