0

I'm trying to send an email template to all users of a certain profile "Sales Ops". I've found the following code and have created a scheduled Apex Class with it. However, I'm not sure if I can use "and Profile.Name = 'Sales Ops'.

Does this look correct? I'm new to Apex Classes so any hints or advice would be appreciated!

Here's my current code:

global class sendEmailToUSer implements Schedulable {
    global void execute(SchedulableContext sc) {
        list<User> lstUser = [Select ID from User where isActive = true and Profile.Name = 'Sales Ops'];
        for(User iterator : lstUser) {
            EmailTemplate objTemp = [SELECT Id FROM EmailTemplate where DeveloperName = 'Campaign_Member_Report' limit 1];
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTemplateId(objTemp.Id);
            mail.setTargetObjectId(iterator.Id);
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        }
    }
}
1

Yes, that is valid SOQL syntax to query based upon the profile name.

You have a different issue, however. This code is completely unbulkified and will rapidly hit limits issues.

for(User iterator : lstUser) {
    EmailTemplate objTemp = [SELECT Id FROM EmailTemplate where DeveloperName = 'Campaign_Member_Report' limit 1];
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setTemplateId(objTemp.Id);
    mail.setTargetObjectId(iterator.Id);
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

You have a SOQL query inside your for loop. That's easy to fix. Just move

    EmailTemplate objTemp = [SELECT Id FROM EmailTemplate where DeveloperName = 'Campaign_Member_Report' limit 1];

outside the for loop, and the behavior will not change - except that you won't get a SOQL limit exception when you have 101 users in this profile.

You should also create a Messaging.SingleEmailMessage[] variable outside your for loop and accumulate messages there, rather than calling Messaging.sendEmail() each time through the loop. Then, call Messaging.sendEmail() with the whole list at the end of the method.

Note that you can only call sendEmail() 10 times in a transaction, so this is another place your code could fail with volume if not remedied.

| improve this answer | |
  • Thanks David. I'm such a beginner with code/Apex that I may just seek alternative routes at this point until I can learn some more about this subject. – Matt Godfroy Jun 27 '18 at 14:17
  • @MattGodfroy, you could probably do this with Process Builder and Flow. If you could write up a detailed question with your objectives, you might post asking whether there is a good declarative-only solution. – David Reed Jun 27 '18 at 14:26
  • Doug Ayer's Mass Action Scheduler app might help with that. – David Reed Jun 27 '18 at 14:27
  • Headless flow is definitely a possibility and something I'm much more familiar working with. I was just watching Doug's demo on his solution. A requirement is you need to have Lightning enabled in your org which we currently do not :( . I'm going to keep researching what I can find. If all else fails I might end up writing a more detailed question like you suggested. Thanks again. – Matt Godfroy Jun 27 '18 at 15:29
  • I believe you need Apex to use email templates, though. Of course, that could potentially be an InvocableAction. – David Reed Jun 27 '18 at 15:35

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.