0

When the user enters their information into the pre-chat form and clicks the Start Chat button, I want to:

  • Look them up in Contacts and return the most specific matches I can find based on Email, LastName, FirstName
  • If I get only 1 result and the Email matches, assign that Contact to the new case
  • If I get only 1 result and it's a LastName match, open a Search Results tab and allow the CSR to choose (or not choose) the existing contact
  • If I get more than 1 result, open a Search Results tab and allow the CSR to choose (or not choose) one of the several existing contacts
  • If I get zero results, create a new Contact with the pre-chat information prefilled

How I'm attempting to achieve this:

  • Use JS remoting to call a remote controller class that performs a SOQL search and returns the results as JSON
  • Dynamically add/remove pre-chat form hidden elements to control what the CSR sees

My Apex class is working as intended, returning contacts as granular as possible, based on Email, LastName and FirstName - in that order. It returns a list of contacts along with their Ids and other information, as well as the types of matches. For example, here's the response for a user who matches by LastName and FirstName, but not email:

{
  "searchType": "LastName,FirstName",
  "results": [
    {
      "Id": "003m0000010xxxxxxx",
      "LastName": "Smith",
      "FirstName": "Daisy",
      "Email": "daisy.smith@fake-daisy-smith-email.com"
    },
    {
      "Id": "003m0000011xxxxxxx",
      "LastName": "Smith",
      "FirstName": "Daisy",
      "Email": "dsmith01@fake-daisy-smith-email.com"
    }
  ]
}

In the case above, I would want the search results tab to open for the CSR so she can decide which Daisy Smith is correct (if either). Here's another example:

{
  "searchType": "Email",
  "results": [
    {
      "Id": "003m0000012xxxxxxx",
      "LastName": "Fake",
      "FirstName": "Fake",
      "Email": "jane.doe@fake-jane-doe-email.com"
    }
  ]
}

In the example above, since they matched by Email and there's only 1 result, assign this exact Contact to the Case.

I'm attempting to do this with client-side JS that receives the JSON result from the remote controller and appends/replaces pre-chat form values. I've tried several different ways to search, but so far nothing is quite working as intended. I have the following issues:

  1. When there is 1 result that matches Email, an existing contact is not mapped to the new case. Instead a new contact is created with the same Email, LastName and FirstName.
  2. Despite showing the Search Results tab correctly when there is more than 1 Contact found, the new case still makes it own assumptions for the Contact Name field, which I guess might be based on Email.

Can anyone steer me in the right direction?

Here is my Apex pre-chat form:

<apex:page showHeader="false" standardStylesheets="false" sidebar="false" docType="html-5.0" title="Live Chat" controller="RemoteController">
    <div class="livechat-prechat">
      <div class="livechat-prechat-container">
        <div class="row livechat-company-logo-container">
          <div class="col-xs">
            <img src="logo.png" class="livechat-company-logo" alt="Logo" />
            <div class="livechat-text">CHAT</div>
            <div class="livechat-close-btn"></div>
          </div>
        </div>
        <div class="row">
          <div class="col-xs-12">
            <div class="livechat-prechat-form-container">
              <form id="livechat-prechat-form" method="post" role="form" novalidate="novalidate" action="DYNAMICALLY_SET" class="livechat-prechat-form form-validation">
                <div class="form-group">
                  <input class="form-control" id="firstName" name="liveagent.prechat:ContactFirstName" type="text" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="firstName">First Name</label>
                </div>
                <div class="form-group">
                  <input class="form-control" id="lastName" name="liveagent.prechat:ContactLastName" type="text" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="lastName">Last Name</label>
                </div>
                <div class="form-group">
                  <input class="form-control" id="email" name="liveagent.prechat:ContactEmail" type="email" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="email">Email</label>
                </div>
                <div class="form-group">
                  <select class="form-control" id="subject" name="liveagent.prechat:CaseReason" aria-required="true" required="true" data-rule-select="true">
                    <option value="None" selected="selected">Reason for Chat</option>
                    <option value="Store Inquiry">Store Inquiry</option>
                    <option value="Return Inquiry">Return Inquiry</option>
                    <option value="General Information or Feedback">General Information or Feedback</option>
                    <option value="Order Inquiry">Order Inquiry</option>
                    <option value="Product Inquiry">Product Inquiry</option>
                  </select>
                </div>
    
                <!-- Static values -->
                <input type="hidden" name="liveagent.prechat:CaseStatus" value="New" />
                <input type="hidden" name="liveagent.prechat:CaseOrigin" value="Chat" />

                <!-- Map contact/case fields to form input -->
                <input type="hidden" name="liveagent.prechat.findorcreate.map:Contact" value="FirstName,ContactFirstName;LastName,ContactLastName;Email,ContactEmail" id="contactMap" />
                <input type="hidden" name="liveagent.prechat.findorcreate.map:Case" value="Reason,CaseReason;Origin,CaseOrigin;Status,CaseStatus;Subject,Subject;SuppliedName,FullName;SuppliedEmail,ContactEmail" />
                
                <!-- If not found, create a contact and a case -->
                <input type="hidden" name="liveagent.prechat.findorcreate.map.doCreate:Contact" value="Email,true;FirstName,true;LastName,true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.map.doCreate:Case" value="Reason,true;Origin,true;Status,true;Subject,true;SuppliedName,true;SuppliedEmail,true" />
                
                <!-- Save the contact/case to the transcript -->
                <input type="hidden" name="liveagent.prechat.findorcreate.linkToEntity:Contact" value="Case,ContactId" />
                <input type="hidden" name="liveagent.prechat.findorcreate.showOnCreate:Contact" value="true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.showOnCreate:Case" value="true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.saveToTranscript:Contact" value="ContactId" />
                <input type="hidden" name="liveagent.prechat.findorcreate.saveToTranscript:Case" value="CaseId" />
                
                <button class="livechat-prechat-submit-btn btn btn-block" id="prechat_submit" type="submit">Start Chat</button>
              </form>
              
              <div class="livechat-close-btn livechat-close-link">Cancel</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- JS Remoting -->
    <script type="text/javascript">
        function onBeforeSubmit() {
            var email = document.getElementById('email');
            var lastName = document.getElementById('lastName');
            var firstName = document.getElementById('firstName');
            
            Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.RemoteController.getContacts}', (email && email.value) || '', (lastName && lastName.value) || '', (firstName && firstName.value) || '', function(results, event) {
              startChat(results);
            }, { buffer: false, escape: true, timeout: 10000 });
        }
    </script>
</apex:page>

The startChat method:

        window.startChat = function (response) {
            var results = response.results;
            var searchType = response.searchType;

            // Creates a mapping to use in inputs - E.g. "Email,true;LastName,true"
            var mapString = searchType.split(',').map(function(type) {
                return type + ',true';
            }).join(';');

            var fullName = $('#firstName').val() + ' ' + $('#lastName').val();

            // Set dynamic fields
            prechatForm.append('<input type="hidden" name="liveagent.prechat.name" value="' + fullName + '" />');
            prechatForm.append('<input type="hidden" name="liveagent.prechat:FullName" value="' + fullName + '" />');
            prechatForm.append('<input type="hidden" name="liveagent.prechat:Subject" value="Live Chat: ' + $('#subject').val() + '" />');

            switch (results.length) {
                // No contacts found
                case 0:
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="Email,true;LastName,true;FirstName,true" />');
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="Email,true;LastName,true;FirstName,true" />');
                break;

                // Exact match found
                case 1:
                    if (~searchType.indexOf('Email')) {
                        // Email matches, so assign this contact
                        prechatForm.append('<input type="hidden" name="liveagent.prechat:ContactId" value="' + results[0].Id + '" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="ContactId,true" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="ContactId,true" />');
                        prechatForm.find('#contactMap').replaceWith('<input type="hidden" name="liveagent.prechat.findorcreate.map:Contact" value="FirstName,ContactFirstName;LastName,ContactLastName;Email,ContactEmail;Id,ContactId" />');
                    } else {
                        // Email does NOT match, so show search results
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="' + mapString + '" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="' + mapString + '" />');                      
                    }
                break;

                default:
                    // Multiple contacts found, so show search results
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="' + mapString + '" />');
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="' + mapString + '" />');
                break;
            }

            // Submit the form and start the chat
            $('.livechat-prechat-form')[0].submit();
        };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.