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
Anton FlärdAnton Flärd 

Triggers and Classes - Extend Email-To-Case through matching TextBody

Hi

I'm trying to extend the Email-To-Case functionality and I'm not sure why it's not working.
The purpose of this is to read two lines from an incoming email and depending on the data from Salesforce, either create a new case or update a case.

I've tried swapping between using EmailMessage and Messaging.InboundEmailHandler but both produce errors and I think it's related to my crappy code. I've just been writing code for 3 days now so I'm very new to APEX/SOQL.

1) I'm pretty sure the RegEx is working since I've tested that in Execute Anonymous Window
2) How can I make this work?
3) In my APEX Class, what should i return when the statements in the code are validated?
4) As it is right now, I don't even know if my code is being triggered. How can I check this?
5) I still need to figure out how to post a message to a user and the Chatter implementation might not be working right now. Is it?

This is my trigger:
trigger op5EmailTrigger on EmailMessage (before insert) {
    op5EmailHandler.getEmailData(Trigger.new);
}

This is my APEX class:
 
global class op5EmailHandler {
    public static void getEmailData(EmailMessage messageList) {
            for(EmailMessage email : messageList) {
            try {
                if(email.fromAddress == 'hidden@for.now') {
                    String emailSubject = email.Subject;
                    String emailBody = email.TextBody;
                    Pattern assetPattern = Pattern.compile('((e)\\: )(.*)');
                    Pattern serialPattern = Pattern.compile('((l)\\: )(.*)');
                    
                    // define separate matchers for asset and serial
                    Matcher assetMatcher = assetPattern.matcher(emailBody);
                    Matcher serialMatcher = serialPattern.matcher(emailBody);
                    
                    if(assetMatcher.find() && serialMatcher.find()) {
                        String asset = assetMatcher.group(3);
                        String serial = serialMatcher.group(3);
                        Asset findAsset = [SELECT Id,AccountId FROM Asset WHERE (Serial_No__c=:serial AND Name=:asset)];
                        
                        String assetAccount = findAsset.AccountId;
                        String assetFound = findAsset.Id;
                        // array, as it may include multiple cases
                        Case[] returnedCases = [SELECT Id,CaseNumber FROM Case WHERE (AssetId=:assetFound AND Origin='Monitoring OP5' AND (Status!='Closed' OR Status!='No fault found') AND Type='Incident')];
                        
                        if(returnedCases.size() == 2) {
                            // create a new case
                            Case newCase = new Case(Subject=emailSubject, AccountId=assetAccount, AssetId=assetFound, Description=emailBody);
                            
                            insert newCase;
                            // post to chatter
                            String multipleCasesExists = 'There is multiple open cases for Asset: ' + assetMatcher.group(1) + ' with S/N: ' + serialMatcher.group(1) + ' and a new case has been created with Case Number: ' + newCase.CaseNumber + '. Please delete the cases that are irrelevant and use one case to track the alerts for this Asset.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, multipleCasesExists);
                            
                            
                        } else if(returnedCases.size() == 1) {
                            EmailMessage newEmail = new EmailMessage(FromAddress = email.FromAddress,
                                                                     FromName = email.FromName,
                                                                     ToAddress = email.ToAddress,
                                                                     Subject = email.Subject,
                                                                     TextBody = email.TextBody,
                                                                     HtmlBody = email.HtmlBody,
                                                                     Incoming = true,
                                                                     MessageDate = System.now(),     
                                                                     ParentId = returnedCases[0].Id);
                            
                            insert newEmail;
                            
                            
                            // post to chatter
                            String chatterMessage = 'New email from OP5 have been inserted into case: ' + returnedCases[0].CaseNumber + '. Please investigate if further action is needed.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, chatterMessage);
                            
                            // send email to case owner
                            
                            
                        } else {
                            // create new case
                            Case newCase = new Case(Subject=emailSubject, AccountId=assetAccount, AssetId=assetFound, Description=emailBody);
                            
                            insert newCase;
                            // post to chatter
                            String newCaseFromOP5 = 'New case: ' + newCase.CaseNumber + ' for Asset: ' + assetMatcher.group(1) + ' with S/N: ' + serialMatcher.group(1) + ' has been created, please take action asap.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, newCaseFromOP5);
                            
                        }
                    }
                }
                return email;
            } catch (Exception e) {
                return email;
            }
        }
    }
}

All I've done is read the error messages produced in the Developer Console. I havn't used the Execute Anonymous Window since I don't know how to with a Email.

Many many thanks in advance!

 
Best Answer chosen by Anton Flärd
Andy BoettcherAndy Boettcher
Intercepting and futzing around with Email to Case is a tricky proposition - most people go to an app on the AppExchange or create their own "Email to Case" functionality via Apex Email Handlers.

The best thing to do to see if this is actually firing or not is to start putting some Debug statements in your code - you will be able to see the logs generated via Developer Console for the user set in: Setup | Customize | Cases | Support Settings | Automated Case User.

I would throw System.Debug messages all over to see what is happening at each step, something like this:
 
global class op5EmailHandler {
    public static void getEmailData(EmailMessage messageList) {

            System.Debug('YAY!  I'M STARTING TO RUN!'); // <-- HERE

            for(EmailMessage email : messageList) {
            try {
                if(email.fromAddress == 'hidden@for.now') {
                    System.Debug('CHECK ME OUT!'); // <-- HERE
                    String emailSubject = email.Subject;
                    String emailBody = email.TextBody;
                    Pattern assetPattern = Pattern.compile('((e)\\: )(.*)');
                    Pattern serialPattern = Pattern.compile('((l)\\: )(.*)');
                    
                    // define separate matchers for asset and serial
                    Matcher assetMatcher = assetPattern.matcher(emailBody);
                    Matcher serialMatcher = serialPattern.matcher(emailBody);
                    
                    if(assetMatcher.find() && serialMatcher.find()) {
                        String asset = assetMatcher.group(3);
                        String serial = serialMatcher.group(3);
                        Asset findAsset = [SELECT Id,AccountId FROM Asset WHERE (Serial_No__c=:serial AND Name=:asset)];
                        
                        String assetAccount = findAsset.AccountId;
                        String assetFound = findAsset.Id;
                        // array, as it may include multiple cases
                        Case[] returnedCases = [SELECT Id,CaseNumber FROM Case WHERE (AssetId=:assetFound AND Origin='Monitoring OP5' AND (Status!='Closed' OR Status!='No fault found') AND Type='Incident')];
                        
                        System.Debug('NUMBER OF RETURNED CASES = ' + returnedCases.size()); // <-- HERE

                        if(returnedCases.size() == 2) {
                            // create a new case
                            Case newCase = new Case(Subject=emailSubject, AccountId=assetAccount, AssetId=assetFound, Description=emailBody);
                            
                            insert newCase;
                            // post to chatter
                            String multipleCasesExists = 'There is multiple open cases for Asset: ' + assetMatcher.group(1) + ' with S/N: ' + serialMatcher.group(1) + ' and a new case has been created with Case Number: ' + newCase.CaseNumber + '. Please delete the cases that are irrelevant and use one case to track the alerts for this Asset.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, multipleCasesExists);
                            
                            
                        } else if(returnedCases.size() == 1) {
                            EmailMessage newEmail = new EmailMessage(FromAddress = email.FromAddress,
                                                                     FromName = email.FromName,
                                                                     ToAddress = email.ToAddress,
                                                                     Subject = email.Subject,
                                                                     TextBody = email.TextBody,
                                                                     HtmlBody = email.HtmlBody,
                                                                     Incoming = true,
                                                                     MessageDate = System.now(),     
                                                                     ParentId = returnedCases[0].Id);
                            
                            insert newEmail;
                            
                            
                            // post to chatter
                            String chatterMessage = 'New email from OP5 have been inserted into case: ' + returnedCases[0].CaseNumber + '. Please investigate if further action is needed.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, chatterMessage);
                            
                            // send email to case owner
                            
                            
                        } else {
                            // create new case
                            Case newCase = new Case(Subject=emailSubject, AccountId=assetAccount, AssetId=assetFound, Description=emailBody);
                            
                            insert newCase;
                            // post to chatter
                            String newCaseFromOP5 = 'New case: ' + newCase.CaseNumber + ' for Asset: ' + assetMatcher.group(1) + ' with S/N: ' + serialMatcher.group(1) + ' has been created, please take action asap.';
                            ConnectApi.FeedElement sendToChatter = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), '0F925000000049v', ConnectApi.FeedElementType.FeedItem, newCaseFromOP5);
                            
                        }
                    }
                }
                return email;
            } catch (Exception e) {
                return email;
            }
        }
    }
}

That will give you insight as to if your code is actually firing or not.