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

使用IMAP获取Gmail未读邮件时触发TypeError错误求助

问题:通过IMAP获取Gmail未读邮件时遇TypeError错误

尝试实现基础Google API功能,用IMAP获取Gmail未读邮件时触发TypeError: str.replace is not a function错误,怀疑是IMAP连接参数错误但无法定位,相关代码、错误信息如下:

相关代码

require('dotenv').config();
const nodemailer = require('nodemailer')
const { google } = require('googleapis')
const Imap = require('imap');

const CLIENT_ID = process.env.GOOGLE_CLIENT_ID
const CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET
const REDIRECT_URI = process.env.GOOGLE_REDIRECT_URL
const REFRESH_TOKEN = process.env.GOOGLE_REFRESH_TOKEN

const oauht2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
oauht2Client.setCredentials({refresh_token : REFRESH_TOKEN})

function newMessages(/*onNewEmailCallback*/) {
    const imap = new Imap({
        user: "mymail@gmail.com",
        xoauth2: oauht2Client.getAccessToken(),
        host: 'imap.gmail.com',
        port: 993,
        tls: true,
        tlsOptions: {
            rejectUnauthorized: false
        }
    });
    function showError(error) {
        console.error('Error:', error);
    }

    function showMessage(msg) {
        onNewEmailCallback(msg.subject);
        console.log(msg.subject);
    }

    imap.connect();
    
    imap.once('ready', () => {
        imap.openBox('INBOX', true, (err, box) => {
            if (err) showError(err);
            imap.on('mail', (numNewMsgs) => {
                imap.search(['UNSEEN'], (err, results) => {
                    if (err) showError(err);
                    results.forEach((result) => {
                        const f = imap.fetch(result, { bodies: '' });
                        f.on('message', (msg) => {
                            msg.on('body', (stream, info) => {
                                let buffer = '';
                                stream.on('data', (chunk) => {
                                    buffer += chunk.toString('utf8');
                                });
                                stream.on('end', () => {
                                    showMessage(Imap.parseHeader(buffer));
                                });
                            });
                        });
                    });
                });
            });
        });
    });

    imap.once('error', showError);
    imap.once('end', () => {
        console.log('Connection terminée');
    });
    return imap;
}

完整错误栈

/home/lerou/B-DEV-500-COT-5-2-area-segnon.gnonlonfoun/Back-End/node_modules/imap/lib/Connection.js:1804
  return str.replace(RE_BACKSLASH, '\\\\').replace(RE_DBLQUOTE, '\\"');
             ^

TypeError: str.replace is not a function
    at escape (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Connection.js:1804:14)
    at Connection.<anonymous> (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Connection.js:1672:24)
    at Connection._resTagged (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Connection.js:1535:22)
    at Parser.<anonymous> (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Connection.js:194:10)
    at Parser.emit (node:events:512:28)
    at Parser._resTagged (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Parser.js:175:10)
    at Parser._parse (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Parser.js:139:16)
    at Parser._tryread (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Parser.js:82:15)
    at Parser._cbReadable (/home/lerou/B-DEV-500-COT-5-2-area-/Back-End/node_modules/imap/lib/Parser.js:53:12)
    at TLSSocket.emit (node:events:512:28)

解决方案

错误根源是**xoauth2参数传入值类型错误**:oauht2Client.getAccessToken()返回的是Promise对象,而非IMAP库所需的字符串格式访问令牌。IMAP库尝试对Promise对象调用replace方法,因此触发TypeError。

修改步骤:

  1. 将newMessages改为异步函数,用await获取实际访问令牌
  2. 提取令牌对象中的token属性,传入IMAP配置

修改后的代码:

require('dotenv').config();
const nodemailer = require('nodemailer')
const { google } = require('googleapis')
const Imap = require('imap');

const CLIENT_ID = process.env.GOOGLE_CLIENT_ID
const CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET
const REDIRECT_URI = process.env.GOOGLE_REDIRECT_URL
const REFRESH_TOKEN = process.env.GOOGLE_REFRESH_TOKEN

const oauht2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
oauht2Client.setCredentials({refresh_token : REFRESH_TOKEN})

// 改为异步函数
async function newMessages(onNewEmailCallback) {
    // 异步获取访问令牌并提取token属性
    const accessTokenObj = await oauht2Client.getAccessToken();
    const accessToken = accessTokenObj.token;

    const imap = new Imap({
        user: "mymail@gmail.com",
        xoauth2: accessToken, // 传入字符串格式令牌
        host: 'imap.gmail.com',
        port: 993,
        tls: true,
        tlsOptions: {
            rejectUnauthorized: false
        }
    });
    function showError(error) {
        console.error('Error:', error);
    }

    function showMessage(msg) {
        onNewEmailCallback(msg.subject);
        console.log(msg.subject);
    }

    imap.connect();
    
    imap.once('ready', () => {
        imap.openBox('INBOX', true, (err, box) => {
            if (err) showError(err);
            imap.on('mail', (numNewMsgs) => {
                imap.search(['UNSEEN'], (err, results) => {
                    if (err) showError(err);
                    results.forEach((result) => {
                        const f = imap.fetch(result, { bodies: '' });
                        f.on('message', (msg) => {
                            msg.on('body', (stream, info) => {
                                let buffer = '';
                                stream.on('data', (chunk) => {
                                    buffer += chunk.toString('utf8');
                                });
                                stream.on('end', () => {
                                    showMessage(Imap.parseHeader(buffer));
                                });
                            });
                        });
                    });
                });
            });
        });
    });

    imap.once('error', showError);
    imap.once('end', () => {
        console.log('Connection terminée');
    });
    return imap;
}

调用时需处理异步逻辑:

// index.js中调用示例
newMessages((subject) => {
    console.log('新邮件主题:', subject);
}).catch(err => console.error(err));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:55:42