Jan 2, 2012

Custom Salesforce Email Service

Email to Salesforce is a nice shrink-wrapped feature, but it lacks some functionality that I think is very necessary. For example, when Highrise CRM users using the Highrise dropbox feature, the email service looks for matching email addresses in the body of the email in addition to the TO and CC lists. To create that functionality in Salesforce, you need to write your own email service.

In this post I am going to concentrate on what I wrote to parse the email addresses out of the TO and CC lists as well as the body of the email. Parsing the TO and CC lists is necessary because these arrays usually include texts that looks like this - "John Doe <john@doe.com>".

I was able to create one method that will do the work for both the lists and the email body. To do that I used the apex classes Pattern and Matcher, which are very useful, but pretty confusing to work with. These classes give you the ability to search through strings and return matches based on a regex (regular expression). I always find it very tedious to write regexes, so I borrowed an email regex from Jan Goyvaerts.

This method is pretty handy. I also used it to find the "from:" email address of a forwarded email so I can create a contact if needed (I didn't include that piece of code as it is using the same stuff - Pattern, Matcher, and my handy method). Note that if you only want to find the first email address in a given string, you only need to change the while to an if.

global class MyEmailService implements Messaging.InboundEmailHandler {

    global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope env) {
 
        Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
  
        // declare an array to hold all the email addresses that we find
        String[] emailAddresses = new String[0];

        // get all the to and cc addresses
        emailAddresses.addall(getEmails(email.toAddresses));
        emailAddresses.addall(getEmails(email.ccAddresses));

        // get all email addresses from the body of the email
        emailAddresses.addall(getEmails(new string[]{email.plainTextBody}));


        ....... Do something with the email addresses we found ......


        return result;
    }

    // get email addresses from an array of strings
    public String[] getEmails(String[] strings) { 
 
        // set up an array to hold the emails
        String[] emailAddresses = new String[0];

        if (strings != null) {
            
            // set up a pattern with an email regex (assume lower case)
            Pattern emailPattern = Pattern.compile('\\b[a-z0-9._%-]+@[a-z0-9.-]+\\.[a-z]{2,4}\\b');
            Matcher emailMatcher;

            // go through each string and add any valid email address to the return array
            for (string str : strings) {
             emailMatcher = emailPattern.matcher(str.toLowerCase());
             while (emailMatcher.find())
                 emailAddresses.add(str.substring(emailMatcher.start(), emailMatcher.end()));
            }
        }
        return emailAddresses; 
    }
}