Saturday 4 June 2011

Force.com Email Service (Execute apex code through email)



Violent way to start the post......SHOOT !! an Email...This is what we hear frequently ....and Salesforce has the ability to shoot email to itself and do relevant tasks based on the email sent. Isn't that cool...Lets see how this can be achieved..

Salesforce can send email to itself(specific org) and retrieve all the information in the email (like subject,text body,attachment etc) .This is facilitated by creating an apex class that implements Messaging.InboundEmailHandler interface. Simple example of this would be say email subject contains text "Create contact for Chaitanya" .We could read this field from subject (using relevant method)and create a contact for Chaitanya in the code. If the subject contains text "Delete contact for Chaitanya" proper delete action can be processed in the code.
 
Steps to Create an Email service .
1) Create an Apex class that implements Messaging.InboundEmailHandler interface .In this class mention all the processing (preferably call other class for complex operations )that needs to be done based on the subject/textbody/attachments of the email. Salesforce provides relevant methods to retrieve the specific information like
fromAddress :Email address mentioned in the from field
subject :Subject text of the email. 
plainTextBody :Plain text version of email etc 
Complete list is found here Doc

global class testEmailService implements Messaging.InboundEmailHandler
   {
     global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,Messaging.InboundEnvelope envelope)
       { 
     Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
    // Do all the processing here based on the information retrieved
    // Go to the following link for all the methods available for this interface    
   // https://na10.salesforce.com/help/doc/en/code_inbound_email.htm 
   return result;
        }
   }




2) Go to  Setup->Develop-> Email Services-> New Email Service
There are multiple fields on the page to fill.Of them some important fields are :
a) Email Service Name : Mention the relevant name for the email service
b) Apex Class: Mention the apex class that implements Messaging.InboundEmailHandler interface (Here in our case  "testEmailService")
c) Accept Email From : If this is filled out,the email service only works if the email is received from the addresses mentioned here.If email service receives a message from an email address or domain not listed out here, then the email service performs the action specified in the Unauthorized Sender Action failure response setting.
d) Active : Now dont ask me why isnt my email service not working .So please make this active  :)
e) Enable Error Routing :Fecilitates sending  email to an alternative email address incase of failure

3) Save the email service .Now the page displays "Email address" section which is the place to generate an automatic email address that will be consumed by our present Email service. Following are the fields on the page
a) Email Address :Its up to the person to give relevant local part of Email address.
b) Active : Do i have to tell this again :)
c) Context User :The email service uses the permissions of the Context User when processing the inbound email
d) Accept Email from : Same functionality as mentioned in the "New Email Service" page.

Click on save and salesforce  will create a unique email address . This is the address you send your email to for further processing .From where to send email entirely depends on the ones own requirement .If sending email from  outside force.com platform just take the unique email address and send email to the address with relevant information(depends on requirement) . If with in Salesforce following code helps 

Say email address is "testEmailService@46hgvb8g1fj0jbjsfj56kngvx.az1foma0.f.apex.salesforce.com"



Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();   
mail.setToAddresses('testEmailService@46hgvb8g1fj0jbjsfj56kngvx.az1foma0.f.apex.salesforce.com');                    
mail.setSubject('Process test Service');                   
mail.setPlainTextBody("Mention the relevant information here");        
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });


Now as per the flow email is recieved by salesforce and email service is triggered which further triggers the code in the "testEmailService" class.


One more use case for using the power of email service is serializing batch apex. At times I know people pulling out their hair and who  literally became "bald" (not literally though :)) thinking on how to instantiate another batch apex call from the present batch apex. Actually its not possible for us to call a batch apex from another batch apex directly. We can instantiate another batch apex call only when the present batch completed its processing .This can be facilitated by using "Email service" . In finish method of batch apex send an email (with the results of the batch in the subject or in plain text body) .Configure respective email service to consume this email. And call another batch apex in the apex class that implements respective interface  



For further reading : 

P:S Image source-Google .I don possess any gun :)