Setting Up Mailgun
This document outlines the steps to integrate Mailgun into your project using Next.js.
0.1. Create a Mailgun Account
To use Mailgun, you need to create an account. You can do this by visiting the Mailgun website (opens in a new tab).
0.2. Create a mailgun domain
0.3. Create a Mailgun Sending API Key
Once you have created an account, you need to create an Sending API key.
- Navigate to the domain dashboard (opens in a new tab).
- Open the domain settings dropdown.
- Navigate to the "Sending API Keys" tab.
- If you have permission to create a new API key, click the "Create API Key" button.
1. Install the Mailgun and FormData NPM Packages
To get started with Mailgun, you need to install the mailgun.js (opens in a new tab) package. Run the following command in your project directory:
npm install mailgun.js form-data --saveNOTE: starting from version 3.0 you need to pass FormData (we need this to keep library universal). For node.js you can use form-data library.
2. Create a Mailgun Client
import Mailgun from "mailgun.js";
import formData from "form-data";
const mailgun = new Mailgun(formData);
const mailgunClient = mailgun.client({
username: "api",
key: process.env.MAILGUN_API_KEY,
});Make sure you have your environment variables set up in your .env file or through your deployment configuration:
MAILGUN_API_KEY=your-api-key
MAILGUN_DOMAIN=your-domain2. Email data
const emailData = {
from: "no-reply@upheave.tech", // or process.env.MAILGUN_DOMAIN
to: "your-email@example.com, jon.doe@upheave.tech",
subject: `email subject`,
template: "your-template-name",
"o:tag": "my-tag",
"h:X-Mailgun-Variables": JSON.stringify({
variable1: "value1",
variable2: "value2",
}),
};2.1. h:X-Mailgun-Variables
The h:X-Mailgun-Variables header is used to pass custom variables to the email template. This can be useful for personalizing the email content based on the user's preferences or other information.
2.2. o:tag
The o:tag in Mailgun can be useful for tracking and filtering emails in the Mailgun dashboard.
3. Sending email
For sending emails, you need to create a Mailgun instance and call the messages.create method.
try {
const response = await mailgunClient.messages.create(process.env.MAILGUN_DOMAIN, emailData);
// do something with the response, or don't...
} catch (error: any) {
console.error(error);
}4. Mailgun template
Mailgun allows you to use templates for your emails. Templates help in maintaining a consistent format and design for your emails. You can create templates in the Mailgun dashboard and then use them in your project.
4.1. Create template
Define your template name inside Template details section and use it in your email data.
const emailData = {
// from: "no-reply@upheave.tech", // or process.env.MAILGUN_DOMAIN
// to: "your-email@example.com, jon.doe@upheave.tech",
// subject: `email subject`,
template: "your-template-name",
// "o:tag": "my-tag",
// "h:X-Mailgun-Variables": JSON.stringify({
// variable1: "value1",
// variable2: "value2",
// }),
};
4.2. Edit template
4.3. Template example
const emailData = {
// from: "no-reply@upheave.tech", // or process.env.MAILGUN_DOMAIN
// to: "your-email@example.com, jon.doe@upheave.tech",
// subject: `email subject`,
// template: "your-template-name",
// "o:tag": "my-tag",
"h:X-Mailgun-Variables": JSON.stringify({
variable1: "value1",
variable2: "value2",
}),
};Variables in the template are defined with doble curly braces {{ variable }}.
5. Mailgun service example
Example is from City-Island project. Notification email service for lease expiration and renewal.
import Mailgun, { Interfaces, MailgunMessageData } from "mailgun.js";
import formData from "form-data";
import logger from "@/logger";
export interface IMailgunService {
sendMail(data: MailgunMessageData): Promise<void>;
}
export class MailgunService implements IMailgunService {
private mailgunClient: Interfaces.IMailgunClient;
private apiKey: string;
private domain: string;
constructor() {
this.apiKey = process.env.MAILGUN_API_KEY || "";
this.domain = process.env.MAILGUN_DOMAIN || "";
if (!this.apiKey || !this.domain) {
throw new Error("Mailgun API key and domain must be provided");
}
const mailgun = new Mailgun(formData);
this.mailgunClient = mailgun.client({
username: "api",
key: this.apiKey,
});
}
async sendMail(data: MailgunMessageData): Promise<void> {
try {
const { from, to, subject, template } = data;
if (!from || !to || !subject || !template) {
throw new Error("Missing required mail data fields");
}
await this.mailgunClient.messages.create(this.domain, data);
} catch (e: any) {
logger.error(e, { module: "Mailgun email service" });
throw e;
}
}
}5.1. Sending email
Sending email is very simple. You just need to pass email data to the service.
await mailgunService.sendMail(emailData);5.2. Email data
Email data is an object with the following properties:
const emailData = {
from: string;
to: string;
subject: string;
template: string;
"o:tag": string;
"h:X-Mailgun-Variables": string;
};// h:X-Mailgun-Variables
const leaseData = {
leaseId: string;
leaseUrl: string;
tenant: string;
leaseStartDate: string;
leaseEndDate: string;
buildings: string;
offices: string;
};5.3. Lease expiration template
