Deflecting Support Cases

With Coveo for Microsoft Dynamics 365 deployed in your portal, any query entered in the portal search box is processed by Coveo (see Deploying Coveo for Microsoft Dynamics 365 in a Portal). Your portal users are therefore provided with search results consisting of the most relevant content, regardless of its source.

However, if your portal users do not try and use the search box to find an answer to their questions, they might not come across the content they need and turn to your customer support team for help. To prevent your portal users from creating a support case when the solution to their issue is available on your portal, you can implement a Coveo for Microsoft Dynamics 365 case deflection interface anticipating your users’ needs and proactively providing helpful content. This interface ensures that users self-serve rather than create a support case whenever possible, which should result in a positive effect on your case creation metrics and in a better user experience.

In the case creation page below, a customer starts creating a support case regarding their defective Speedbit fitness tracker. In the Title field, they enter speedbit skipping steps. Meanwhile, on the right-hand side of the page, a Coveo for Microsoft Dynamics 365 search interface proactively suggests content matching these keywords, similarly to the Insight panel with entity context (see Understanding Entity Context). If an item seems to provide a solution to their issue, the user clicks it and is redirected to the item page, thus dropping the case creation process.

If the user does not find the displayed items helpful, they continue to fill the form, providing Coveo for Microsoft Dynamics 365 with additional keywords. The Coveo interface is then refreshed with new results. Typically, if the initial items displayed are not immediately helpful to the user, the next items become more relevant as the user keeps typing and thus providing more information.

Case creation page in a portal

This article guides you through the addition of a Coveo for Microsoft Dynamics 365 interface to your case creation page to automatically provide your portal users with helpful content and deflect case creation whenever possible.

Creating the Recommendation Interface

The recommendation interface is a Coveo for Microsoft Dynamics 365 search page adapted to the case deflection usage.

In Microsoft Dynamics 365, create a new web template (see Store source content by using web templates):

  1. In the Name box, enter Coveo Case Recommendations - Result Template.
  2. In the Website menu, select your portal.
  3. In the Source box, enter the following code, which defines the structure of each item displayed in the recommendation interface:

     <!-- Case deflection panel template displaying items relevant to the case that the user is creating. -->
     <div class="CoveoResultList" data-layout="list" data-wait-animation="none">
       <div class="coveo-show-if-no-results">
         Your case did not match any existing items.</a>
       </div>
    
       <!-- Result template for a case. -->
       <script id="CRMCase" class="result-template" type="text/html" data-layout="list" data-field-dyincidentid=""><div class="coveo-result-frame">
         <div class="coveo-result-frame">
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="font-size:16px;">
               <a class="CoveoResultLink" data-always-open-in-new-window="true" data-field="@dyclickableuriportal"></a>
             </div>
           </div>
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center">
               <span class="CoveoIcon" data-small="true" data-with-label="false"></span>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center; margin:0px; padding:0px">
                   <div class="CoveoQuickview"></div>
                 </div>
               </div>
             </div>
             <div class="coveo-result-cell" style="font-size:13px">
               <span class="CoveoExcerpt"></span>
               <div class="coveo-result-row" style="margin-top:0;vertical-align:top; text-align:left; font-size:12px">
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@date" data-helper="date" data-helper-options-include-time-if-this-week="false" data-helper-options-use-weekday-if-this-week="false" style="margin-right:30px;"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dysubjectidstring"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dystatuscodestring"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dyprioritycodestring" data-text-caption="Priority"></span>
                 </div>
               </div>
             </div>
           </div>
         </div>
       </script>
    
       <!-- Result template for a generic item from Dynamics. -->
       <script id="CRMDefault" class="result-template" type="text/html" data-layout="list" data-field-connectortype="Dynamics2Crawler">
         <div class="coveo-result-frame">
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="font-size:16px;">
               <a class="CoveoResultLink" data-always-open-in-new-window="true" data-field="@dyclickableuriportal"></a>
             </div>
           </div>
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center">
               <span class="CoveoIcon" data-small="true" data-with-label="false"></span>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center; margin:0px; padding:0px">
                   <div class="CoveoQuickview"></div>
                 </div>
               </div>
             </div>
             <div class="coveo-result-cell" style="font-size:13px">
               <span class="CoveoExcerpt"></span>
               <div class="coveo-result-row" style="margin-top:0;vertical-align:top; text-align:left; font-size:12px">
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@date" data-helper="date" data-helper-options-include-time-if-this-week="false" data-helper-options-use-weekday-if-this-week="false" style="margin-right:30px;"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dyname"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dytotalamount" data-text-caption="Total"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@dystatuscodestring" data-text-caption="Status"></span>
                 </div>
               </div>
             </div>
           </div>
         </div>
       </script>
    
       <!-- Result template for a YouTube video. -->
       <script id="YouTubeVideo" class="result-template" type="text/html" data-layout="list" data-field-filetype="YouTubeVideo">
         <div class="coveo-result-frame">
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="vertical-align:top; text-align:right; width:68px">
               <span class="CoveoYouTubeThumbnail" data-height="38px" data-width="68px"></span>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="text-align:right; font-size:12px">
                   <span class="CoveoFieldValue" data-field="@ytvideoduration" data-helper="timeSpan" data-helper-options-is-milliseconds="false"></span>
                 </div>
               </div>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="text-align:right; font-size:12px">
                   <span class="CoveoFieldValue" data-field="@date" data-helper="dateTime" data-helper-options-include-time-if-this-week="false" data-helper-options-use-weekday-if-this-week="false"></span>
                 </div>
               </div>
             </div>
             <div class="coveo-result-cell" style="vertical-align: top;padding-left: 16px;">
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="font-size:16px">
                   <a class="CoveoResultLink"></a>
                 </div>
               </div>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="font-size:13px">
                   <span class="CoveoExcerpt"></span>
                 </div>
               </div>
             </div>
           </div>
         </div>
       </script>
    
       <!-- Default template applying to any item that is not displayed using one of the previous templates. -->
       <script id="Default" class="result-template" type="text/html" data-layout="list">
         <div class="coveo-result-frame">
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="font-size:16px;">
               <a class="CoveoResultLink" data-always-open-in-new-window="true"></a>
             </div>
           </div>
           <div class="coveo-result-row" style="margin-top:0;">
             <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center">
               <span class="CoveoIcon" data-small="true" data-with-label="false"></span>
               <div class="coveo-result-row" style="margin-top:0;">
                 <div class="coveo-result-cell" style="vertical-align:top; width:36px; text-align:center; margin:0px; padding:0px">
                   <div class="CoveoQuickview"></div>
                 </div>
               </div>
             </div>
             <div class="coveo-result-cell" style="font-size:13px">
               <span class="CoveoExcerpt"></span>
               <div class="coveo-result-row" style="margin-top:0;vertical-align:top; text-align:left; font-size:12px">
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@date" data-helper="date" data-helper-options-include-time-if-this-week="false" data-helper-options-use-weekday-if-this-week="false" style="margin-right:30px;"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@source" data-text-caption="Source" style="margin-right:30px;"></span>
                 </div>
                 <div class="coveo-result-cell">
                   <span class="CoveoFieldValue" data-field="@filetype" data-text-caption="File Type" style="margin-right:30px;"></span>
                 </div>
               </div>
             </div>
           </div>
         </div>
       </script>
     </div>
    

    The value of @clickableuri for items from Microsoft Dynamics 365 is the address to the respective item within Dynamics. In the result template above, @dyclickableuriportal is an example of custom field that overrides the default behavior to redirect the user to an URI inside portal (see Adding a Portal URI Field).

  4. At the bottom of the page, click the floppy disk icon to save.

Alternative: Create a New Result Template

Alternatively, instead of copying the sample code above, you might want to create your own result template (see Configuring JavaScript Search Result Templates).

  1. In Coveo for Microsoft Dynamics 365, create a new search page with the following characteristics (see Creating a Search Page):

    • Classic page type
    • No tabs (deselect all check boxes)
  2. In the Interface Editor, edit the search page result templates so that the URI leading to Microsoft Dynamics 365 items is the appropriate one (see Interface Editor and Editing Search Result Templates).
  3. Switch to the Code View (see Code View).
  4. In the page source code, locate the HTML tag <div class="CoveoResultList" ...</div> and copy it.
  5. In the top-right corner, click Save.
  6. Back in the Search Pages page, publish your search page (see Publishing a Search Page).
  7. Follow the steps in Creating the Recommendation Interface. In the Source box, paste the HTML tag <div class="CoveoResultList" ...</div> that you just created, replacing any content defined previously for this field.

Adding the Recommendation Web Template

Once you have created your recommendation interface, you must make it available to your portal.

  1. In Coveo for Microsoft Dynamics 365, access the code of search page you created for your portal, and then copy it somewhere (see Creating the Recommendation Interface).
  2. In Microsoft Dynamics 365, create a new web template (see Store source content by using web templates):

    1. In the Name box, enter Coveo Case Recommendations.
    2. In the Website menu, select your portal.
    3. In the Source box, enter the following code, which initializes the recommendation interface:

      <script>
        {% assign apikey = settings['Coveo/ApiKey'] | default:'' %}
        {% assign organizationId = settings['Coveo/OrganizationId'] | default:'' %}
        {% assign platformUri = settings['Coveo/PlatformUrl'] | default:'' %}
        document.addEventListener('DOMContentLoaded', function() {
          Coveo.SearchEndpoint.configureCloudV2Endpoint('{{organizationId}}', '{{apikey}}', '{{platformUri}}rest/search');
          let root = document.getElementById("coveo-case-recommendations");
          Coveo.init(root);
          // Changes in the Title and Description form fields triggers queries to Coveo.
          const fieldsSelector = "#title, #description";
          // Adds the content of the Title and Description form fields to the Coveo longQueryExpression for every query sent to Coveo.
          Coveo.$$(root).on(Coveo.QueryEvents.buildingQuery, (event, args) => {
            $(fieldsSelector).each((index, inputField) => {
              const fieldValue = $(inputField).val();
              if (fieldValue) {
                args.queryBuilder.longQueryExpression.add(fieldValue);
                {% if user and user.jobtitle %}
                  // Contextual information about the job title or department of the authenticated user, if any.
                  args.queryBuilder.addContextValue("jobtitle", "{{ user.jobtitle }}");
                {% endif %}
              }
            });
          });
          // Triggers a search when the user has stopped typing for 300ms.
          let typingTimer;
          const typingTimerInterval = 300;
          // Listens for the changes in the Title and Description form fields and triggers new queries as the customer types.
          $(fieldsSelector).each((index, inputField) => {
            $(inputField).on('keyup', () => {
              clearTimeout(typingTimer);
              typingTimer = setTimeout(() => {
                // Instructs the 'executeQuery' to log a search event in Coveo Usage Analytics.
                caseCreationLogger.hookLogCaseInputChangeToExecuteQuery();
                // Makes a call to Coveo Cloud querying for new case recommendations based on new user input.
                Coveo.executeQuery(root);
              }, typingTimerInterval);
            });
          });
          const caseCreationLogger = {
            // Instructs the 'executeQuery' action to log a search event in Coveo Usage Analytics.
            hookLogCaseInputChangeToExecuteQuery:() => {
              Coveo.logSearchAsYouTypeEvent(root, { name: "CaseCreationInputChange", type: "InputChange" }, caseCreationLogger._getMetadata());
              caseCreationLogger.hasInputChange = true;
            },
            // Instructs the submit action to log a case submit event in Coveo Usage Analytics.
            hookLogCaseCreationToSubmitAction:() => {
              const addCaseSubmitEvent = (fn) => {
                const WebForm_OnSubmit_Original = WebForm_OnSubmit;
                WebForm_OnSubmit = () => {
                  return WebForm_OnSubmit_Original() && fn();
                };
              };
              addCaseSubmitEvent(() => {
                Coveo.logCustomEvent(root, { name: "CaseCreationSubmit", type: "Submit" }, caseCreationLogger._getMetadata());
                caseCreationLogger.hasSubmit = true;
                return true;
              });
            },
            // Instructs the unload action to log a case deflected event in Coveo Usage Analytics.
            hookLogCaseCreationDeflectedToUnloadAction:() => {
              window.addEventListener("beforeunload", function (event) {
                if (caseCreationLogger.hasInputChange && !caseCreationLogger.hasSubmit) {
                  Coveo.logCustomEvent(root, { name: "CaseCreationDeflected", type: "Unload" }, caseCreationLogger._getMetadata());
                }
              });
            },
            // Creates a JSON object with the content of the Title and Description form fields in the format { title: "", description: "" }.
            _getMetadata:() => {
              let metadata = {};
              $(fieldsSelector).each((index, element) => { metadata[element.id] = element.value; });
              return metadata;
            },
            hasInputChange: false,
            hasSubmit: false
          };
          caseCreationLogger.hookLogCaseCreationToSubmitAction();
          caseCreationLogger.hookLogCaseCreationDeflectedToUnloadAction();
        });
      </script>
      
      <!-- Case deflection panel template in which the content recommendations are displayed. -->
      <style>
        .coveo-search-title {
          margin-top:0;
        }
        .coveo-initial-state-message {
          font-size:small;
        }
      </style>
      
      <h3 class="coveo-search-title">Content Relevant to Your Case</h3>
      <span class="coveo-initial-state-message">You might want to check these items before submitting your case.</span>
      <div id="coveo-case-recommendations" class='CoveoSearchInterface' data-design="new" data-allow-queries-without-keywords="true" data-excerpt-length="150" data-enable-history="true" data-enable-duplicate-filtering="true">
        <div class="CoveoAnalytics" data-search-hub="PortalCaseRecommendation" data-endpoint="{{ settings['Coveo/UsageAnalyticsUrl'] | default:'' }}"></div>
        <div class="coveo-main-section">
          <div class="coveo-results-column">
            <div class="CoveoErrorReport"></div>
            {% include 'Coveo Case Recommendations - Result Template' %}
          </div>
        </div>
      </div>
      

      In the script above, logSearchAsYouTypeEvent and logCustomEvent sends usage analytics data to Coveo Cloud Usage Analytics regarding the cases that are created and those that are deflected. It helps understand how visitors behave and ultimately provides insight on the efficiency of the cases recommendation panel (see Logging Your Own Search Events and Logging Your Own Custom Events).

      • Under the HTML tag <div class="CoveoErrorReport"></div>, the Coveo Case Recommendations - Result Template imports the search page code that you created at the previous step. This provides your portal with the search interface to display.
      • Ensure that the web template name provided in the include tag matches the name you entered when you created the recommendation interface (see Creating the Recommendation Interface).
    4. At the bottom of the page, click the floppy disk icon to save.

Query Builder and Long Queries

The content of the Title and Description fields in the case creation page is injected in the form of a long query expression into the query builder (see Long Query Expression). In the script above, this operation is represented by args.queryBuilder.longQueryExpression.add(fieldValue).

Large texts sent to Coveo Machine Learning, like the whole description of a support case, for instance, are first handled by Intelligent Term Detection (ITD). It understands the intent of the text, extracts the most relevant terms from the paragraphs, and adds these keywords to the basic query expression (q).

Context Arguments

The job title of the current visitor is passed as contextual information to Coveo Usage Analytics (Coveo UA) through args.queryBuilder.addContextValue (see Custom Context Leveraging Leading Practices). Together with the long query, this information is also sent to Coveo Machine Learning, empowering it with the insight to deliver personalized recommendations to the visitor. For a complete list of methods available, see Class QueryBuilder.

Adding the Case Creation Layout Web Template

You must edit your case creation page to make room for the Coveo for Microsoft Dynamics 365 recommendation interface. Coveo for Microsoft Dynamics 365 recommends dividing the page vertically, in two equal parts, with the recommendation interface on the right.

In Microsoft Dynamics 365, create a new web template (see Store source content by using web templates):

  1. In the Name box, enter Layout 2 Columns Equal Width.
  2. In the Website menu, select your portal.
  3. In the Source box, enter the following code. It is a copy of the existing Layout 2 Column Wide Left template provided with some portals. The CSS classes have been modified to provide two columns of the same width.

     <div class="container">
       <div class="page-heading">
       {% block breadcrumbs %}
           {% include 'Breadcrumbs' %}
         {% endblock %}
       {% block title %}
         {% include 'Page Header' %}
       {% endblock %}
       </div>
       <div class="row">
       <div class="col-sm-6 col-lg-6 left-column">
         {% block main %}
         {% include 'Page Copy' %}
         {% endblock %}
       </div>
       <div class="col-sm-6 col-lg-6 right-column">
         {% block aside %}{% endblock %}
       </div>
       </div>
     </div>
    
  4. At the bottom of the page, click the floppy disk icon to save.

Implementing Case Deflection

Once the layout of your case deflection page has a dedicated space for the Coveo recommendation interface, you can add this interface to the page.

  1. In Microsoft Dynamics 365, open the Customer Service - Create Case web template, which is provided out of the box with some portals, or your own case creation web template.

  2. In the Source box:

    1. Replace the extends statement with:

       {% extends 'Layout 2 Columns Equal Width' %}
      

      This makes the template inherit from the template you created before (see Adding the Case Creation Layout Web Template).

    2. At the bottom of the template, add the following code:

       {% block aside %}
         {% include 'Coveo Case Recommendations' %}
         {% include 'Coveo Usage Analytics - Push View Event' , content_type:'incident' %}
       {% endblock %}
      

      This replaces the aside block in the Layout 2 Column Wide Left template with two Coveo templates.

  3. At the bottom of the page, click the floppy disk icon to save.

Validating Your Changes

Ensure that the recommendation interface is refreshed as you fill the case creation form.

  1. Go to your case creation page.
  2. Validate that there is a Coveo recommendation interface next to the case creation page.
  3. Enter keywords in the form to validate that the provided suggestions are updated as you type.