Send emails using Sendgrid in Salesforce
Introduction
Salesforce has an inbuilt way of sending emails using Apex. You can even use Email Templates to setup a HTML template and use apex to personalise it for each recipient.
However, Salesforce really isn’t a tool for sending emails. Here are some of the issues while using Salesforce for sending automated email -
- The template editor is limited - No drag & drop support, you have to paste the actual HTML in the editor
- Sending Limits - There are limits on how many email you can send. Salesforce describes them here -https://help.salesforce.com/s/articleView?id=000312442&type=1
- Feature limitations - A good email sending service generally has bounce management, dedicated IP, subscription management, open & click tracking features
To send the automated emails in Salesforce, it’s much easier to use a dedicated email platform and use the APIs to send the actual emails. This results in better experience and reduced cost. Some of the well known email solutions are Sendgrid, Mailchimp, Postmark, Mailgun etc
Using Sendgrid for sending emails
All these platform have well documented REST APIs to send emails. Let’s see an example with Sendgrid
- Create a dynamic template in Sendgrid. Use merge fields anywhere in the subject or email body by wrapping it in double curly braces like
{{this}}
. - Get the dynamic template id, and the API key from Sendgrid
- Use the following apex code to send the email
Apex Code Guide
Create a Email class
public with sharing class Email {
private static final string SENDGRID_API_KEY = 'SG.xxxxxx';
private static final String SENDGRID_API_URL = 'https://api.sendgrid.com/v3/mail/send';
public static HttpResponse send(
List<Message> messages,
String senderName,
String senderEmail,
String replyToName,
String replyToEmail,
String templateId
) {
HttpRequest request = new HttpRequest();
request.setEndpoint(SENDGRID_API_URL);
request.setMethod('POST');
request.setHeader('Authorization', 'Bearer ' + SENDGRID_API_KEY);
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
SendGridEmail e = new SendGridEmail();
User sender = new User();
sender.name = senderName;
sender.email = senderEmail;
User replyTo = new User();
replyTo.name = replyToName;
replyTo.email = replyToEmail;
e.sender = sender;
e.reply_to = replyTo;
e.template_id = templateId;
e.personalizations = messages;
request.setBody(
// replace "sender" with "from", as sendrid expects "from" which is reserved in apex
JSON.serialize(e).replace('"sender"', '"from"')
);
Http http = new Http();
HttpResponse res = http.send(request);
return res;
}
public class Message {
public Message(String receiverEmail, Map<String, String> params) {
List<User> receivers = new List<User>();
User receiver = new User();
receiver.email = receiverEmail;
receivers.add(receiver);
this.to = receivers;
this.dynamic_template_data = params;
}
public List<User> to;
public Map<String, String> dynamic_template_data;
}
public class User {
public String name;
public String email;
}
public class SendGridEmail {
public User sender;
public User reply_to;
public String template_id;
public List<Message> personalizations;
}
}
Use it as following -
private static final string SENDGRID_TEMPLATE_ID = 'd-xxxxxxxxxxxxxxxxx';
Map<String, String> params = new Map<String, String>();
params.put('mergeFieldName', 'mergeFieldValue');
List<Email.Message> messages = new List<Email.Message>();
messages.add(new Email.Message('toAddress', params);)
Email.send(
messages,
'Support', // from name
'support@yourcompany.com', // from address
'Support', // reply-to name
'support@yourcompany.com', // reply-to email
SENDGRID_TEMPLATE_ID
);
That’s it! Now you can use a dedicated email service without worrying about email limits or costs and can enjoy advance email features.
Happy coding!