You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nodemailer+Google OAuth在AWS Amplify部署后无法发送邮件问题排查

Next.js + Nodemailer Google OAuth邮件发送问题:本地正常,AWS Amplify部署后收不到邮件

问题描述

开发的Next.js应用,API路由通过Nodemailer结合Google OAuth实现邮件发送功能,本地运行时邮件可正常收发,但部署至AWS Amplify后,浏览器网络面板显示请求返回200状态,却无法收到邮件。

相关代码

import { type NextRequest, NextResponse } from 'next/server';
import nodemailer from 'nodemailer';
const { google } = require('googleapis');
const OAuth2 = google.auth.OAuth2;

export async function POST(request: NextRequest) {
  const { email, name, userNote } = await request.json();
  // Create Transporter with Google OAuth2
  const createTransporter = async () => {
    console.log('inside createTransporter ~~~~~~~');
    const oauth2Client = new OAuth2(
      process.env.GOOGLE_CLIENT_ID,
      process.env.GOOGLE_CLIENT_SECRET,
      'https://developers.google.com/oauthplayground',
    );
    // obtain Refresh Token:
    oauth2Client.setCredentials({
      refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
    });
    // Obtain Access Token by calling getAccessToken
    const accessToken = await new Promise((resolve, reject) => {
      oauth2Client.getAccessToken((err, token) => {
        if (err) {
          console.log('----- Error here cannot getAccessToken boo ------', err);
          reject();
        }
        resolve(token);
      });
    });
    // Create transporter with OAuth2
    const transporter = nodemailer.createTransport({
      service: 'gmail',
      auth: {
        type: 'OAuth2',
        user: process.env.NODEMAILER_MY_EMAIL,
        accessToken,
        clientId: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        refreshToken: process.env.GOOGLE_REFRESH_TOKEN,
      },
    });

    return transporter;
  };
  // send secure google email
  const sendSecureGoogleMail = async () => {
    try {
      const mailOptions = {
        from: process.env.NODEMAILER_MY_EMAIL,
        to: process.env.NODEMAILER_MY_EMAIL,
        subject: `💌 -  ‼  - YO K8 Message from ${name} (${email})`,
        text: userNote,
      };
      let emailTransporter = await createTransporter();
      await emailTransporter.sendMail(mailOptions);

    } catch (err) {
      return NextResponse.json({ error: err }, { status: 500 });
      console.log('ERROR: ', err);
    }
  };
  // call send email
  try {
    await sendSecureGoogleMail();
    return NextResponse.json({ message: 'Email sent' });
  } catch (err) {
    return NextResponse.json({ error: err }, { status: 500 });
  }
}

浏览器网络面板截图

Nodemailer Google OAuth2 请求返回200


可能原因及解决办法

1. 环境变量配置错误

  • 问题:AWS Amplify中未正确配置Google OAuth相关环境变量(GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET、GOOGLE_REFRESH_TOKEN、NODEMAILER_MY_EMAIL),或变量名拼写、大小写错误。
  • 解决:登录Amplify控制台,进入应用的环境变量设置页,逐一核对变量名和值,确保与本地.env文件完全一致。

2. Google OAuth授权限制

  • 问题:本地生成的Refresh Token绑定了本地回调地址,Amplify部署域名不在Google OAuth授权列表;或Gmail API未启用。
  • 解决:
    • 登录Google Cloud控制台,进入对应项目的OAuth同意屏幕,将Amplify部署域名添加到已获授权的域名。
    • 确认Gmail API已在API库中启用。
    • 若Refresh Token失效,重新在OAuth Playground生成(确保回调地址匹配Amplify域名)。

3. 错误处理逻辑缺陷

  • 问题:sendSecureGoogleMail内部catch直接返回响应,外层try/catch无法捕获错误,导致即使邮件发送失败仍返回200,无法定位问题。
  • 解决:修改错误处理逻辑,抛出错误让外层捕获,同时保留日志:
    const sendSecureGoogleMail = async () => {
      try {
        // 原有邮件发送逻辑
      } catch (err) {
        console.log('ERROR: ', err);
        throw err; // 抛出错误给外层捕获
      }
    };
    
    同时查看Amplify控制台监控→日志,获取API路由的运行错误信息。

4. Amplify网络访问限制

  • 问题:Amplify的网络策略阻止了出站SMTP请求(Gmail SMTP端口587)或Google OAuth服务器访问。
  • 解决:进入Amplify控制台的应用设置→环境→网络设置,确保出站流量允许访问smtp.gmail.com:587及accounts.google.com等Google服务域名。

内容的提问来源于stack exchange,提问作者Catto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:28:31