Next.jsアプリのNodemailerをResendに置き換えた
はじめに
バニッシュ・スタンダードの深田です。
私は業務でGoとReactをメインとしたサービス開発に携わっていますが、個人開発ではT3 Stack(Next.js、TypeScript、tRPC、Prisma、Tailwind CSS、NextAuth.jsの開発スタック)をベースとした効率的な小規模開発にも取り組んでいます。この個人開発をVercelにデプロイしましたが、メール送信機能が不安定な問題に遭遇しました。そこで、Resendを利用してこの問題を解決した方法について説明します。
問題
アプリケーション内でのユーザー登録やパスワードリセット機能にはメール送信が必要で、Nodemailerを使用して実装していました。しかし、Vercel環境ではメールが送信される場合もありましたが、何らかの制限で送信されないケースも多く発生しました。Vercelの公式ドキュメントでも、Nodemailerを使用する場合にも外部のSMTPプロバイダーを使用することが推奨されているようでした。
以下に、現状のNodemailerを使用していたコード例を示します。
import { TRPCError } from "@trpc/server"
import nodemailer from "nodemailer"
// SMTPサーバの設定
const transporter = nodemailer.createTransport({
pool: true,
service: "gmail",
port: 465, // GmailのSMTPサーバのポート
auth: {
user: process.env.GMAILUSER || "",
pass: process.env.GMAILPASSWORD || "",
},
maxConnections: 1,
})
// メール送信
export const sendEmail = async (
subject: string,
body: string,
sendTo: string
) => {
const mailOptions = {
// 送信元
from: `深田 <${process.env.GMAILUSER}>`,
// 送信先
to: sendTo,
// 件名
subject: subject,
// 本文
html: body,
}
// メール送信
transporter.sendMail(mailOptions, (error) => {
if (error) {
console.log(error)
throw new TRPCError({
code: "BAD_REQUEST",
message: "メールの送信に失敗しました",
})
}
})
}
Resendの導入
Vercelの公式ドキュメントにもサードパーティのメールサービスを導入することが推奨されていたので、Nodemailerの代わりに、Resendを導入してこの問題を解決することにしました。Resendにしたのは、公式に次世代のSnedGridと書かれていたからです。
Resendを導入する手順を下記を元に進めていきます。
1.Resendアカウントの設定
まず、Resendの公式サイトにアクセスし、アカウントを作成します。アカウント作成後、APIキーを取得します。
2. 独自ドメインの設定
Resendを利用して独自ドメインでメールを送信するためには、ドメイン認証を行う必要があります。動作確認を優先したい方はここはスキップして、Resendが提供する既定のドメイン(@resend.dev
)を使用してください。
注意点として、既定のドメイン(@resend.dev
)を利用したメール送信は、自身のメールアドレスに対してのみ実行可能です。他のメールアドレスへメール送信を行うためには、独自ドメインの認証が必要です。
独自ドメインはこちらを参考にしてください。
Resendに独自ドメインを登録
DNSレコード設定にDNSレコードを追加
ご利用のDNSプロバイダの管理画面で、以下のレコードを追加してください。ここではXserverを例に説明していますが、ご自身の環境に応じて対応してください。
- MXレコード:Resendが提供するMXレコードを追加します。
- SPFレコード(TXTレコード):Resendが指定するSPFレコードをTXTレコードとして追加します。
- DKIMレコード(TXTレコード):Resendが提供するDKIMレコードをTXTレコードとして追加します。
- DMARCレコード(オプション、TXTレコード):必要に応じてDMARCレコードをTXTレコードとして追加します
認証開始
Resend側で認証を開始してください。画像は一度失敗したものなので Restarg verification
となっています。
認証済み確認
Resend側で認証済みであることを確認してください。
3.環境変数の登録
RESEND_API_KEY="API Key"
4.Resendのインストール
npm install resend
5.Resendによるメール送信ロジックの実装
import { TRPCError } from "@trpc/server";
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY || "");
interface SendEmailOptions {
subject: string;
body: string;
sendTo: string;
}
// メール送信
export const sendEmailByResend = async ({
subject,
body,
sendTo,
}: SendEmailOptions) => {
try {
const response = await resend.emails.send({
from: "深田 <onboarding@resend.dev>", // 独自ドメインの認証が通ったら置き換える
to: [sendTo],
subject: subject,
html: body,
});
if (!response) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "メールの送信に失敗しました",
});
}
} catch (error) {
console.error(error);
throw new TRPCError({
code: "BAD_REQUEST",
message: "メールの送信に失敗しました",
});
}
};
6.動作確認
ローカルでもVercelでもResend経由でメールが送信されるようになりました。何度か試していますが、送信されないという問題は今のことろ発生していません。
まとめ
今回のケースでは、VercelにデプロイしWEBアプリケーション上でNodemailerを使用したメール送信がうまく機能しない問題に直面しましたが、Resendを利用することで問題を解決しました。
最後に
弊社「株式会社バニッシュ・スタンダード」では、現在エンジニアおよびデザイナーを積極的に募集しています。
私も入社してから数ヶ月ですが、幅広い技術領域に携わることができ、日々充実した仕事ができています。技術レベルの高いエンジニアが多く、成長意欲のある方には特におすすめです。また、みんなが仕事に対して責任感を持ち、親切な人ばかりなので、非常に働きやすい環境です。
少しでも興味を持たれた方は、ご応募をお待ちしています。
Discussion