从 Outlook 加载项调用 Web 服务

外接程序可以使用 Exchange Web Services (EWS) 运行 Exchange Server 的计算机、在提供外接程序 UI 源位置的服务器上提供的 Web 服务或 Internet 上可用的 Web 服务。 本文提供展示 Outlook 外接程序如何从 EWS 请求信息的示例。

重要

旧版 Exchange 令牌已弃用。 从 2024 年 10 月开始,将开始关闭 Exchange Online 租户的旧版 Exchange 用户标识回调 令牌。 有关时间线和详细信息,请参阅 我们的常见问题解答页面。 这是 Microsoft的“安全未来计划”的一部分,该计划为组织提供了应对当前威胁环境所需的工具。 Exchange 用户标识令牌仍适用于本地 Exchange。 嵌套应用身份验证是今后令牌的建议方法。

调用 Web 服务的方式因 Web 服务所在的位置而异。 下表列出了基于位置调用 Web 服务的不同方法。

Web 服务位置 调用 Web 服务的方法
承载客户端邮箱的 Exchange 服务器 使用 mailbox.makeEwsRequestAsync 方法可调用外接程序支持的 EWS 操作。 承载邮箱的 Exchange 服务器还会公开 EWS。
为加载项 UI 提供源位置的 Web 服务器 使用标准 JavaScript 技术调用 Web 服务。 UI 框架中的 JavaScript 代码将在提供 UI 的 Web 服务器的上下文中运行。 因此,此代码可以调用该服务器上的 Web 服务,而不会导致出现跨网站脚本错误。
所有其他位置 为提供 UI 源位置的 Web 服务器上的 Web 服务创建代理。 如果您不提供代理,跨网站脚本错误将阻止外接程序运行。 提供代理的一种方式是使用 JSON/P。 有关详细信息,请参阅 Office 外接程序的隐私和安全性

使用 makeEwsRequestAsync 方法访问 EWS 操作

重要

在 Android 和 iOS 上的 Outlook 中运行的加载项中不支持 EWS 调用和操作。

可以使用 mailbox.makeEwsRequestAsync 方法向托管用户邮箱的 Exchange 服务器发出 EWS 请求。

EWS 服务支持 Exchange 服务器中的不同操作;例如复制、查找、更新或发送项目的项目级操作,以及创建、获取或更新文件夹的文件夹级操作。 若要执行 EWS 操作,请为该操作创建 XML SOAP 请求。 当操作完成时,您将获得包含该操作相关数据的 XML SOAP 响应。 EWS SOAP 请求和响应遵循 Messages.xsd 文件中定义的架构。 正如其他 EWS 架构文件一样,Message.xsd 文件位于承载 EWS 的 IIS 虚拟目录中。

若要使用 makeEwsRequestAsync 方法启动 EWS 操作,请提供以下内容:

  • 该 EWS 操作的 SOAP 请求的 XML,作为 数据 参数的参数

  • 回调函数 (为 回调 参数)

  • 该回调函数的任何可选输入数据 (为 userContext 参数)

EWS SOAP 请求完成后,Outlook 会使用一个参数(即 AsyncResult 对象)调用回调函数。 回调函数可以访问 对象的两个 AsyncResult 属性: value 属性(包含 EWS 操作的 XML SOAP 响应)和 (可选) asyncContext 属性(包含作为 userContext 参数传递的任何数据)。 通常,回调函数会分析 SOAP 响应中的 XML 以获取任何相关信息,并相应地处理该信息。

解析 EWS 响应的提示

分析来自 EWS 操作的 SOAP 响应时,请注意以下与浏览器相关的问题。

  • 使用 DOM 方法 getElementsByTagName时指定标记名称的前缀,以包括对 Internet Explorer 和 Trident Webview 的支持。

    getElementsByTagName 行为因浏览器类型而异。 例如,EWS 响应可以包含以下 XML (格式和缩写,以便) 显示。

    <t:ExtendedProperty><t:ExtendedFieldURI PropertySetId="00000000-0000-0000-0000-000000000000" 
    PropertyName="MyProperty" 
    PropertyType="String"/>
    <t:Value>{
    ...
    }</t:Value></t:ExtendedProperty>
    

    代码(如下所述)将在 Chrome 等浏览器上工作,以获取标记括起来的 ExtendedProperty XML。

    const mailbox = Office.context.mailbox;
    mailbox.makeEwsRequestAsync(mailbox.item.itemId, function(result) {
         const response = $.parseXML(result.value);
         const extendedProps = response.getElementsByTagName("ExtendedProperty")
    });
    

    对于三叉星 (Internet Explorer) webview,必须包括 t: 标记名称的前缀,如下所示。

    const mailbox = Office.context.mailbox;
    mailbox.makeEwsRequestAsync(mailbox.item.itemId, function(result) {
         const response = $.parseXML(result.value);
         const extendedProps = response.getElementsByTagName("t:ExtendedProperty")
    });
    
  • 使用 DOM 属性 textContent 在 EWS 响应中获取标记的内容,如下所示。

    content = $.parseJSON(value.textContent);
    

    对于 EWS 响应中的某些标记,其他属性(如 innerHTML )可能无法在 Trident (Internet Explorer) Webview 上工作。

示例

以下示例调用 makeEwsRequestAsync 以使用 GetItem 操作获取项的主题。 此示例包括以下三个函数。

  • getSubjectRequest – 采用项 ID 作为输入,并返回 SOAP 请求的 XML,以调用 GetItem 指定项。

  • sendRequest – 调用 getSubjectRequest 以获取所选项的 SOAP 请求,然后将 SOAP 请求和回调函数 callback传递给 makeEwsRequestAsync ,以获取指定项的主题。

  • callback – 处理 SOAP 响应,其中包括有关指定项的任何主题和其他信息。

function getSubjectRequest(id) {
   // Return a GetItem operation request for the subject of the specified item. 
   const result = 
    '<?xml version="1.0" encoding="utf-8"?>' +
    '<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"' +
    '               xmlns:xsd="https://www.w3.org/2001/XMLSchema"' +
    '               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"' +
    '               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">' +
    '  <soap:Header>' +
    '    <RequestServerVersion Version="Exchange2013" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" soap:mustUnderstand="0" />' +
    '  </soap:Header>' +
    '  <soap:Body>' +
    '    <GetItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">' +
    '      <ItemShape>' +
    '        <t:BaseShape>IdOnly</t:BaseShape>' +
    '        <t:AdditionalProperties>' +
    '            <t:FieldURI FieldURI="item:Subject"/>' +
    '        </t:AdditionalProperties>' +
    '      </ItemShape>' +
    '      <ItemIds><t:ItemId Id="' + id + '"/></ItemIds>' +
    '    </GetItem>' +
    '  </soap:Body>' +
    '</soap:Envelope>';

   return result;
}

function sendRequest() {
   // Create a local variable that contains the mailbox.
   const mailbox = Office.context.mailbox;

   mailbox.makeEwsRequestAsync(getSubjectRequest(mailbox.item.itemId), callback);
}

function callback(asyncResult)  {
   const result = asyncResult.value;
   const context = asyncResult.context;

   // Process the returned response here.
}

外接程序支持的 EWS 操作

Outlook 加载项可以通过 方法访问 EWS makeEwsRequestAsync 中可用的操作子集。 如果不熟悉 EWS 操作以及如何使用 makeEwsRequestAsync 方法访问操作,请从 SOAP 请求示例开始自定义 数据 参数。

下面介绍了如何使用 makeEwsRequestAsync 方法。

  1. 在 XML 中,用适当值替换所有项目 ID 和相关 EWS 操作属性。

  2. 包含 SOAP 请求作为 的数据 参数的参数 makeEwsRequestAsync

  3. 指定回调函数并调用 makeEwsRequestAsync

  4. 在回调函数中,验证 SOAP 响应中的操作结果。

  5. 根据需要使用 EWS 操作的结果。

下表列出了外接程序支持的 EWS 操作。 若要查看 SOAP 请求和响应的示例,请选择各操作对应的链接。 有关 EWS 操作的详细信息,请参阅 在交换 EWS 操作

EWS 操作 说明
CopyItem 操作 在 Exchange 存储的指定文件夹中复制指定项目并在其中放入新项目。
CreateFolder 操作 在 Exchange 存储中的指定位置创建文件夹。
CreateItem 操作 在 Exchange 存储中创建指定项目。
ExpandDL 操作 显示通讯组列表的完整成员身份。
FindConversation 操作 在 Exchange 存储的指定文件夹中枚举会话列表。
FindFolder 操作 查找指定文件夹的子文件夹并返回描述这组子文件夹的一组属性。
FindItem 操作 标识位于 Exchange 存储的指定文件夹中的项目。
GetConversationItems 操作 在会话中获取排列为节点的一个或多个项集。
GetFolder 操作 从 Exchange 存储中获取文件夹的指定属性和内容。
GetItem 操作 从 Exchange 存储中获取项目的指定属性和内容。
GetUserAvailability 操作 提供特定时间段内有关一组用户、会议室和资源的可用性的详细信息。
MarkAsJunk 操作 将电子邮件移动到"垃圾邮件"文件夹,并相应地在阻止的发件人名单中添加或删除邮件的发件人。
MoveItem 操作 将项目移动到 Exchange 存储中的单个目标文件夹。
ResolveNames 操作 解析不确定的电子邮件地址和显示名称。
SendItem 操作 发送位于 Exchange 存储中的电子邮件。
UpdateFolder 操作 修改 Exchange 存储中现有文件夹的属性。
UpdateItem 操作 修改 Exchange 存储中现有项的属性。

注意

FAI(文件夹关联信息)项不能通过外接程序进行更新(或创建)。 这些隐藏的消息存储在文件夹中,用于存储各种设置和辅助数据。 尝试使用 UpdateItem 操作会导致以下 ErrorAccessDenied 错误抛出:“不得使用 Office 扩展来更新此类项”。 此外,也可以使用 EWS 托管 API 通过 Windows 客户端或服务器应用更新这些项。 建议谨慎操作,因为内部服务类型数据结构可能会发生变化并破坏解决方案。

makeEwsRequestAsync 的身份验证和权限注意事项

使用 makeEwsRequestAsync 方法时,将使用当前用户的电子邮件帐户凭据对请求进行身份验证。 方法 makeEwsRequestAsync 会为你管理凭据,这样就不必随请求一起提供身份验证凭据。

注意

服务器管理员必须使用 New-WebServicesVirtualDirectorySet-WebServicesVirtualDirectory cmdlet 在客户端访问服务器 EWS 目录上将 OAuthAuthentication 参数设置为 true ,以便使 方法能够 makeEwsRequestAsync 发出 EWS 请求。

若要使用 makeEwsRequestAsync 方法,加载项必须在清单中请求 读/写邮箱 权限。 标记因清单类型而异。

  • 仅外接程序清单:将 <Permissions> 元素设置为 ReadWriteMailbox
  • Microsoft 365 的统一清单:将“authorization.permissions.resourceSpecific”数组中对象的“name”属性设置为“Mailbox.ReadWrite.User”。

有关使用 读/写邮箱 权限的信息,请参阅 读/写邮箱权限

另请参阅

请参阅以下内容,了解如何使用 ASP.NET Web API 为加载项创建后端服务。