首页 > 解决方案 > 使用 PHP 通过 EWS 从 Outlook.com 邮箱中检索电子邮件附件

问题描述

我正在开发一个 Outlook 插件,它应该为我们的用例将电子邮件同步到另一台服务器。我能够获取存储在远程数据库上的邮件,但问题在于获取附件。由于加载项本身不能发送附件,我必须向远程服务器发送一些详细信息,例如(ews url、访问令牌、附件 ID 等),以便它可以使用该信息联系 Outlook 服务器以获取相应的附件。无论我如何尝试,它似乎都失败了。这基本上让我想,outlook.com 是否支持 EWS?很难找到合适的参考资料,但其中一些参考资料说“不”。但我的信念是,由于 outlook.com 看起来像是“在线交流”的一部分(尽管是免费的),所以它也应该支持 EWS。这一点很明显,我可以通过 Outlook 加载项执行 Office.context.mailbox 对象的 getCallbackTokenAsync() 方法来检索 ewsUrl 和 attachmentToken。加载项文档说:

“Office.context.mailbox 对象提供 getCallbackTokenAsync 函数来获取远程服务器可用于与 Exchange 服务器进行身份验证的令牌。”

就这样。但是,当我尝试使用 XML 有效负载(来自我的远程服务器)对 ewsUrl 执行 SOAP 请求时,Outlook 服务器端点(https://outlook.office365.com/EWS/Exchange.asmx)不断返回错误 500 -内部服务器错误。响应中也没有太多确凿的细节,因此我可以追踪我发送给它的请求是否有任何问题。我对此感到非常困惑。感谢已经这样做的人的一些帮助。以下是我执行的代码块(Laravel)供您参考:

        // check for attachments
        if(is_object($incoming->attachments))
        {
            // we have attachments
            $attachments = $incoming->attachments->attachments;
            $ewsToken = $incoming->attachments->attachmentToken;
            $ewsUrl = $incoming->attachments->ewsUrl;

            foreach($attachments as $k => $v){

                Log::info('Attachment ID: '.$v->id);

                $attachmentSoapRequest = <<<EOD
@"<?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>
<t:RequestServerVersion Version=""Exchange2013"" />
</soap:Header>
    <soap:Body>
    <GetAttachment xmlns=""http://schemas.microsoft.com/exchange/services/2006/messages""
    xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"">
        <AttachmentShape/>
        <AttachmentIds>
        <t:AttachmentId Id=""$v->id""/>
        </AttachmentIds>
    </GetAttachment>
    </soap:Body>
</soap:Envelope>"
EOD;
                try{

                    $response = Http::withBody($attachmentSoapRequest, 'text/xml')->withToken($ewsToken)->withOptions([
                        'debug' => true,
                        'allow_redirects' => false
                    ])->post($ewsUrl);
                    
                    // process response
                    if ($response->successful()) {
                
                        Log::info('received ews response!');
                        $responseEnvelope = $response->body();
                        Log::info($responseEnvelope);
                
                    } else {
                
                        $response->throw();
                
                    }
                } catch (RequestException $e) {
                    Log::info('ews request error!');
                    Log::info($e->getMessage());
                }

                Log::info(print_r($response, true));

            }
        }

如果有人知道答案,它不一定是 Laravel 特定的。即使是纯 PHP 解决方案也是受欢迎的。

谢谢。

标签: phplaravelsoapexchangewebservicesoutlook-web-addins

解决方案


推荐阅读