如何在Node.js中使用EWS/MAPI获取邮件内容
使用node-ews读取Exchange收件箱邮件及附件
以下是基于node-ews实现读取收件箱邮件、提取正文及下载附件的完整示例:
1. 安装依赖
npm install node-ews
2. 配置EWS连接
首先初始化EWS客户端,填入你的Exchange账号信息:
const EWS = require('node-ews'); const fs = require('fs'); // EWS配置 const ewsConfig = { username: '你的Exchange邮箱账号', password: '你的邮箱密码', host: 'outlook.office365.com' // 替换为你的Exchange服务器地址,比如内部Exchange服务器域名 }; const ews = new EWS(ewsConfig);
3. 获取收件箱邮件列表
通过FindItem请求获取收件箱的邮件基本信息(主题、接收时间、邮件ID等),示例中获取最新10封邮件:
// 构造获取收件箱邮件的SOAP请求 const getInboxEmailsRequest = ` <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2016" /> </soap:Header> <soap:Body> <m:FindItem Traversal="Shallow"> <m:ItemShape> <t:BaseShape>IdOnly</t:BaseShape> <t:AdditionalProperties> <t:FieldURI FieldURI="item:Subject" /> <t:FieldURI FieldURI="item:DateTimeReceived" /> <t:FieldURI FieldURI="message:From" /> </t:AdditionalProperties> </m:ItemShape> <m:IndexedPageItemView MaxEntriesReturned="10" Offset="0" BasePoint="Beginning" /> <m:ParentFolderIds> <t:DistinguishedFolderId Id="inbox" /> </m:ParentFolderIds> </m:FindItem> </soap:Body> </soap:Envelope> `; // 发送请求获取邮件列表 ews.run(getInboxEmailsRequest, function(err, result) { if (err) { console.error('获取邮件列表失败:', err); return; } // 处理返回结果,兼容单封/多封邮件的情况 const emails = Array.isArray(result.ResponseMessages.FindItemResponseMessage.RootFolder.Items.Message) ? result.ResponseMessages.FindItemResponseMessage.RootFolder.Items.Message : [result.ResponseMessages.FindItemResponseMessage.RootFolder.Items.Message]; emails.forEach(email => { console.log('\n邮件主题:', email.Subject); console.log('接收时间:', email.DateTimeReceived); console.log('发件人:', email.From.Mailbox.Name, `<${email.From.Mailbox.EmailAddress}>`); console.log('邮件ID:', email.ItemId.Id); // 调用方法获取单封邮件的详细内容 getEmailDetails(email.ItemId.Id, email.ItemId.ChangeKey); }); });
4. 获取单封邮件详情(正文+附件信息)
通过GetItem请求获取邮件的完整内容,包括正文和附件列表:
function getEmailDetails(itemId, changeKey) { // 构造获取邮件详情的SOAP请求,BodyType可选HTML/Text const getEmailRequest = ` <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2016" /> </soap:Header> <soap:Body> <m:GetItem> <m:ItemShape> <t:BaseShape>Default</t:BaseShape> <t:BodyType>Text</t:BodyType> <t:AdditionalProperties> <t:FieldURI FieldURI="item:Attachments" /> </t:AdditionalProperties> </m:ItemShape> <m:ItemIds> <t:ItemId Id="${itemId}" ChangeKey="${changeKey}" /> </m:ItemIds> </m:GetItem> </soap:Body> </soap:Envelope> `; ews.run(getEmailRequest, function(err, result) { if (err) { console.error('获取邮件详情失败:', err); return; } const email = result.ResponseMessages.GetItemResponseMessage.Items.Message; console.log('\n邮件正文:', email.Body._); // 处理附件,兼容单个/多个附件的情况 if (email.Attachments?.FileAttachment) { const attachments = Array.isArray(email.Attachments.FileAttachment) ? email.Attachments.FileAttachment : [email.Attachments.FileAttachment]; attachments.forEach(attachment => { console.log('\n附件名称:', attachment.Name); console.log('附件大小:', attachment.Size, '字节'); // 调用方法下载附件 downloadAttachment(attachment.AttachmentId.Id, attachment.Name); }); } }); }
5. 下载附件
通过GetAttachment请求获取附件的base64编码内容,解码后保存到本地:
function downloadAttachment(attachmentId, fileName) { const getAttachmentRequest = ` <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2016" /> </soap:Header> <soap:Body> <m:GetAttachment> <m:AttachmentIds> <t:AttachmentId Id="${attachmentId}" /> </m:AttachmentIds> </m:GetAttachment> </soap:Body> </soap:Envelope> `; ews.run(getAttachmentRequest, function(err, result) { if (err) { console.error('下载附件失败:', err); return; } const attachment = result.ResponseMessages.GetAttachmentResponseMessage.Attachments.FileAttachment; // 解码base64内容并保存文件 const buffer = Buffer.from(attachment.Content, 'base64'); fs.writeFileSync(`./${fileName}`, buffer); console.log(`附件 ${fileName} 已成功保存到本地`); }); }
注意事项
- 服务器版本适配:
RequestServerVersion中的Version需要和你的Exchange服务器版本匹配,比如Exchange2013、Exchange2016或ExchangeOnline(针对Office365)。 - 认证方式:如果你的Office365租户禁用了基本认证,需要改用OAuth2认证,此时需要扩展
node-ews的请求头,添加OAuth令牌。 - 结果兼容性:EWS返回的结果在单条数据时是对象,多条时是数组,所以需要用
Array.isArray做兼容处理。 - 正文格式:
BodyType可选HTML获取富文本正文,或者Text获取纯文本,根据需求调整。
内容的提问来源于stack exchange,提问作者Talha Noyon
相关产品推荐
相关产品推荐

