Skip to content

Salesforce Apex – Send weekly emails to respective owners with their open tasks

The following apex class implements the Schedulable interface, which allows it to be scheduled to run at specific times or intervals. This class sends an email to each active standard user in Salesforce, listing their open tasks that were created either this year or last year.

The email is sent from an org-wide email address specified by the DisplayName [email protected]. Make sure to update the email with a valid org-wide email.

global class SendOpenTasksEmailToUsers implements Schedulable {
    
    global void execute(SchedulableContext sc) {
        
        List<Task> tasks = [SELECT Id, FORMAT(CreatedDate), Subject, Description, ActivityDate, WhatId, What.Name, WhoId, Who.Name, OwnerId FROM Task WHERE Status = 'Open' AND (CreatedDate = THIS_YEAR OR CreatedDate = LAST_YEAR) Order By CreatedDate ASC];
        List<User> users = [SELECT Id, Name, Email FROM User WHERE IsActive = true AND UserType = 'Standard'];
        Map<Id, List<Task>> userTasks = new Map<Id, List<Task>>();
        
        for (Task task : tasks) {
            if (userTasks.containsKey(task.OwnerId)) {
                userTasks.get(task.OwnerId).add(task);
            } else {
                userTasks.put(task.OwnerId, new List<Task>{task});
            }
        }
        
        OrgWideEmailAddress[] orgWideEmailAddresses = [SELECT Id, Address FROM OrgWideEmailAddress WHERE DisplayName = '[email protected]'];
        
        List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
        
        for (User user : users) {
            if (userTasks.containsKey(user.Id)) {
                
                system.debug(user.Name+' --> '+userTasks.get(user.Id).size());
                
                String emailBody = '<html><body>';
                emailBody += 'See the list of your open tasks below: <br/><br/>';
                emailBody += '<table style="border-collapse: collapse; width: 100%;">';
                emailBody += '<tr><th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Created Date</th>';
                emailBody += '<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Related to</th>';
                emailBody += '<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Subject</th>';
                emailBody += '<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Due Date</th>';
                emailBody += '<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Description</th>';
                emailBody += '<th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Assigned to</th></tr>';
                
                for (Task task : userTasks.get(user.Id)) {
                    
                    String WhatName = task.WhatId == NULL ? '' : task.What.Name;
                    String WhoName = task.WhoId == NULL ? '' : task.Who.Name;
                    String RelatedTo = string.IsBlank(WhatName) ? whoName : WhatName;                    
                    String Description = task.Description == NULL ? '' : task.Description;
                    String ActivityDate = task.ActivityDate == NULL ? '' : task.ActivityDate.format();
                    String CreatedDate = task.CreatedDate == NULL ? '' : task.CreatedDate.format();
                    
                    emailBody += '<tr>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">' + CreatedDate + '</td>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">' + RelatedTo + '</td>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;"><a href="' +URL.getOrgDomainURL().toExternalForm() + '/' + task.Id + '">' + task.Subject + '</a></td>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">' + ActivityDate + '</td>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">' + Description+ '</td>';
                    emailBody += '<td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">' + user.Name + '</td>';
                    emailBody += '</tr>';
                }
                
                emailBody += '</table></body></html>';
                Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
                email.setSubject('Your Salesforce Open Tasks');
                email.setHtmlBody(emailBody);
                email.setOrgWideEmailAddressId(orgWideEmailAddresses[0].Id);
                email.setTargetObjectId(user.Id);
                email.setSaveAsActivity(false);
                emails.add(email);
            }
        }
        
        if(emails.size() > 0){
            Messaging.sendEmail(emails);
        }
    }
}

Now schedule the apex class run at specific times and intervals. You can schedule the apex class by Setup > Apex Classes > Click “Schedule Apex” button. Now select the apex class you just created and frequency, as shown in the attached screenshot.

Test Class for the above apex code.

@isTest
public class SendOpenTasksEmailToUsers_Test{

    static testmethod void SendOpenTasksEmailToUsersTest(){
        
        Task t1 = new Task(Subject='My Test Task 1', OwnerId = UserInfo.getUserId(), Status='Open', Priority='Normal', Description='Test Memo');
        insert t1;
        
        SendOpenTasksEmailToUsers cls = new SendOpenTasksEmailToUsers();
        cls.Execute(null);
    }
}

In summary, this Apex class is used to send a summary of open tasks to each active standard user in Salesforce, helping them stay informed about their pending tasks. The email is sent from a specified org-wide email address, and the tasks are listed in a table format within the email.