Verwenden von Webhooks für E-Mail-, Kalender- und Kontakt-REST-Benachrichtigungen

Wir freuen uns über die Einführung der Outlook-Benachrichtigungen-REST-API für E-Mail, Kalender und Kontakte in Office 365 und Outlook.com. Die Outlook-Benachrichtigungen-REST-API verwendet einen Webhook-Mechanismus zum Übermitteln von Benachrichtigungen an Clients. Ein Client in diesem Zusammenhang ist tatsächlich ein Drittanbieter-Webdienst, der eine eigene Benachrichtigungs-URL konfiguriert, an die Office 365 per Push diese Benachrichtigungen übermittelt. E-Mail- und Kalender-Apps verwenden normalerweise Benachrichtigungen für die Aktualisierung des lokalen Cache und den entsprechenden Clientansichten bei Änderungen. Darüber hinaus verwenden CRM-Apps in der Regel Benachrichtigungen, um die eigenen Systeme entsprechend den an relevanten Unterhaltungen vorgenommenen Änderungen zu aktualisieren.

Beim Verwenden der Outlook-Benachrichtigungen-REST-API kann eine App nun Benachrichtigungen zu einer bestimmten Ressource (z. B. Nachrichten im Posteingang) abonnieren, um über Änderungen an der Ressource informiert zu werden. Sobald der Outlook-Benachrichtigungsdienst die Abonnementanforderung akzeptiert, übermittelt er die Benachrichtigungen per Push über Webhooks an die in dem Abonnement angegebene Benachrichtigungs-URL. Die App führt dann Aktionen gemäß der Geschäftslogik aus (z. B. Abrufen neuer Nachrichten, Aktualisieren der Anzahl ungelesener Nachrichten, Entfernen gelöschter Nachrichten aus der Clientansicht).

Apps müssen ihre Abonnements verlängern, bevor diese ablaufen. Abonnements können auch jederzeit gekündigt werden, um keine weiteren Benachrichtigungen zu erhalten.

Im Folgenden wird der Abonnementprozess beschrieben.

Erstellen eines Abonnements

Um Benachrichtigungen für eine bestimmte Entitätssammlung zu erhalten, muss in einem ersten Schritt ein Abonnement erstellt werden. Der Abonnementprozess läuft wie folgt ab:

  1. Der Client sendet eine Abonnementanforderung (POST) für eine bestimmte Entitätssammlung.
  2. Der Outlook-Benachrichtigungsdienst überprüft die Anforderung, überprüft die Benachrichtigungs-URL und sendet die Antwort an den Client.
    1. Erfolg: Der Dienst erstellt ein Abonnement mit eindeutiger ID und sendet die entsprechende Antwort.
    2. Fehler: Der Dienst sendet eine Fehlerantwort mit Fehlercode und Details.
  3. Der Client muss die Abonnement-ID speichern, um eine Benachrichtigung mit dem entsprechenden Abonnement korrelieren zu können.

Merkmale von Abonnements

  • Abonnements können für Entitätssammlungen (z. B. Nachrichten, Ereignisse und Kontakte) ausgeführt werden.
    • Bestimmte Ordner einschließlich Suchordner:
      • https://outlook.office.com/api/v2.0/me/mailfolders('inbox')/messages
    • Sammlung auf oberster Ebene:
      • https://outlook.office.com/api/v2.0/me/events
      • https://outlook.office.com/api/v2.0/me/messages
  • Ein Abonnement bleibt während der Gültigkeitsdauer bestehen. Dies ist ein Vorteil gegenüber unseren älteren SOAP-API-Exchange-Webdiensten (EWS), in denen Abonnements aufgrund von Problemen auf Serverseite wie Anwendungspoolabstürzen oder Serverausfällen verloren gehen können.
  • Zum Erstellen eines Abonnement sind Lesebereiche der Ressource erforderlich. Es ist z. B. erforderlich, dass mail.read Benachrichtigungen über Nachrichten im Posteingang erhält.
  • Abonnements funktionieren für normale Order wie Posteingang sowie für Suchordner.
  • Abonnements laufen ab. Der aktuelle maximale Ablaufzeitpunkt ist 3 Tage ab dem Zeitpunkt der Erstellung. Apps müssen ihre Abonnements vor dem Ablaufzeitpunkt erneuern, andernfalls ist ein erneutes Abonnieren erforderlich.

Überprüfung der Benachrichtigungs-URL

Der Outlook-Benachrichtigungsdienst überprüft die Benachrichtigungs-URL in einer Abonnementanforderung vor dem Erstellen eines neuen Abonnements. Der Überprüfungsprozess läuft wie folgt ab:

  1. Der Outlook-Benachrichtigungsdienst sendet eine POST-Anforderung an die Benachrichtigungs-URL:

     POST https://{notificationUrl}?validationtoken={TokenDefinedByService}
     ClientState: {Data sent in ClientState value in subscription request (if any)}
    
  2. Der Webhooks-Dienst muss innerhalb von 5 Sekunden eine 200-Antwort mit dem validationtoken-Wert im Textbereich vom Typ plain/text bereitstellen. Das Überprüfungstoken ist eine zufällige Zeichenfolge, die vom Webhook verworfen werden sollte, nachdem es in der Antwort bereitgestellt wurde.

Beispiel für Anforderung zum Erstellen eines Abonnements

POST https://outlook.office.com/api/v2.0/me/subscriptions  HTTP/1.1
Content-Type: application/json
{
  "@odata.type": "#Microsoft.OutlookServices.PushSubscription",
  "Resource": "https://outlook.office.com/api/v2.0/me/mailfolders('inbox')/messages",
  "NotificationURL": "https://mywebhook.azurewebsites.net/api/send/myNotifyClient",  
  "ChangeType": "Created, Updated, Deleted",
  "SubscriptionExpirationDateTime": "2015-11-20T23:05:01.9420124Z"
  "ClientState": "MySecretClientStateString"
}

Die @odata.type, Resource-, NotificationURL- und ChangeType-Eigenschaften sind erforderlich, während die übrigen optional sind. Informationen zu Eigenschaftsdefinitionen und -werten finden Sie unter https://msdn.microsoft.com/de-de/office/office365/APi/notify-rest-operations.

Beispiel für Antwort auf Anforderung zum Erstellen eines Abonnements

Abonnementantwort ist eine Wiedergabe der Anforderung mit den folgenden zusätzlichen Eigenschaften und Werten:

  • Id – Eindeutiger Bezeichner pro Abonnement. Client muss diesen Bezeichner zum Abstimmen mit den Benachrichtigungen speichern.
  • SubscriptionExpirationDateTime Die tatsächliche Ablaufzeitdauer, falls nicht in der Anforderung angegeben, oder die in der Anforderung angegebene Ablaufdauer war größer als 3 Tage.
  • ChangeType fügt zwei Arten von Benachrichtigungen hinzu: Acknowledgment und Missed. Diese werden im Abschnitt „Benachrichtigung“ erläutert.

Die oben genannte Beispielanforderung generiert eine Antwort, die wie folgt aussieht:

{
  "@odata.context": "https://outlook.office.com/api/v2.0/$metadata#Me/Subscriptions/$entity",
  "@odata.id": "https://outlook.office.com/api/v2.0/Users('user@contoso.com')/subscriptions('NDc0MEE4...QQ==')",
  "@odata.type": "#Microsoft.OutlookServices.PushSubscription",
  "ChangeType": "Created, Updated, Deleted, Acknowledgment, Missed",
  "ClientState": "MySecretClientStateString",
  "Id": "NDc0MEE4...QQ==",
  "NotificationURL": "https://mywebhook.azurewebsites.net/api/send/myNotifyClient",
  "Resource": "https://outlook.office.com/api/v2.0/me/folders('inbox')/messages",
  "SubscriptionExpirationDateTime": "2015-11-20T23:05:01.9420124Z"
}

Verlängern eines Abonnements

Der Client kann ein Abonnement mit einem bestimmten Ablaufdatum (von bis zu drei Tagen ab dem Zeitpunkt der Anforderung) verlängern. Die SubscriptionExpirationDateTime-Eigenschaft ist optional. Wenn kein Wert angegeben ist, wird das Abonnement um 3 Tage ab dem Zeitpunkt der Anforderung erneuert.

Beispiel für Anforderung zum Erneuern eines Abonnements

PATCH https://outlook.office.com/api/v2.0/me/subscriptions('NDc0MEE4...QQ==') 

{
  "@odata.type": "#Microsoft.OutlookServices.PushSubscription",
  "SubscriptionExpirationDateTime": "2015-11-22T23:16:31.3604491Z"
}

Beispiel für Antwort auf Anforderung zum Erneuern eines Abonnements

Die Antwort auf Anforderung zum Erneuern eines Abonnements ist eine Wiedergabe der Anforderung zum Erstellen eines Abonnements mit dem neuen Ablaufzeitpunkt.

{
  "@odata.context": "https://outlook.office.com/api/v2.0/$metadata#Me/Subscriptions/$entity",
  "@odata.id": "https://outlook.office.com/api/v2.0/Users('user@contoso.com')/subscriptions('NDc0MEE4...QQ==')",
"@odata.type": "#Microsoft.OutlookServices.PushSubscription",
  "ChangeType": "Created, Updated, Deleted, Acknowledgment, Missed",
  "ClientState": "MySecretClientStateString",
  "Id": "NDc0MEE4...QQ==",
  "Resource": "https://outlook.office.com/api/v2.0/me/folders('inbox')/messages",
  "SubscriptionExpirationDateTime": "2015-11-22T23:16:31.3604491Z"
}

Kündigen eines Abonnements

Der Client kündigt ein Abonnement, indem das Abonnement unter Verwendung der ID gelöscht wird.

DELETE https://outlook.office.com/api/v2.0/me/subscriptions('NDc0MEE4...QQ==')

Eine erfolgreiche Antwort wird mit einem HTTP-204 No Content-Antwortcode angegeben.

Benachrichtigungen

Sobald ein Abonnement eingerichtet wurde, erhält der Client Benachrichtigungen über Änderungen im Zusammenhang mit der entsprechenden Ressource über ein Webhook an die Benachrichtigungs-URL gemäß dem angegebenen Änderungstyp des Clients (z. B. Changed).

Wahrscheinlich haben Sie festgestellt, dass die Abonnementantwort über zwei weitere Änderungstypen verfügt: Missed und Acknowledgment. Dies sind spezielle Typen von Benachrichtigungen, die wie folgt verwendet werden:

  • Die Benachrichtigungsdienste senden eine Missed-Benachrichtigung, wenn der Dienst die angeforderten Benachrichtigungen nicht senden kann. Obwohl dies für Clients hilfreich ist, um diese Benachrichtigung zu verarbeiten, wird dieses Thema in späteren erweiterten Artikeln erläutert.
  • Acknowledgement-Benachrichtigung ist veraltet, da sie durch den Überprüfungsvorgang der Benachrichtigungs-URL ersetzt wurde. Wir arbeiten daran, diese aus der Abonnementantwort zu entfernen.

Struktur

Jede Benachrichtigung weist unabhängig vom Typ die folgende Struktur auf:

  • ClientState-Header: NUR, wenn der Client die ClientState-Eigenschaft in der Abonnementanforderung angegeben hat.
  • SubscriptionId: Die ID für das Abonnement, zu dem diese Benachrichtigung gehört.
  • SubscriptionExpirationDateTime: Die Ablaufzeit für das Abonnement.
  • ChangeType: Der Ereignistyp, der die Benachrichtigung ausgelöst hat. (Z. B. Created bei Erhalt einer E-Mail oder Update, wenn eine Nachricht als gelesen markiert wird.)
  • SequenceNumber: Dient zur Identifizierung, wenn der Client eine Benachrichtigung verpasst hat. Der Umgang der Sequenznummer auf dem Client wird später im Rahmen der erweiterten Themen erläutert.

Darüber hinaus verfügt eine Benachrichtigung, die mit einer Ressourcenänderung einhergeht (z. B. Empfangen, Lesen oder Löschen einer Nachricht), eine zusätzliche ResourceData-Eigenschaft, die die ID des Elements enthält, das geändert wurde. Ein Client kann diese ID verwenden, um dieses Element entsprechend der Geschäftslogik zu behandeln (z. B. dieses Element abzurufen, den Ordner zu synchronisieren).

Beispielbenachrichtigungen

Benachrichtigung über das Empfangen von E-Mails

Wenn der Benutzer eine neue Nachricht im Posteingang empfängt, sendet der Benachrichtigungsdienst eine Benachrichtigung mit einem ChangeType-Element, das auf Created festgelegt ist.

{
  "value": [
    {
      "@odata.type": "#Microsoft.OutlookServices.Notification",
      "Id": null,
      "SubscriptionId": "NDc0MEE4...QQ==",
      "SubscriptionExpirationDateTime": "2015-11-20T23:16:31.3604491Z",
      "SequenceNumber": 8,
      "ChangeType": "Created",
      "Resource": "https://outlook.office365.com/api/v2.0/Users('user@contoso.com')/Messages('AAMkAGY1...AAA=')",
      "ResourceData": {
        "@odata.type": "#Microsoft.OutlookServices.Message",
        "@odata.id": "https://outlook.office365.com/api/v2.0/Users('user@contoso.com')/Messages('AAMkAGY1...AAA=')",
        "@odata.etag": "W/\"CQAAABYAAABU4oDY3YDWSanCtdlMJCDOAADe14EA\"",
        "Id": "AAMkAGY1...AAA="
      }
    }
  ]
}

Benachrichtigung über das Lesen von E-Mails

Wenn der Benutzer eine Nachricht als gelesen markiert hat, sendet der Benachrichtigungsdienst eine Benachrichtigung mit einem ChangeType-Element, das auf Updated festgelegt ist.

{
  "value": [
    {
      "@odata.type": "#Microsoft.OutlookServices.Notification",
      "Id": null,
      "SubscriptionId": "NDc0MEE4...QQ==",
      "SubscriptionExpirationDateTime": "2015-11-20T23:16:31.3604491Z",
      "SequenceNumber": 2,
      "ChangeType": "Updated",
      "Resource": "https://outlook.office365.com/api/v2.0/Users('user@contoso.com')/Messages('AAMkAGY1...AAA=')",
      "ResourceData": {
        "@odata.type": "#Microsoft.OutlookServices.Message",
        "@odata.id": "https://outlook.office365.com/api/v2.0/Users('user@contoso.com')/Messages('AAMkAGY1...AAA=')",
        "@odata.etag": "W/\"CQAAABYAAABU4oDY3YDWSanCtdlMJCDOAADe14EA\"",
        "Id": "AAMkAGY1...AAA="
    }
  ]
}

Verpasste Benachrichtigungen

{
  "value": [
    {
      "@odata.type": "#Microsoft.OutlookServices.Notification",
      "Id": null,
      "SubscriptionId": "NDc0MEE4...QQ==",
      " SubscriptionExpirationDateTime": "2015-11-20T23:16:31.3604491Z ",
      "SequenceNumber": 1,
      "ChangeType": "Missed"
    }
  ]
}

Nächste Schritte

Wir freuen uns wirklich über die Outlook-Benachrichtigungen-REST-API und Webhooks für E-Mail, Kalender und Kontakte. Testen Sie sie, und und senden Sie uns Ihr Feedback an UserVoice. Dies hilft uns dabei, unsere APIs zu verbessern und somit angenehme Erfahrungen in Apps zu gewährleisten.