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

如何在Nodemailer中通过messageId获取已发送邮件的状态或详情?

通过Message ID获取已发送邮件详情(检查退信状态)

你当前用Nodemailer发送邮件后得到的messageId,仅代表邮件已被Gmail的SMTP服务器接收,但Nodemailer本身没有能力通过这个ID查询后续的送达状态或退信信息。要实现这个需求,得借助Gmail官方API来获取邮件详情并判断是否退信。

实现步骤

  1. 启用Gmail API并获取OAuth2凭据
    前往Google Cloud控制台,启用Gmail API,创建OAuth2客户端ID(类型选桌面应用即可),下载包含client_id、client_secret的JSON配置文件。

  2. 安装依赖
    安装Google API的Node.js客户端:

    npm install googleapis
    
  3. 扩展原有邮件类,添加查询方法
    对现有的SendMailWithAppPass类进行扩展,新增查询邮件状态的方法,注意要先把messageId的尖括号去除(Gmail API使用的ID不带尖括号):

    const { google } = require('googleapis');
    const fs = require('fs');
    
    class SendMailWithAppPass{
        #user
        #appPassword
        #transporter
        #oauthClient
    
        constructor(userEmail, appPassword, oauthConfigPath){
            this.#user = userEmail;
            this.#appPassword = appPassword;
    
            // 初始化SMTP transporter(保留原代码逻辑)
            this.#transporter = nodemailer.createTransport({
                host:  'smtp.gmail.com',
                port: 465,
                secure: true,
                auth: {
                    user: this.#user,
                    pass: this.#appPassword,
                },
                tls: {
                    rejectUnauthorized: false
                },
            });
    
            // 初始化OAuth2客户端用于Gmail API调用
            const oauthConfig = JSON.parse(fs.readFileSync(oauthConfigPath));
            this.#oauthClient = new google.auth.OAuth2(
                oauthConfig.web.client_id,
                oauthConfig.web.client_secret,
                'http://localhost:3000/oauth2callback' // 需和控制台配置的回调地址一致
            );
            // 需提前完成授权获取刷新令牌,首次运行可通过Google官方授权流程获取
            this.#oauthClient.setCredentials({
                refresh_token: '你的刷新令牌'
            });
        }
    
        // 保留原有的send方法
        async send(from, to, sub, text, html=null){
            let info = await this.#transporter.sendMail({
                from: `"Automata" <${from}>`,
                to: to,
                subject: sub,
                text: text,
                html: html,
            });
            
            if(info){
                console.log(info);
                return info;
            }
        }
    
        // 新增:通过messageId查询邮件详情及退信状态
        async getEmailStatus(messageId){
            // 去除messageId中的尖括号
            const cleanMessageId = messageId.replace(/[<>]/g, '');
            const gmail = google.gmail({ version: 'v1', auth: this.#oauthClient });
    
            try {
                // 获取完整邮件信息,包含headers和内容
                const res = await gmail.users.messages.get({
                    userId: 'me',
                    id: cleanMessageId,
                    format: 'full'
                });
    
                const message = res.data;
                let isBounced = false;
                let bounceReason = '';
    
                // 检查邮件头中的退信标识
                const headers = message.payload.headers;
                headers.forEach(header => {
                    if(header.name === 'X-Failed-Recipients'){
                        isBounced = true;
                        bounceReason = `收件人地址无效:${header.value}`;
                    } else if(header.name === 'Diagnostic-Code'){
                        bounceReason = `退信原因:${header.value}`;
                    }
                });
    
                // 辅助检查主题是否包含退信关键词
                const subjectHeader = headers.find(h => h.name === 'Subject');
                if(subjectHeader?.value.includes('Delivery Status Notification')){
                    isBounced = true;
                    if(!bounceReason) bounceReason = '邮件送达失败';
                }
    
                return {
                    messageId: message.id,
                    isBounced,
                    bounceReason,
                    fullMessage: message
                };
            } catch (err) {
                console.error('查询邮件状态失败:', err);
                throw err;
            }
        }
    }
    

使用说明

  • 首次使用需完成OAuth2授权流程获取刷新令牌,可参考Google官方文档的授权示例。
  • 调用getEmailStatus方法时,直接传入发送邮件后得到的messageId(如<1b796af0-d69b-f497-a91c-84d7970cd8b1@gmail.com>),方法会自动处理格式并返回退信状态。

注意事项

  • 若使用其他邮箱服务商(如Outlook、网易邮箱),需对应使用其官方API查询邮件状态,逻辑思路一致。
  • 退信存在延迟,建议在发送邮件后间隔一段时间再执行查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:00:57