如何在Node.js中通过IMAP读取并保存邮件附件到数据库?
扩展Node.js IMAP代码以读取邮件附件并保存到数据库
步骤说明
- 安装必要依赖:除原有的
imap外,还需mailparser(解析邮件结构与附件)和数据库驱动(以MongoDB的mongoose为例):
npm install imap mailparser mongoose
- 定义数据库模型:创建用于存储附件的模型:
const mongoose = require('mongoose'); const attachmentSchema = new mongoose.Schema({ messageSeqno: Number, // 对应邮件序号 filename: String, contentType: String, content: Buffer, // 存储二进制文件内容 createdAt: { type: Date, default: Date.now } }); const Attachment = mongoose.model('Attachment', attachmentSchema); // 连接数据库 mongoose.connect('mongodb://localhost:27017/email_attachments') .then(() => console.log('数据库连接成功')) .catch(err => console.error('数据库连接失败:', err));
- 修改IMAP读取逻辑:调整邮件获取方式,解析完整邮件结构以提取附件并保存到数据库:
完整修改后的代码
const Imap = require('imap'); const { simpleParser } = require('mailparser'); const mongoose = require('mongoose'); // 数据库模型定义 const attachmentSchema = new mongoose.Schema({ messageSeqno: Number, filename: String, contentType: String, content: Buffer, createdAt: { type: Date, default: Date.now } }); const Attachment = mongoose.model('Attachment', attachmentSchema); // 连接数据库 mongoose.connect('mongodb://localhost:27017/email_attachments') .then(() => console.log('数据库连接成功')) .catch(err => console.error('数据库连接失败:', err)); const imap = new Imap({ user: 'abc@gmail.com', password: 'password', host: 'imap.gmail.com', port: 993, tls: true, tlsOptions: { rejectUnauthorized: false }, authTimeout: 3000 }); function openInbox(cb) { imap.openBox('INBOX', true, cb); } imap.once('ready', function() { openInbox(function(err, box) { if (err) throw err; // 调整fetch参数,获取完整邮件内容以解析附件 const f = imap.seq.fetch('714:715', { bodies: '' }); f.on('message', function(msg, seqno) { const prefix = '(#' + seqno + ') '; msg.on('body', function(stream) { // 解析完整邮件结构 simpleParser(stream, async (err, mail) => { if (err) { console.error(prefix + '邮件解析错误:', err); return; } // 处理附件 if (mail.attachments && mail.attachments.length > 0) { console.log(prefix + '发现附件:', mail.attachments.map(att => att.filename)); for (const attachment of mail.attachments) { try { // 创建附件文档并保存到数据库 const newAttachment = new Attachment({ messageSeqno: seqno, filename: attachment.filename, contentType: attachment.contentType, content: attachment.content }); await newAttachment.save(); console.log(prefix + '附件已保存:', attachment.filename); } catch (saveErr) { console.error(prefix + '附件保存失败:', saveErr); } } } }); }); msg.once('end', function() { console.log(prefix + '邮件处理完成'); }); }); f.once('error', function(err) { console.log('Fetch error: ' + err); }); f.once('end', function() { console.log('Done fetching all messages!'); // 处理完成后关闭数据库与IMAP连接 mongoose.connection.close(); imap.end(); }); }); }); imap.once('error', function(err) { console.log(err); }); imap.once('end', function() { console.log('Connection ended'); }); imap.connect();
关键修改说明
- 邮件获取调整:将
fetch的bodies参数设为空字符串,获取完整邮件内容,确保simpleParser能解析出附件信息。 - 附件处理逻辑:通过
mail.attachments获取附件数组,提取每个附件的文件名、类型、二进制内容,直接存入数据库。 - 异步操作处理:使用
async/await确保数据库保存操作完成,避免异步回调导致的逻辑错误。
注意事项
- 若使用MySQL、PostgreSQL等其他数据库,需调整连接代码及存储类型(如MySQL用
LONGBLOB存储二进制数据)。 - Gmail需开启IMAP权限,开启两步验证的情况下需使用应用专用密码。
- 大附件建议做流式处理,避免内存溢出。
内容的提问来源于stack exchange,提问作者Manikandan Rajaboopathi
相关产品推荐
相关产品推荐

