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

移动端Outlook插件中替代不支持的getAsFileAsync函数获取Base64格式邮件的可行方案(无需Azure令牌)

移动端Outlook插件中替代不支持的getAsFileAsync函数获取Base64格式邮件的可行方案(无需Azure令牌)

我太懂你现在的处境了——桌面端用Office.context.mailbox.item.getAsFileAsync一键把邮件转成Base64的EML文件,别提多顺手了,结果到了移动端这个函数直接失效,还要绕开麻烦的Azure令牌流程,确实头疼。

别慌,咱们可以换个思路:既然getAsFileAsync本质是返回标准EML格式的Base64内容,那我们完全可以用移动端支持的Outlook插件API手动拼凑出EML文件,再转成Base64,全程不需要Azure令牌。

具体实现步骤

下面是一步步的操作思路和示例代码:

1. 收集邮件的核心元数据

先通过移动端支持的属性获取邮件的基础信息:

// 获取主题
const subject = Office.context.mailbox.item.subject;
// 获取发件人
const from = Office.context.mailbox.item.from;
// 获取收件人、抄送人
const toRecipients = Office.context.mailbox.item.to;
const ccRecipients = Office.context.mailbox.item.cc || [];
// 获取邮件发送日期(用item的dateReceived或当前时间兜底)
const date = Office.context.mailbox.item.dateReceived?.toUTCString() || new Date().toUTCString();

2. 获取邮件正文

用body.getAsync获取HTML格式的正文(移动端完全支持):

Office.context.mailbox.item.body.getAsync(Office.CoercionType.Html, (asyncResult) => {
  if (asyncResult.status === Office.AsyncResultStatus.Failed) {
    console.error(`获取正文失败: ${asyncResult.error.message}`);
    return;
  }
  const bodyHtml = asyncResult.value;
  // 拿到正文后继续处理附件和组装逻辑
});

3. 获取附件内容

用getAttachmentsAsync和getAttachmentContentAsync获取所有附件的Base64内容:

Office.context.mailbox.item.getAttachmentsAsync((asyncResult) => {
  if (asyncResult.status === Office.AsyncResultStatus.Failed) {
    console.error(`获取附件列表失败: ${asyncResult.error.message}`);
    return;
  }
  const attachments = asyncResult.value;
  // 用Promise批量获取附件内容
  const attachmentPromises = attachments.map(att => {
    return new Promise((resolve, reject) => {
      Office.context.mailbox.item.getAttachmentContentAsync(att.id, (attResult) => {
        if (attResult.status === Office.AsyncResultStatus.Failed) {
          reject(attResult.error.message);
          return;
        }
        resolve({
          name: att.name,
          contentType: att.contentType,
          content: attResult.value.content
        });
      });
    });
  });

  Promise.all(attachmentPromises).then(attachmentsContent => {
    // 拿到所有附件内容后,开始组装EML
  }).catch(err => {
    console.error(`获取附件内容失败: ${err}`);
  });
});

4. 手动组装EML格式

按照RFC 5322标准拼接邮件头、正文和附件,这里给一个简化的示例(复杂场景如内嵌图片可扩展MIME嵌套结构):

function buildEML(subject, from, to, cc, date, bodyHtml, attachments) {
  // 生成随机MIME边界
  const boundary = `----=_NextPart_${Date.now().toString(16)}`;
  let eml = '';

  // 邮件头部分
  eml += `From: "${from.displayName}" <${from.emailAddress}>\r\n`;
  eml += `To: ${to.map(recp => `"${recp.displayName}" <${recp.emailAddress}>`).join(', ')}\r\n`;
  if (cc.length > 0) {
    eml += `Cc: ${cc.map(recp => `"${recp.displayName}" <${recp.emailAddress}>`).join(', ')}\r\n`;
  }
  eml += `Subject: ${subject}\r\n`;
  eml += `Date: ${date}\r\n`;
  eml += `MIME-Version: 1.0\r\n`;
  eml += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n`;

  // 正文部分
  eml += `--${boundary}\r\n`;
  eml += `Content-Type: text/html; charset="UTF-8"\r\n`;
  eml += `Content-Transfer-Encoding: base64\r\n\r\n`;
  eml += btoa(unescape(encodeURIComponent(bodyHtml))) + '\r\n\r\n';

  // 附件部分
  attachments.forEach(att => {
    eml += `--${boundary}\r\n`;
    eml += `Content-Type: ${att.contentType}\r\n`;
    eml += `Content-Disposition: attachment; filename="${att.name}"\r\n`;
    eml += `Content-Transfer-Encoding: base64\r\n\r\n`;
    eml += att.content + '\r\n\r\n';
  });

  // 结束边界
  eml += `--${boundary}--\r\n`;
  return eml;
}

5. 转成Base64编码

把组装好的EML字符串转成Base64,就和getAsFileAsync返回的结果一致了:

const emlString = buildEML(subject, from, toRecipients, ccRecipients, date, bodyHtml, attachmentsContent);
const emlBase64 = btoa(unescape(encodeURIComponent(emlString)));
// 这里的emlBase64就是你需要的最终结果

注意事项

  • 上面的EML组装是基础场景版本,若要处理带内嵌图片的HTML邮件、特殊编码内容,需要额外扩展MIME的嵌套结构,但日常使用完全够用。
  • 所有用到的API都是移动端Outlook插件官方支持的,兼容性没问题。

备注:内容来源于stack exchange,提问作者DavidDunham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:53:07