+ Start a Discussion
Simon MertonSimon Merton 

Creating New Contacts from Email-To-Case

Hi all

I'm very new to Salesforce, and my first assignment is to get our Production Org's Email-To-Case working correctly, and to find a way to create new Contacts for the Cases if they did not already exist.

After some searching on these forums I found an Apex Trigger that worked perfectly within our Sandbox. However, it fails to create Contacts in Production.

I've checked the trigger is active and triggered and I have also checked permssions. It also has 96% code coverage in Production. Has anyone got any ideas why Sandbox works and Production does not?

Apex Trigger as follows:

trigger TriggertoCreateContactformCase on Case (before insert) {
    List<String> UseremailAddresses = new List<String>();
    //First exclude any cases where the contact is set
    for (Case c:Trigger.new) {
        if (c.ContactId==null &&
            c.SuppliedEmail!=''|| c.SuppliedEmail==null)
        {
            UseremailAddresses.add(c.SuppliedEmail);
        }
    }

    //Now we have a nice list of all the email addresses.  Let's query on it and see how many contacts already exist.
    List<Contact> listofallContacts = [Select Id,Email From Contact Where Email in:UseremailAddresses];
    Set<String> ExstingEmails = new Set<String>();
    for (Contact c:listofallContacts) {
        ExstingEmails.add(c.Email);
    }
    
    Map<String,Contact> emailToContactMap = new Map<String,Contact>();
    List<Case> casesToUpdate = new List<Case>();

    for (Case c:Trigger.new) {
        if (c.ContactId==null &&
            c.SuppliedName!=null &&
            c.SuppliedEmail!=null &&
            c.SuppliedName!='' &&
           !c.SuppliedName.contains('@') &&
            c.SuppliedEmail!='' &&
           !ExstingEmails.contains(c.SuppliedEmail))
        {
            //The case was created with a null contact
            //Let's make a contact for it
            String[] Emailheader = c.SuppliedName.split(' ',2);
            if (Emailheader.size() == 2)
            {
                Contact conts = new Contact(FirstName=Emailheader[0],
                                            LastName=Emailheader[1],
                                            Email=c.SuppliedEmail
                                            );
                emailToContactMap.put(c.SuppliedEmail,conts);
                casesToUpdate.add(c);
            }
        }
    }
    
    List<Contact> newContacts = emailToContactMap.values();
    insert newContacts;
    
    for (Case c:casesToUpdate) {
        Contact newContact = emailToContactMap.get(c.SuppliedEmail);
        
        c.ContactId = newContact.Id;
    }
}


Many thanks in advance!!!!

Best Answer chosen by Simon Merton
Kaustubh LabheKaustubh Labhe
Hi Simon,

Thas right. Its triggering. 

Now do me a favour. put system.debug statements in the loops to check if the logic goes there or not. 

So for example, put a debug statement after the for statement, to check if the userEmailAddress list has anything populated there. 
...
for (Case c:Trigger.new) {
        if (c.ContactId==null &&
            c.SuppliedEmail!=''|| c.SuppliedEmail==null)
        {
            UseremailAddresses.add(c.SuppliedEmail);
        }
    }
System.debug('Simon was here ' +  UseremailAddresses + '  ' +  UseremailAddresses.size());

//Now we have a nice list of all the email addresses.  Let's query on it and see how many contacts already exist.
    List<Contact> listofallContacts = [Select Id,Email From Contact Where Email in:UseremailAddresses];
    Set<String> ExstingEmails = new Set<String>();
    for (Contact
...

Then in Setup ==> Debug logs, in the latest log, check for Simon was here. Do you get the idea? You can add system.debug('text') anywhere in the code and check if the logic hits it or not.

Thx

All Answers

Kaustubh LabheKaustubh Labhe
Hi,

Can you help me understand this? 
 
for (Case c:Trigger.new) {
        if (c.ContactId==null &&
            c.SuppliedEmail!=''|| c.SuppliedEmail==null)
        {
            UseremailAddresses.add(c.SuppliedEmail);
        }
    }

So you are checking if the case doesnt have contact and supplied email is null or empty? shouldnt it be SuppliedEmail != null? 
So that you get a list of such cases where contacts aint there but has a email. Am I  missing something here?
Simon MertonSimon Merton
I copied this trigger from another post here on the forum, so didn't originate the code. When I started to look through it I thought it was odd that SuppliedEmail==null and not SuppliedEmail!=null.

I've changed the trigger accordingly. Yet again, it works in Sandbox but not in Production, so I guess something else must be the issue.
Kaustubh LabheKaustubh Labhe
Hey, can you put system.debugs in the code, and check when a case is created, is the trigger fired? 
Also is the trigger active in production? On the trigger there is a checkbox.
Simon MertonSimon Merton
Hi Kaustubh. The trigger is active in production.

I'm not sure where to put the system.debug? In the trigger?

If I create a new case (rather than let Email-to-Case create a case) and look at the log I get the following lines that I assumed related to the trigger:

15:05:55.0 (352213)|CODE_UNIT_STARTED|[EXTERNAL]|TRIGGERS
15:05:55.0 (375971)|CODE_UNIT_STARTED|[EXTERNAL]|01q2X000000VAfG|TriggertoCreateContactformCase on Case trigger event BeforeInsert|__sfdc_trigger/TriggertoCreateContactformCase
15:05:55.0 (13522975)|SOQL_EXECUTE_BEGIN|[13]|Aggregations:0|SELECT Id, Email FROM Contact WHERE Email IN :tmpVar1
15:05:56.571 (1571820663)|SOQL_EXECUTE_END|[13]|Rows:14179
*** Skipped 1499862 bytes of detailed log

Does this mean it is triggering?
 
Kaustubh LabheKaustubh Labhe
Hi Simon,

Thas right. Its triggering. 

Now do me a favour. put system.debug statements in the loops to check if the logic goes there or not. 

So for example, put a debug statement after the for statement, to check if the userEmailAddress list has anything populated there. 
...
for (Case c:Trigger.new) {
        if (c.ContactId==null &&
            c.SuppliedEmail!=''|| c.SuppliedEmail==null)
        {
            UseremailAddresses.add(c.SuppliedEmail);
        }
    }
System.debug('Simon was here ' +  UseremailAddresses + '  ' +  UseremailAddresses.size());

//Now we have a nice list of all the email addresses.  Let's query on it and see how many contacts already exist.
    List<Contact> listofallContacts = [Select Id,Email From Contact Where Email in:UseremailAddresses];
    Set<String> ExstingEmails = new Set<String>();
    for (Contact
...

Then in Setup ==> Debug logs, in the latest log, check for Simon was here. Do you get the idea? You can add system.debug('text') anywhere in the code and check if the logic hits it or not.

Thx
This was selected as the best answer
Simon MertonSimon Merton
Thanks Kaustubh. This is suddenly make sense to me.

I'll add some System.debug statements to the trigger and report back my findings.
Kaustubh LabheKaustubh Labhe
If your issue is resolved, can you close this post and mark my answer as best answer? 

Cheers Simon. 
Simon MertonSimon Merton
Thanks Kaustubh

After spending some time debugging, the Apex Trigger does seemt to work as intended. However, it looks like the Outlook settings were the issue. A rule was being used to redirect emails to the email-to-case routing address, rather that forwarding emails via the settings. Consequently, Salesforce interpreted the sender as our Team's inbox instead of the original sender.

I wouldn't have discovered this without your tips on debugging :)

Simon