はじめに (対象読者・この記事でわかること)

この記事は、Azure App Service(Linux)上で Node.js アプリを運用しているエンジニアを対象としています。
Gmail の SMTP サーバーを利用してメール送信を実装したものの、「メールが送れない」エラーに直面した方が対象です。

本記事を読むことで、以下のことが理解・実践できるようになります。

  • Gmail で必要な「アプリ パスワード」や OAuth2 設定の意味
  • Azure App Service の環境変数・ネットワーク制限がメール送信に与える影響
  • Nodemailer を用いた正しいコード例とデバッグ手順

背景として、2024 年に Google が「安全性の低いアプリのアクセス」を完全に廃止し、従来の平文認証が使えなくなったことがあります。そのため、既存の実装が突然動かなくなるケースが増えています。この記事では、実際に起きたエラーとその対策を具体的に示します。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Node.js と npm の基本的な操作
  • Azure ポータルで App Service の設定画面を操作できること
  • SMTP(Simple Mail Transfer Protocol)の基礎概念と、TLS/STARTTLS の意味

背景と問題の概要

Azure App Service(Linux)上で動作する Web アプリから Gmail の SMTP (smtp.gmail.com) に対してメール送信を行う際、次のようなエラーが頻出します

535-5.7.8 Username and Password not accepted. Learn more at 
535 5.7.8 https://support.google.com/mail/?p=InvalidCredentials

または

Error: connect ECONNREFUSED 52.95.xxx.xxx:587

主な原因は大きく分けて 3 つあります。

  1. Google 側の認証方式変更
    従来のユーザー名+パスワード(「安全性の低いアプリ」)が無効化され、アプリ パスワードや OAuth2 が必須となった。

  2. Azure App Service のアウトバウンド制限
    Azure はポート 25(SMTP の標準ポート)へのアウトバウンドをブロックしていますが、ポート 587/465 は許可されています。TLS 設定が不適切だと接続が遮断されます。

  3. 環境変数の設定ミス
    App Service の「Configuration」画面で設定した環境変数が正しく読み込まれていない、または特殊文字がエスケープされていないケースが多いです。

このような問題を解決するために、以下の手順で設定を見直し、コードを修正します。次のセクションでは、実際の手順とサンプルコードを段階的に示します。

具体的な手順と実装方法

ステップ 1:Gmail 側でアプリ パスワードを取得

  1. Google アカウントにログインし、Google アカウントのセキュリティページへ移動。
  2. 「2 段階認証プロセス」を有効化します(未設定の場合はまず設定)。
  3. 「アプリ パスワード」セクションで「アプリの選択」→「メール」, 「デバイスの選択」→「その他(Custom name)」に「AzureAppService」など分かりやすい名前を入力し、生成 をクリック。
  4. 表示された 16 桁のパスワードを コピー して、後ほど App Service の環境変数に貼り付けます。

※ OAuth2 を利用したい場合は、Google Cloud Console で「OAuth 同意画面」を作成し、クライアント ID/シークレットを取得したうえで、nodemailerXOAUTH2 プラグインを使用してください。ここでは手軽さのため、アプリ パスワード方式を採用します。

ステップ 2:Azure App Service に環境変数を設定

  1. Azure ポータルで対象の App Service を開く。
  2. 左メニューの 「Configuration」「Application settings」 を選択。
  3. 以下のキーと取得した値を追加。
キー名 説明
GMAIL_USER Gmail のメールアドレス (example@gmail.com)
GMAIL_APP_PASSWORD 先ほど取得した 16 桁のアプリ パスワード
SMTP_HOST smtp.gmail.com
SMTP_PORT 587 (STARTTLS 用)
SMTP_SECURE false (STARTTLS の場合は false)
  1. 変更を保存し、「再起動」 ボタンで Web アプリを再起動します。環境変数は Node.js 側で process.env から取得できます。

ステップ 3:Node.js (Nodemailer) のコード修正

以下は最小構成のサンプルです。package.jsonnodemailer をインストールしてください。

Bash
npm install nodemailer
Javascript
// mailer.js const nodemailer = require('nodemailer'); // 環境変数から設定を取得 const { GMAIL_USER, GMAIL_APP_PASSWORD, SMTP_HOST = 'smtp.gmail.com', SMTP_PORT = 587, SMTP_SECURE = false } = process.env; // transporter の作成 const transporter = nodemailer.createTransport({ host: SMTP_HOST, port: Number(SMTP_PORT), secure: SMTP_SECURE, // true なら TLS(ポート 465)、false なら STARTTLS(ポート 587) auth: { user: GMAIL_USER, pass: GMAIL_APP_PASSWORD }, tls: { // Gmail が使用する最新の暗号スイートに合わせる rejectUnauthorized: false } }); // テスト送信関数 async function sendTestMail() { try { const info = await transporter.sendMail({ from: `"Azure App Service" <${GMAIL_USER}>`, to: 'receiver@example.com', subject: '【テスト】Azure App Service からのメール送信', text: 'このメールは Azure App Service (Linux) から送信されました。', // html: '<p>HTML 形式でも送信可能です。</p>' }); console.log('Message sent: %s', info.messageId); } catch (err) { console.error('メール送信エラー:', err); // 詳細エラーを Azure のログに出力 console.error('エラーコード:', err.code); console.error('レスポンス:', err.response); } } // 起動時にテストメールを送信(デバッグ用) if (require.main === module) { sendTestMail(); }

ポイント解説

  • secure: false + port: 587STARTTLS を使用。Azure では 587 が開放されているため、接続が拒否されることは少ない。
  • tls.rejectUnauthorized: false は、自己署名証明書等でエラーになる場合の回避策ですが、実運用では可能な限り true に戻すことを推奨。
  • エラーハンドリングで err.code(例: EAUTH, ECONNECTION)や err.response をログに出すと、Azure の「Log stream」や「Application Insights」で原因を追跡しやすくなる。

ステップ 4:デプロイと動作確認

  1. コードを GitHub などにプッシュし、Azure の デプロイセンター で自動デプロイを設定。
  2. デプロイ完了後、Azure ポータルの「Log stream」 を開き、アプリ起動時に sendTestMail() が実行されているか確認。
  3. 受信側メールボックスにテストメールが届けば成功です。届かない場合は、以下の「ハマった点やエラー解決」セクションを参照してください。

ハマった点やエラー解決

発生したエラー 原因の可能性 解決策
535-5.7.8 Username and Password not accepted アプリ パスワードが正しく設定されていない、または 2 段階認証が無効 Google アカウントの 2FA が有効か確認し、正しいアプリ パスワードを再生成して環境変数に再設定
connect ECONNREFUSED 52.xx.xx.xx:587 Azure のネットワーク制限か、SMTP_SECURE の設定ミス ポート 587 が開放されていることを確認し、secure:false に変更。必要なら tls: {rejectUnauthorized:false} を一時的に有効化
self signed certificate in certificate chain Gmail の TLS 証明書チェーンが検証できない tls.rejectUnauthorized: false を一時的に設定し、根本的には最新の Node.js バージョンにアップデート
メールは送信成功だが スパムフォルダ に入る 送信元ドメインが SPF/DKIM で認証されていない カスタムドメインを使用し、Azure の DNS に SPF/TXT レコードを追加。もしくは SendGrid 等の認証済みサービスへ切り替え

解決策まとめ

  1. Google 側で必ずアプリ パスワード(または OAuth2)を取得。
  2. Azure App Service の環境変数に正しく設定し、再起動。
  3. Nodemailer の secureportfalse + 587 に統一し、tls オプションで一時的にエラー回避。
  4. ログストリームでエラー出力を確認し、エラーメッセージに応じて対処。

以上で、Azure App Service (Linux) から Gmail へのメール送信が安定して行えるようになります。

まとめ

本記事では、Azure App Service(Linux)上で Gmail の SMTP にメール送信できない典型的な原因と、アプリ パスワード取得 → 環境変数設定 → Nodemailer の正しい構成という三段階の解決フローを解説しました。

  • Google の認証変更に伴うアプリ パスワードの必須化
  • Azure のアウトバウンド制限とポート設定(587/STARTTLS)への対応
  • 環境変数のミス防止とデバッグログの活用

これらを実践すれば、メールが届かないというトラブルを迅速に解消でき、アプリの通知機能やユーザーへのメール配信を安定させられます。次回は OAuth2 による認証SendGrid との比較といった、さらに高度なメール送信手法についても取り上げる予定です。

参考資料