0

I am trying to set up an invocable apex class to send an email to a contact with merge fields from other record ID types with an optional variable to set the sender. I have looked at this question for guidance, however, am having trouble using variable sender.

Can someone have a look over what I have done and offer some suggestions?

global class Invocable_SendEmail {

    global class DataWrapper {

        @InvocableVariable(label='Record ID' required=true)
        public String recordID;
        @InvocableVariable(label='Email Template ID' required=true)
        public String emailTemplateID;
        @InvocableVariable(label='Contact ID' required = true)
        public String contactID;
        @InvocableVariable(label='Sender Email' required=false)
        public String sender;
    }

    @invocableMethod(label='Send Email to Applicant')
    global static void sendMailToLead (List<DataWrapper> passedData) {

        // Send the email:

        for (DataWrapper dw: passedData) {


            // Get the email template
            EmailTemplate selectedTemplate = [SELECT Id FROM EmailTemplate WHERE Id =: dw.emailTemplateId];

            // Get sender details
                // fetch Org Wide Email Address if sender is filled
                if (dw.sender != null) {
                    OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = sender];
                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    if ( owea.size() > 0 ) {
                        mailToSend.setOrgWideEmailAddressId(owea.get(0).Id);
                    }
                }

            // Create SingleEmailMessage object and set the target and template.
            Messaging.SingleEmailMessage mailToSend = new Messaging.SingleEmailMessage();
            mailToSend.setTargetObjectId(dw.contactID);
            mailToSend.setWhatId(dw.recordID);
            mailToSend.setTemplateID(selectedTemplate.Id);


            // Send the email and debug results
            List<Messaging.SendEmailResult> sendResults = Messaging.sendEmail(new List<Messaging.Email> { mailToSend });
            System.debug(sendResults[0]);


        }

    }

}
  • How are you having trouble, exactly? Errors? What's the debug logs say? What have you figured out so far? – sfdcfox Jun 24 at 4:28
  • Oh, that's good. P.S. You should consider bulkifying your code. Extract the addresses and templates in one loop, query them, then do the mail creation in a second loop. This will enable you to use the method in bulk actions like Process Builder. – sfdcfox Jun 24 at 4:38
  • Thanks @sfdcfox for the advice can you show me how you would do this? I have it working with process builder now but any advise on better code is welcomed – Tess Gillard Jun 24 at 4:43
0

You can bulkify your code so it will work with more than 10 records (e.g. if you use an import wizard or data loader tool).

@invocableMethod(label='Send Email to Applicant')
global static void sendMailToLead (List<DataWrapper> passedData) {
    // Validate email tempaltes and org-wide addresses
    Map<String, Id> emails = new Map<String, Id>();
    Set<Id> emailTemplateIds = new Set<Id>();
    for(DataWrapper wrapper: passedData) {
        emails.put(wrapper.emailTemplateId, null);
        emailTemplateIds.add(wrapper.sender);
    }
    for(OrgWideEmailAddress address: [SELECT Address FROM OrgWideEmailAddress WHERE Address = :emails.keySet()]) {
        emails.put(address.Address, address.Id);
    }
    emailTemplateIds.retainAll(
        new Map<Id, EmailTemplate>([SELECT Id FROM Emailtemplate WHERE Id = :emailTemplateIds]).keySet()
    );
    // Build emails
    Messaging.Email[] mailsToSend = new Messaging.Email[0];
    for (DataWrapper dw: passedData) {
        if(!emailTemplateIds.contains(dw.emailTemplateId)) {
            continue; // Invalid email template?
        }
        Id orgSenderId = emails.get(dw.sender);
        Messaging.SingleEmailMessage mailToSend = new Messaging.SingleEmailMessage();
        // fetch Org Wide Email Address if sender is filled
        if (orgSenderId != null) {
            mailToSend.setOrgWideEmailAddressId(orgSenderId);
        }

        // Create SingleEmailMessage object and set the target and template.
        mailToSend.setTargetObjectId(dw.contactID);
        mailToSend.setWhatId(dw.recordID);
        mailToSend.setTemplateID(selectedTemplate.Id);
        mailsToSend.add(mailToSend);
    }
    // Send the emails
    List<Messaging.SendEmailResult> sendResults = Messaging.sendEmail(mailsToSend);
}
| improve this answer | |
0

Fixed the issues,

global class Invocable_SendEmail {

global class DataWrapper {

    @InvocableVariable(label='Record ID' required=true)
    public String recordID;
    @InvocableVariable(label='Email Template ID' required=true)
    public String emailTemplateID;
    @InvocableVariable(label='Contact ID' required = true)
    public String contactID;
    @InvocableVariable(label='Sender Email' required=false)
    public String sender;
}

@invocableMethod(label='Send Email to Applicant')
global static void sendMailToLead (List<DataWrapper> passedData) {

    // Send the email:

    for (DataWrapper dw: passedData) {


        // Get the relevant template based on the supplied ID.
        EmailTemplate selectedTemplate = [SELECT Id FROM EmailTemplate WHERE Id =: dw.emailTemplateId];

        // Create SingleEmailMessage object and set the target and template.
        Messaging.SingleEmailMessage mailToSend = new Messaging.SingleEmailMessage();
        mailToSend.setTargetObjectId(dw.contactID);
        mailToSend.setWhatId(dw.recordID);
        mailToSend.setTemplateID(selectedTemplate.Id);

        // Get sender details
            // fetch Org Wide Email Address if sender is filled
            if (dw.sender != null) {
                OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address =: dw.sender];
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                if ( owea.size() > 0 ) {
                    mailToSend.setOrgWideEmailAddressId(owea.get(0).Id);
                }
            }


        // Send the email and debug results
        List<Messaging.SendEmailResult> sendResults = Messaging.sendEmail(new List<Messaging.Email> { mailToSend });
        System.debug(sendResults[0]);


    }

}

}

Fix includes updating line: OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = sender]; to: OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address =: dw.sender];

And putting // Get sender details section after creation of SingleEmailMessage object

| improve this answer | |

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.