Sendgrid

This page denotes how we should do integration with SendGrid in spring boot for sending mail

Why Use SendGrid in Spring Boot?

  • SendGrid ensures high deliverability rates by managing email infrastructure.

  • SendGrid can handle millions of emails per day, making it ideal for applications with growing user bases.

  • It provides a simple REST API and SMTP integration, making it easy to integrate with Spring Boot applications.

  • SendGrid provides detailed analytics, including open rates, click-through rates, and bounce rates.

  • It offers free 100 mails per day.

How to Integrate SendGrid with Spring Boot

Step 1: Create a SendGrid Account

  • Sign up for a free SendGrid account at https://sendgrid.com.

  • Verify the domain or create identity and generate an API key.

Step 2: Add SendGrid Dependency

  • Add the following dependency inpom.xml:

    <dependency>
        <groupId>com.sendgrid</groupId>
        <artifactId>sendgrid-java</artifactId>
        <version>4.10.3</version>
    </dependency>

Step 3: Configure SendGrid API Key

  • Configure API key in spring boot app properties file.

spring.sendgrid.api.key=SENDGRID_API_KEY
spring.sendgrid.fromEmail=example@email.com #need to be same as account one

Step 4: Create a Service to Send Emails

  • Create a service class to send emails using SendGrid's Java SDK:

    import com.sendgrid.*;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    @Service
    @Log4j2
    @RequiredArgsConstructor
    public class EmailService {
    
        @Value("${spring.sendgrid.api-key}")
        private String apiKey;
    
        @Value("${spring.sendgrid.from-email}")
        private String fromEmail; // should be same as registered identity
    
        @Async
        public void sendMail(String to, String subject, String body, boolean isHtmlContent) {
            log.info("Sending email to: {} with subject: {}", to, subject);
    
            Email fromEmail = new Email(this.fromEmail);
            Email toEmail = new Email(to);
            Content contentObj = new Content(isHtmlContent?"text/html":"text/plain", body);
            Mail mail = new Mail(fromEmail, subject, toEmail, contentObj);
    
            SendGrid sg = new SendGrid(apiKey);
    
            try {
                Request request = new Request();
                request.setMethod(Method.POST);
                request.setEndpoint("mail/send");
                request.setBody(mail.build());
    
                Response response = sg.api(request);
    
                System.out.println("Status Code: " + response.getStatusCode());
                System.out.println("Response Body " + response.getBody());
                System.out.println("Response Headers " + response.getHeaders());
    
                if (response.getStatusCode() == 202) {
                    System.out.println("Email sent successfully!");
                } else {
                    System.err.println("Error sending email: " + response.getStatusCode() + " - " + response.getBody());
                    throw new IOException("Failed to send email");
                }
            }catch (Exception e){
                log.error("Error sending email: {}", e.getMessage());
            }
    
        }

Advanced Use Cases

1. Dynamic Templates

  • Use SendGrid's dynamic templates to create personalized emails with placeholders.

  • Example:

    Mail mail = new Mail();
    mail.setTemplateId("your-template-id");
    mail.addPersonalization(new Personalization()
        .addDynamicTemplateData("name", "John Doe")
        .addDynamicTemplateData("link", "https://example.com/reset-password"));

2. Email Scheduling

  • Schedule emails to be sent at a specific time using the send_at parameter.

mail.setSendAt(System.currentTimeMillis() / 1000L + 3600); // Send after 1 hour

3. Event Webhooks

  • Set up webhooks to receive real-time notifications about email events (e.g., opens, clicks, bounces).

  • Use these events to trigger actions in your application, such as retrying failed emails.

Implementing a Webhook to Track Email Status and Bounce Emails with SendGrid

  • First we need to configure webhook in SendGrid, need to enable it and give endpoint of our application that will consume this webhook call.

    • e. g. https://example.com/sendgrid/webhook

  • Create a rest controller to handler incoming webhook events

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class SendGridWebhookController {

    @PostMapping("/sendgrid/webhook")
    public String handleSendGridWebhook(@RequestBody String payload) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            List<Map<String, Object>> events = objectMapper.readValue(payload, List.class);

            // Process each event
            for (Map<String, Object> event : events) {
                String eventType = (String) event.get("event");
                String email = (String) event.get("email");
                String reason = (String) event.get("reason"); // For bounce events
                String timestamp = (String) event.get("timestamp");

                switch (eventType) {
                    case "delivered":
                        System.out.println("Email delivered to: " + email);
                        break;
                    case "open":
                        System.out.println("Email opened by: " + email);
                        break;
                    case "click":
                        System.out.println("Link clicked by: " + email);
                        break;
                    case "bounce":
                        System.out.println("Email bounced for: " + email + ", Reason: " + reason);
                        // Handle bounce (e.g., mark email as invalid in database)
                        break;
                    case "spamreport":
                        System.out.println("Email marked as spam by: " + email);
                        // Handle spam report (e.g., stop sending emails to this address)
                        break;
                    default:
                        System.out.println("Unhandled event type: " + eventType);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "Webhook received!";
    }
}

Pros and Cons of Using SendGrid

Pros

  1. Ease of Use: Simple API and SDKs make integration straightforward.

  2. Scalability: Handles high email volumes effortlessly.

  3. Analytics: Provides detailed insights into email performance.

  4. Reliability: High deliverability rates and robust infrastructure.

  5. Templates and Personalization: Supports dynamic templates and personalized emails.

Cons

  1. Cost: While there’s a free tier, high-volume usage can become expensive.

  2. Learning Curve: Advanced features like templates and analytics may require time to master.

  3. Dependency: Relying on a third-party service means potential downtime or API changes.

Last updated