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
Dan Dodd 3Dan Dodd 3 

Display htmlBody of original email in Case Description

Our org in new to case managment and we are using email-to-case
We receive emails from a third party system that has a formatted body.
We would like to view the formatted body instead of the cse description that is plain text
I added a RichText field to save the body into and have tried a trigger, workflow and process builder.

Here is the section of the trigger ( before insert )
// bulkify by only doing this if Trigger.New.Size == 1
if ( true ) {
// Insert Email Body into custom field
EmailMessage emailMsg = [SELECT id, ParentId, FromName, FromAddress, HtmlBody, TextBody
FROM EmailMessage
WHERE Id = :cs.SourceId
AND Incoming = true
Limit 1];
if ( emailMsg != null && emailMsg.HtmlBody != null) {
cs.lutd_Description_Rich__c = 'Not Null htmlBody';
//cs.lutd_Description_Rich__c = emailMsg.HtmlBody;
} else if ( emailMsg != null && emailMsg.TextBody != null){
cs.lutd_Description_Rich__c = 'Checking textBody'; //emailMsg.textBody;
} else {
cs.lutd_Description_Rich__c = 'Null email message';
}
//cs.lutd_Description_Rich__c = cs.description ; works as expected
}
I dont get the htmlBody.
In the developer console I see the htmlBody using the same SOQL subtitutng the SourceId of the case. 


 
Best Answer chosen by Dan Dodd 3
Derrick AbbeyDerrick Abbey
Hi Dan,

Using Email-To-Case is a bit of an odd way of handling what you're trying to do.  If you want to have a custom Apex handler for inbound emails, you're better off using an Email Serivce.  You can check out the Email Service documentation here (https://help.salesforce.com/articleView?id=code_email_services_overview.htm&type=5).

As far as the code, I see that you've got line 11 commented out.  Is that intentional?  That is the line that would normally be putting your html body into your rich text area field.

Here's some updates to clean things up a bit as well.
// bulkify by only doing this if Trigger.New.Size == 1  --This isn't really bulkifying, it's just making the trigger not break if there's more than one.

if ( true ) {//I assume that this condition will be updated to only run on cases created via Email-To-Case
	// Insert Email Body into custom field
	EmailMessage emailMsg = [SELECT id, ParentId, FromName, FromAddress, HtmlBody, TextBody
							FROM EmailMessage
							WHERE Id = :cs.SourceId
							AND Incoming = true
							Limit 1];
	
	//I removed the emailMsg != null condition because the query in line 5 will return an error and cause the trigger to fail if no record is found.
	if (emailMsg.HtmlBody != null) {
		//cs.lutd_Description_Rich__c = 'Not Null htmlBody';  -- this was just a placeholder
		cs.lutd_Description_Rich__c = emailMsg.HtmlBody;//I uncommented this since this line is where the HTMLBody is inserted.
	} else if (emailMsg.TextBody != null){
		cs.lutd_Description_Rich__c = 'Checking textBody'; //emailMsg.textBody;
	} else {
		cs.lutd_Description_Rich__c = 'Null email message';
	}
	//cs.lutd_Description_Rich__c = cs.description ; works as expected
}

 

All Answers

Derrick AbbeyDerrick Abbey
Hi Dan,

Using Email-To-Case is a bit of an odd way of handling what you're trying to do.  If you want to have a custom Apex handler for inbound emails, you're better off using an Email Serivce.  You can check out the Email Service documentation here (https://help.salesforce.com/articleView?id=code_email_services_overview.htm&type=5).

As far as the code, I see that you've got line 11 commented out.  Is that intentional?  That is the line that would normally be putting your html body into your rich text area field.

Here's some updates to clean things up a bit as well.
// bulkify by only doing this if Trigger.New.Size == 1  --This isn't really bulkifying, it's just making the trigger not break if there's more than one.

if ( true ) {//I assume that this condition will be updated to only run on cases created via Email-To-Case
	// Insert Email Body into custom field
	EmailMessage emailMsg = [SELECT id, ParentId, FromName, FromAddress, HtmlBody, TextBody
							FROM EmailMessage
							WHERE Id = :cs.SourceId
							AND Incoming = true
							Limit 1];
	
	//I removed the emailMsg != null condition because the query in line 5 will return an error and cause the trigger to fail if no record is found.
	if (emailMsg.HtmlBody != null) {
		//cs.lutd_Description_Rich__c = 'Not Null htmlBody';  -- this was just a placeholder
		cs.lutd_Description_Rich__c = emailMsg.HtmlBody;//I uncommented this since this line is where the HTMLBody is inserted.
	} else if (emailMsg.TextBody != null){
		cs.lutd_Description_Rich__c = 'Checking textBody'; //emailMsg.textBody;
	} else {
		cs.lutd_Description_Rich__c = 'Null email message';
	}
	//cs.lutd_Description_Rich__c = cs.description ; works as expected
}

 
This was selected as the best answer
Dan Dodd 3Dan Dodd 3
Derrick thanks!
Good points here 
  • Yes not really a bulkify but a problem preventer. The rest of the code is bulkified.  Will this cause a problem if there are several emails coming in at once? Will SF run two cases thru the code if it can, causing me to miss one?
  • Right,  the "true" was for testing as was the putting a comment in the description field.   Would Trigger.New.Size == 1 outside the loop and cs.Origin == 'Email' inside  be more reliable?
  • The query in line 5 will return an error and cause the trigger to fail if no record is found. What is the best way to trap this and not fail? Try catch or is there some other test I can do or is wrapping it with if (cs.Origin == 'Email' ) enough?
  • And finally yes I want to put the htmlBody into the new field which is the pointonce I can see it..
Thanks


 
Derrick AbbeyDerrick Abbey
Hi Dan,

So I ran some tests in a scratch org.  It looks like doing this with a trigger is a bit problematic. The reason is because the EmailMessage record is saved to the database after the case is.  So a trigger on the case insert won't find the EmailMessage record because it hasn't been created yet. You could create a trigger on the EmailMessage object, but I wouldn't recommend that.

As I mentioned, creating an Email Service to handle these with an Apex handler is probably the best option.  It only took me about 20 minutes to create a simple handler and set up the service.  I tested it, and it works great.  Here's the Apex:
global class EmailToCaseHandler implements Messaging.InboundEmailHandler {
    
    global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email,Messaging.InboundEnvelope env){
        Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

        //Create the case to insert
        Case cs = new Case(Subject = email.subject, Description = email.plainTextBody, Origin = 'Email', lutd_Description_Rich__c = email.htmlBody);
        try{
            //insert the case
            insert cs;

            //set the result success to true
            result.success = true;
        } catch (Exception exp){

            //very simple error handling
            System.debug('Error occurred:' + exp.getMessage());
        }

        //return the result
        return result;
    }
}

 
Dan Dodd 3Dan Dodd 3
Hi Derrick, 
In our situation we are creating the case from the email using On Demand Email-To-Case so that is why I was expecting the email to exist before the case.
Where would this sample code fit in the process? I wouldn't want to take over from Email-To-Case
I need to read up on the InboundEmailHandler.

its a puzzler.
I am displaying the HtmlBody via a visualforce page that I picked up here : 
How To Show HTML Email Right On Your Case Page (https://success.salesforce.com/ideaView?id=087300000007TOe)
And in testing for that I found this about someone doing about the same thing:
Test coverage of Case and EmailMessage triggers (https://salesforce.stackexchange.com/questions/159544/test-coverage-of-case-and-emailmessage-triggers)
Which gave me some ideas.
thanks for your help.

Dan D.