When manually creating the Case in a console component instead of letting Salesforce create the Case automatically via pre-chat or deployment API then you will need to use an apex trigger on the LiveChatTranscript
object and add a custom text field Chat Key to your Case object to correlate the records in the trigger.
Custom Console Component
Here is sample javascript that listens for a new chat session to start and creates a new Case record, populating the Case record with the Chat Key.
<apex:page>
<apex:includeScript value="/support/console/37.0/integration.js"/>
<apex:remoteObjects>
<apex:remoteObjectModel name="Case" fields="Id,Chat_Key__c"/>
</apex:remoteObjects>
<script type="text/javascript">
// on chat start, create case manually and populate the chat_key__c field.
// once agent closes the chat/case tabs then salesforce creates transcript.
// because we created case manually and not through pre-chat or deployment api then
// salesforce does not automatically link the transcript to this case, that is
// where the LiveChatTranscriptTrigger comes into play and links them for us.
sforce.console.chat.onChatStarted( function( chatResult ) {
if ( chatResult.success ) {
// create case and set the chat_key__c field
// you can use the sforce.connection API, REST API, Remote Actions, etc.
// just make sure when you create the case you get that chat key field populated
var cs = new SObjectModel.Case({
Subject : 'Live Chat Test',
Origin : 'Web',
Chat_Key__c : chatResult.chatKey
});
cs.create( function( err, records, evt ) {
console.log( err );
console.log( records );
console.log( evt );
if ( err ) {
alert( err.message );
} else {
sforce.console.getFocusedPrimaryTabId( function( primaryTabResult ) {
console.log( 'getFocusedPrimaryTabId' );
console.log( primaryTabResult );
if ( primaryTabResult.success ) {
console.log( 'primaryTabId: ' + primaryTabResult.id );
console.log( 'caseId: ' + records[0] );
sforce.console.openSubtab(
primaryTabResult.id,
'/' + records[0] + '/e',
true,
'Edit Case',
null,
function( openSubtabResult ) {
console.log( 'openSubtabResult' );
console.log( openSubtabResult );
}
); // end open sub tab
} // end if
}); // end get focused primary tab id
} // end if
}); // end case create callback
} // end if
}); // end on chat started callback
</script>
</apex:page>
LiveChatTranscript Trigger
The LiveChatTranscript
record will have the ChatKey populated on it but the CaseId will be blank (in this scenario). So we look up the related Case indirectly by the chat key custom field we setup earlier.
trigger LiveChatTranscriptTrigger on LiveChatTranscript ( after insert ) {
Set<String> chatKeys = new Set<String>();
for ( LiveChatTranscript transcript : Trigger.new ) {
if ( String.isBlank( transcript.caseId ) && String.isNotBlank( transcript.chatKey ) ) {
chatKeys.add( transcript.chatKey );
}
}
System.debug( 'chatKeys=' + chatKeys );
if ( chatKeys.size() > 0 ) {
// chat_key__c should be a unique, external id field
// populated in the console once the chat has started and case created
List<Case> cases = new List<Case>([
SELECT
id, chat_key__c
FROM
Case
WHERE
chat_key__c IN :chatKeys
ORDER BY
createdDate ASC
]);
// chatKey => case
Map<String, Case> chatKeyCasesMap = new Map<String, Case>();
for ( Case cs : cases ) {
chatKeyCasesMap.put( cs.chat_key__c, cs );
}
System.debug( 'chatKeyCasesMap=' + chatKeyCasesMap );
List<LiveChatTranscript> transcriptsToUpdate = new List<LiveChatTranscript>();
for ( LiveChatTranscript transcript : Trigger.new ) {
if ( String.isBlank( transcript.caseId ) && String.isNotBlank( transcript.chatKey ) ) {
Case cs = chatKeyCasesMap.get( transcript.chatKey );
if ( cs != null ) {
transcriptsToUpdate.add( new LiveChatTranscript(
id = transcript.id,
caseId = cs.id
));
}
}
}
if ( transcriptsToUpdate.size() > 0 ) {
System.debug( 'transcriptsToUpdate: ' + transcriptsToUpdate );
update transcriptsToUpdate;
}
}
}
Unit Test
Simple unit test for code coverage of above trigger.
@isTest
private class LiveChatTranscriptTriggerTest {
@isTest
static void link_transcript_to_case() {
Case cs = new Case(
subject = 'Test Case',
origin = 'Web',
chat_key__c = '123'
);
insert cs;
LiveChatVisitor visitor = new LiveChatVisitor();
insert visitor;
Test.startTest();
LiveChatTranscript tx = new LiveChatTranscript(
chatKey = '123',
liveChatVisitorId = visitor.id
);
insert tx;
Test.stopTest();
tx = [ SELECT id, caseId, chatKey FROM LiveChatTranscript WHERE id = :tx.id ];
System.assertEquals( cs.chat_key__c, tx.chatKey );
System.assertEquals( cs.id, tx.caseId );
}
}
Best Answer
I have also worked on Live Agent Product and experienced same sort of issues.
Some common rules i follow is as follows:
1)Check whether the Agent is assigned a Live Agent Licence by making sure Live Agent user check box is ticked for the user
2)You can integrate the Live Agent with Service Cloud Console and hence this will avoid the switching of the App
3)Always avoid use of your own CSS to customize the Chat window as we have seen lot of issues with this
If all fails last option is to raise a case with support and make them aware .