2

I'm looking for a way, through Apex to Schedule sending SingleEmailMessages using Messaging.sendEmail();.

I've got a Trigger that sends e-mail straight away once the method is invoked that looks like below:

List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

email.setToAddresses(toAddress);
email.setTemplateId(templateId);
email.setTargetObjectId(application.ts2__Candidate_Contact__c);

mailList.add(email);

However before I call the Messaging.sendEmail(mailList); method, I'm checking to see what time it is. Specifically, if it's between 9am and 9pm, we can instantly send the e-mail. Otherwise we want to schedule sending it as below:

Integer hour = System.now().hour();

if (hour > 9 && hour < 21) {
  Messaging.SendEmailResult[] r = Messaging.sendEmail(mailList);
}
else {
  // Schedule the e-mail
}

Now I've tried a few things and feel like I'm on the right track, but I think I'm going about it the wrong way. For instance, within the else statement:

String day = System.now().addDays(1).format('dd');
String month = System.now().addDays(1).format('MM');
String year = System.now().addDays(1).format('yyyy');

String CRON_EXP = '0 0 9 ' + day + ' ' + month + ' ? ' + year + '';
System.schedule('Schedule_Send_Email', CRON_EXP, new Messaging.sendEmail(mailList));

This fails expecting something totally different.

I've also tried using System.schedule on a class that implements Schedulable which inevitably failed (clutching at straws I think!) and even considered a Batch class although this seems totally wrong and I'm not entirely sure what the syntax of that would be.

Simple question: How can I schedule/delay sending an e-mail until a given time?

If you were wondering, Time-Based Workflows can't be used.

1

You still must implement Schedulable. Unfortunately, the Messaging.SingleEmailMessage type is not serializable, so you'll need to store a wrapper instead. Something like:

public class DeferredEmail implements Schedulable
{
    public void execute(SchedulableContext  context)
    {
        Messaging.sendEmail(generateEmails());
    }

    final List<MessagePacket> messages;
    public DeferredEmail()
    {
        messages = new List<MessagePacket>{new MessagePacket()};
    }
    public List<Messaging.SingleEmailMessage> generateEmails()
    {
        List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
        for (MessagePacket message : messages) emails.add(message.generateEmail());
        return emails;
    }
    public DeferredEmail add(String toAddress, Id templateId, Id targetObjectId)
    {
        messages.add(new MessagePacket(toAddress, templateId, targetObjectId));
        return this;
    }

    public class MessagePacket
    {
        public final Id templateId;
        public final Id targetObjectId;
        public final String toAddress;
        public Messaging.SingleEmailMessage generateEmail()
        {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setToAddresses(new List<String> { toAddress });
            email.setTargetObjectId(targetObjectId);
            email.setTemplateId(templateId);
            return email;
        }
    }
}
  • Thanks for this, I've tried creating a separate Schedule class (I'll add it to the question) but I'm getting the error: System.UnexpectedException: Not Serializable: com/salesforce/api/fast/List$$lcom/salesforce/api/Messaging/SingleEmailMessage$$r (). Do you know what this means? Not come across it before. – Dan Jones Aug 18 '16 at 12:18
  • 1
    That's beautiful, thanks Adrian. Salesforce is taking at least 10 minutes to compile today. As soon as it wakes up I'll let you know! – Dan Jones Aug 18 '16 at 12:43
  • 1
    Works like a charm. Sorry it took so long to get back to you, watching the equals sign bounce around in Sublime for 30 minutes is more excruciating than it should be. – Dan Jones Aug 18 '16 at 13:42
  • 1
    @Poet No problem! When it's really bad I just switch to developer console. Are you using Metadata API or Tooling API? I've heard there are serious compile issues using the Metadata API these days. salesforce.stackexchange.com/questions/136379/… – Adrian Larson Aug 18 '16 at 13:44
  • 1
    I'm actually using the Tooling API as it happens although slow compiling pretty intermittent to be fair, sometimes I wonder if it's our Org. Regardless, it doesn't seem to be a whole lot better than what the Metadata API right now! ¯_(ツ)_/¯ – Dan Jones Aug 18 '16 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.