Я пытаюсь подписаться на почтовый ящик пользователя с помощью подписок Microsoft Graph. Я пытаюсь подписаться на почтовый ящик определенного пользователя c, используя только «созданный» changeType, доступ к которому осуществляется через токен, созданный с использованием учетных данных клиента на клиенте моей компании в AD (регистрация приложения). Это делается в моей среде разработки (Laravel framework, используя Laravel Valet + ngrok).
Я могу успешно создать подписку на стороне MS, сделав URL-адрес уведомления URL-адресом ngrok, и я могу чтобы пройти проверку et c, но MS, кажется, не возвращает подтверждение, что подписка была создана с ответом «201 Created», как это говорится в документах .
Я могу подтвердить, что подписка работает, потому что я могу отправить электронное письмо на этот почтовый ящик, и ngrok перехватывает запрос, содержащий правильную информацию - только первоначальная настройка webhook не возвращает 201 при успешном создании.
Я бы хотел бы получить это подтверждение, чтобы я мог сохранить идентификатор webhook et c в приложении для дальнейшего использования (обновление срока действия cron et c).
Извинения, если я не предоставил достаточно информации чтобы прояснить вопрос - просто спросите соответствующие детали.
Как мне поступить с этим?
РЕДАКТИРОВАТЬ - включая примеры кода и маршрутизацию
Код, который я использую, является пользовательским классом, поэтому я не могу включить все, но он построен таким образом:
Microsoft. php
public function subscribe($resource)
{
$this->verb = "POST";
$this->endpoint = "/subscriptions";
$this->body = [
"notificationUrl" => config('app.env') === 'production'
? env('APP_URL') . route('ms', null, false)
: env('NGROK_URL') . route('ms', null, false),
"resource" => $resource,
"expirationDateTime" => Carbon::now('UTC')->addDay(),
"latestSupportedTlsVersion" => "v1_2"
];
return $this;
}
public function changes($array)
{
$this->body['changeType'] = implode(",", $array);
return $this;
}
public function send()
{
$token = $this->getToken()->token;
$this->headers['Authorization'] = "Bearer $token";
try {
$response = $this->client
->request($this->verb, env('GRAPH_BASE_URL') . $this->endpoint, [
'headers' => $this->headers,
'body' => json_encode($this->body, JSON_UNESCAPED_SLASHES)
]);
return json_decode($response->getBody());
} catch (RequestException $e) {
echo Psr7\str($e->getRequest());
if ($e->hasResponse()) {
echo Psr7\str($e->getResponse());
}
}
}
Код запускаемой команды:
public function handle()
{
$client = new MicrosoftClient();
$webhookUrl = "users/" .
env('AZURE_USER_ID') .
"/mailFolders('Inbox')/messages";
$changes = ['created'];
$client->subscribe($webhookUrl)->changes($changes)->send();
}
POST-маршрут в логах моего приложения c:
Route::post('[my webhook url]', function (Request $request) {
if ($request->query('validationToken')) {
// MS requires that successful requests must send back a 200 status code
// using a plain text response
return response($request->query('validationToken', 200))
->header('Content-Type', 'text/plain');
} else {
// just a regular webhook create/update...
Log::info('Got email' . $request->input('value.resourceData'));
Log::debug($request);
}
})->name('ms');
^ в операторе else я разместил там логи, чтобы посмотреть, перехватывает ли Laravel какие-либо дополнительные ответы, но 201 не было. Тем не менее, реальные уведомления веб-крючка были перехвачены.
Это дамп запроса перед его отправкой, JSON, отформатированный для красивости:
POST /v1.0/subscriptions HTTP/1.1
User-Agent: GuzzleHttp/6.5.1 curl/7.68.0 PHP/7.4.3
Host: graph.microsoft.com
Content-Type: application/json
Authorization: Bearer [token]
{
"notificationUrl":"[ngrok url]/[my chosen webhook endpoint]",
"resource":"users/[user id]/mailFolders('Inbox')/messages",
"expirationDateTime":"[24 hours after request made]",
"latestSupportedTlsVersion":"v1_2",
"changeType":"created"
}
Это то, что я получаю от MS для проверки подписки:
POST /[my webhook url]?validationToken=Validation%3a+Testing+client+application+reachability+for+subscription+Request-Id%3a+262d7fae-31c3-4541-8de0-c1fc26ddd41b HTTP/1.1
Host: ticket-system.test:60
Content-Length: 0
Content-Type: text/plain; charset=utf-8
X-Forwarded-For: 40.113.95.219
X-Forwarded-Proto: https
X-Original-Host: [ngrok url]
Это ответ проверки, который я отправляю обратно в MS (бит маркера проверки):
HTTP/1.1 200 OK
Server: nginx/1.15.11
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/7.4.3
Cache-Control: no-cache, private
Date: Fri, 03 Apr 2020 08:42:34 GMT
Set-Cookie: XSRF-TOKEN=[XSRF token]; expires=Fri, 03-Apr-2020 10:42:34 GMT; Max-Age=7200; path=/
Set-Cookie: [sluggified_app_name]_session=[session]; expires=Fri, 03-Apr-2020 10:42:34 GMT; Max-Age=7200; path=/; httponly
75
Validation: Testing client application reachability for subscription Request-Id: 262d7fae-31c3-4541-8de0-c1fc26ddd41b
0
И это все, что ngrok, кажется, ловит после все сказано и сделано, код ответа 200, который выглядит как «проверяющий» запрос перед созданием webhook:
Ссылка на пример ответа Webhook Извините, я не могу Опубликуйте изображения здесь, потому что я новый участник.
Как вы можете видеть, я не получаю ничего, чтобы подтвердить детали веб-крючка.