feat(contact-center): wxcc-6026 wxapp answer, mute sync, dtmf keypad - #734
feat(contact-center): wxcc-6026 wxapp answer, mute sync, dtmf keypad#734akulakum wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5158542d05
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (taskId && !this.wxAppMuteStateListeners[taskId]) { | ||
| const wxAppMuteListener = (payload: {muted: boolean}) => this.handleWxAppMuteStateUpdated(payload, task); | ||
| this.wxAppMuteStateListeners[taskId] = wxAppMuteListener; | ||
| task.on(TASK_EVENTS.TASK_WXAPP_MUTE_STATE_UPDATED, wxAppMuteListener); |
There was a problem hiding this comment.
Rebind the mute listener when the SDK replaces a task
When TASK_HYDRATE or TASK_MERGED supplies a replacement task object with the same interaction ID, registerTaskEventListeners is called again, but this ID-only guard skips attaching the mute listener to the replacement. Subsequent TASK_WXAPP_MUTE_STATE_UPDATED events emitted by the new task therefore never update store.isMuted, and removal also tries to detach the callback from the wrong task object. Track both the task and listener and detach/rebind when the task identity changes, as the adjacent real-time-assist listener does.
Useful? React with 👍 / 👎.
|
|
||
| handleTaskEnd = () => { | ||
| this.setIsDeclineButtonEnabled(false); | ||
| this.setIsMuted(false); |
There was a problem hiding this comment.
Reset mute only when the current task ends
In a multi-task session, every task is registered with the same handleTaskEnd callback, so ending a background or digital task while the current wxApp call is muted unconditionally resets the global mute state. The UI then shows the active call as unmuted, and the next toggle derives muted: true instead of unmuting it. Pass the ending task identity into the handler or defer the reset to the existing current-task-aware removal path.
Useful? React with 👍 / 👎.
| | 'toggleHold' | ||
| | 'toggleRecording' | ||
| | 'toggleMute' | ||
| | 'sendDtmf' |
There was a problem hiding this comment.
Keep the new DTMF callback backward-compatible
Any external consumer that directly renders the published CallControlComponent or CallControlCADComponent now fails type checking unless it supplies sendDtmf, even for calls where the keypad is never visible, because CallControlComponentProps is exported and the newly picked field is required. Make this callback optional with a safe default, or treat and document the change as a breaking major-version contract update.
Useful? React with 👍 / 👎.
| if (isWxAppCallingOffer(task) && typeof wxTask.acceptOnWebex === 'function') { | ||
| return wxTask.acceptOnWebex(); |
There was a problem hiding this comment.
Route the new wxApp operations through the store
For wxApp accept, reject, mute, and DTMF paths, this widget-package utility directly invokes newly duck-typed SDK task methods, moving SDK compatibility and dispatch outside the repository's sole SDK boundary. Expose these operations and their types from @webex/cc-store instead so SDK upgrades remain isolated to the store rather than coupling @webex/cc-task to the SDK.
AGENTS.md reference: AGENTS.md:L61-L62
Useful? React with 👍 / 👎.
| @@ -0,0 +1,37 @@ | |||
| import React from 'react'; | |||
There was a problem hiding this comment.
Update the cc-components spec for the keypad surface
This change adds a new cc-components keypad and changes the exported CallControl prop surface, but only the task and store module specs were updated; packages/contact-center/cc-components/ai-docs/cc-components-spec.md remains unchanged. Update the owning module spec and public-contract documentation in this change so consumers and validators do not retain the old CallControl contract.
AGENTS.md reference: AGENTS.md:L68-L68
Useful? React with 👍 / 👎.
|
This pull request is automatically being deployed by Amplify Hosting (learn more). |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5fe744901a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (isWxAppCallingOffer(task) && typeof wxTask.acceptOnWebex === 'function') { | ||
| return wxTask.acceptOnWebex(); | ||
| } | ||
| return task.accept(); |
There was a problem hiding this comment.
Bump the SDK before routing wxApp calls
When this commit is installed as-is, packages/contact-center/store/package.json remains pinned to @webex/contact-center 3.12.0-next.96 even though these methods and the new mute event come from the required companion SDK change. Because this helper duck-types the missing surface, wxApp offers silently fall through to the legacy accept()/decline() paths, mute falls through to toggleMute(), and DTMF becomes a no-op rather than exposing the incompatible dependency. Update the pinned SDK and lockfile to a release containing the new APIs before enabling these routes.
AGENTS.md reference: AGENTS.md:L56-L57
Useful? React with 👍 / 👎.
| if (!getKeypadControl(controls)?.isVisible) { | ||
| logger.warn('Keypad control not available', {module: 'useCallControl', method: 'sendDtmf'}); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Honor the keypad enabled state before sending tones
If the SDK updates keypad controls to {isVisible: true, isEnabled: false} while its popover is already open, the trigger becomes disabled but the rendered digit buttons remain clickable. This guard checks only isVisible, so those clicks still call transmitDtmfForTask() despite the SDK explicitly disabling DTMF; check isEnabled here and/or disable the individual keys.
Useful? React with 👍 / 👎.
| | `ai-docs/_archive/.../task/ai-docs/widgets/TaskList/AGENTS.md` + `ARCHITECTURE.md` | architecture / overview / API | reconciled | Task selection / accept / decline flow → Sequence Diagram(s). | | ||
| | `packages/contact-center/ai-docs/migration/*.md` (7 files) | architecture (planned refactor) | reference-only | Describes a planned SDK `task.uiControls` migration that is NOT in current code. Used only to mark conflicts; current behavior documented as-is. | | ||
| | `packages/contact-center/task/src/` | source of truth | migrated | All requirements, flows, state, and error tables derive from real code here. | | ||
| | `packages/contact-center/ai-docs/features/thick-client-answer/intake.md` | feature intake (WXCC-6026) | reference-only (implemented) | wxApp Answer/Decline/Mute + Mercury mute sync — see § Feature: Accept on Webex thick client | |
There was a problem hiding this comment.
Commit the canonical intake before linking it
The newly declared canonical intake resolves to packages/contact-center/ai-docs/features/thick-client-answer/intake.md, but a repository-wide filename and WXCC-6026 search finds no such file or generated equivalent. Consequently the task and store specs both direct maintainers and validators to nonexistent feature evidence; add the intake in this change or retain the existing source-of-truth entry instead.
AGENTS.md reference: AGENTS.md:L68-L68
Useful? React with 👍 / 👎.
COMPLETES WXCC-6026
This pull request addresses
Third-party CRM embeds need Answer on Webex: agents working in Contact Center widgets should accept, decline, mute, and send DTMF from the embed while Webex App (thick client) handles telephony on the same machine and user.
This widgets PR wires the UI and store layer to the new SDK wxApp telephony APIs. Widgets do not call usersub or Mercury directly — that is SDK-owned.
by making the following changes
@webex/cc-taskacceptOnWebex()/rejectOnWebex()instead of standard task accept/decline.wxapp-task.utils.ts— shared helpers (isWxAppEngagedCall,toggleMuteForTask, accept/decline routing).toggleMuteOnWebex({ muted })with explicit UI intent (fixes Mercury desync); DTMF viatransmitDtmfOnWebex().store.taskListso Accept stays enabled when uiControls update.task-spec.md(spec-currency).@webex/cc-storeTASK_WXAPP_MUTE_STATE_UPDATEDper task;handleWxAppMuteStateUpdated→setIsMuted()when task iscurrentTask.handleTaskRemove(prevent duplicate/stale listeners).store-spec.md(spec-currency).@webex/cc-componentsSample app (
widgets-samples/cc/samples-cc-react-app)store.isAgentLoggedIn.store.cc.setManageWebexCallingInWxcc()(usersub publish in SDK).Change Type
The following scenarios were tested
Automated (unit):
@webex/cc-task— wxApp accept/decline routing,toggleMuteForTask, CallControl mute/DTMF, IncomingTask live task resolution@webex/cc-store—TASK_WXAPP_MUTE_STATE_UPDATEDlistener attach/detach,handleWxAppMuteStateUpdated@webex/cc-components— CallControl snapshots and utilsManual (end-to-end, with SDK #5167):
false(toast suppression cleared)The GAI Coding Policy And Copyright Annotation Best Practices
Checklist before merging
Merge order: Merge SDK PR #5167 first (or bump
@webex/contact-centerin store before release). Widgets depend on SDK wxApp methods,TASK_WXAPP_MUTE_STATE_UPDATED, andsetManageWebexCallingInWxcc().Make sure to have followed the contributing guidelines before submitting.