You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Outlook推送通知REST API(C#):如何配置POST请求推送邮件至Azure函数

实现Outlook新邮件推送通知到Azure函数

Got it, let's walk through how to set up that push notification subscription in your .NET web app and hook it up to your Azure Function. I'll break this down step by step since you already have the access token flow working:

1. 先确保你的Azure函数能处理验证和通知请求

First, your Azure Function needs to handle two types of requests from Outlook:

  • Validation GET request: When you create a subscription, Outlook will send a GET request to your function URL with a validationToken query parameter. You must return this token as plain text to confirm your endpoint is valid.
  • Notification POST request: When a new email arrives, Outlook will send a POST request with the notification payload.

Here's a quick C# example for your Azure Function:

using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

[FunctionName("NewMailListener")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    log.LogInformation("Received request from Outlook");

    // Handle validation request (GET)
    if (req.Method == HttpMethod.Get.Method)
    {
        var validationToken = req.Query["validationToken"];
        if (!string.IsNullOrWhiteSpace(validationToken))
        {
            log.LogInformation($"Validating with token: {validationToken}");
            return new OkObjectResult(validationToken);
        }
    }

    // Handle notification request (POST)
    if (req.Method == HttpMethod.Post.Method)
    {
        var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        var notificationResponse = JsonConvert.DeserializeObject<NotificationRoot>(requestBody);

        foreach (var notification in notificationResponse.Value)
        {
            // Verify clientState matches what you set during subscription creation
            if (notification.ClientState != "YOUR_RANDOM_CLIENT_STATE_STRING")
            {
                log.LogWarning("Invalid clientState - ignoring notification");
                continue;
            }

            // Here you can fetch the actual email details using the Resource or ResourceId
            log.LogInformation($"New email notification received: {notification.Resource}");
            // Example: Call Graph API to get the email with notification.ResourceId
        }
    }

    return new OkResult();
}

// Helper classes to deserialize the notification payload
public class NotificationRoot
{
    public List<Notification> Value { get; set; }
}

public class Notification
{
    public string Id { get; set; }
    public string Resource { get; set; }
    public string ResourceData { get; set; }
    public string ClientState { get; set; }
}

2. 在你的.NET Web应用中发送订阅POST请求

Now, use the user's access token you already retrieve to send a POST request to Microsoft Graph API (note: the old Outlook REST API is deprecated, so Microsoft Graph is the modern replacement). This will create the subscription that triggers notifications to your Azure Function.

Here's how to implement this in your web app:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

public async Task CreateOutlookSubscription(string accessToken, string azureFunctionUrl)
{
    // Generate a unique clientState to validate notifications later
    var clientState = Guid.NewGuid().ToString();
    // Save this clientState somewhere (like your database) to verify incoming notifications

    var subscriptionPayload = new
    {
        changeType = "created", // Listen for new emails being created
        notificationUrl = azureFunctionUrl, // Your Azure Function's HTTPS URL
        resource = "/me/mailFolders('inbox')/messages", // Target the user's inbox
        expirationDateTime = DateTime.UtcNow.AddDays(3).ToString("o"), // Subscriptions max out at 3 days
        clientState = clientState
    };

    var jsonPayload = JsonConvert.SerializeObject(subscriptionPayload);

    using (var httpClient = new HttpClient())
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var response = await httpClient.PostAsync(
            "https://graph.microsoft.com/v1.0/subscriptions",
            new StringContent(jsonPayload, Encoding.UTF8, "application/json")
        );

        if (response.IsSuccessStatusCode)
        {
            var responseContent = await response.Content.ReadAsStringAsync();
            var subscription = JsonConvert.DeserializeObject<dynamic>(responseContent);
            // Save subscription.Id to your database - you'll need it to renew/delete the subscription later
            Console.WriteLine($"Subscription created successfully! ID: {subscription.id}");
        }
        else
        {
            var errorDetails = await response.Content.ReadAsStringAsync();
            Console.WriteLine($"Failed to create subscription: {errorDetails}");
            // Handle errors here (e.g., missing permissions, invalid notification URL)
        }
    }
}

3. 关键注意事项

  • HTTPS Required: Outlook will only send notifications to HTTPS endpoints, so make sure your Azure Function uses a valid HTTPS URL.
  • Permissions: Your app must have the Mail.Read delegated permission (since you're using a user access token). Ensure this is added in your Azure AD app registration, and that the user has consented to this permission.
  • Subscription Renewal: Subscriptions expire after 3 days. You'll need to implement a background job to renew them by sending a PATCH request to https://graph.microsoft.com/v1.0/subscriptions/{subscriptionId} with a new expirationDateTime.
  • ClientState Validation: Always check the clientState in incoming notifications against the value you saved during subscription creation. This prevents spoofed requests.

内容的提问来源于stack exchange,提问作者OrFe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:45:37