4

I'm trying to create a person account instead of a contact in the Pre-Chat Code form. According to the documentation from Salesforce it looks like this:

    embedded_svc.settings.extraPrechatInfo = [{
  "entityName": "Contact",
  "entityFieldMaps": [{
    "isExactMatch": true,
    "fieldName": "FirstName",
    "doCreate": true,
    "doFind": true,
    "label": "firstName"
  }, {
    "isExactMatch": true,
    "fieldName": "LastName",
    "doCreate": true,
    "doFind": true,
    "label": "LastName"
  }, {
    "isExactMatch": true,
    "fieldName": "Email",
    "doCreate": true,
    "doFind": true,
    "label": "Email"
  }]
}, {
  "entityName": "Case",
  "entityFieldMaps": [{
    "isExactMatch": false,
    "fieldName": "Subject",
    "doCreate": true,
    "doFind": false,
    "label": "issue"
  }, {
    "isExactMatch": false,
    "fieldName": "Status",
    "doCreate": true,
    "doFind": false,
    "label": "Status"
  }, {
    "isExactMatch": false,
    "fieldName": "Origin",
    "doCreate": true,
    "doFind": false,
    "label": "Origin"
  }]
}, {
  "entityName": "Account",
  "entityFieldMaps": [{
    "isExactMatch": true,
    "fieldName": "Name",
    "doCreate": true,
    "doFind": true,
    "label": "LastName"
  }]
}];
embedded_svc.settings.extraPrechatFormDetails = [{
  "label": "firstName",
  "value": "John",
  "displayToAgent": true
}, {
  "label": "LastName",
  "value": "Doe",
  "displayToAgent": false
}, {
  "label": "Email",
  "value": "[email protected]",
  "displayToAgent": true
}, {
  "label": "issue",
  "value": "Do the work",
  "displayToAgent": true
}];

The values are hardcoded in the example - how can I instead create a person account with the field values that the user fills in in the form?

7
  • 1
    Working on the exact same problem, but haven't figured it out. Perhaps we can help each other. Found this today with some suggestions, but no luck yet:success.salesforce.com/ideaView?id=0873A000000cRe9QAE Hopefully you're smarter than I am.
    – RickForce
    Commented Nov 19, 2019 at 17:03
  • Tried that one too without success. Been scavenging the internet for answers!
    – erikvm
    Commented Nov 19, 2019 at 18:51
  • 1
    Hopefully the code below helps you along, don't have the testclass yet, but will update the answer later when I do.
    – RickForce
    Commented Nov 20, 2019 at 12:12
  • Still running into a really weird bug. After closing the transcript the case gets removed from the transcript by a process that skips triggers. Have not been able to figure it out yet.
    – RickForce
    Commented Nov 20, 2019 at 15:54
  • Hey Rick, thanks a lot for keeping the thread alive! I'll also try out the trigger right now and see if I can get it to work
    – erikvm
    Commented Nov 20, 2019 at 16:24

1 Answer 1

4

UPDATE 09-04-2020

The workaround below has worked fine, but I had to remove it due to a change to our Org which enforces unicity on e-mail address. Anyway, I figured out what the problem was with the embedded service deployment. It turns out it does actually work and you can create person-accounts from it.

The main problem in my case was that our chat is in Dutch and thus uses translated values for 'First Name', 'Last Name' and 'Email', the most important of which is 'Email' is written as 'E-mail'. The docs do say to use the label, but it does not mention anything about translated labels. So be really careful when you have a multi-lingual implementation.

The way I found this out is by debugging the script in my browser console, I then discovered the labels being passed are the literal labels as they are shown in the chat-form:

Screenshot from console

When I found that out, it was pretty straightforward writing the code for the prechat. The default case status was also set incorrectly due to translation issues.

This is the code, you can ignore the custom e-mail field I use, this is org specific. This code creates a personaccount if non exists and or if it is found it links the personcontact to the transcript and the personaccount as well, enabling chat history. I have not been able to connect the personcontact when it is newly created.

embedded_svc.settings.extraPrechatFormDetails = [{
    "label": "RecordTypeId",
    "value": "0120N000000Uwb8QAC",
    "displayToAgent": false
},
{
    "label": "CaseStatus",
    "value": "Nieuw",
    "displayToAgent": false
}];


embedded_svc.settings.extraPrechatInfo = [{
    "entityName": "Contact",
    "saveToTranscript": "ContactId",
    "showOnCreate": true,
    "entityFieldMaps": [{
        "isExactMatch": false,
        "fieldName": "FirstName",
        "doCreate": false,
        "doFind": false,
        "label": "Voornaam"
    }, {
        "isExactMatch": false,
        "fieldName": "LastName",
        "doCreate": false,
        "doFind": false,
        "label": "Achternaam"
    }, {
        "isExactMatch": true,
        "fieldName": "Email_GG__c",
        "doCreate": false,
        "doFind": true,
        "label": "E-mail"
    }]
},
{
    "entityName": "Account",
    "showOnCreate": true,
    "linkToEntityName": "Case",
    "linkToEntityField": "AccountId",
    "saveToTranscript": "AccountId",
    "entityFieldMaps": [
        {
            "isExactMatch": false,
            "fieldName": "LastName",
            "doCreate": true,
            "doFind": false,
            "label": "Achternaam"
        },
        {
            "isExactMatch": false,
            "fieldName": "RecordTypeId",
            "doCreate": true,
            "doFind": false,
            "label": "RecordTypeId"
        },
        {
            "fieldName": "PersonEmail",
            "doCreate": true,
            "label": "E-mail"
        },
        {
            "doCreate": false,
            "doFind": true,
            "fieldName": "Email_GG__pc",
            "isExactMatch": true,
            "label": "E-mail"
        }]
},
{
    "entityName": "Case",
    "showOnCreate": true,
    "entityFieldMaps": [
        {
            "doCreate": true,
            "doFind": false,
            "fieldName": "Status",
            "isExactMatch": false,
            "label": "CaseStatus"
        }]
}];

Old Answer:

After contacting Salesforce support I decided that I had no other option than to create an apex trigger for this to have a short term solution. The code might be a little rough and have room for improvement, but I thought I'd share it with you hoping it will help you a bit. Please let me know if you have any questions.

I created a 'before update' trigger on the livechattranscript object.

public void BeforeUpdate(List<SObject> newList, Map<Id, SObject> newItems, List<SObject> oldList, Map<Id, SObject> oldMap)
{
    //change isolated contacts to person accounts
    List<LiveChatTranscript> transcriptsForConversion = new List<LiveChatTranscript>();
    List<Id>                 transcriptContactIds     = new List<Id>();
    for (LiveChatTranscript transcript : (List<LiveChatTranscript>)newList) {
        if (transcript.ContactId != null && transcript.CaseId != null (transcript.ContactId != null && transcript.CaseId != null && transcript.AccountId == null) {
            transcriptsForConversion.add(transcript);
            transcriptContactIds.add(transcript.ContactId);
        }
    }
    convertToPersonAccount(transcriptsForConversion, transcriptContactIds);
}

And this is the method that does the actual work:

//Converts the isolated contacts created for chat to person accounts
public static void convertToPersonAccount(List<LiveChatTranscript> chatTranscriptList, List<Id> transcriptContactIds){
    List<LiveChatTranscript> transcriptsToUpdate     = new List<LiveChatTranscript>();
    List<Contact>            contactsToRemove        = new List<Contact>();
    List<Account>            newPersonAccounts       = new List<Account>();
    List<Case>               casesToReassign         = new List<Case>();
    Map<Id, Account>         contactIdToPersonAccMap = new Map<Id, Account>();
    Map<Id, Contact>         transcriptContactDetails;

    //Get the correct record type id for personaccounts
    String b2cRecordType = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('PersonAccount').getRecordTypeId();

    //Retrieve additional needed attributes on the chat transcript
    transcriptContactDetails = new Map<Id, Contact>([SELECT FirstName
                                                     , LastName
                                                     , Email
                                                     , AccountId
                                                     FROM Contact WHERE Id IN: transcriptContactIds]);

    //Make sure to only handle change isolated contacts
    for (LiveChatTranscript transcript : chatTranscriptList) {
        if (transcript.ContactId != null && transcriptContactDetails.get(transcript.ContactId).AccountId == null) {
            transcriptsToUpdate.add(transcript);
            contactsToRemove.add(transcriptContactDetails.get(transcript.ContactId));
            Account newPersonAcc = new Account(RecordTypeId = b2cRecordType,
                                               FirstName   = transcriptContactDetails.get(transcript.ContactId).FirstName,
                                               LastName    = transcriptContactDetails.get(transcript.ContactId).LastName,
                                               PersonEmail = transcriptContactDetails.get(transcript.ContactId).Email
                                               );
            newPersonAccounts.add(newPersonAcc);
            contactIdToPersonAccMap.put(transcript.ContactId, newPersonAcc);
        }
    }
    insert newPersonAccounts;

    //reassign the cases
    casesToReassign = [SELECT AccountId, ContactId FROM Case WHERE ContactId IN :contactsToRemove];
    for (Case reassignedCase : casesToReassign) {
        reassignedCase.AccountId = contactIdToPersonAccMap.get(reassignedCase.ContactId).Id;
        reassignedCase.ContactId = null;
    }

    //reassign cases and remove the no longer needed contacts
    update casesToReassign;
    delete contactsToRemove;

    //reassign the chat
    for (LiveChatTranscript transcript : transcriptsToUpdate) {
        Account personAcc = contactIdToPersonAccMap.get(transcript.ContactId);
        transcript.AccountId = personAcc.Id;
        transcript.ContactId = null;
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .