API Docs for: 2.0.20133.2
Show:

File: src\internal\ui\Survey\survey.ts

/// <reference path="./surveyResponseConfig.ts" />
/// <reference path="../../telemetry/eventData.ts" />
/// <reference path="surveyConfig.ts" />
/// <reference path="component.ts" />
/// <reference path="../../packages.ts" />
/// <reference path="../../api/modalities/callbackModality.ts" />
/// <reference path="../../telemetry/awa/eventWriter.ts" />
/// <reference path="../../telemetry/telemetry.ts" />
/// <reference path="../../utils/modality.ts" />
/// <reference path="../../utils/object.ts" />
/// <reference path="../constants.ts" />
/// <reference path="config.ts" /> 
/// <reference path="surveyOfferBuilder.ts" /> 
/// <reference path="surveyResponseBuilder.ts" /> 
/// <reference path="surveyRequestConfig.ts" /> 
/// <reference path="surveyModel.ts" /> 

namespace internal.ui.survey {
    // AWA Logging Cosntants
    const AWA_PAGE_NAME = "WebSDK";
    const AWA_BEHAVIOR_SUBMIT_SURVEY = 142; // awa.behavior.SurveyComplete
    const AWA_BEHAVIOR_SURVEY_INITIATE = 141; // awa.behavior.SurveyInitiate
    const AWA_ACTION_TYPE_AUTOMATIC = "A";

    const SURVEY_COMPONENT = "Survey";

    const SURVEY_PLATFORM_PROD = "survey.support.services.microsoft.com";

     /**
     * Class that defines operations that can be performed on a survey
     * @class Survey
     * @constructor
     */
    export class Survey {

        private surveyConfig: SurveyConfig;
        private responseId: string;

        /**
         * Create a survey instance
         * @class Survey
         * @constructor
         * @param {ui.survey.SurveyConfig} config A {{#crossLink "ui.survey.SurveyConfig"}}{{/crossLink}} class to configure this instance and all subsequent survey calls
         * @example
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         */
        constructor(config: SurveyConfig) {
            this.surveyConfig = utils.cloneObject({}, config);
            this.responseId = utils.createFormattedGuid();
        }

        /**
         * Returns the response ID for this survey isntance.
         * @method getResponseId
         * @return {string} The response ID set for this survey instance
         * @example
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         *     var responseId = survey.getResponseId();
         */
        getResponseId(): string {
            return this.responseId;
        }

        /**
         * Log a survey offer
         * @method logOfferResponse
         * @param {string} offerState The {{#crossLink "ui.survey.OfferState"}}{{/crossLink}} offer state
         * @example
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         *     survey.logOfferResponse(window.MsSupportSdk.ui.survey.OfferState.DISPLAYED);
         */
        logOfferResponse(offerState: string) {
            let surveyOfferBuilder = new SurveyOfferBuilder();
            let awaEvent = surveyOfferBuilder.createSurveyOffer(this.responseId, this.surveyConfig, offerState);
            telemetry.awa.writeAwaEvent(awaEvent);

            let content: any = {
                responseId: this.responseId,
                partnerId: internal.SdkConfig.current.partnerId,
                surveyId: this.surveyConfig.surveyId,
                locale: this.surveyConfig.locale,
                flightId: this.surveyConfig.flightId,
                offerState: offerState,
                partnerContextJson: this.surveyConfig.partnerContext
            };

            let overrideValues: any = {
                appId: awaEvent.appId,
                behavior: AWA_BEHAVIOR_SURVEY_INITIATE,
                Uri: window.location.href,
                referrerUri: document.referrer,
                pageName: AWA_PAGE_NAME,
                actionType: AWA_ACTION_TYPE_AUTOMATIC, // automatic. Alternative could be C or CL (click / left click)
                pageHeight: window.innerHeight,
                content: content // Automatically strigified by awa
            };

            // JSLL4 is required for AWA logging, otherwise this event will be dropped.
            let awaInstance = internal.telemetry.getAwaInstance();

            if (awaInstance && awaInstance.ct && awaInstance.ct.captureContentPageAction instanceof Function) {
                awaInstance.ct.captureContentPageAction(overrideValues);
            }
        }

        /**
         * Render the Survey UI
         * @method render
         * @param {ui.survey.Config} config A {{#crossLink "ui.survey.Config"}}{{/crossLink}} object
         * @return {Promise} A promise that resolves to a {{#crossLink "ui.survey.SDK"}}{{/crossLink}} object when the UI component has successfully loaded
         * @example
         *
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         * 
         *     // Please handle survey offers in addition to this
         *     var surveyRenderConfig = {
         *       "preview": false,
         *       "viewMode": "wizard",
         *       "environment": "https://survey.support.services.microsoft.com/viewsurvey.html",
         *       "surveyPlatformEnvironment": "production",
         *       "uiInfo": {
         *         "type": 1,
         *         "containerSelector": "#iframe_container"
         *       }
         *     }; 
         * 
         *     survey.render(surveyRenderConfig);
         */
        render(config: Config): JQueryPromise<any> {
            // Note we bypass renderComponent due to the requirement to pass multiple config objects
            return telemetry.captureIncomingRequestAsync(
                (qos: telemetry.QosEventData): JQueryPromise<any> => {
                    return new Component(this.surveyConfig, config, this.responseId).render();
                },
                internal.ui.RENDER_OPERATION_NAME,
                SURVEY_COMPONENT,
                config.uiInfo);
        }

        /**
         * Log a survey response
         * @method logSurveyResponse
         * @param {ui.survey.surveyResponseConfig} config A {{#crossLink "ui.survey.SurveyResponseConfig"}}{{/crossLink}} object
         * @example
         *
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         * 
         *     // Log a survey response. It is suggested you first get the survey before logging a response
         *     var config = {
         *       "mode": "mode",                    // Mode of the submitted survey (from the survey platform)
         *       "quality": "good"                  // Quality of the submitted survey. poor | good. Set to poor to ignore the data during reports.
         *       "type": "site"                     // Type of the survey. site | email
         *       "locale": "en-us",                 // Locale of the submitted survey
         *       "isPartialResponse": true,         // Set to true if the survey is partially completed. Otherwise set to false
         *       "displayTime": 2017-07-14T22:29:37.714Z,  // Time the survey was displayed to the user (NOT the current time)
         *       "partnerContext": "{c1:true}",     // Partner context data (any JSON KVP)
         *       "surveyResponse": [{               // A collection of  {{#crossLink "ui.survey.SurveyQuestionConfig"}}
         *         "questionId": 1,                 // ID of the submitted question (from the survey platform)
         *         "questionDisplayIndex": 0,       // 0 based index of the question display order
         *         "questionCategory": "CSAT",      // Category of the question (from the survey platform)
         *         "percannedResponse": 0,          // either a precanned response (preset ID for an option from the survey platform)
         *         "verbatim": "Your site rules",   // or a verbatim response (freeform text) should be provided
         *       ]}
         *     }; 
         * 
         *     survey.logSurveyResponse(config);
         */
        logSurveyResponse(responseConfig: SurveyResponseConfig) {
            let surveyResponseBuilder = new SurveyResponseBuilder();
            let awaEvent = surveyResponseBuilder.createSurveyResponse(this.responseId, responseConfig, this.surveyConfig);
            telemetry.awa.writeAwaEvent(awaEvent);

            let content = {
                responseId: this.responseId,
                partnerId: internal.SdkConfig.current.partnerId,
                surveyId: this.surveyConfig.surveyId,
                flightId: responseConfig.flightId,
                mode: responseConfig.mode,
                quality: responseConfig.quality,
                type: responseConfig.type,
                locale: this.surveyConfig.locale,
                isPartialResponse: responseConfig.isPartialResponse,
                displayTime: responseConfig.displayTime,
                surveyResponseJson: responseConfig.surveyResponse,
                partnerContextJson: this.surveyConfig.partnerContext
            };

            let overrideValues: any = {
                appId: awaEvent.appId,
                behavior: AWA_BEHAVIOR_SUBMIT_SURVEY,
                Uri: window.location.href,
                referrerUri: document.referrer,
                pageName: AWA_PAGE_NAME,
                actionType: AWA_ACTION_TYPE_AUTOMATIC, // automatic. Alternative could be C or CL (click / left click)
                pageHeight: window.innerHeight,
                content: content // Automatically strigified by awa
            };

            // JSLL4 is required for AWA logging, otherwise this event will be dropped.
            let awaInstance = internal.telemetry.getAwaInstance();

            if (awaInstance && awaInstance.ct && awaInstance.ct.captureContentPageAction instanceof Function) {
                awaInstance.ct.captureContentPageAction(overrideValues);
            }
        }

        /**
         * Get survey data
         * @method getSurveyData
         * @param [requestConfig=""] {ui.survey.SurveyRequestConfig} requestConfig A {{#crossLink "ui.survey.SurveyRequestConfig"}}{{/crossLink}} object
         * @return {Promise} A promise that resolves to a {{#crossLink "ui.survey.SurveyModel"}}{{/crossLink}} object when response has been received
         * @example
         *
         *     var surveyConfig = {
         *       "surveyId": "integrationsurvey",
         *       "locale": "en-us"
         *     };
         *  
         *     var survey = window.MsSupportSdk.ui.survey.createSurvey(surveyConfig);
         * 
         *     var requestConfig = {
         *       "preview": true                    // Optional Set to true to return preview survey data
         *       "surveyPlatformHostName": "survey.com"   // Optional hostname for the survey platform
         *     }; 
         * 
         *     // config is optional
         *     survey.getSurveyData(requestConfig).then(
         *       function(data) {
         *         console.log("Survey data loaded. See survey platform documentation for details");
         *       },
         *       function(err) {
         *         console.log(err);
         *       });
         */
        getSurveyData(requestConfig?: SurveyRequestConfig): JQueryPromise<SurveyModel> {
            // Setup the deferral
            let deferred = jQuery.Deferred();

            // Fail early if parameters do not match.
            if (!(this.surveyConfig && this.surveyConfig.locale && this.surveyConfig.surveyId)) {
                deferred.reject("Invalid Parameters. Missing Locale or Survey ID.");
                return deferred;
            }
            // Build the survey platform URL
            let surveyHostName = (requestConfig && requestConfig.surveyPlatformHostName) || SURVEY_PLATFORM_PROD;
            let surveyPlatformUrl = `https://${surveyHostName}/surveyplatform/api/v1/locale/${this.surveyConfig.locale}/partner/${internal.SdkConfig.current.partnerId}/survey/${this.surveyConfig.surveyId}`;

            if (this.surveyConfig.flightId) {
                surveyPlatformUrl += `/flight/${this.surveyConfig.flightId}`;
            }

            if (requestConfig && requestConfig.preview) {
                surveyPlatformUrl += `/preview/${requestConfig.preview}`;
            }

            // Get the survey data
            let requestOptions: internal.HttpRequestOptions = {
                url: surveyPlatformUrl,
                operationName: "WebSdkGetSurveyData",
                dependencyName: "SurveyPlatform",
                dependencyOperationName: "getSurvey"
            };

            utils.httpRequest.get(requestOptions).then((result) => {
                let surveyData: SurveyModel = result;

                if (this.validateSurveyData(surveyData)) {
                    deferred.resolve((surveyData));
                }
                else {
                    deferred.reject("Survey response failed basic validation.");
                }
            }).fail((xhr) => {
                deferred.reject(xhr.responseText);
            });

            return deferred;
        }

        private validateSurveyData(surveyData: SurveyModel) {
            return surveyData &&
                surveyData.description &&
                surveyData.flights &&
                surveyData.flights[0] &&
                surveyData.flights[0].flightId &&
                surveyData.flights[0].mode &&
                surveyData.flights[0].questions &&
                surveyData.flights[0].questions[0] &&
                surveyData.flights[0].title;
        }
    }
}