Writing an Inbound Email Service for Salesforce.com
March 12th, 2010
Creating an inbound email service for Salesforce.com is a relatively straight forward process but there are a few thing to explain to make your life easier. The email service is an Apex class that implements the Messaging.InboundEmailHandler interface which allows you to process the email contents, headers and attachments. Using the information in the email, you could for instance, create a new contact if one does not exists with that email address, receive job applications and attached the person’s resume to their record or have an integration process that emails data files for processing.
You access email services from Setup -> Develop -> Email Services. This page contains the basic code you will always use to start your Apex class. Simply copy this code and create your new class with it. Click the “New Email Service” button to get started and fill out the form. There are a number of options so make sure you read carefully and check out the docs. One handy option is the “Enable Error Routing” which will send the inbound email to an alternative email address when the processing fails. You can can also specify email address(es) to accept mail from. This works great if you have some sort of internal process that emails results or file for import into Salesforce.com. Just like Workflow, make sure you mark it as “Active” or you will pull your hair out during testing.
After you save the new email service, you will need to scroll down to the bottom of the page and create a new email address for the service. An email service can have multiple email addresses and therefore process the same message differently for each address. When you create a new email service address you specify the “Context User” and “Accept Email From”. The email service uses the permissions of the Context User when processing the inbound message. So you could, for example, have the same email service that accepts email from US accounts and processes them with a US context user and another address that accepts email from EMEA accounts and processes them with an EMEA context user. After you submit the from the Force.com platform will create a unique email address like the following. This is the address you send your email to for processing.
testemailservice@8q8zrtgg1w37vpomrhpqftj25.in.sandbox.salesforce.com
Now that the email service is configured we can get down to writing the Apex code. Here’s a simple class the creates a new contact and attaches any documents to the record.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | global class ProcessJobApplicantEmail implements Messaging.InboundEmailHandler {
global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,
Messaging.InboundEnvelope envelope) {
Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
Contact contact = new Contact();
contact.FirstName = email.fromname.substring(0,email.fromname.indexOf(' '));
contact.LastName = email.fromname.substring(email.fromname.indexOf(' '));
contact.Email = envelope.fromAddress;
insert contact;
System.debug('====> Created contact '+contact.Id);
if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) {
for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) {
Attachment attachment = new Attachment();
// attach to the newly created contact record
attachment.ParentId = contact.Id;
attachment.Name = email.binaryAttachments[i].filename;
attachment.Body = email.binaryAttachments[i].body;
insert attachment;
}
}
return result;
}
} |
One of the difficult thing about email service is debugging them. You can either create a test class for this or simply send the email and check the debug logs. Any debug statements you add to your class will show in the debug logs. Go to Setup -> Administration Setup -> Monitoring -> Debug Logs and add the Context User for the email service to the debug logs. Simply send an email to the address and check the debug log for that user.
One thing I wanted to see was the actual text and headers that are coming through in the service. Here’s an image of virtually all fields and headers in a sample email. Click for more details.
![]()
The following unit test will get you 100% code coverage.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | static testMethod void testMe() {
// create a new email and envelope object
Messaging.InboundEmail email = new Messaging.InboundEmail() ;
Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
// setup the data for the email
email.subject = 'Test Job Applicant';
email.fromname = 'FirstName LastName';
env.fromAddress = 'someaddress@email.com';
// add an attachment
Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment();
attachment.body = blob.valueOf('my attachment text');
attachment.fileName = 'textfile.txt';
attachment.mimeTypeSubType = 'text/plain';
email.binaryAttachments =
new Messaging.inboundEmail.BinaryAttachment[] { attachment };
// call the email service class and test it with the data in the testMethod
ProcessJobApplicantEmail emailProcess = new ProcessJobApplicantEmail();
emailProcess.handleInboundEmail(email, env);
// query for the contact the email service created
Contact contact = [select id, firstName, lastName, email from contact
where firstName = 'FirstName' and lastName = 'LastName'];
System.assertEquals(contact.firstName,'FirstName');
System.assertEquals(contact.lastName,'LastName');
System.assertEquals(contact.email,'someaddress@email.com');
// find the attachment
Attachment a = [select name from attachment where parentId = :contact.id];
System.assertEquals(a.name,'textfile.txt');
} |
Here are a few links that may be helpful:
- Inbound Email docs with object definitions
- Retrieving Information from Incoming Email Messages (Force.com Cookbook)
- Force.com Email Services Unsubscribe
- String methods
Categories: Apex, Code Sample, Salesforce













Hi Jeff,
Thanks for the wonderful post on this topic.
How can we know the data size limits on email message body and the attachment that can be processed by this inbound handler.
thanks,
roge.
Check the Salesforce docs for the actual size limits.
Great post Jeff. What do you think about using text vs binary attachments? The email service setup screen offers to convert text attachments to binary to save on size limitations.
Thoughts?
I honestly didn’t put much thought into it at the time. I believe I originally changed the code to accept both types.
Great posting Jeff! I’ve been searching all day for something similar and I think you just ended my search!
)
Question – when I ran my tests I had multiple Contacts created with the same email. I’m not seeing where it searches SFDC for the contact’s email address to see if it already exists? What am I missing?
Thanks for any help you can provide!
@Rachael, my code above doesn’t search for duplicate email addresses. It simply creates a new contact with that email address.
Oh
At the top of your posting it said something about searching for the email and then creating one if it doesn’t already exist. I think I have some code that I can use to modify your posting to my needs. Thanks again for the awesome post!
jeff.. nice.. keep going…
u rock
Sweet… I’ve been looking or a decent example of how to achieve test coverage for an inbound message handler for two days. Thanks Jeff!
Hey Jeff,
Nice post. Am using an Inbound email service and I’ve added the System User (with which I created the org wide email address) to debug logs. However, system.debug()s from inside the inbound email service don’t seem to show up there – other stuff are creating logs properly. Any idea what I might be missing?
Great post. I’ve been running into alot of bounce back emails when sending to the email service. This happens both in Developer and in Sandbox. Of course ive added those test emails to the “Allow Email From” field, but the messages from those senders is still getting bounced back. Also simply left the field blank to allow email from all users and still, they get bounced. However sending from hotmail seems to work flawlessly, outlook and gmail not so much.
Any thoughts?
Figured it out. Apparently there’s an “Allow Email From” in both the Email Service and the Email Service Email Address. They must both match.
Hello Jeff
Your blog and your book are absolutely wonderful, I’ve followed many tidbits from your blogs and am a big fan.
I just recently had the opportunity to write an inbound email handler and test class similar to one you have listed above and I’m noticing that my test passes with 100% coverage, however when I go to send an email to the email service I’m getting delivery failure. Just wondering if you had any insights.
Thanks
Unni
@Unni, I would add some debug statements in your to your test class and then check the error logs. You might even have a network issue so make sure your email is even making it to the handler.
Thanks for sharing…
[...] to the email address associated with our Email Service. (More info on this can be found here, here, here and here.) When our email service receives a valid Apex Application email, it call the [...]
Hi Jeff,
Excellent post and really helpful.
If I had to send an email to test the above Email service, what will be the subject and content of the body in my email.
Does it have to be in a specific format, for the contact to be created ?
@Vineeth, take a look at the attached test class and they should give you the info you need.
Hi Jeff, That worked fine. thanks.
If I send an email with the following email body:
Name: George
Status: New
Priority: High
I would like to populate the fields, Name(Text), Status(Picklist) and Priority(CheckBox) on the object. Is there any way to accomplish this ?
Jeff,
I’m new (brand new) to writing Apex code. I have a need to use the email services you refer to here in this blog. What should I do to get started for the very first time.
Hi Jeff,
Do you know why the ‘single email message’ ‘reply-to’ is not working when I specify an ‘email service’ address?
I’m trying to complete an email service to handle an approval process requests. Everything is working fine if I manually put the email service address in the ‘to’ box of my email. I cant figure out why the email service address is not showing up in my ‘to’ box automatically when i click ‘reply’ to the email and the single email message reply-to was set to the email service address.
I also tried to setup the email service address as an organizational wide email address so I can just send from the email service address and hopefully force the correct reply-to. However the verification email sent when you setup an Org Wide email is not coming through. I do not understand this either as I have setup an inbound email class for the address to create a task for my user. So I could receive and click on the verification link. No email comes through.
Thanks in advance for any advise.
Jeff, I am trying to do a similar thing to Vineeth, I am sending an auto email to a Shipping Carrier for a quote on an existing opportunity, where they respond back quoting me a price with their quote id. He will use the opp id as his reference back, of course once i figure out how to parse out the email subject I will just put in subject line, the ex. is,
Opportunity Id:
PriceQuote (custom field inside opportunity):
ABFQuoteId (custom field inside opportunity):
I tried and tried and can’t seem to figure out how to do it?
Thanks for the help in advance.
Matthew, I would look into using regex to find the field in the email. It’s a painful operation unfortunately.
@Kelvin, check out the Salesforce Help in the upper right of your org. There is alot of sample code. Also check out http://developer.force.com/cookbook for some sample code.