我正在使用Microsoft Graph,我需要设置一个Webhook来接收对电子邮件和日历事件的更改。我可以在我的PHP Laravel应用程序上使用它,但是现在我尝试订阅通知,因此在验证notificationUrl
(它指向我的公共服务器)时遇到了问题。
用于创建Webhook的脚本返回以下错误:
Client error: POST https://graph.microsoft.com/v1.0/subscriptions resulted in a 400 Bad Request response:
{
"error": {
"code": "InvalidRequest",
"message": "Subscription validation request failed. Response must ex (truncated...)
我认为截断的部分是
订阅验证请求失败。必须以200 OK响应此请求。
这是我创建订阅的代码:
$data = [
"changeType" => "created",
"notificationUrl" => "https://anatbanielmethod.successengine.net/office365/webhooks/events",
"resource" => "me/events",
"expirationDateTime" => "2018-12-20T18:23:45.9356913Z",
"clientState" => "secret",
];
$result = $graph->createRequest('POST', '/subscriptions')
->attachBody($data)
->execute();
这是我的notificationUrl
方法:
public function events()
{
//if validationToken exists return that to validate notificationUrl
if(isset($_REQUEST['validationToken'])){
return response($_REQUEST['validationToken'], 200)
->header('Content-Type', 'text/plain');
}
//process event normally for those that have already been validated
}
该URL再次为public and live,我已经通过使用邮递员向其发送测试文章进行了测试,并且工作正常。另外,我将此路由添加到了VerifyCsrfToken
中间件中,以允许第三方发布访问此URL。
最初,我设置了一个简单的单页PHP脚本来测试对notificationUrl
的验证,并且该简单脚本可以正常工作。它成功验证了创建指向它的Webhooks。这是一页脚本代码:
<?php
if(isset($_REQUEST['validationToken'])){
echo $_REQUEST['validationToken']; // needed only once when subscribing
} else {
//process like normal not a validation Token request...
}
}
因此,我希望Laravel端点可以像简单的一页PHP脚本一样工作,并且是在邮递员中测试两个URL时,但是当Office365尝试在创建新的Webhook时对其进行验证时,Laravel端点无法进行验证。
我到处搜索有关此问题的帮助,并通读了我在webhooks上可以找到的所有Microsoft开发人员文档,这些是文档中一些更有用的部分,但是我仍然找不到此问题的答案:
https://docs.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0
https://docs.microsoft.com/en-us/graph/webhooks#notification-endpoint-validation
对此有何想法?
答案 0 :(得分:0)
谢谢马克!您对于换行是问题是正确的,但我仍然不确定换行来自何处,Laravel似乎是如何添加换行的。不用说,我通过添加“ ob_clean();”找到了解决方案。在返回响应之前。下面是我更新的notificationUrl方法:
public function events()
{
//if validationToken exists return that to validate notificationUrl
if(isset($_REQUEST['validationToken'])){
ob_clean();//this line is cleaning out that previously added linefeed
return response($_REQUEST['validationToken'], 200)
->header('Content-Type', 'text/plain');
}
//process event normally for those that have already been validated
}
答案 1 :(得分:0)
奇怪的是,JakeD的答案要求使用ob_clean()。这是我的Laravel 5.7.x应用程序中的webhook控制器方法:
@ContentChildren(StepComponent) steps: QueryList<StepComponent> = new QueryList<StepComponent>();
我看不到多余的换行符,并且Microsoft Graph API订阅已验证并创建。