function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Mike Reynolds 6Mike Reynolds 6 

Using trigger to update case when first emailMessage is received

Hey, 

I'm trying to update a case with some details of the related email message. I need the case to be updated before Assignment rules are run. I would also like to limit the trigger to only fire when this is the first email associated to the case. I've been able to get it this far, but it's not working and I have no idea where I've gone wrong. Any help is greatly appreciated. 

Once this is working I'll move much of the work into a helper class and refactor the trigger into the existing case trigger. 
 
trigger EmailToCaseTrigger on Case(after insert) {
    system.debug('Here in Trigger');
    List<case> cases=new List<Case>();
    for(Case c:Trigger.new){
        List<EmailMessage> em=[select ToAddress,FromAddress,CcAddress,FromName from EmailMessage 
                               where ParentId=:c.Id and Incoming=true and Parent.Number_of_Messages_Received__c=0];
        	if(em!=null && em.size()>0){
            	c.Email_To_Address__c=em[0].ToAddress;
            	c.From_Address__c=em[0].FromAddress;
            	c.Email_CC_Address__c=em[0].CcAddress;
            	c.Email_From_Name__c=em[0].FromName;
            	cases.add(c);
        	}
    	}
    if(cases.size()>0)
    update cases;         
}

 
Best Answer chosen by Mike Reynolds 6
Vivian Charlie 1208Vivian Charlie 1208

Hi Mike,

 

I see that the trigger you have developed does not follow Salesforce best practices. You have SOQL queries inside the for loop which is a bad practice. Please review the below link for the best practices.

https://developer.salesforce.com/page/Apex_Code_Best_Practices

 

Try this piece of code for now

trigger EmailToCaseTrigger on Case(after insert) {
    system.debug('Here in Trigger');
    List<case> cases=new List<Case>();
    
	List<EmailMessage> em=[select ToAddress,FromAddress,CcAddress,FromName from EmailMessage 
                           where ParentId IN : trigger.newMap.keyset() 
						   and Incoming = true 
						   and Parent.Number_of_Messages_Received__c = 0];
	
	map<Id,EmailMessage> mapCaseId_Email = new map<Id,EmailMessage>();
	for(EmailMessage objEmail : em){
		mapCaseId_Email.put(objEmail.ParentId, objEmail); // I am assuming you have only 1 EmailMessage record else need the most recent record
	}
	
	if(!mapCaseId_Email.isEmpty()){
		for(Case c:Trigger.new){
			if(mapCaseId_Email.containsKey(c.Id)){}
				c.Email_To_Address__c=em[0].ToAddress;
				c.From_Address__c=em[0].FromAddress;
				c.Email_CC_Address__c=em[0].CcAddress;
				c.Email_From_Name__c=em[0].FromName;
				cases.add(c);
			}
		if(cases.size()>0){
			update cases;
		}
	}
}

Let me know in case you face any issues.

Thanks

Vivian

All Answers

Vivian Charlie 1208Vivian Charlie 1208

Hi Mike,

 

I see that the trigger you have developed does not follow Salesforce best practices. You have SOQL queries inside the for loop which is a bad practice. Please review the below link for the best practices.

https://developer.salesforce.com/page/Apex_Code_Best_Practices

 

Try this piece of code for now

trigger EmailToCaseTrigger on Case(after insert) {
    system.debug('Here in Trigger');
    List<case> cases=new List<Case>();
    
	List<EmailMessage> em=[select ToAddress,FromAddress,CcAddress,FromName from EmailMessage 
                           where ParentId IN : trigger.newMap.keyset() 
						   and Incoming = true 
						   and Parent.Number_of_Messages_Received__c = 0];
	
	map<Id,EmailMessage> mapCaseId_Email = new map<Id,EmailMessage>();
	for(EmailMessage objEmail : em){
		mapCaseId_Email.put(objEmail.ParentId, objEmail); // I am assuming you have only 1 EmailMessage record else need the most recent record
	}
	
	if(!mapCaseId_Email.isEmpty()){
		for(Case c:Trigger.new){
			if(mapCaseId_Email.containsKey(c.Id)){}
				c.Email_To_Address__c=em[0].ToAddress;
				c.From_Address__c=em[0].FromAddress;
				c.Email_CC_Address__c=em[0].CcAddress;
				c.Email_From_Name__c=em[0].FromName;
				cases.add(c);
			}
		if(cases.size()>0){
			update cases;
		}
	}
}

Let me know in case you face any issues.

Thanks

Vivian

This was selected as the best answer
Mike Reynolds 6Mike Reynolds 6
Hey @Vivian Charlie 1208 that was perfect. I didn't even notice that I had the SOQL in the for loop. As I'm sure you can tell I'm really new to the coding side of things. Thanks for the help!