Table of Contents

WxCC Widgets

References

My Widgets

Headless Social Auto Answer Widget

This was based on the headless sample provided by Cisco. Most of the code was then removed and then new code was added which uses the Agent Contact Module.

When this headless gadget is added to the Agent's desktop layout - any incoming Social Tasks (e.g. WhatsApp) will get accepted automatically (i.e. enable auto answer for social chats).

Reference: https://github.com/WebexSamples/webex-contact-center-api-samples/tree/main/widget-samples/headless-crm-widget-sample

Headless Social Auto Answer Package

Package: headless-social-autoanswer-widget.zip

If you then want to host the file - copy the ./srv/build/bundle.js file and place it on a public facing web server (and update your Desktop Layout with the new URL) - an example Desktop layout for this headless widget is below.

headless-widget-social-autoanswer.js
import { Desktop } from '@wxcc-desktop/sdk';
 
// This is the logger initializer factory method for the headless widget
export const logger = Desktop.logger.createLogger('headless-social-autoanswer-widget'); 
 
// Some sample data points
let version = 1.00;
 
customElements.define(
  'headless-social-autoanswer-widget',
  class extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
    }
 
  // Mounting the headless widget and initializing
  async connectedCallback() 
  {
    logger.info('Log: Version: ' + version);
    this.init(); 
    logger.info('Log: Webcomponent connectedCallback function');
  }
 
 
  // Init Method - called to configure the WebexCC Desktop JS SDK inside the headless widget
  async init() 
  {  
    await Desktop.config.init();
    logger.info('Log: init function');
    this.registerEventListeners();
  }
 
 
  // This method registers all the event listeners supported by the JS SDK.
  // The event listeners are asynchronous and require handlers within each of the listeners.
  // Sample handlers below are only console logs as examples
  async registerEventListeners()
  {
 
    // Listener for agent contact offered event - Customized by GOR
    Desktop.agentContact.addEventListener('eAgentOfferContact', async (agentContact) => {
      logger.info('Log: Agent Offered Contact');
      //logger.info('Log: Agent Offered Contact: Details: '+ JSON.stringify(agentContact));
 
	  let callOfferedContactDirection = agentContact.data['interaction'].contactDirection.type;
      logger.info('Log: callOffered contactDirection: '+ callOfferedContactDirection);
	  let callOfferedInteractionId = agentContact.data['interaction'].interactionId;
      logger.info('Log: callOfferedInteractionId: '+ callOfferedInteractionId);
      let callOfferedMediaType = agentContact.data['interaction'].mediaType;
      logger.info('Log: callOfferedMediaType: '+ callOfferedMediaType);
 
	  if(callOfferedContactDirection.toLowerCase() === 'inbound' && callOfferedMediaType.toLowerCase() === 'social'){
		logger.info('Log: Incoming Social Task Offered. Let\'s attempt to Auto Answer!');
		let acceptContactResponse = await Desktop.agentContact.accept({interactionId: callOfferedInteractionId});
		//logger.info('Log: acceptContactResponse: '+ JSON.stringify(acceptContactResponse));
 
		try{
		let acceptContactResponseInteractionState = acceptContactResponse.data['interaction'].state;
		//logger.info('Log: acceptResponseInteractionState: '+ acceptContactResponseInteractionState);
		if (acceptContactResponseInteractionState === "connected"){
			logger.info('Log: Accepted Task Successfully. Now connected.');
		}else{
			logger.info('Log: Failed to Accept task? acceptResponseInteractionState: '+ acceptContactResponseInteractionState);
			}
		} catch(error){
		logger.info('Log: acceptResponseInteractionState - error:'+ error);
		}
	  }  
 
    });
 
  } 	
 
  disconnectedCallback() {;}
 
});

Desktop Layout Code snippet

            "headless": {
                "id": "dw-headless",
                "widgets": {
                    "comp1": {
			"comp": "headless-social-autoanswer-widget",
                        "script": "http://localhost:5000/build/bundle.js"
                    }
                },
                "layout": {
                    "areas": [
                        [
                            "comp1"
                        ]
                    ],
                    "size": {
                        "cols": [
                            1
                        ],
                        "rows": [
                            1
                        ]
                    }
                }
            }

Console Logs

Change RONA V2

This Widget is based on Aashish Berry change-rona widget which is located here:

It has 2 enhancements over the original.

Package: change-rona_20260226.7z

change-rona.js
/*
/*
Update on Sample Gadget provided by Aashish Berry (aaberry) - https://github.com/aashishberry/desktopWidgets/tree/main
This version checks BEFORE attempting to make the agent available that the agent state is Idel with Idle Code of 'RONA'
Only then will it allow the agent state to move back to available.
 
This allows an agent to go Idle with different reason code (manually) and the widget will NOT pushed the agent back into available automatically 
It also not allow the gadget to attempt to move the agent into available again even if the agent is already available!
*/
 
import { Desktop } from '@wxcc-desktop/sdk';
 
const logger = Desktop.logger.createLogger('change-ronaV2');
logger.info('Change RONA Widget Loading...');
let initialized = false;
 
class changeRona extends HTMLElement {
 
    constructor() {
        super();
        this.attachShadow({ mode: "open" });
    }
 
    connectedCallback() {
        if (initialized) return; // stop double initialization of Widget
		this.init();
		initialized = true;
    }
 
    disconnectedCallback() {
        Desktop.agentContact.removeAllEventListeners();
        Desktop.agentStateInfo.removeAllEventListeners();
    }
 
    sleep = (delay) => new Promise(r => setTimeout(r, delay));
 
 
    async init() {
		logger.info('init(): Waiting 15 Seconds, the agent needs to complete login within this time for this gadget to work. Otherwise RONA Event Listner does not trigger (I do not know why?)');
        await this.sleep(15000);
        await Desktop.config.init({ widgetName: "change-ronaV2", widgetProvider: "GOR" });
 
		if (this.delaySeconds) {
			logger.info('Delay read from layout: ' + this.delaySeconds + ' seconds.');
			this.delaySeconds = this.delaySeconds * 1000;
		}
		else {
			this.delaySeconds = 10000;
			logger.info('Delay unavailable in layout. Default 10 seconds.');
		}
 
        logger.info("Widget initialized");
        this.agentInteractionEvents();
    }
 
    async agentInteractionEvents() {
		//logger.info(Desktop.agentStateInfo.latestData);
        Desktop.agentContact.addEventListener("eAgentOfferContactRona", () => {
            logger.info('RONA triggered - lets sleep for ' +  this.delaySeconds/1000 + ' seconds before we attempt to move the agent back into Available state');
            this.triggerChange();
        });
 
    }
 
    async triggerChange() {
        await this.sleep(this.delaySeconds);
		logger.info("Our RONA sleep timer has completed.");
        if (Desktop.agentStateInfo.latestData.idleCode.name === 'RONA'){
			logger.info("Agent is in an idle state with an idleCode name of 'RONA', hence we will attempt to move back to Available...");
			try {
				await Desktop.agentStateInfo.stateChange({
					state: 'Available',
					auxCodeIdArray: '0',
				});
				logger.info("Agent State changed to Available!");
			} catch (e) {
				logger.error(e);
			}
		}else{
			logger.info("Agent is no longer in an idle state so we will NOT attempt to move back to Available...");
		}
	}
}
 
window.customElements.define("change-rona", changeRona);