首页 > 解决方案 > 通过 Microsoft Graph API 订阅消息,无需用户交互

问题描述

我正在尝试使用 Microsoft Graph API 在没有用户交互的情况下创建一个订阅 Office 365 中的邮件事件(新邮件、创建、更新)的应用程序。如果有新电子邮件,我想向使用 C# MVC5 和 .Net 4.5 构建的应用程序发送通知。我正在关注的一个示例是在 Github 中(使用 Daemon Service Github 项目 Link),但它是在 .Net Core 中构建的。我遇到了另一个使用 WebJobs 的应用程序,它非常接近我的
Azure webjobs要求,但它在过去 2 年没有更新。我遵循了这些步骤,但其中大多数与我的 Azure 开发人员帐户(免费)不匹配。有人可以帮我吗?

应用设置:

应用设置:

<add key="tenantId" value="[Tenant_ID]" />
    <add key="clientId" value="[AppID]" />
    <add key="clientSecret" value="[Client Secret]" />
    <add key="webjobs" value="DefaultEndpointsProtocol=https;AccountName=onvidawebjob1aa1b;AccountKey=Z3xewALbEc43gE/dL06HxCGIjVtpaiTkIY4ZolkjZt9Z86xHIZLzMwXBlujNI8/PcTJbM1LIs5KNceVTGgESmA==" />
    <add key="subscriptionblobname" value="subscriptions/subscription1" />
    <add key="notificationurl" value="https://onvidawebjob1.azurewebsites.net/api/HttpTrigger1?code=H7liZOlcQc5qjcZOkRXEb0x4JVqTzoXnrl6mAswsEKl4LlmAYm/ACw==" />

我试图重新创建应用程序得到以下问题 Trace

Development settings applied
Found the following functions:
WebHooksSample.Functions.ManageSubscriptions
WebHooksSample.Functions.OnNotificationReceived
Singleton lock acquired (cd016b3464fa4d8aa8f41f884a064168/WebHooksSample.Functions.ManageSubscriptions.Listener)
Function 'WebHooksSample.Functions.ManageSubscriptions' is configured to run on startup. Executing now.
Executing 'Functions.ManageSubscriptions' (Reason='Timer fired at 2018-11-16T19:05:27.4182054+05:30', Id=155f7f8a-c352-427f-a7c3-a55ab3518c9a)
Exception while executing function: Functions.ManageSubscriptions
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ManageSubscriptions ---> System.Net.Http.HttpR
equestException: Response status code does not indicate success: 400 (Bad Request).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at WebHooksSample.Functions.<ManageSubscriptions>d__14.MoveNext() in D:\354132\office365_sample_app\webjobs\webjobs-webhooks-sample-master\WebHooks
Sample\Functions.cs:line 128
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`1.<InvokeAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<InvokeAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__13.MoveNext()
   --- End of inner exception stack trace ---
Exception while executing function: Functions.ManageSubscriptions
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ManageSubscriptions ---> System.Net.Http.HttpR
equestException: Response status code does not indicate success: 400 (Bad Request).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at WebHooksSample.Functions.<ManageSubscriptions>d__14.MoveNext() in D:\354132\office365_sample_app\webjobs\webjobs-webhooks-sample-master\WebHooks
Sample\Functions.cs:line 128
--- End of stack trace from previous location where exception was thrown ---

--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`1.<InvokeAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<InvokeAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at `enter code here`System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__13.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<TryExecuteAsync>d__10.MoveNext()
The next 5 occurrences of the schedule will be:
11/16/2018 7:06:03 PM
11/16/2018 7:06:33 PM
11/16/2018 7:07:03 PM
11/16/2018 7:07:33 PM
11/16/2018 7:08:03 PM
Job host started
Executing 'Functions.ManageSubscriptions' (Reason='Timer fired at 2018-11-16T19:05:57.4122054+05:30', Id=405fe97b-2b8a-48bb-a761-7c46a293622c)
Exception while executing function: Functions.ManageSubscriptions
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ManageSubscriptions ---> System.Net.Http.HttpR
equestException: Response status code does not indicate success: 400 (Bad Request).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at WebHooksSample.Functions.<ManageSubscriptions>d__14.MoveNext() in D:\354132\office365_sample_app\webjobs\webjobs-webhooks-sample-master\WebHooks
Sample\Functions.cs:line

编辑1:

我能够使用类似于此处描述的 Outlook 连接器和 Office 365 Webhook API(使用 azure logic App 中可用的默认连接器)完成接收电子邮件(无需用户登录) 。但是,Outlook 连接器每 x 秒(我设置的自定义值)轮询邮箱中的任何更改,但我希望服务自动触发 Webhook 事件而不进行轮询。如果我理解正确的话,应该是这样的——

  1. 创建一个已注册以监视事件的 webhook

  2. 创建一个使用上述 webhook 的 Outlook 连接器。

  3. Outlook 连接器将通知应用程序(REST API 调用)作为工作流的一部分。

标签: c#azure-active-directoryoffice365microsoft-graph-apiazure-webjobs

解决方案


以下是一些需要考虑的关键点:

  • 无论您使用什么语言/平台,使用 Microsoft Graph Webhook 通知都是一样的。唯一的区别是您托管通知端点的方式/位置。

  • 要在没有用户交互的情况下订阅通知,您的应用需要仅应用权限

您可能想查看 Azure Functions;它们为 Microsoft Graph 提供了一些易于使用的绑定:https ://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-microsoft-graph


推荐阅读