Sunday 25 November 2012

Approval Process via Apex Email Services

Hello,
Read my previous post on Approval Process via Chatter Feed for better Understanding, where the importance of speeding up the Approval Process and the method of Approving records via Chatter Feed.

We all know that Email Service is an automated process that uses Apex class to do some process based on the email contents.

This post demonstrates another easy and speedy way of Providing Approvals (Approving/Rejecting) by sending mails and processing the Approval Process using the Apex Email Services. Based on the mail contents and Apex class logic, certain actions can be made which is the Approval Process in this post.

Let us assume that we have a Approval Process sending email alert to the Approver asking to Approve the record whenever a record is submitted for Approval, additionally the mail contains information about the record which is submitted for Approval and the Service Email Address to Reply To.

Once the Approver received this mail, he/she can send their Approval/Rejection/Recall just by sending a reply to the Service Email Address.

The Apex Class associated with this Service Address will then analyses the mail contents like Subject,Body and based on it Approves/Rejects/Recalls the Approval Process.

Create an Apex Class to process the inbound mail as below which operates on Contract Object,

global class ContractApproval implements Messaging.InboundEmailHandler 

{
    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,Messaging.InboundEnvelope envelope)
    {  
        Messaging.InboundEmailResult emailresult = new Messaging.InboundEmailResult();
        system.debug(email.plainTextBody);
        if(email.subject.containsIgnoreCase('Contract Approval'))
        {
            String str = email.subject.normalizeSpace();
            String ContractNumber = str.substring(str.indexOf('-')+1,str.length());
            System.debug('ContractNumber :'+ContractNumber);            
            Contract con = [Select Id,ContractNumber From Contract WHERE ContractNumber=:ContractNumber];
            try
            {        
            List<ProcessInstance> pi = [SELECT Id FROM ProcessInstance WHERE TargetObjectId=:con.Id AND Status='Pending'];  
            if(pi.size()==0)
                return emailresult;
            List<ProcessInstanceWorkitem> piw = [SELECT Id,ActorId,ProcessInstanceId FROM ProcessInstanceWorkitem WHERE Actor.Email=:email.fromAddress and ProcessInstanceId=:pi[0].Id];            
            if(piw.size()==0)
                return emailresult;
            Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();                        
            if(email.plainTextBody.containsIgnoreCase('<approved>'))
            {
                req.setComments('Request Approved by Email Approval..!!');
                req.setAction('Approve');
            }                                    
            else if(email.plainTextBody.containsIgnoreCase('<rejected>'))
            {
                req.setComments('Request Rejected by Email Approval..!!');
                req.setAction('Reject');
            }
            else if(email.plainTextBody.containsIgnoreCase('<recalled>'))
            {
                req.setComments('Request Recalled by Email Approval..!!');
                req.setAction('Removed');        
            }
            req.setWorkitemId(piw[0].Id);                                  
            Approval.ProcessResult result = Approval.process(req);
            FeedItem a = new FeedItem(ParentId=con.Id,Type='TextPost');  
            if(result.isSuccess())                                    
            {
                a.Body='Email received from Approver and the process was '+result.getInstanceStatus();                
            }
            else if(!result.isSuccess())
            {
                a.Body='Email received from Approver but some error occured, please contact sys admin';
            }
            a.Body+=email.plainTextBody;
            Insert a;
            }
            catch(Exception e)
            {
                system.debug(e);
            }            
        }
        return emailresult;       
    } 
} 
This trigger takes the Contract Auto Number from the mail subject line and queries for the Contract record. Based on the tag in the email body <Approved> or <Rejected> or <Recalled>, the Approval Process was Approved or Rejected or Recalled.

To create email services, click Your Name | Setup | Develop | Email Services and create a New Email Address for it. Associate the Email Service with the ContractApproval Apex class which was created.


Checkout this link What is the Apex Email Service? , to know more about creating and defining a Email Service.



Screenshot of the mail received and the reply to the Service Address :




Screenshot of the Chatter in SFDC UI :




18 comments:

  1. hello Sir i got an error when reply to the Email below the error , please let you tell me how can i fixed it ?
    The attached message was sent to the Email Service address but could not be processed because the following error occurred:

    554 System.QueryException: List has no rows for assignment to SObject

    Class.MyReq.TravelRequest.handleInboundEmail: line 12, column 1

    ReplyDelete
  2. Faisal,

    This is because the List SOQL WHERE condition is not met, and hence showing up this error.
    When the incoming mail is received, i believe you are using SOQL statement with WHERE condition and assigning it to a List. But the incoming mail didnt satisfy the where condition and hence failed further processing

    Let me know, if you need any further help on this.

    Thanks,
    Bharathi

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. thank you for reply , but im not assign where clause into any list , simply i want to update or change my custom filed of custom object , here is the code if(email.subject.containsIgnoreCase('leave Approval‏'))
    {
    String str = email.subject.normalizeSpace();

    MyReq__leave__c con = [Select Id From MyReq__leave__c ];
    try{ ...

    so what i do to update status filed of this object MyReq__leave__c ?

    ReplyDelete
  5. Wonderful blog & good post.Its really helpful for me, awaiting for more new post. Keep Blogging!

    Salesforce Training

    ReplyDelete
  6. Your article on Apex Email Services is really informative. It assist me to understand whole concept with ease. Thanks for sharing.

    ReplyDelete
  7. Really a fantastic post, easy and quite helpful... Thanks for this wonderful blog...

    Keep Posting....!!!

    ReplyDelete
  8. Nice post. Oracle is a relational database management system produced by oracle corporation. Nowadays most of the multinational companies used this oracle database for storing and managing their data's and programs. So learning Oracle Training in Chennai is one of the best idea to make a bright career.

    ReplyDelete
  9. Cloud computing is storing and accessing the large data sets over the internet instead of your PC computer. So that you can manage the data and program anywhere through the internet.
    Regards..
    Cloud Training in Chennai

    ReplyDelete
  10. Can we please appreciate the knowledge of the fellow writer, and take our advertising of training to someplace else.
    I believe such comments did stop him for posting further.

    ReplyDelete
  11. Nice Article! Mostly I have gathered knowledge from the blogger, because its provides more information over the books & here I can get more experienced skills from the professional, thanks for taking your to discussing this topic.
    Regards,
    Informatica training in chennai|Best Informatica Training In Chennai

    ReplyDelete
  12. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging…
    Regards,
    sas training in Chennai|sas training institutes in Chennai|sas training center in Chennai

    ReplyDelete
  13. Thanks a lot very much for the high quality and results-oriented help. I won’t think twice to endorse your blog post to anybody who wants and needs support about this area.

    Hadoop training in bangalore

    ReplyDelete
  14. This is an awesome post.Really very informative and creative contents. These concept is a good way to enhance the knowledge.I like it and help me to development very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge.
    java training in chennai

    java training in tambaram

    aws training in chennai

    aws training in tambaram

    python training in chennai

    python training in tambaram

    selenium training in chennai

    selenium training in tambaram

    ReplyDelete