Wednesday 9 October 2013

Understanding Inbound Email Services in Salesforce

Use of Inbound Email Service in one of my projects named Order Capture triggered my attention to know more deeply about this awesome process provided by Salesforce. So today I took some time to know about it and share it here.
As a part of Order Capture, in a nutshell, when we are creating/updating an Opportunity on a Prospect Account, the following steps happen:

     Workflow Rule --> Email Alert --> Inbound Email Service --> Execute an Apex Class --> Create a Prospect/Customer Account in SAP CRM

Moving forward, I would like to go through some of the basic steps which we follow while implementing Inbound Email Service in Salesforce.

An Introduction

Email services are one of the important Force.com processes that use Apex classes to process incoming email messages. When we set up an email service, we could generate a special email address on which Force.com will receive your emails. You also supply an Apex class adhering to a particular interface. The email services will then invoke a method on the Apex class whenever an email is received on the email address.Since they result in Apex logic being executed, the emails can be made to invoke any number of actions.

The rest of this section shows an example how to set up your inbound email service and write a simple Apex class to react to incoming email. Setting up an email service is simple:

  •   Build an inbound email handler Apex class for processing the email
  •   Configure the email service, binding it to the Apex class

Inbound Email Handler

An Apex class that acts as an inbound email handler simply needs to implement the Messaging.InboundEmailHandler interface.
The interface defines a single method: Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope envelope)
The message contents are available through the email argument, and the envelope stores the to and from address.

  This example processes incoming email as follows:

  •        Create a new Account record with the email subject as the account name
  •        Save the text and binary attachments
  •        Store the email body as a note

First, the class implements the Messaging.InboundEmailHandler interface, and all the activity happens in the handleInboundEmail() method.

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

          try {
          The email and envelope arguments have several public attributes you can access directly. First, let’s grab the email’s subject and create a new account record if it doesn’t already exist.
           // 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;
                       insert account;
                 } else {
                       account = [select Id from Account where Name =:email.subject];
                 }

       You can even access text and binary attachments:

       // 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;
       }

       And of course, you can access the body of an email as well. In this case we’re assuming a plain email (not an HTML one) and use the plainTextBody field:

       // 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;

       Here we explicitly indicate success or failure by setting the success field of our InboundEmailResult object.

      result.success = true;
     } catch (Exception e) {
           result.success = false;
           result.message = ‘Oops, I failed.’
    }

    return result;
  }
}


If a failure was indicated (if the success field is set to false) then the platform automatically rejects the inbound email and sends a reply email to the original sender containing the message specified in the message field.

Email Service

Next, you need to define the email service. This establishes an email address, which you can then tie to the Apex class that you’ve just written. Define the email service by logging into your environment:

  • Log into Force.com and select on Setup->App Setup->Develop->Email Services
  • Select New Email Service. You’ll see a screen:

          Give a name for Email Service Name, like say “EmailDemoReceive”
            For Apex Class, specify the Apex class you just built
            You can leave the rest of the fields at their default values for starters
            Hit Save

            That’s it, you’ve created your first email service. But you still need to generate an email address on which Force.com will listen for incoming emails. To do that, select New Email Address and fill as follows:

            Choose an id for Email address. This can be anything, like say "invoices" if you plan to process invoices with this address.
            Check Active.
            Set Context User – this specifies the context under which the Apex class will run. It defaults to you, but you’re free to pick another user from your organization.
            For Accept Emails From, give a comma-separated list of addresses (a@b.com) or domains (b.com) that Email Services can accept emails from. If you leave it blank, all addresses will work.
            Hit Save


  You will see a new email address that Force.com will monitor: emails received on this address will trigger the associated Apex code.

  That’s it! Any email sent to the above email address will now result in the Apex class being executed.

To Sum Up

In summary, to handle inbound emails all you have to do is:

  •      Create an Apex class that implements Messaging.InboundEmailHandler
  •      Create an email service that binds to that Apex class
  •      Create one or more email addresses, associated with the email service

In order to leverage the Inbound Email Service, for instance, we could create Contacts from the CC-ed part of Email. At that time, the following objects could be useful.


Happy Apex Coding! 

2 comments:

  1. Thank you very much.. As a beginner this helped a lot!

    ReplyDelete

Thank you for visiting. Your comments are highly appreciated.