API Docs for: 2.0.20133.2
Show:

File: src\internal\ui\virtualAgent\component.ts

/// <reference path="../../common/sdkConfig.ts"/>
/// <reference path="../../telemetry/telemetry.ts" />
/// <reference path="../../utils/typecheck.ts"/>
/// <reference path="../../utils/url.ts" />
/// <reference path="../constants.ts" />
/// <reference path="../uiComponent.ts" />
/// <reference path="config.ts" />
/// <reference path="constants.ts" />
/// <reference path="sdk.ts" />
/// <reference path="content/content.ts" />

/**
 * @module UI
 * @submodule UI VirtualAgent
 * @namespace ui
 */

/**
 * Virtual Agent UI Module
 * @class virtualAgent
 * @static
 */
namespace internal.ui.virtualAgent {

    const LOAD_TIMEOUT_MS = 15000; // Use this to overwrite the default loaded timeout  
    const REPORT_HEIGHT_CHANGE = false; // set to true to report height change events
    const VIRTUAL_AGENT_PATH = "/contact/virtual-agent/";
    const VIRTUAL_AGENT_REPLAY_PATH = "/contact/virtual-agent/replay";
    const USER_INPUT_MAX_LENGTH = 1024;
    const VIRTUAL_AGENT_EVENT_PREFIX = "VA";
    const VIRTUAL_AGENT_MESSAGE_EVENT_NAME = "VAMessage";
    const VIRTUAL_AGENT_STARTOVER_EVENT_NAME = "VAStartOver";
    const VIRTUAL_AGENT_ENDCHAT_EVENT_NAME = "VAEndChat";
    const VIRTUAL_AGENT_SHOWFEEDBACK_EVENT_NAME = "VAShowFeedback";
    const VIRTUAL_AGENT_COMPONENT = "VirtualAgent";

    /**
     * Render the VirtualAgent UI
     * @method render
     * @static
     * @param {ui.virtualAgent.Config} config A {{#crossLink "ui.virtualAgent.Config"}}{{/crossLink}} object
     * @param {ui.UIInfo} [config.uiInfo] A {{#crossLink "ui.UIInfo"}}{{/crossLink}} object
     * @param {ui.HostType} [config.uiInfo.type] A value in {{#crossLink "ui.HostType"}}{{/crossLink}} which indicates the type of UI to render e.g. IFRAME, POPUP.
     * @param {String} [config.uiInfo.containerSelector] Only required for iframe -- a JQuery selector statement to define the element into which the iframe will be loaded
     * @param {Number} [config.uiInfo.height] The height of the rendered UI
     * @param {Number} [config.uiInfo.width] The width of the rendered UI
     * @return {Promise} A promise that resolves to a {{#crossLink "ui.virtualAgent.SDK"}}{{/crossLink}} object when the UI component has successfully loaded
     * @example
     *
     *     // Render virtualAgent as a POPUP.
     *     // More UIInfo examples available {{#crossLink "ui.UIInfo"}}here{{/crossLink}}
     *     var uiInfo = {
     *         type: {{#crossLink "ui.HostType"}}MsSupportSdk.ui.HostType.POPUP{{/crossLink}},
     *         width: 600,
     *         height: 800
     *     };
     *
     *     // Create a {{#crossLink "ui.chat.Config"}}virtual agent config{{/crossLink}}
     *     var config = {
     *         uiInfo: uiInfo
     *         locale:"en-us"
     *         environment: MsSupportSdk.ui.virtualAgent.Environment.PRODUCTION, // use DEV for testing
     *         onInitialized: function() {
     *             console.log("Virtual Agent initialized");
     *         }
     *      };
     *
     *     // Render virtual agent UI
     *     MsSupportSdk.ui.virtualAgent.render(config).then(
     *         function(vaSDK) {
     *             // See {{#crossLink "ui.virtualAgent.SDK"}}ui.virtualAgent.SDK{{/crossLink}} for details about virtualAgentSDK.
     *             // vaSDK.sendMessage("Test message"); // Send a message to virtual agent
     *         },
     *         function(err) {
     *             console.log(err.message);
     *         });
     */
    export function render(config: Config): JQueryPromise<any> {
        return ui.renderComponent(Component, config, VIRTUAL_AGENT_COMPONENT);
    }

    export class Component extends UIComponent {
        private virtualAgentSDK: SDK;
        private listeners: Map<EventListener>;
        private url: string;

        constructor(config: Config) {
            if (!config) {
                throw new Error("config is a mandatory parameter");
            }
            config.environment = config.environment || virtualAgent.Environment.PRODUCTION;
            verifyConfig(config);
            super(config, LOAD_TIMEOUT_MS, REPORT_HEIGHT_CHANGE);
        }

        public getComponentUrl(): string {
            return this.url || (this.url = getVirtualAgentUrl(<Config>this.config));
        }

        public getComponentSdk(): SDK {
            if (!this.virtualAgentSDK) {
                this.virtualAgentSDK = {
                    sendMessage: (message: any) => sendMessage(this.proxy, message),
                    startOver: () => startOver(this.proxy),
                    endChat: () => endChat(this.proxy),
                    showFeedback: () => showFeedback(this.proxy)
                };
            }
            return this.virtualAgentSDK;
        }

        public getXframeProxyUrl(): string {
            return `${utils.getOriginFromUrl(this.getComponentUrl())}/xframeproxy/`;
        }

        protected getEventListeners(): Map<EventListener> {
            if (!this.listeners) {
                // get event listeners from virtualAgentConfig
                this.listeners = UIComponent.getEventListeners(this.config, VIRTUAL_AGENT_EVENT_PREFIX);

                // get event listeners from extensionConfig and merge with virtual agent event listeners
                if ((<Config>this.config).content && (<Config>this.config).content.flowExtensionOption) {
                    let extensionConfig = (<Config>this.config).content.flowExtensionOption;
                    let extensionListeners = UIComponent.getEventListeners(extensionConfig);
                    jQuery.extend(this.listeners, extensionListeners);
                }
            }

            return this.listeners;
        }
    }

    function sendMessage(proxy: proxy.SdkClientProxy, message: any): JQueryPromise<any> {
        if (message.length > USER_INPUT_MAX_LENGTH) {
            return jQuery.Deferred().reject();
        }
        else {
            proxy.dispatchEvent(VIRTUAL_AGENT_MESSAGE_EVENT_NAME, message);
            return jQuery.Deferred().resolve();
        }
    }

    function startOver(proxy: proxy.SdkClientProxy): void {
        proxy.dispatchEvent(VIRTUAL_AGENT_STARTOVER_EVENT_NAME, undefined);
    }

    function endChat(proxy: proxy.SdkClientProxy): void {
        proxy.dispatchEvent(VIRTUAL_AGENT_ENDCHAT_EVENT_NAME, undefined);
    }

    function showFeedback(proxy: proxy.SdkClientProxy): void {
        proxy.dispatchEvent(VIRTUAL_AGENT_SHOWFEEDBACK_EVENT_NAME, undefined);
    }

    function verifyConfig(config: Config): void {
        utils.verifyString("environment", config.environment, true);
        utils.verifyString("locale", config.locale, true);
    }

    function getVirtualAgentUrl(config: Config): string {
        let url = "https://" + config.environment + "/" + config.locale;
        let values = {};
        if (config.replayInfo) {
            url += VIRTUAL_AGENT_REPLAY_PATH;

            if (config.replayInfo.visidId && config.replayInfo.visidId === "UC_REPLAY_REQUIRED") {
                config.replayInfo.userToken = config.replayInfo.engagementId;
                values = parseVirtualAgentConfig(config);
            }
        }
        else {
            url += VIRTUAL_AGENT_PATH;
            values = parseVirtualAgentConfig(config);
        }
        return utils.appendParams(url, values, true);
    }

    function parseVirtualAgentConfig(config: Config): any {
        let values: any = {};

        if (config.flights && utils.isString(config.flights)) {
            values["flighting"] = encodeURIComponent(config.flights);
        }

        if (config.preview && utils.isBoolean(config.preview)) {
          values["sky.preview"] = encodeURIComponent(String(config.preview));
        }

        if (config.areaId && utils.isString(config.areaId)) {
            values["area"] = encodeURIComponent(config.areaId);
        }

        if (config.flowId && utils.isString(config.flowId)) {
            values["flowId"] = encodeURIComponent(config.flowId);
        }

        if (config.queryParams && utils.isString(config.queryParams)) {
            let splitQueryParams = config.queryParams.split("&");
            for (let queryParam of splitQueryParams) {
                let queryParamParts = queryParam.split("=");
                if (queryParamParts.length !== 2) {
                    continue;
                }
                values[encodeURIComponent(queryParamParts[0])] = encodeURIComponent(queryParamParts[1]);
            }
        }

        return values;
    }
}