4IT580: Docs
4IT580 WebGitLab

5th Practical Class:
Sending Emails with SMTP!

Overview

Currently, your Quacker application uses a ConsoleMailerAdapter that only logs emails to the console. In this practical class, we'll replace it with a real SMTP adapter that can send actual emails through services like Gmail, SendGrid, or any SMTP provider.

We'll also learn how to create and compile beautiful email templates using MJML (Mailjet Markup Language). MJML is a markup language designed to reduce the pain of coding responsive emails. It abstracts away the complexity of responsive HTML emails and generates clean, responsive HTML that works across all email clients. Think of it as "Bootstrap for emails" - you write simple, semantic markup and MJML converts it to email-compatible HTML with all the necessary table layouts and inline styles.

Current Email Setup

The application currently has a console-based email system that logs emails instead of sending them:

This is registered in the :

Setting Up SMTP Provider

1. Configure SMTP Environment Variables

First, you need to add SMTP configuration to your file. The application already has the necessary configuration fields ready in service:

Note for Gmail users: You'll need to generate an app-specific password. Go to Google Account Settings → 2-Step Verification → App passwords.

Popular SMTP Providers Configuration Examples

Provider

SMTP_HOST

SMTP_PORT

SMTP_SECURE

Gmail

smtp.gmail.com

587

false

SendGrid

smtp.sendgrid.net

587

false

Outlook

smtp-mail.outlook.com

587

false

Mailgun

smtp.mailgun.org

587

false

2. Fix EmailModule Type Issue

Before we proceed, there's a TypeScript type issue in the EmailModule that needs to be fixed. Update the to use instead of :

Important: This change from to is necessary to avoid TypeScript errors when injecting services like into the factory function.

3. Understanding the SMTP Configuration Interface

The SMTP adapter requires a specific configuration interface:

4. Replace Console Mailer with SMTP Adapter

Now we need to update the to use the SMTP adapter instead of the console mailer:

That's it! Your application will now send real emails through SMTP instead of just logging them to the console.

Important: Set the "from" address

The SMTP adapter ships with a placeholder sender. Update it to a valid address you control (ideally your domain) to avoid rejections and spam flags by providers.

Using EmailService in Your Modules

Important: Module Import Requirements

To use in any module, you need to import the into that module. The email configuration is not global by default, so each module that needs to send emails must explicitly import the .

Example: Adding Email Support to a Module

If you want to use in a module (e.g., ), you need to:

  1. Import in your module
  2. Import to access the Config service
  3. Configure EmailModule with the same factory function
  4. Inject into your services

Then in your service:

Alternative: Creating a Shared Email Module

To avoid duplicating the email configuration in every module, you can create a shared email module that's configured once and imported everywhere:

Then import in any module that needs email functionality:

Working with Email Templates

The application uses MJML (Mailjet Markup Language) for creating responsive email templates. MJML is a framework that makes it easy to create beautiful, responsive emails that work across all email clients.

Understanding the Email Flow

Creating a New Email Template

Let's create a welcome email template as an example:

Step 1: Create the MJML Template

Create a new file :

Step 2: Compile MJML to HTML

Run this command from the backend directory to compile your MJML template:

This generates an HTML file that's responsive and works across all email clients.

Step 3: Use the Template in Your Code

Now you can use this template in your application. Here's an example of sending a welcome email:

Existing Email Templates

The application already includes two email templates that are used by BetterAuth:

1. Email Verification Template

2. Password Reset Template

Using Emails with BetterAuth

BetterAuth automatically sends emails in these scenarios:

  1. User Registration: Sends a verification email when is true
  2. Password Reset: Sends a reset link when user requests password reset
  3. Email Change: Can send verification for email changes (if configured)

The email sending is configured in the BetterAuth provider:

If you want to require verification of the user and not signing up immediately, follow Better Auth documentation from this part: https://www.better-auth.com/docs/concepts/email#2-require-email-verification

Testing Your Email Setup

1. Test SMTP Connection

You can create a simple test endpoint to verify your SMTP configuration. First, make sure to import in your :

Then add the test endpoint to your controller:

Then test it by visiting:

2. Test Registration Flow

  1. Register a new user through your frontend or GraphQL playground
  2. Check if the verification email is received
  3. Click the verification link to confirm it works

3. Test Password Reset

  1. Request a password reset for an existing user
  2. Check if the reset email is received
  3. Verify the reset link works correctly

Troubleshooting

Common Issues and Solutions

  1. "Invalid login" or authentication errors

    • Double-check your SMTP credentials
    • For Gmail, ensure you're using an app-specific password
    • Some providers require enabling "Less secure app access"
  2. Connection timeout

    • Check if your firewall allows outbound connections on the SMTP port
    • Try different port numbers (587, 465, 25)
    • Verify the SMTP_HOST is correct
  3. Emails going to spam

    • Use a proper "from" address that matches your domain
    • Add SPF, DKIM, and DMARC records to your domain
    • Avoid spam trigger words in subject and content
  4. Template not found errors

    • Ensure you've compiled MJML to HTML
    • Check the file paths in
    • Verify the template files exist in

Development Tips

Using Mailtrap for Development

Mailtrap is a great service for testing emails in development without sending real emails:

Email Preview Tools

You can use the MJML online editor at mjml.io/try-it-live to preview your templates before compiling them.

Conditional Email Sending

You might want to use different email adapters based on the environment:

Summary

You should now be able to: