Email Service

The Email Service component provides a production-ready solution for sending emails in Servercn using nodemailer. It supports multiple email providers including Gmail, SMTP servers, SendGrid, and more.

Installation Guide

Install this component using the following command:

npx servercn-cli add email-service

Prerequisites

  1. Enable 2-Step Verification on your Google Account
  2. Generate an App Password:
    • Go to Google Account → Security → 2-Step Verification → App passwords
    • Create a new app password for "Mail"
    • Copy the generated password

Add the following to your .env file:

SMTP Server

SMTP_HOST='smtp.gmail.com'
SMTP_PORT='465'
SMTP_USER=''
SMTP_PASS=''
EMAIL_FROM=""

Resend

RESEND_API_KEY="your-resend-api-key"

Mailtrap

MAILTRAP_API_KEY="your-mailtrap-api-key"

Basic Implementation

1. Nodemailer with SMTP

Nodemailer SMTP Configuration

MVC Path: src/configs/nodemailer.ts

Feature Path: src/shared/configs/nodemailer.ts

import nodemailer from "nodemailer";
import env from "./env";
 
let transporter: nodemailer.Transporter | null = null;
 
export function getTransporter() {
  if (transporter) return transporter;
  const host = env.SMTP_HOST;
  const port = Number(env.SMTP_PORT || 465);
  const user = env.SMTP_USER;
  const pass = env.SMTP_PASS;
  const from = env.EMAIL_FROM;
  if (!host || !user || !pass || !from) {
    throw new Error("SMTP/EMAIL env not configured");
  }
 
  transporter = nodemailer.createTransport({
    host,
    port,
    secure: port === 465,
    auth: { user, pass }
  });
  return transporter;
}

Send Email Function

MVC Path: src/utils/send-mail.ts

Feature Path: src/shared/utils/send-mail.ts

import env from "../configs/env";
import { getTransporter } from "../configs/nodemailer";
import { ApiError } from "./api-error";
 
type sendMail = {
  from?: string;
  subject: string;
  data: Record<string, any>;
  email: string;
  html: string;
};
 
export async function sendEmail({
  from,
  email,
  subject,
  html
}: sendMail) {
  const transporter = getTransporter();
 
  return transporter
    .sendMail({
      from: from || `<${env.EMAIL_FROM}>`,
      to: email,
      subject,
      html
    })
    .catch(() => {
      throw ApiError.badRequest("Failed to send email");
    });
}

2. Resend

Resend configuration

MVC Path: src/configs/resend.ts

Feature Path: src/shared/configs/resend.ts

import { Resend } from "resend";
import env from "./env";
 
export const resend = new Resend(env.RESEND_API_KEY);

Send Email Function

MVC Path: src/utils/send-mail.ts

Feature Path: src/shared/utils/send-mail.ts

import env from "../configs/env";
import { resend } from "../configs/resend";
import { ApiError } from "./api-error";
 
type sendMail = {
  from?: string;
  subject: string;
  data: Record<string, any>;
  email: string;
  html: string;
};
 
export async function sendEmail({
  from,
  email,
  subject,
  html
}: sendMail) {
 
  return await resend.emails.send({
    from: from || `<${env.EMAIL_FROM}>`,
      to: email,
      subject,
      replyTo: email,
      html
    });
}

3. Mailtrap

Mailtrap configuration

MVC Path: src/configs/mailtrap.ts

Feature Path: src/shared/configs/mailtrap.ts

import { MailtrapClient } from "mailtrap";
import env from "./env";
 
export const mailtrap = new MailtrapClient({
  token: env.MAILTRAP_API_KEY
});

Send Email Function

MVC Path: src/utils/send-mail.ts

Feature Path: src/shared/utils/send-mail.ts

import env from "../configs/env";
import { mailtrap } from "../configs/mailtrap";
 
type sendMail = {
  from?: string;
  subject: string;
  data: Record<string, any>;
  email: string;
  html: string;
};
 
export async function sendEmail({ from, email, subject, html }: sendMail) {
  const htmlContent = html || "";
  try {
    await mailtrap.send({
      from: {
        email: from || env.EMAIL_FROM
      },
      to: [{ email }],
      subject,
      html: htmlContent
    });
  } catch (error) {
    throw error;
  }
}

Usage Examples

import { sendEmail } from "../utils/send-mail";
 
const html = `
  <h1>Welcome to Servercn</h1>
  <p>Thank you for joining us!</p>
`;
 
await sendEmail({
  email: "john.doe@example.com",
  subject: "Welcome to Servercn",
  html
});
import { sendEmail } from "../utils/send-mail";
const html = `
  <h1>Reset Your Password</h1>
  <p>Click <a href="https://example.com/reset">here</a> to reset your password.</p>
`;
 
await sendEmail({
  email: "john.doe@example.com",
  subject: "Reset Your Password",
  html,
  from: "Servercn <servercn@example.com>"
});

File & Folder Structure

Loading files...

Installation

npx servercn-cli add email-service