Sending Email Notification when Salesforce Tasks are updated

Salesforce does a great job of sending out workflow-based email notifications for a lot of different objects. These allow you to notify a group of people via email when a workflow action completes. Unfortunately, this functionality does not exist for Tasks and Events (It does, but not to the granularity you want… read on…..). Worse, even when we use the default “Send Email Notification” checkbox functionality, there are too little details in the email notification for the end user to make any sense of it (below is how it looks in my gmail) :-

image

However, you can get past all these limitations by using the Salesforce Email API. The logic goes as follows :

(A) Create a trigger on the Task/Event object
(B) In the code for the trigger, extract all the relevant information and put in an HTML email body.
(C) Send an email to chosen recipients.

Let us take an example:-

I want to implement a trigger that sends me an email every time a task that I’m assigned to is modified. Note that this is just an example- you can have any sort of custom functionality control whether an email is sent out, who it gets sent to etc..

Implement Email trigger on the task object

Let us now implement a trigger on the task object. It will fire every time a task that I created is updated, and send out an email.

Code Snippet
  1. trigger Trigger_Task_Send_Email on Task (before insert) {
  2.     // Don't forget this- all triggers in SF are bulk triggers and so
  3.     // they can fire on multiple objects. So you need to process objects
  4.     // in a FOR loop.
  5.     for(Task tsk: Trigger.New)
  6.     {
  7.         // Get the OwnerID for this task       
  8.         List<User> owners = [select Name from User where id = :tsk.OwnerId LIMIT 1];
  9.         for(User owner : owners)
  10.         {
  11.             // Check if I am the owner (replace the "MY NAME" with your user name)
  12.             if(owner.Name == 'MY NAME')
  13.             {
  14.                 // We will add the send email code here
  15.             }
  16.         }
  17.     }       
  18.    
  19. }

Send out HTML email for task update

The requirement is to send an email to the task assignee when his task is modified. To complicate matters, I even added a custom field to my task object, called “My Custom Field”. I want the value of this field in my email alert. Note that the standard email alert does not add custom fields to the email alert, so if this is your requirement, look at the code below:-

Code Snippet
  1. trigger Trigger_Task_Send_Email on Task (before update) {
  2.     // Don't forget this- all triggers in SF are bulk triggers and so
  3.     // they can fire on multiple objects. So you need to process objects
  4.     // in a FOR loop.
  5.     Set<Id> ownerIds = new Set<Id>();
  6.    
  7.     for(Task tsk: Trigger.New)
  8.         ownerIds.add(tsk.ownerId);
  9.    
  10.     // Build a map of all users who are assigned the tasks.
  11.     Map<Id, User> userMap = new Map<Id,User>([select Name, Email from User where Id in :ownerIds]);
  12.     for(Task tsk : Trigger.New)
  13.     {
  14.         User theUser = userMap.get(tsk.ownerId);
  15.         Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  16.         String[] toAddresses = new String[] {theUser.Email};
  17.         mail.setToAddresses(toAddresses);    // Set the TO addresses
  18.         mail.setSubject('A task owned by you has been updated');    // Set the subject
  19.         // Next, create a string template. Specify {0}, {1} etc. in place of actual values.
  20.         // You can replace these values with a call to String.Format.
  21.         String template = 'Hello {0}, \nYour task has been modified. Here are the details - \n\n';
  22.         template+= 'Subject - {1}\n';
  23.         template+= 'Due Date - {2}\n';
  24.         template+= 'My Test Field - {3}\n';
  25.         String duedate = '';
  26.         if (tsk.ActivityDate==null)
  27.             duedate = '';
  28.         else
  29.             duedate = tsk.ActivityDate.format();
  30.         List<String> args = new List<String>();
  31.         args.add(theUser.Name);
  32.         args.add(tsk.Subject);
  33.         args.add(duedate);
  34.         args.add(tsk.MyTestField__c);
  35.        
  36.         // Here's the String.format() call.
  37.         String formattedHtml = String.format(template, args);
  38.        
  39.         mail.setPlainTextBody(formattedHtml);
  40.         Messaging.SendEmail(new Messaging.SingleEmailMessage[] {mail});
  41.     }
  42. }

This sends out an email which looks slightly better than the standard one, since this has the custom field as well.

image

I spent a few hours trying to get the HTML formatted email to work, but I failed at various points and had to give up. To save time for those who try to go down that path, here’s the stuff I tried and why it failed :-

(A) You cannot create a mail template for a task. So if your goal is to use a nice email template to send alerts for your task updates, don’t go down that road.
(B) I was hoping to load an HTML resource file on the fly from static resources, and then replace the {0}, {1} etc. variables using string.format. However, I ran into a limitation too since you cannot access static resources in Apex triggers (go figure !!).
(C) You can construct HTML by hand, and use the mail.setHTMLBody() function to create the Html body for the email. However, when I tried to format a fairly complex HTML, I started getting issues due to colons in my Html (for e.g., style=width:100%). This one could be done, but it is a **huge** pain to manage and get to work.

So there you go, that’s how you can send out an email alert to the task assignee whenever the task is updated.

6 comments:

  1. Nice post with helpful details. I really appreciate your info. Thanks for sharing.

    emergency mass notification software

    ReplyDelete
  2. This is great!

    Any chance you can write a blog on how to send reminder notifications for all tasks for all users that are due in a couple of days? I'm a nube at Salesforce and this really has me stumped.

    ReplyDelete
  3. Hi,

    Thanks for your code,

    It will help me a lot.

    ReplyDelete
  4. You mention a "for loop" as i'm not a developer i would like to know have you already accounted for that in the code you posted?

    ReplyDelete
  5. Nice code, but how do I filter this to only run if the task is completed? Right now it runs on any change to the task status!

    ReplyDelete
  6. Thank U so much for code help... !

    ReplyDelete