获取和设置 Outlook 加载项的元数据
您可以通过使用以下任一项管理 Outlook 外接程序中的自定义数据:
- 漫游设置,可管理用户邮箱的自定义数据。
- 自定义属性,可管理用户邮箱中某个项目的自定义数据。
这两种方法都允许访问只有 Outlook 加载项可访问的自定义数据,但每种方法都分别存储数据。 也就是说,自定义属性无法访问通过漫游设置存储的数据,反之亦然。 漫游设置存储在用户的邮箱上,而自定义属性存储在邮件或约会上。 可以在加载项支持的所有外形规格的后续 Outlook 会话中访问存储的数据。
每个邮箱的自定义数据:漫游设置
You can specify data specific to a user's Exchange mailbox using the RoamingSettings object. Examples of such data include the user's personal data and preferences. Your mail add-in can access roaming settings when it roams on any device it's designed to run on (desktop, tablet, or smartphone).
对该数据的更改存储在当前 Outlook 会话的这些设置的内存副本中。 更新后,应显式保存所有漫游设置,以便在用户下次打开加载项时,在同一台或任何其他受支持的设备上使用这些设置。
漫游设置格式
RoamingSettings 对象中的数据存储为序列化的 JavaScript 对象表示法 (JSON) 字符串。
下面是 结构的一个示例,假设有三个名为 add-in_setting_name_0
、 add-in_setting_name_1
和 add-in_setting_name_2
的已定义的漫游设置。
{
"add-in_setting_name_0": "add-in_setting_value_0",
"add-in_setting_name_1": "add-in_setting_value_1",
"add-in_setting_name_2": "add-in_setting_value_2"
}
加载漫游设置
邮件加载项通常在 Office.initialize 事件处理程序中加载漫游设置。 以下 JavaScript 代码示例演示如何加载现有漫游设置并获取两个设置( customerName 和 customerBalance)的值。
let _mailbox;
let _settings;
let _customerName;
let _customerBalance;
// The initialize function is required for all add-ins.
Office.initialize = function () {
// Initialize instance variables to access API objects.
_mailbox = Office.context.mailbox;
_settings = Office.context.roamingSettings;
_customerName = _settings.get("customerName");
_customerBalance = _settings.get("customerBalance");
}
创建或分配漫游设置
继续前面的示例,以下 JavaScript 函数 setAddInSetting
演示如何使用 RoamingSettings.set 方法设置名为 cookie
的设置,并使用 RoamingSettings.saveAsync 方法将所有漫游设置保存到用户的邮箱。
如果设置尚不存在,则 set
方法创建设置,并将设置分配给指定的值。 方法 saveAsync
异步保存漫游设置。 此代码示例将回调函数 saveMyAddInSettingsCallback
传递给 saveAsync
。 异步调用完成后, saveMyAddInSettingsCallback
使用一个参数 asyncResult 调用 。 此参数是一个 AsyncResult 对象,其中包含异步调用的结果和所有详细信息。 可以使用可选的 userContext 参数从异步调用向回调函数传递任何状态信息。
// Set a roaming setting.
function setAddInSetting() {
_settings.set("cookie", Date());
// Save roaming settings to the mailbox, so that they'll be available in the next session.
_settings.saveAsync(saveMyAddInSettingsCallback);
}
// Callback function after saving custom roaming settings.
function saveMyAddInSettingsCallback(asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
// Handle the failure.
}
}
删除漫游设置
此外,扩展前面的示例,以下 JavaScript 函数 removeAddInSetting
,演示如何使用 RoamingSettings.remove 方法删除 cookie
设置并将所有漫游设置保存到邮箱。
// Remove an add-in setting.
function removeAddInSetting()
{
_settings.remove("cookie");
// Save changes to the roaming settings for the mailbox, so that they'll be available in the next session.
_settings.saveAsync(saveMyAddInSettingsCallback);
}
邮箱中每个项目的自定义数据:自定义属性
您可以使用 CustomProperties 对象指定用户邮箱中某个项目的特定数据。 例如,您的邮件外接程序可以对特定邮件进行分类,并使用自定义属性 messageCategory
标记类别。 或者,如果您的邮件外接程序使用邮件中的会议建议创建约会,您可以使用自定义属性跟踪这些约会。 这可确保如果用户再次打开邮件,则邮件加载项不会提供第二次创建约会。
与漫游设置类似,对自定义属性的更改将存储在当前 Outlook 会话的属性的内存副本中。 若要确保这些自定义属性在下一个会话中可用,请使用 CustomProperties.saveAsync。
这些特定于加载项、特定于项的自定义属性只能使用 CustomProperties
对象进行访问。 这些属性不同于 Outlook 对象模型中基于 MAPI 的自定义 UserProperties ,以及 Exchange Web Services (EWS) 中的扩展属性。 无法使用 Outlook 对象模型、EWS 或 REST 直接访问 CustomProperties
。 若要了解如何使用 EWS 或 REST 进行访问 CustomProperties
,请参阅 使用 EWS 或 REST 获取自定义属性部分。
注意
自定义属性仅适用于创建它们的加载项,并且只能通过保存自定义属性的邮件项使用。 因此,在撰写模式下设置的属性不会传输到邮件项目的收件人。 发送具有自定义属性的邮件或约会时,可以从“ 已发送邮件” 文件夹中的项访问其属性。 若要允许收件人接收外接程序集的自定义数据,请考虑改用 InternetHeaders 。
使用自定义属性
使用自定义属性之前,必须通过调用 loadCustomPropertiesAsync 方法加载这些自定义属性。 创建属性包后,可以使用 set 和 get 方法来添加和检索自定义属性。 必须使用 saveAsync 方法才能保存对属性包所做的任何更改。
注意
在 Outlook 外接程序中使用自定义属性时,请记住:
- Mac 版 Outlook 不缓存自定义属性。 如果用户的网络出现故障,Outlook on Mac 中的加载项将无法访问其自定义属性。
- 在经典 Outlook on Windows 中,在撰写模式下保存的自定义属性仅在正在撰写的项目关闭或调用后
Office.context.mailbox.item.saveAsync
保留。
自定义属性示例
以下示例演示使用自定义属性的 Outlook 外接程序的简化函数和方法集。 可以将此示例用作使用自定义属性的外接程序的起点。
此示例包括以下函数和方法。
Office.initialize -- 初始化外接程序并从 Exchange 服务器中加载自定义属性包。
customPropsCallback -- 获取从服务器返回的自定义属性包,并将其保存在本地以供以后使用。
updateProperty -- 设置或更新特定属性,然后将更改保存到本地属性包。
removeProperty -- 从属性包中删除特定属性,然后保存这些更改。
let _mailbox;
let _customProps;
// The initialize function is required for all add-ins.
Office.initialize = function () {
_mailbox = Office.context.mailbox;
_mailbox.item.loadCustomPropertiesAsync(customPropsCallback);
}
// Callback function from loading custom properties.
function customPropsCallback(asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
// Handle the failure.
}
else {
// Successfully loaded custom properties,
// can get them from the asyncResult argument.
_customProps = asyncResult.value;
}
}
// Get individual custom property.
function getProperty() {
const myProp = _customProps.get("myProp");
}
// Set individual custom property.
function updateProperty(name, value) {
_customProps.set(name, value);
// Save all custom properties to the mail item.
_customProps.saveAsync(saveCallback);
}
// Remove a custom property.
function removeProperty(name) {
_customProps.remove(name);
// Save all custom properties to the mail item.
_customProps.saveAsync(saveCallback);
}
// Callback function from saving custom properties.
function saveCallback() {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
// Handle the failure.
}
}
使用 EWS 或 REST 获取自定义属性
要使用 EWS 或 REST 获取 CustomProperties,首先应确定基于 MAPI 的扩展属性的名称。 然后可使用与获取基于 MAPI 的扩展属性相同的方式获取属性。
如何存储项的自定义属性
加载项设置的自定义属性不等同于基于 MAPI 的普通属性。 外接程序 API 将所有加载项 CustomProperties
序列化为 JSON 有效负载,然后将其保存在一个基于 MAPI 的扩展属性中,该属性的名称 (cecp-<app-guid>
<app-guid>
外接程序的 ID) ,属性集 GUID 为 {00020329-0000-0000-C000-000000000046}
。 (有关此对象的详细信息,请参阅 MS-OXCEXT 2.2.5 邮件应用程序自定义属性。)随后可使用 EWS 或 REST 获取此基于 MAPI 的属性。
使用 EWS 获取自定义属性
邮件加载项可以使用 EWS GetItem 操作获取CustomProperties
基于 MAPI 的扩展属性。 使用回调令牌在服务器端访问,或使用 mailbox.makeEwsRequestAsync 方法在客户端进行访问GetItem
。 在请求中 GetItem
,使用上一节中提供的详细信息在其属性集中指定 CustomProperties
基于 MAPI 的属性。
以下示例显示如何获取某个项目及其自定义属性。
重要
在以下示例中,将 <app-guid>
替换为外接程序 ID。
let request_str =
'<?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 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"' +
'xmlns:wsa="http://www.w3.org/2005/08/addressing">' +
'<t:RequestServerVersion Version="Exchange2010_SP1"/>' +
'</soap:Header>' +
'<soap:Body>' +
'<m:GetItem>' +
'<m:ItemShape>' +
'<t:BaseShape>AllProperties</t:BaseShape>' +
'<t:IncludeMimeContent>true</t:IncludeMimeContent>' +
'<t:AdditionalProperties>' +
'<t:ExtendedFieldURI ' +
'DistinguishedPropertySetId="PublicStrings" ' +
'PropertyName="cecp-<app-guid>"' +
'PropertyType="String" ' +
'/>' +
'</t:AdditionalProperties>' +
'</m:ItemShape>' +
'<m:ItemIds>' +
'<t:ItemId Id="' +
Office.context.mailbox.item.itemId +
'"/>' +
'</m:ItemIds>' +
'</m:GetItem>' +
'</soap:Body>' +
'</soap:Envelope>';
Office.context.mailbox.makeEwsRequestAsync(
request_str,
function(asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
console.log(asyncResult.value);
}
else {
console.log(JSON.stringify(asyncResult));
}
}
);
如果在请求字符串中将其指定为其他 ExtendedFieldURI 元素,也可以获得更多自定义属性。
使用 REST 获取自定义属性
可以在加载项中构建针对消息和事件的 REST 查询,以获取具有自定义属性的消息和事件。 在查询中,应包括使用如何存储项的自定义属性部分提供的详细信息的 CustomProperties 基于 MAPI 的属性及其属性集。
以下示例显示了如何获取具有加载项设置的自定义属性的所有事件,并确保响应中包括对应的属性值,以便你能够应用其他筛选逻辑。
重要
在以下示例中,将 <app-guid>
替换为加载项 ID。
GET https://outlook.office.com/api/v2.0/Me/Events?$filter=SingleValueExtendedProperties/Any
(ep: ep/PropertyId eq 'String {00020329-0000-0000-C000-000000000046}
Name cecp-<app-guid>' and ep/Value ne null)
&$expand=SingleValueExtendedProperties($filter=PropertyId eq 'String
{00020329-0000-0000-C000-000000000046} Name cecp-<app-guid>')
有关使用 REST 获取基于 MAPI 的单值扩展属性的其他示例,请参阅获取 singleValueExtendedProperty。
以下示例显示如何获取某个项目及其自定义属性。 在 done
方法的回调函数中,item.SingleValueExtendedProperties
包含所请求的自定义属性的列表。
重要
在以下示例中,将 <app-guid>
替换为外接程序 ID。
Office.context.mailbox.getCallbackTokenAsync(
{
isRest: true
},
function (asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Succeeded
&& asyncResult.value !== "") {
let item_rest_id = Office.context.mailbox.convertToRestId(
Office.context.mailbox.item.itemId,
Office.MailboxEnums.RestVersion.v2_0);
let rest_url = Office.context.mailbox.restUrl +
"/v2.0/me/messages('" +
item_rest_id +
"')";
rest_url += "?$expand=SingleValueExtendedProperties($filter=PropertyId eq 'String {00020329-0000-0000-C000-000000000046} Name cecp-<app-guid>')";
let auth_token = asyncResult.value;
$.ajax(
{
url: rest_url,
dataType: 'json',
headers:
{
"Authorization":"Bearer " + auth_token
}
}
).done(
function (item) {
console.log(JSON.stringify(item));
}
).fail(
function (error) {
console.log(JSON.stringify(error));
}
);
} else {
console.log(JSON.stringify(asyncResult));
}
}
);
消息中的平台行为
下表汇总了各种 Outlook 客户端的邮件中保存的自定义属性行为。
应用场景 | Outlook 网页版和新 Windows 客户端 | 经典 Outlook on Windows | Mac 版 Outlook |
---|---|---|---|
新建撰写 | 空 | 空 | 空 |
答复,全部答复 | 空 | 空 | 空 |
转发 | 空 | 加载父级的属性 | 空 |
从新撰写发送的项目 | 空 | 空 | 空 |
已从答复发送项目或全部答复 | 空 | 空 | 空 |
从转发发送的项目 | 空 | 如果未保存,则删除父级的属性 | 空 |
若要处理经典 Outlook on Windows 中的情况,
- 在初始化加载项时检查现有属性,并根据需要保留或清除它们。
- 设置自定义属性时,请包含一个附加属性,以指示是否在读取模式下添加了自定义属性。 这有助于区分属性是在撰写模式下创建的,还是从父级继承的。
- 若要检查用户是否正在转发或答复邮件,可以使用要求集 1.10) 中提供的 item.getComposeTypeAsync (。