ブログ一覧

Nodemailerの使い方

Node.jsの定番メール送信ライブラリにNodemailerがあります。必要な機能が一通り揃っていて、Promiseベースで扱いやすく、TypeScript環境にも問題なく導入できます。

この記事は2021年に書いたものですが、Nodemailerは現在v8になっています。とはいえ基本的な書き方は当時から変わっていないので、コードを現行バージョン(v8)で確認した上で全体を整理し直しました。

インストール

npm install nodemailer

TypeScript環境では型定義を別途インストールします。型は今もNodemailer本体には同梱されていないため、 @types/nodemailer を使います(v8系に対応済み)。

npm install -D @types/nodemailer

設定

スマホやパソコンで独自ドメインのメールを使うときと同じ設定です。

  • ホスト名(Host Name)
  • メールアドレス(User Name)
  • パスワード(Password)

の3つの情報を使ってメールを送信します。これらの情報は、メールアドレスを設定したサービス(レンタルサーバーなど)の管理画面で確認できます。

import { createTransport } from "nodemailer";

const transporter = createTransport({
	host: "mail.example.com", // ホスト名
	port: 465,
	secure: true,
	auth: {
		user: "mail@example.com", // メールアドレス
		pass: "********", // パスワード
	},
});

注意点として、パスワードをこのままコードに書くと、GitHubなどにそのままアップロードされてしまいます。セキュリティー上の理由から、以下のように環境変数を使ってください。プライベートなリポジトリだとしてもです。

import { createTransport } from "nodemailer";

const transporter = createTransport({
	host: "mail.example.com",
	port: 465,
	secure: true,
	auth: {
		user: process.env.MAIL_AUTH_USER, // 環境変数
		pass: process.env.MAIL_AUTH_PASS, // 環境変数
	},
});

メールを送信する

送信はsendMail関数で、Promiseが返ってきます。成功と失敗で処理を分けたいときはtry/catchが使えます。

sendMailに最低限必要なオプションは以下の通りです。

  • from(送信元)
  • to(送信先)
  • subject(件名)
  • text(メール本文)

その他のオプションには、返信先を指定するreplyTo、ファイルを添付できるattachments、HTML形式の本文を送れるhtmlなどがあります。

try {
	await transporter.sendMail({
		from: `"Shinobi Works" <no-reply@example.com>`,
		to: "administer@example.com",
		subject: "問い合わせがありました",
		text: "サイトにお問い合わせがありました...(略)",
	});
} catch (error) {
	console.log("メールを送信できませんでした");
	throw error;
}

注意点として、try/catchで拾えるのは、ホスト名やパスワードの不備などで送信処理そのものが失敗した場合だけです。toオプション(送信先メールアドレス)が間違っていたとしても送信は「成功」になります。PHPのmail関数と同じで、送信先に届くかどうかは別問題だからです。

これはfromにも言えることで、認証に使ったメールアドレスとfromのアドレスが一致していなくても送信できます。たとえばadminister@example.comの認証情報で送信しつつ、fromにはno-reply@example.comを指定する、といった使い方ができます。システムの自動返信メールに役立ちます。

メールが送れない場合

国外IPからのアクセスを制限しているレンタルサーバーがあるため、Netlifyのような海外のサーバーから実行する場合は、制限を解除しないと送信できないことがあります。私が試したときは502エラーが返ってきました。

また、Cloudflare WorkersやPages Functionsのような環境では、そもそもNodemailerが前提とするSMTP接続が使えないことがあります。この話は Cloudflare Pages Functionsでメールが送信できない場合の対処法 に書きました。

全体コード

import { createTransport } from "nodemailer";

const transporter = createTransport({
	host: "mail.example.com",
	port: 465,
	secure: true,
	auth: {
		user: process.env.MAIL_AUTH_USER,
		pass: process.env.MAIL_AUTH_PASS,
	},
});

try {
	await transporter.sendMail({
		from: `"Shinobi Works" <no-reply@example.com>`,
		to: "administer@example.com",
		subject: "問い合わせがありました",
		text: "サイトにお問い合わせがありました...(略)",
	});
} catch (error) {
	console.log("メールを送信できませんでした");
	throw error;
}