diff --git a/docs/samples/contact-center/app.js b/docs/samples/contact-center/app.js index ab0a2b55b83..58ba7973b82 100644 --- a/docs/samples/contact-center/app.js +++ b/docs/samples/contact-center/app.js @@ -26,6 +26,7 @@ const saveElm = document.querySelector('#access-token-save'); const authStatusElm = document.querySelector('#access-token-status'); const oauthFormElm = document.querySelector('#oauth'); const oauthStatusElm = document.querySelector('#oauth-status'); +const disableWebRTCRegistrationElm = document.querySelector('#disable-webrtc-registration'); const registerBtn = document.querySelector('#webexcc-register'); const deregisterBtn = document.querySelector('#webexcc-deregister'); const teamsDropdown = document.querySelector('#teamsDropdown'); @@ -405,7 +406,14 @@ function initOauth() { } webex = window.webex = Webex.init({ - config: webexConfig + config: { + ...webexConfig, + cc: { + ...(webexConfig.cc || {}), + allowMultiLogin: true, + disableWebRTCRegistration: disableWebRTCRegistrationElm?.checked === true, + }, + } }); localStorage.setItem('OAuth', true); @@ -1878,7 +1886,14 @@ function initWebex(e) { } webex = window.webex = Webex.init({ - config: webexConfig, + config: { + ...webexConfig, + cc: { + ...(webexConfig.cc || {}), + allowMultiLogin: true, + disableWebRTCRegistration: disableWebRTCRegistrationElm?.checked === true, + }, + }, credentials: { access_token: tokenElm.value } diff --git a/docs/samples/contact-center/index.html b/docs/samples/contact-center/index.html index 7dc7cb5b191..4479630aacb 100644 --- a/docs/samples/contact-center/index.html +++ b/docs/samples/contact-center/index.html @@ -72,6 +72,12 @@

Not Logged In.

+
+ +
diff --git a/packages/@webex/contact-center/src/cc.ts b/packages/@webex/contact-center/src/cc.ts index f640c2aa137..b483da52f02 100644 --- a/packages/@webex/contact-center/src/cc.ts +++ b/packages/@webex/contact-center/src/cc.ts @@ -724,6 +724,15 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter } } + /** + * Checks whether WebRTC registration should be skipped by config. + * @returns {boolean} + * @private + */ + private isWebRTCRegistrationDisabled(): boolean { + return this.$config?.disableWebRTCRegistration === true; + } + /** * Connects to the websocket and fetches the agent profile * @returns {Promise} Agent profile information @@ -785,7 +794,8 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter if ( this.agentConfig.webRtcEnabled && - this.agentConfig.loginVoiceOptions.includes(LoginOption.BROWSER) + this.agentConfig.loginVoiceOptions.includes(LoginOption.BROWSER) && + !this.isWebRTCRegistrationDisabled() ) { try { await this.$webex.internal.mercury.connect(); @@ -799,6 +809,14 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter method: METHODS.CONNECT_WEBSOCKET, }); } + } else if (this.isWebRTCRegistrationDisabled()) { + LoggerProxy.info( + 'Skipping Mobius registration because disableWebRTCRegistration is enabled', + { + module: CC_FILE, + method: METHODS.CONNECT_WEBSOCKET, + } + ); } if (this.$config && this.$config.allowAutomatedRelogin) { @@ -883,8 +901,24 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter }, }); - if (this.agentConfig.webRtcEnabled && data.loginOption === LoginOption.BROWSER) { + if ( + this.agentConfig.webRtcEnabled && + data.loginOption === LoginOption.BROWSER && + !this.isWebRTCRegistrationDisabled() + ) { await this.webCallingService.registerWebCallingLine(); + } else if ( + this.agentConfig.webRtcEnabled && + data.loginOption === LoginOption.BROWSER && + this.isWebRTCRegistrationDisabled() + ) { + LoggerProxy.info( + 'Skipping web calling line registration because disableWebRTCRegistration is enabled', + { + module: CC_FILE, + method: METHODS.STATION_LOGIN, + } + ); } const resp = await loginResponse; @@ -1391,6 +1425,16 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter this.agentConfig.deviceType = deviceType; switch (deviceType) { case LoginOption.BROWSER: + if (this.isWebRTCRegistrationDisabled()) { + LoggerProxy.info( + 'Skipping web calling line registration because disableWebRTCRegistration is enabled', + { + module: CC_FILE, + method: METHODS.HANDLE_DEVICE_TYPE, + } + ); + break; + } try { await this.webCallingService.registerWebCallingLine(); } catch (error) { diff --git a/packages/@webex/contact-center/src/disable-webrtc-config.md b/packages/@webex/contact-center/src/disable-webrtc-config.md new file mode 100644 index 00000000000..47b2fa384da --- /dev/null +++ b/packages/@webex/contact-center/src/disable-webrtc-config.md @@ -0,0 +1,212 @@ +# Disable WebRTC Registration Config - Detailed Spec + +## Objective + +Add a Contact Center SDK configuration flag, `disableWebRTCRegistration`, read from `Webex.init({ config: { cc: ... }})`, to control whether Mobius/WebRTC registration is performed for browser login flows. + +This preserves existing behavior by default and allows consumers to explicitly disable WebRTC registration when needed. + +## Configuration Contract + +### Input location + +The flag is provided through: + +`Webex.init({ config: { cc: { disableWebRTCRegistration: true }}})` + +### Flag definition + +- Name: `disableWebRTCRegistration` +- Type: `boolean` +- Default: `false` when omitted +- Scope: Contact Center plugin configuration (`cc` config object) + +### Effective rule + +WebRTC/Mobius registration must happen only when: + +- browser station login path applies (`loginOption === LoginOption.BROWSER` where relevant), and +- `disableWebRTCRegistration !== true` + +## Functional Behavior Changes + +### 1) Registration-time Mobius connect gate + +In `register()` inside `packages/@webex/contact-center/src/cc.ts`, current behavior attempts `this.$webex.internal.mercury.connect()` when: + +- `agentConfig.webRtcEnabled` is true, and +- `agentConfig.loginVoiceOptions` includes `LoginOption.BROWSER` + +Enhancement: + +- Add config gate so `mercury.connect()` is skipped when `disableWebRTCRegistration === true`. + +Effective condition: + +- `agentConfig.webRtcEnabled` +- `agentConfig.loginVoiceOptions.includes(LoginOption.BROWSER)` +- `this.$config?.disableWebRTCRegistration !== true` + +### 2) Station login browser calling line registration gate + +In `stationLogin(data)` in `cc.ts`, current behavior registers calling line when: + +- `agentConfig.webRtcEnabled` is true, and +- `data.loginOption === LoginOption.BROWSER` + +Enhancement: + +- Add config gate so `this.webCallingService.registerWebCallingLine()` is skipped when `disableWebRTCRegistration === true`. + +Effective condition: + +- `agentConfig.webRtcEnabled` +- `data.loginOption === LoginOption.BROWSER` +- `this.$config?.disableWebRTCRegistration !== true` + +### 3) Device-type handling gate for browser flows + +In `handleDeviceType(deviceType, dn)` in `cc.ts`, current behavior calls `registerWebCallingLine()` for `LoginOption.BROWSER`. + +Enhancement: + +- Add config gate so browser device type does **not** register WebRTC line when `disableWebRTCRegistration === true`. +- This ensures consistency for all browser device-type transitions (including update/relogin paths that route through `handleDeviceType`). + +Effective condition for BROWSER case: + +- `deviceType === LoginOption.BROWSER` +- `this.$config?.disableWebRTCRegistration !== true` + +If config is true, skip registration and continue method flow without throwing. + +## Default/Backward Compatibility + +- When `disableWebRTCRegistration` is omitted or `false`, behavior remains unchanged. +- Existing browser login and WebRTC registration paths continue to function exactly as today. +- No change to non-browser login options (`AGENT_DN`, `EXTENSION`) behavior. + +## Sample App Changes + +Files: + +- `docs/samples/contact-center/index.html` +- `docs/samples/contact-center/app.js` + +### UI change in sample (`index.html`) + +Add a new unchecked toggle (checkbox) in the authentication/config area: + +- Label: `Disable WebRTC Registration` +- Element id (proposed): `disable-webrtc-registration` +- Default: unchecked (preserves current behavior) + +### Config wiring in sample (`app.js`) + +#### Read toggle state + +- Query the new checkbox element and read `checked` value at init time. + +#### Pass flag to SDK init + +Both init paths in the sample should pass the flag: + +- token-based init (`initWebex`) +- OAuth init (`initOauth`) + +Required init shape: + +`Webex.init({ config: { ...webexConfig, cc: { disableWebRTCRegistration: }}, ... })` + +Notes: + +- Preserve existing `webexConfig` generation and env-dependent service overrides. +- Ensure `cc` config merge does not clobber other `config` fields. +- Boolean value should map directly from checkbox state. + +## Proposed Implementation Details (SDK) + +### Types/config + +Update Contact Center plugin config typing to include: + +- `disableWebRTCRegistration?: boolean` + +This should be part of the existing config type consumed by `this.$config` in `cc.ts`. + +### Helper (recommended) + +To avoid repeating inline checks, add a private helper in `cc.ts`: + +- `private isWebRTCRegistrationDisabled(): boolean` +- Returns `this.$config?.disableWebRTCRegistration === true` + +Use this helper in all three touchpoints (`register`, `stationLogin`, `handleDeviceType`). + +### Logging (recommended) + +Add informational logs when registration is intentionally skipped due to config, e.g.: + +- "Skipping Mobius/WebRTC registration because disableWebRTCRegistration is enabled" + +This helps debugging without treating it as an error condition. + +## Behavior Matrix + +| webRtcEnabled | Login option / capability context | disableWebRTCRegistration | Expected behavior | +| --- | --- | --- | --- | +| false | any | false/true/unset | No Mobius/WebRTC line registration | +| true | non-BROWSER login path | false/true/unset | No browser calling line registration | +| true | BROWSER-capable/path | unset | Register Mobius/WebRTC (existing behavior) | +| true | BROWSER-capable/path | false | Register Mobius/WebRTC (existing behavior) | +| true | BROWSER-capable/path | true | Skip Mobius/WebRTC registration | + +## Acceptance Criteria + +1. `disableWebRTCRegistration` is read from `Webex.init({ config: { cc: ... }})`. +2. If flag is `true`, SDK does not: + - call `webex.internal.mercury.connect()` in registration path for browser WebRTC capability. + - call `registerWebCallingLine()` during browser `stationLogin`. + - call `registerWebCallingLine()` for browser branch in `handleDeviceType`. +3. If flag is `false` or omitted, current behavior is unchanged. +4. Sample app includes a new unchecked toggle and passes the value into `Webex.init` as `config.cc.disableWebRTCRegistration` in both auth flows. +5. No regressions for non-browser station login types. + +## Test Plan + +### SDK behavior validation + +1. **Default path (flag omitted)** + - Initialize SDK without `config.cc.disableWebRTCRegistration`. + - Perform browser station login. + - Verify Mobius/WebRTC registration path executes (current behavior). + +2. **Explicit false** + - Initialize with `disableWebRTCRegistration: false`. + - Perform browser station login. + - Verify Mobius/WebRTC registration still executes. + +3. **Explicit true** + - Initialize with `disableWebRTCRegistration: true`. + - Perform browser station login. + - Verify no Mobius connect / no calling line registration; station login still succeeds for non-calling concerns. + +4. **Non-browser login** + - Use `AGENT_DN` or `EXTENSION` login with flag true/false. + - Verify existing non-browser behavior unchanged. + +5. **Profile/device type update path** + - Trigger flow that reaches `handleDeviceType(LoginOption.BROWSER, ...)`. + - With flag true, verify no calling line registration attempt. + +### Sample app validation + +1. Toggle unchecked (default), init via token and OAuth; verify existing behavior. +2. Toggle checked, init via token and OAuth; verify `Webex.init` receives `config.cc.disableWebRTCRegistration: true`. +3. Confirm setting toggles behavior without other init regressions. + +## Out of Scope + +- Changing server-side station-login semantics. +- Altering WebRTC capability (`webRtcEnabled`) determination logic. +- Adding new APIs/events beyond config-driven registration gating. diff --git a/packages/@webex/contact-center/src/types.ts b/packages/@webex/contact-center/src/types.ts index 91a66207030..4024c2c6501 100644 --- a/packages/@webex/contact-center/src/types.ts +++ b/packages/@webex/contact-center/src/types.ts @@ -156,6 +156,8 @@ export interface CCPluginConfig { }; /** Configuration for the calling client */ callingClientConfig: CallingClientConfig; + /** Whether to skip Mobius/WebRTC registration for browser login flows */ + disableWebRTCRegistration?: boolean; } /**