有没有办法让所有收件人都进入“收件人”或“抄送”字段?

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.toREST 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);
    }
  });
});