1

Within an email-service apex class, I am trying to scan the body of an incoming email for the following text:

Name: James Johnson
Email Address: [email protected]

How would I use my apex class to capture "James Johnson" from the body of the email, and insert it into the Account's "Name" field? Likewise I would like to capture "[email protected]" and insert it into the "Email" field.

global class EmailDemoReceive implements Messaging.InboundEmailHandler {
global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, 
                                                     Messaging.Inboundenvelope envelope) {
Account account;
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
System.debug('############'+result);

try 
{
    // Look for account whose name is the subject and create it if necessary
    if ([select count() from Account where Name = :email.subject] == 0) 
    {
         account = new Account();
         account.Name = email.subject;
         System.debug('############'+account.Name );
         insert account;
         System.debug('account inserted');
    } 
    else 
    {
        account = [select Id from Account where Name = :email.subject];
    }
    // Convert cc'd addresses to contacts
    for (String address : email.ccAddresses) 
    {
         System.debug('for loop activated');
         Contact contact = new Contact();
         Matcher matcher = Pattern.compile('<.+>').matcher(address);

         // Parse addresses to names and emails
         if (matcher.find()) 
         {
            String[] nameParts = address.split('[ ]*<.+>')[0].replace('"', '').split('[ ]+');

            contact.FirstName = nameParts.size() > 1 ? nameParts[0] : '';
            contact.LastName = nameParts.size() > 1 ? nameParts[nameParts.size()-1] : nameParts[0];
            contact.Email = matcher.group().replaceAll('[<>]', '');
         } 
         else 
         {
             contact.LastName = address;
             contact.Email = address;
         }

        // Add if new
         if ([select count() from Contact where Email = :contact.Email] == 0) 
         {
             contact.AccountId = account.Id;
             insert contact;
         }
    }
    // Save attachments, if any
    for (Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments) 
    {
        Attachment attachment = new Attachment();

        attachment.Name = tAttachment.fileName;
        attachment.Body = Blob.valueOf(tAttachment.body);
        attachment.ParentId = account.Id;
        insert attachment;
    }

    for (Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) 
    {
         Attachment attachment = new Attachment();

         attachment.Name = bAttachment.fileName;
         attachment.Body = bAttachment.body;
         attachment.ParentId = account.Id;
         insert attachment;
    }
    // Turn email body into note
    Note note = new Note();

    note.Title = email.fromName + ' (' + DateTime.now() + ')';
    note.Body = email.plainTextBody;
    note.ParentId = account.Id;
    insert note;
    result.success = true;
} 
catch (Exception e) 
{
  result.success = false;
  //result.message = "Oops, I failed";
  System.debug('Oops I failed');
}

return result;
 }
 }
8
  • and what have you tried so far? --- etiquette is to not have the folks at the community write your code for you without a good faith effort on your part
    – cropredy
    Sep 10, 2015 at 16:52
  • Sure. I didn't want to overwhelm anyone with the code. But you're right. Let me post it anyways. @crop1645 Sep 10, 2015 at 16:54
  • You can save the body to a custom long text field and trim the text to map the account fields. Sep 10, 2015 at 17:02
  • Thank you again @SalesforceLearner .. What is the process of saving the entire body to a text field? Just Text_field__c = email.body? Or is it more complex? Sep 10, 2015 at 17:06
  • In the above code I shared, we are saving the email body to Notes so comment that part of code and map it to your account text field and try Sep 10, 2015 at 17:12

2 Answers 2

3

You will need to determine if the inbound email has a plain text body. If it doesn't then you need to convert the html to plain text.

string bodyText;
if (string.isEmpty(email.plainTextBody)
   bodyText = HtmlToText(email.htmlBody);
else
   bodyText = email.plainTextBody;

public static string HtmlToText(string html){
   //replace all <BR> tags with \n to support new lines
   string result = html.replaceAll('<br/>', '\n');
   result = result.replaceAll('<br />', '\n');

   //all HTML/XML tags
   string HtmlPattern = '<.*?>';

   Matcher match =  Pattern.compile(HtmlPattern).matcher(result);

   //remove the tags and return string     
   return match.replaceAll('');
}

Next, use a Matcher to search for 'Name:' and 'Email Address:'. These are two possible regular expressions that will return a line of text that starts with 'Name:' and 'Email Address:'

(?m)(?i)^name:.*

(?m)(?i)^email address:.*

These are multiline (?m) case-insensitive (?i) patterns that will match lines starting with Name: and Email Address:

Once you have the name and email address lines you can parse again to get the values you need to update the Account or Contact object.

The regular expressions above are based on my limited knowledge of what the actually email looks like. Be sure to test thoroughly in your unit test.

2
  • Thank you. I am still having trouble getting the parsed text to populate in one of my fields..but I will reference this until I figure it out. I am brand new to the pattern and matcher classes. Sep 11, 2015 at 0:09
  • I find it easier to test and refine regular expressions outside of my programs. There are many online sites to test expressions. Sep 11, 2015 at 12:35
1

stripHtmlTags() string function will work for you.

Following example is from the official documentation -

String s1 = '<b>hello world</b>';
String s2 = s1.stripHtmlTags();
System.assertEquals('hello world', s2);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .