有没有办法让所有收件人都进入“收件人”或“抄送”字段?
Is there a way to get all recipients in `to` or `cc` fields?
Office.MessageRead.to
的文档中提到:
The to property returns an array that contains an EmailAddressDetails object for each recipient listed on the To line of the message. The collection is limited to a maximum of 100 members.
此限制正常工作,如果我有一封邮件发送给超过 100 个收件人,我只能获得 100 个 Office.context.mailbox.item.to
的电子邮件地址。
Office.AppointmentRead.requiredAttendees
的文档中没有提到类似的限制,但我只能得到 100 个 Office.context.mailbox.item.requiredAttendees
的电子邮件地址。
问题
我试图让收件人同时拥有 Office.context.mailbox.item.to
和 REST API,但我只能获得 100 个电子邮件地址。 有没有办法获得完整的收件人列表?
您可以尝试使用 EWS 中提供的 GetItem 方法。
有关 Exchange 限制的详细信息,请参阅 Exchange Online Throttling and Limits FAQ。
Eugene 的回答建议使用 Office.context.mailbox.makeEwsRequestAsync
发送 SOAP XML 请求以检索完整的收件人列表。如果您在 Office 加载项清单中指定了 ReadWriteMailbox
权限,它就会起作用。
<Permissions>ReadWriteMailbox</Permissions>
使用Office.context.mailbox.makeEwsRequestAsync
的代码示例:
/**
* @param {HTMLElement} node The `t:Mailbox` node. As in
* <t:Mailbox>
* <t:Name>At The Table</t:Name>
* <t:EmailAddress>atthetable@microstrategy.com</t:EmailAddress>
* <t:RoutingType>SMTP</t:RoutingType>
* <t:MailboxType>Mailbox</t:MailboxType>
* </t:Mailbox>
* @return {string} A string as in `Name (email@address.com)` when success;
* empty string otherwise.
*/
const parseMailboxNode = (node) => {
const nameNode = node.getElementsByTagName('t:Name')[0];
const addressNode = node.getElementsByTagName('t:EmailAddress')[0];
return {
displayName: nameNode.textContent,
emailAddress: addressNode.textContent,
};
};
const parseEmailAddresses = (doc, messageFieldName) => {
const fieldNode = doc.getElementsByTagName(`t:${messageFieldName}`)[0];
if (!fieldNode) {
return [];
}
const emailAddresses = [];
const mailboxes = fieldNode.getElementsByTagName('t:Mailbox');
for (let i = 0, l = mailboxes.length; i < l; i += 1) {
emailAddresses.push(parseMailboxNode(mailboxes[i]));
}
return emailAddresses;
};
const parseGetItemSoapResponse = (xml) => {
try {
const parser = new DOMParser();
// https://developer.mozilla.org/en-US/docs/Web/API/XMLDocument
const doc = parser.parseFromString(xml, 'application/xml');
const message = {
ReplyTo: parseEmailAddresses(doc, 'ReplyTo')[0],
};
return [
'ToRecipients',
'CcRecipients',
'BccRecipients',
'RequiredAttendees',
'OptionalAttendees',
].reduce((result, fieldName) => {
result[fieldName] = parseEmailAddresses(doc, fieldName);
return result;
}, message);
} catch (error) {
throw new Error('Failed to parse XML response of Office.context.mailbox.makeEwsRequestAsync', xml);
return null;
}
};
const getRecipients = async (item) => new Promise((resolve, reject) => {
const { context } = window.Office || {};
const { mailbox } = context || {};
if (!mailbox || !mailbox.makeEwsRequestAsync) {
const error = new Error('Office.context.mailbox.makeEwsRequestAsync is not available.');
reject(error);
return;
}
const { itemId } = item || {};
if (!itemId) {
const error = new Error('Office.context.mailbox.item.itemId is invalid.');
reject(error);
return;
}
// See https://docs.microsoft.com/en-us/outlook/add-ins/web-services
// See https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation-email-message
// See https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/fielduri
const request = `<?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="message:ReplyTo"/>
<t:FieldURI FieldURI="message:ToRecipients"/>
<t:FieldURI FieldURI="message:CcRecipients"/>
<t:FieldURI FieldURI="message:BccRecipients"/>
<t:FieldURI FieldURI="calendar:RequiredAttendees"/>
<t:FieldURI FieldURI="calendar:OptionalAttendees"/>
</t:AdditionalProperties>
</ItemShape>
<ItemIds><t:ItemId Id="${itemId}"/></ItemIds>
</GetItem>
</soap:Body>
</soap:Envelope>
`;
mailbox.makeEwsRequestAsync(request, (result) => {
if (result.error) {
reject(result.error);
} else {
const value = parseGetItemSoapResponse(result.value);
resolve(value);
}
});
});
Office.MessageRead.to
的文档中提到:
The to property returns an array that contains an EmailAddressDetails object for each recipient listed on the To line of the message. The collection is limited to a maximum of 100 members.
此限制正常工作,如果我有一封邮件发送给超过 100 个收件人,我只能获得 100 个 Office.context.mailbox.item.to
的电子邮件地址。
Office.AppointmentRead.requiredAttendees
的文档中没有提到类似的限制,但我只能得到 100 个 Office.context.mailbox.item.requiredAttendees
的电子邮件地址。
问题
我试图让收件人同时拥有 Office.context.mailbox.item.to
和 REST API,但我只能获得 100 个电子邮件地址。 有没有办法获得完整的收件人列表?
您可以尝试使用 EWS 中提供的 GetItem 方法。
有关 Exchange 限制的详细信息,请参阅 Exchange Online Throttling and Limits FAQ。
Eugene 的回答建议使用 Office.context.mailbox.makeEwsRequestAsync
发送 SOAP XML 请求以检索完整的收件人列表。如果您在 Office 加载项清单中指定了 ReadWriteMailbox
权限,它就会起作用。
<Permissions>ReadWriteMailbox</Permissions>
使用Office.context.mailbox.makeEwsRequestAsync
的代码示例:
/**
* @param {HTMLElement} node The `t:Mailbox` node. As in
* <t:Mailbox>
* <t:Name>At The Table</t:Name>
* <t:EmailAddress>atthetable@microstrategy.com</t:EmailAddress>
* <t:RoutingType>SMTP</t:RoutingType>
* <t:MailboxType>Mailbox</t:MailboxType>
* </t:Mailbox>
* @return {string} A string as in `Name (email@address.com)` when success;
* empty string otherwise.
*/
const parseMailboxNode = (node) => {
const nameNode = node.getElementsByTagName('t:Name')[0];
const addressNode = node.getElementsByTagName('t:EmailAddress')[0];
return {
displayName: nameNode.textContent,
emailAddress: addressNode.textContent,
};
};
const parseEmailAddresses = (doc, messageFieldName) => {
const fieldNode = doc.getElementsByTagName(`t:${messageFieldName}`)[0];
if (!fieldNode) {
return [];
}
const emailAddresses = [];
const mailboxes = fieldNode.getElementsByTagName('t:Mailbox');
for (let i = 0, l = mailboxes.length; i < l; i += 1) {
emailAddresses.push(parseMailboxNode(mailboxes[i]));
}
return emailAddresses;
};
const parseGetItemSoapResponse = (xml) => {
try {
const parser = new DOMParser();
// https://developer.mozilla.org/en-US/docs/Web/API/XMLDocument
const doc = parser.parseFromString(xml, 'application/xml');
const message = {
ReplyTo: parseEmailAddresses(doc, 'ReplyTo')[0],
};
return [
'ToRecipients',
'CcRecipients',
'BccRecipients',
'RequiredAttendees',
'OptionalAttendees',
].reduce((result, fieldName) => {
result[fieldName] = parseEmailAddresses(doc, fieldName);
return result;
}, message);
} catch (error) {
throw new Error('Failed to parse XML response of Office.context.mailbox.makeEwsRequestAsync', xml);
return null;
}
};
const getRecipients = async (item) => new Promise((resolve, reject) => {
const { context } = window.Office || {};
const { mailbox } = context || {};
if (!mailbox || !mailbox.makeEwsRequestAsync) {
const error = new Error('Office.context.mailbox.makeEwsRequestAsync is not available.');
reject(error);
return;
}
const { itemId } = item || {};
if (!itemId) {
const error = new Error('Office.context.mailbox.item.itemId is invalid.');
reject(error);
return;
}
// See https://docs.microsoft.com/en-us/outlook/add-ins/web-services
// See https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation-email-message
// See https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/fielduri
const request = `<?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="message:ReplyTo"/>
<t:FieldURI FieldURI="message:ToRecipients"/>
<t:FieldURI FieldURI="message:CcRecipients"/>
<t:FieldURI FieldURI="message:BccRecipients"/>
<t:FieldURI FieldURI="calendar:RequiredAttendees"/>
<t:FieldURI FieldURI="calendar:OptionalAttendees"/>
</t:AdditionalProperties>
</ItemShape>
<ItemIds><t:ItemId Id="${itemId}"/></ItemIds>
</GetItem>
</soap:Body>
</soap:Envelope>
`;
mailbox.makeEwsRequestAsync(request, (result) => {
if (result.error) {
reject(result.error);
} else {
const value = parseGetItemSoapResponse(result.value);
resolve(value);
}
});
});