Example of Sample Custom Apex Class to Send Email
This section explains in detail a use case and its related sample code to send email. You can use this example as a reference to create your own custom Apex class to send email.
Use Case
Consider there are three Order Types: Depot Repair, Onsite Repair, and Service Repair. A customer wants to send an email based on the Work Order's Order Type. The customer has configured the following Email Templates: Depot Repair Email Template, Onsite Repair Email Template, and Service Repair Email Template. The purpose is to send the relevant email with the relevant email template to the intended user.
The customer performs the following steps:
1. Goes to the Salesforce org > App Launcher > Email Templates.
2. Creates the following Email Templates:
WorkClosure_DepotRepair
WorkClosure_OnsiteService
WorkClosure_Others
3. Creates an Org-Wide Email Address.
4. Creates a custom Apex class for the ServiceMax Email Service to do the following:
Use the Email Template “WorkClosure_DepotRepair“ if WorkOrder.OrderType = Depot Repair
Use the Email Template “WorkClosure_OnsiteService“ if WorkOrder.OrderType = Onsite Service
Use the Email Template “WorkClosure_Others“ if WorkOrder.OrderType not in (Onsite Service, Depot Repair)
5. Goes to ServiceMax Setup > Service Flow Manager > Custom Action.
6. Creates a custom action of type Email as follows:
Uses the Org-Wide Email Address created in step 3.
Does not select the option Email Template.
Sets the Send Mail Method to Custom.
Sets the Class name to the custom class defined in step 4.
Configures the following custom action parameters:
To: Sets the email id to the Work Order.Contact.Email
CC: Sets the email id to any email address.
Recipient Id: Sets the email id to the WorkOrder.Contact.Id
7. Creates an SFM Wizard step for the custom action configured in step 6.
8. Goes to the ServiceMax Go app and does the following:
Performs a Config sync. The new SFM Wizard is available in the list of SFM Wizards on the app.
Launches the SFM Wizard for the Send Email. Ensures that the Send Email SFM Wizard picks the relevant email template and sends an email to the intended user.
Sample Code
The sample code for the use-case explained above is as follows:
global class SendEmailCustomExtention implements callable{

public class SVMXException extends Exception{}

private static final String EMAIL_TO = 'to';
private static final String EMAIL_CC = 'cc';
private static final String EMAIL_BCC = 'bcc';
private static final String EMAIL_FROM = 'from';
private static final String EMAIL_RECIPIENT_ID = 'receipientId';
private static final String RECORD_ID = 'recordId';
private static final String EMAIL_ATTACHMENT_IDS = 'attachmentId';
private static final String EMAIL_TEMPLATE_ID = 'templateId';

/**
* Override method invoked by Servicemax class when the custom action for sending email is executed.
*
* @param action Method name
* @param argsMap Parameter map
*
* @return Returns a map indicating whether the email sent successfully or not.
*/
public Object call(String action, Map<String, Object> argsMap) {
switch on action {
when 'sendEmail' {
return sendCustomEmail(argsMap);
}
when else {
throw new SVMXException('Method not implemented');
}
}
}

/**
* This method validates the email parameters and send an email
*
* @param argsMap Parameter map
*
* @return Returns a map indicating whether the email sent successfully or not.
*/
public Map<String, Object> sendCustomEmail(Map<String, Object> argMap){
System.debug(LoggingLevel.DEBUG, 'Custom Send Email Input Parameters are = ' + argMap);
Map<String, Object> returnMap = new Map<String, Object>();
try{
if(argMap == null || argMap.isEmpty()){
throw new SVMXException('Argument map is empty');
}
Id recordId = (Id) argMap.get(RECORD_ID);

String recordObjectName = recordId.getSobjectType().getDescribe().getName();

List<SVMXC__Service_Order__c> woList = [SELECT SVMXC__Order_Type__c, SVMXC__Contact__c, SVMXC__Contact__r.Email FROM SVMXC__Service_Order__c WHERE ID =: recordId LIMIT 1];
if(woList.isEmpty()){
throw new SVMXException('Record not exist.');
}

List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
mails.add(getSingleEmailMessage(argMap, woList));

try{
Messaging.SendEmailResult[] results = Messaging.sendEmail(mails);
System.debug('results '+ results);
for(Messaging.SendEmailResult singleEmailresult : results){
if(!singleEmailresult.success){
String errorMessage = '';
for(Messaging.SendEmailError sendEmailError: singleEmailresult.getErrors()){
System.debug(LoggingLevel.ERROR, 'sendEmailError - '+ sendEmailError);
errorMessage += sendEmailError.getMessage() + ' ; ';
}
System.debug(LoggingLevel.ERROR, 'Error occurred while sending the email. errorMessage - '+ errorMessage);
throw new SVMXException(errorMessage);
}
}
} catch(Exception ex){
System.debug(LoggingLevel.ERROR, 'Error occurred while sending the email. errorMessage - '+ ex.getMessage());
throw new SVMXException( ex.getMessage());
}
returnMap.put('success', true);
}catch(Exception ex){
System.debug(LoggingLevel.ERROR, 'Error occurred while sending the email. errorMessage - '+ ex.getMessage());
returnMap.put('success', false);
}
return returnMap;
}

/**
* This method validate the requried parameters for sending an email and create and object of Messaging.SingleEmailMessage.
*
* @param argsMap Parameter map
* @param woList List of work order
*
* @return Returns a map indicating whether the email sent successfully or not.
*/
private Messaging.SingleEmailMessage getSingleEmailMessage(Map<String, Object> emailInformationMap, List<SVMXC__Service_Order__c> woList){
System.debug(LoggingLevel.DEBUG, 'getSingleEmailMessage - enter; emailInformationMap - '+ emailInformationMap);

SVMXC__Service_Order__c wo = woList.get(0);

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

mail.setWhatId(wo.Id);

Id receipientId = wo.SVMXC__Contact__c;
if(receipientId == null){
System.debug(LoggingLevel.DEBUG, 'Email recipient is missing. receipientId - ' + receipientId);
throw new SVMXException( 'Email recipient is missing.' );
}
mail.setTargetObjectId(receipientId);

List<OrgWideEmailAddress> orgEmailList = [SELECT Id FROM OrgWideEmailAddress WHERE DisplayName = 'Servicemax Org wide email' LIMIT 1];
if(!orgEmailList.isEmpty()){
mail.setOrgWideEmailAddressId(orgEmailList.get(0).Id);
}

mail.setToAddresses( (List<String>)emailInformationMap.get(EMAIL_TO) );

Id emailTemplateId = getEmailTemplateId(wo);
if(emailTemplateId == null){
System.debug(LoggingLevel.DEBUG, 'Email template is missing. emailTemplateId - ' + emailTemplateId);
throw new SVMXException( 'Email template is missing.' );
}
mail.setTemplateId(emailTemplateId);

List<String> ccList = (List<String>) emailInformationMap.get(EMAIL_CC);
if(ccList != null && !ccList.isEmpty()){
mail.setCcAddresses(ccList);
}

List<String> bccList = (List<String>) emailInformationMap.get(EMAIL_BCC);
if(bccList != null && !bccList.isEmpty()){
mail.setBccAddresses(bccList);
}

List<Id> attachmentIdList = (List<Id>) emailInformationMap.get(EMAIL_ATTACHMENT_IDS);
if(attachmentIdList != null && !attachmentIdList.isEmpty()){
mail.setEntityAttachments(attachmentIdList);
}

System.debug(LoggingLevel.DEBUG, 'getSingleEmailMessage - exit; mail - '+ mail);
return mail;
}

/**
* This method selects the email template id based on the Work order's order type.
*
* @param wo - Work order
*
* @return Returns Email template id based on the Work order's order type.
*/
public Id getEmailTemplateId(SVMXC__Service_Order__c wo){
Id emailTemplateId;
String emailTemplateName;
if(wo.SVMXC__Order_Type__c == 'Depot Repair'){
emailTemplateName = 'WorkClosure_DepotRepair';
} else if(wo.SVMXC__Order_Type__c == 'Onsite Service'){
emailTemplateName = 'WorkClosure_OnsiteService';
} else {
emailTemplateName = 'WorkClosure_Others';
}

EmailTemplate et = Database.query('SELECT Id FROM EmailTemplate WHERE Name = \'' + emailTemplateName + '\'');
return et.Id;
}
}
Was this helpful?