Salesforce.com’s LiveAgent Chat

After being a long time customer of LivePerson, we have switched to Salesforce.com Live Agent as we now have this included in our edition. After reading through the I felt confident we could set this all up quickly. Implementing Live Agent and being able to chat, was super easy…almost too easy.
What took a bit of time was working through creating the pre-chat form and setting up the process to create a lead if a contact record was not found.
After attempting to figure this out myself and not successfully getting the lead record to create, I went to a developer’s best friend, Google.
Between these three blogs: Live Agent Pre-Chat API , Salesforce Live Agent Review & Customization & Extending the Salesforce LiveAgent pre-chat form through javascript and VF Remoting;the developer guide, and some additional searches on javascript, I’ve created a beautiful pre-chat survey, it searches for contacts, and if not found creates a lead record and displays the new record to the agent.

The visualforce page: (replace the XXXXXXXXXXX in the apex:variable with your record id’s)


<apex:page showHeader="false" standardController="Account" extensions="LiveAgent_preChatRemoting_Con">
<apex:variable var="deploymentId" value="XXXXXXXXXXX" />
<apex:variable var="orgId" value="XXXXXXXXXXX" />
<apex:variable var="buttonId" value="XXXXXXXXXXX" />

<!-- This script takes the endpoint URL parameter passed from the deployment page and makes it the action for the form -->

<script type="text/javascript">
(function() {
function handlePageLoad() {
var endpointMatcher = new RegExp("[\\?\\&]endpoint=([^&#]*)");
document.getElementById('prechatForm').setAttribute('action',
decodeURIComponent(endpointMatcher.exec(document.location.search)[1]));
} if (window.addEventListener) {
window.addEventListener('load', handlePageLoad, false);
} else { window.attachEvent('onload', handlePageLoad, false);
}})();

function SubmitForm(createLead) {

if (!createLead) { //We found a matching contact based on email provided, so DO NOT send parameters to create a new lead.
document.getElementById("optionA").value="";
document.getElementById("optionB").value="false";
}
else { //No matching contact was found, so send parameters required to create a new lead.
document.getElementById("optionA").value="FirstName,true;LastName,true;Company,true;Email,true;LeadSource,true;Phone,true;Status,true;Description,true;Rating,true;";
document.getElementById("optionB").value="true";
}
document.getElementById("prechatForm").submit();
}

function getRemoteContact()
{
var contactEmail = document.getElementById('contactEmail').value;
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.LiveAgent_preChatRemoting_Con.getcontact}', contactEmail, function(result, event){
if (event.status) {
SubmitForm(false); //contact found, don't create a lead
} else if (event.type === 'exception') {
SubmitForm(true); //contact NOT found, DO create a lead
} else {
SubmitForm(false); //unknown error, DON'T create a lead
}
},
{escape: true}
);
}
</script>
<style>
body
{
background-color:#fff;
}
#chatFormDiv
{
width:300px;
text-align:center;
padding:5px;
}
#chatHeader
{
color:#6d6d6d;
font-size:18px;
font-weight:bold;
float: center;
}
#prechat_submit
{
font-weight:bold;
float: center;
}
label
{
width:150px;
font-weight:bold;
}
input[type=text], textarea
{
width:280px;
background: #fff;
border: 1px solid #CCCCCC;
border-radius: 3px;
margin-bottom: 5px;
padding: 0 10px;
}
input[type=email]
{
height: 30px;
width:280px;
background: #fff;
border: 1px solid #CCCCCC;
border-radius: 3px;
margin-bottom: 5px;
padding: 0 10px;
}
input[type=tel]
{
height: 30px;
width:280px;
background: #fff;
border: 1px solid #CCCCCC;
border-radius: 3px;
margin-bottom: 5px;
padding: 0 10px;
}
input[type=text]
{
height: 30px;
}
textarea
{
height:140px;
padding-top: 10px;
padding-bottom: 10px;
}
.chatStatusDiv
{
display:none;
}
</style>
<div id="chatFormDiv">
<form method="post" id="prechatForm" action="https://c.la2w2.salesforceliveagent.com/content/s/chat?language=en_US#deployment_id={!deploymentId}&org_id={!orgId}&button_id={!buttonId}">

<!-- Company Log on top of the form -->
<img src="{!URLFOR($Resource.company_logo)}"/> <span id="chatHeader"></span><br/>
<hr />

<!-- Detail inputs -->
<input type="text" name="liveagent.prechat:leadFirstName" placeholder= "First Name*" onchange="javascript: document.getElementById('prechat_field').value=this.value;" required="required"/>

<input type="text" name="liveagent.prechat:leadLastName" placeholder= "Last Name*" required="required"/>

<input type="text" id="contactEmail" name="liveagent.prechat:leadEmail" placeholder= "Email*" required="required"/>

<input type="tel" name="liveagent.prechat:leadPhone" placeholder= "Phone" />

<input type="text" name="liveagent.prechat:leadCompany" placeholder= "Company" />

<textarea name="liveagent.prechat:leadDescription" placeholder= "How can we help?" ></textarea>


<!--greeting field, copies from FirstName input-->
<input type="hidden" name="liveagent.prechat.name" id='prechat_field'/>

<!--hidden fields written to the new lead-->
<input type="hidden" name="liveagent.prechat:leadStatus" value="Open" />
<input type="hidden" name="liveagent.prechat:leadSource" value="Chat" />
<input type="hidden" name="liveagent.prechat:leadRating" value="A" />

<!-- Creates an auto-query for a matching Contact record’s Email field based on the value of the liveagent.prechat:leadEmail field -->
<input type="hidden" name="liveagent.prechat.query:leadEmail" value="Contact,Contact.Email" />


<!-- Map the detail inputs to the Lead fields -->
<input type="hidden" name="liveagent.prechat.findorcreate.map:Lead" value="FirstName,leadFirstName;LastName,leadLastName;Company,leadCompany;Email,leadEmail;LeadSource,leadSource;Phone,leadPhone;Status,leadStatus;Description,leadDescription;Rating,LeadRating;" />

<!-- Map the detail inputs to the Contact fields -->
<input type="hidden" name="liveagent.prechat.findorcreate.map:Contact" value="FirstName,leadFirstName;LastName,leadLastName;Email,leadEmail;" />


<!-- Try to find Contact by email (exact match) -->
<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="Email,true;" />
<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="Email,true;" />


<!-- Try to find the Lead by email (exact match) -->
<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Lead" value="Email,true;" />
<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Lead" value="Email,true;" />

<!-- If the Lead is not found, then create one with the following fields set -->
<input type="hidden" id="optionA" name="liveagent.prechat.findorcreate.map.doCreate:Lead" value="FirstName,true;LastName,true;Company,true;Email,true;LeadSource,true;Phone,true;Status,true;Description,true;Rating,true;" />

<!-- Save the Lead on the Live Chat Transcript -->
<input type="hidden" name="liveagent.prechat.findorcreate.saveToTranscript:Lead" value="Lead" />

<!-- Show the Lead when it is found or created -->
<input type="hidden" id="optionB" name="liveagent.prechat.findorcreate.showOnCreate:Lead" value="true" />

<!-- Show the Contact when it is found or created -->
<input type="hidden" name="liveagent.prechat.findorcreate.showOnCreate:Contact" value="true" />

<input type="submit" value="Begin Chat Session" id="prechat_submit" onsubmit="return validateForm('prechatForm',javascript: getRemoteContact());"/>
</form>

</div>
</apex:page>

Results in this page:
prechatform

And here is the controller:


public class LiveAgent_preChatRemoting_Con
{
public LiveAgent_preChatRemoting_Con(ApexPages.StandardController controller)
{

}
@RemoteAction
public static contact getcontact(string contactemail)
{
Contact testContact=new Contact();
testContact=[Select Id,Name from Contact where email=:contactemail limit 1];
return testContact;
}

}

I’m thankful there were such great developers that shared their code and took the time to make notes in it!

Sd

5 thoughts on “Salesforce.com’s LiveAgent Chat

  1. Need to launch the window in a certain size? Set that option in your deployment code by adding:
    liveagent.setChatWindowHeight(xxx);
    liveagent.setChatWindowWidth(xxx);
    So you’d end up with something like:

    <script type='text/javascript' src='https://c.la1cs.salesforceliveagent.com/content/g/js/33.0/deployment.js'></script>
    <script type='text/javascript'>
    liveagent.init('https://d.la1cs.salesforceliveagent.com/chat', 'xxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxx');
    liveagent.setChatWindowHeight(525);
    liveagent.setChatWindowWidth(340);
    </script>
    

    Like

  2. Very nice work Stephen, this was well written! I was wondering if you could lend a quick hand, I am the Salesforce Admin for my company and have less experience on the development end. I rolled our live agent to our company a few months back, however I fumbled through it and the logic is not solid like yours. I am working to add the conditional functionality so that I can search contacts/leads by email and if not exist create the lead. This is my first attempt at using an Apex Class in Sandbox and trying to push into live. I have never done a Test Class and was wondering if you could lend a hand and provide a sample Test Class for the above so that my code can pass the inbound changeset 75% code requirement. I am getting stuck here and was hoping to get the function to work.

    Thanks,
    Patrick

    Like

    1. Sorry for the delay in reply Patrick. Been working hard on projects that went live last week. Anyhow, I’m happy to help out. So if you used the article’s visual force and apex class, then you will not need a test class. as classes are used when triggered by something else such as a trigger, another class, or visualforce pages. Did you set up the controller class as a trigger perhaps? Feel free to email me with details. stephenfdavis3@gmail.com

      Like

Leave a reply to Patrick Kloiber Cancel reply