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;
}