EWS API 发送电子邮件时出现错误“请求的 Web 方法对此调用方或应用程序不可用”

问题描述 投票:0回答:0

我编写了一个 Outlook Web 插件,它使用 EWS API 读取电子邮件属性,包括 MIME 内容,并在 Outlook 外部处理数据。这一切都很好。

一个新的要求是能够通过单击任务窗格中的按钮来发送电子邮件草稿。我使用

EmailMessage.SendAndSaveCopy()
方法实现了这个。此调用失败,并显示
ServiceResponseException
消息
"The requested web method is unavailable to this caller or application."

我调查了一下,发现我需要增加插件清单中请求的权限到最高级别

ReadWriteMailbox
。我这样做了,但 API 调用仍然失败。

我在私有开发 Microsoft 365 租户中运行加载项,在其中我对所有内容都拥有完全管理员权限。

我想知道:

  • 我做错了吗?如果是这样,应该怎么做?
  • Microsoft 是否弃用了 Send 方法,转而将所有人推向 Graph API?

插件清单的相关部分:

<Hosts>
    <Host Name="Mailbox" />
</Hosts>

<Requirements>
    <Sets>
        <Set Name="Mailbox" MinVersion="1.1" />
    </Sets>
</Requirements>

<Permissions>ReadWriteMailbox</Permissions>

<Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs" ItemType="Message" FormType="ReadOrEdit" />
</Rule>

<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
    <Requirements>
        <bt:Sets DefaultMinVersion="1.3">
            <bt:Set Name="Mailbox" />
        </bt:Sets>
    </Requirements>
    <Hosts>
        <Host xsi:type="MailHost">
            <DesktopFormFactor>
                <ExtensionPoint xsi:type="MessageReadCommandSurface">
                    <OfficeTab id="TabDefault">
                        <Group id="Group.MessageRead">
                            <Label resid="Group.Label" />
                            <Control xsi:type="Button" id="HomeButton.MessageRead">
                                <!-- ... -->
                            </Control>
                        </Group>
                    </OfficeTab>
                </ExtensionPoint>
                <ExtensionPoint xsi:type="MessageComposeCommandSurface">
                    <OfficeTab id="TabDefault">
                        <Group id="Group.MessageCompose">
                            <Label resid="Group.Label" />
                            <Control xsi:type="Button" id="HomeButton.MessageCompose">
                                <!-- ... -->
                            </Control>
                        </Group>
                    </OfficeTab>
                </ExtensionPoint>
            </DesktopFormFactor>
        </Host>
    </Hosts>
</VersionOverrides>

获取电子邮件数据(EWS API URL、EWS API 令牌、所选项目 ID)的 JavaScript 函数:

var _getMailboxItem = function(onSuccess) {
    var ewsItemId = Office.context.mailbox.item.itemId;
    var afterSave = function() {
        var ewsUrl = Office.context.mailbox.ewsUrl;
        Office.context.mailbox.getCallbackTokenAsync({}, function(getCallbackTokenResult) {
            if(getCallbackTokenResult.status !== Office.AsyncResultStatus.Succeeded) {
                _handleOfficeError(getCallbackTokenResult, "Cannot read the mailbox item.");
                return;
            }
            var ewsToken = getCallbackTokenResult.value;
            onSuccess({ url: ewsUrl, token: ewsToken, itemId: ewsItemId });
        });
    };
    if(ewsItemId) {
        // We have the item ID already, it's safe to continue.
        afterSave(onSuccess);
    } else {
        // We must save the item first before we can read data.
        console.log("Saving the item first...");
        Office.context.mailbox.item.saveAsync(function(saveAsyncResult) {
            if(saveAsyncResult.status !== Office.AsyncResultStatus.Succeeded) {
                _handleOfficeError(saveAsyncResult, "Cannot save a draft of the mailbox item.");
                return;
            }
            ewsItemId = saveAsyncResult.value;
            afterSave(onSuccess);
        });
    }
};

发送草稿消息的相关控制器代码(ASP.NET MVC 4.8):

private static ExchangeService GetExchangeService(MailboxItemModel mailboxItem) => new ExchangeService {
    Url = new Uri(mailboxItem.Url),
    Credentials = new OAuthCredentials(mailboxItem.Token)
};

private static EmailMessage GetEmailMessage(MailboxItemModel mailboxItem) => EmailMessage.Bind(
    GetExchangeService(mailboxItem),
    mailboxItem.ItemId,
    new PropertySet(BasePropertySet.IdOnly) {
        ItemSchema.MimeContent
    });

private static void Send(EmailMessage emailMessage) {
    // This is the single unambiguous determinator: if the addin was opened in message compose mode, then we try to send.
    if(!IsSendable()) { return; }
    // Belt and braces safety check: if the javascript didn't pass valid email propertes, then we can't do anything.
    if(emailMessage == null) { return; }
    emailMessage.Load();
    // Belt and braces safety check: only send if EWS confirms that the message is a draft.
    if(!emailMessage.IsDraft) { return; }
    emailMessage.SendAndSaveCopy();
}
c# asp.net-mvc exchangewebservices outlook-web-addins
© www.soinside.com 2019 - 2024. All rights reserved.