Erste Schritte mit SharePoint-Webhooks

In diesem Artikel wird beschrieben, wie Sie eine Anwendung zum Hinzufügen und Bearbeiten von SharePoint-Webhook-Anforderungen erstellen. Sie erfahren, wie Sie SharePoint-Webhook-Anforderungen mit dem Postman-Client schnell erstellen und ausführen können, unter Verwendung einer einfachen ASP.NET-Web-API als Webhook-Empfänger.

Sie werden mit einfachen HTTP-Anforderungen arbeiten, die ideal geeignet sind, um Ihnen einen ersten Einblick in die Funktionsweise von Webhooks zu verschaffen.

Damit Sie die Schritt-für-Schritt-Anleitungen in diesem Artikel nachvollziehen können, müssen Sie die folgenden Tools herunterladen und installieren:

Schritt 1: Registrieren Sie eine Azure AD-Anwendung den Postman-Client

Damit der Postman-Client mit SharePoint kommunizieren kann, müssen Sie eine Microsoft Azure Active Directory (Azure AD)-App in dem Azure AD-Mandanten registrieren, der mit Ihrem Office 365-Mandanten verknüpft ist.

  1. Registrieren Sie die Anwendung unbedingt als Webanwendung.

  2. Für den Zugriff auf SharePoint Online ist es wichtig, der Azure AD-App Berechtigungen für die Office 365 SharePoint Online-Anwendung zu gewähren und die Berechtigung read and write items and lists in all site collections auszuwählen.

    Hinweis

    Weitere Informationen dazu, wie Sie Azure AD-Anwendungen hinzufügen und Anwendungen Berechtigungen gewähren können, finden Sie unter Hinzufügen einer Anwendung.

  3. Geben Sie den folgenden Endpunkt als Antwort-URL (Umleitung) für die App ein. Dies ist der Endpunkt, an den Azure AD die Authentifizierungsantwort einschließlich des Zugriffstokens sendet, wenn die Authentifizierung erfolgreich war.

    https://www.getpostman.com/oauth2/callback
    
  4. Generieren Sie einen Schlüssel, der als geheimer Clientschlüssel fungiert.

  5. Die folgenden Eigenschaften werden in späteren Schritten benötigt. Kopieren Sie sie also an einen sicheren Ort:

    • Client-ID
    • Client Secret

Schritt 2: Erstellen eines Webhook-Empfängers

In diesem Beispiel erstellen Sie den Webhook-Empfänger mit einem Visual Studio-Web-API-Projekt.

Erstellen eines neuen ASP.NET-Web-API-Projekts

  1. Öffnen Sie Visual Studio.
  2. Wählen Sie Datei>Neu>Projekt.
  3. Wählen Sie im Bereich Vorlagen die Option Installed Templates aus, und erweitern Sie den Knoten Visual C#.
  4. Wählen Sie unter Visual C# die Option Web aus.
  5. Wählen Sie aus der Liste der Projektvorlagen die Option ASP.NET-Webanwendung aus.
  6. Nennen Sie das Projekt SPWebhooksReceiver, und wählenSie OK.
  7. Wählen Sie im Dialogfeld Neues ASP.NET-Projekt die Vorlage Web API aus der Gruppe ASP.NET 4.5 aus.
  8. Ändern Sie die Authentifizierungsoption in Keine Authentifizierung. Wählen Sie dazu die Schaltfläche Authentifizierung ändern.
  9. Wählen Sie OK, um das Web-API-Projekt zu erstellen.

Hinweis

Sie können das Kontrollkästchen In der Cloud hosten deaktivieren, da Sie dieses Projekt nicht in der Cloud bereitstellen werden.

Visual Studio erstellt nun Ihr Projekt.

Erstellen des Webhook-Empfängers

Installieren der NuGet-Pakete

Verwenden Sie die ASP.NET-Web-API-Ablaufverfolgung zur Protokollierung der eingehenden SharePoint-Anforderungen. Gehen Sie wie folgt vor, um das Paket für die Ablaufverfolgung zu installieren:

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.
  2. Öffnen Sie per Rechtsklick das Kontextmenü des Projekts, und wählen Sie NuGet-Pakete verwalten aus.
  3. Geben Sie Microsoft.AspNet.WebApi.Tracing in das Suchfeld ein.
  4. Wählen Sie aus den Suchergebnissen das Paket Microsoft.AspNet.WebApi.Tracing aus, und wählen Sie dann Installieren, um das Paket zu installieren.

Erstellen des SPWebhookNotification-Modells

Jede vom Dienst generierte Benachrichtigung wird in eine WebhookNotification-Instanz serialisiert. Sie müssen ein einfaches Modell erstellen, das diese Benachrichtigungsinstanz abbildet.

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.

  2. Öffnen Sie per Rechtsklick das Kontextmenü des Ordners Models, und wählen Sie Hinzufügen>Klasse aus.

  3. Geben Sie SPWebhookNotification als Name für die Klasse ein, und wählen Sie Hinzufügen aus, um die Klasse zu Ihrem Projekt hinzuzufügen.

  4. Tragen Sie den folgenden Code in den Body der Klasse SPWebhookNotification ein:

    public string SubscriptionId { get; set; }
    public string ClientState { get; set; }
    public string ExpirationDateTime { get; set; }
    public string Resource { get; set; }
    public string TenantId { get; set; }
    public string SiteUrl { get; set; }
    public string WebId { get; set; }
    

Erstellen des SPWebhookContent-Modells

Da in einer einzigen Anforderung mehrere Benachrichtigungen an einen Webhook-Empfänger gesendet werden können, werden alle Anforderungen in einem Objekt mit einem einzigen Arraywert zusammengefasst. Erstellen Sie ein einfaches Modell, das dieses Array abbildet.

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.

  2. Öffnen Sie per Rechtsklick das Kontextmenü des Ordners Models, und wählen Sie Hinzufügen>Klasse aus.

  3. Geben Sie SPWebhookContent als Name für die Klasse ein, und wählen Sie Hinzufügen aus, um die Klasse zu Ihrem Projekt hinzuzufügen.

  4. Tragen Sie den folgenden Code in den Body der Klasse SPWebhookContentein:

      public List<SPWebhookNotification> Value { get; set; }
    

Hinzufügen des SharePoint-Webhook-Clientstatus

Webhooks erlauben die Verwendung eines optionalen Zeichenfolgenwerts, der in der Benachrichtigungsmitteilung für Ihr Abonnement zurückgegeben wird. Anhand dieses Werts lässt sich verifizieren, dass die Anforderung wirklich von einer vertrauenswürdigen Quelle stammt, in diesem Fall von SharePoint.

Fügen Sie einen Clientzustandswert hinzu, mit dem die Anwendung die eingehenden Anforderungen verifizieren kann.

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.

  2. Öffnen Sie die Datei web.config, und fügen Sie den folgenden Schlüssel als Clientzustand im Abschnitt <appSettings> hinzu:

    <add key="webhookclientstate" value="A0A354EC-97D4-4D83-9DDB-144077ADB449"/>
    

Aktivieren der Ablaufverfolgung

Aktivieren Sie in der Datei web.config die Ablaufverfolgung, indem Sie den folgenden Schlüssel im Element <system.web> im Abschnitt <configuration> hinzufügen:

<trace enabled="true"/>

Da ein Ablauf-Writer erforderlich ist, müssen Sie einen Ablauf-Writer zur Controllerkonfiguration hinzufügen. (Verwenden Sie für dieses Beispiel den Writer unter System.Diagnostics.)

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.

  2. Öffnen Sie WebApiConfig.cs im Ordner App_Start.

  3. Fügen Sie die folgende Zeile in die Methode Register ein:

    config.EnableSystemDiagnosticsTracing();
    

Erstellen des SharePoint-Webhook-Controllers

Jetzt erstellen Sie den Webhook-Empfänger-Controller, der die eingehenden Anforderungen von SharePoint bearbeiten und die entsprechenden Aktionen einleiten wird.

  1. Wechseln Sie in Visual Studio zum Projektmappen-Explorer.

  2. Öffnen Sie per Rechtsklick das Kontextmenü des Ordners Controllers, und wählen Sie Hinzufügen>Controller aus.

  3. Wählen Sie im Dialogfeld Gerüst hinzufügen die Option Web API 2-Controller – Leer aus.

  4. Klicken Sie auf Hinzufügen.

  5. Nennen Sie den Controller SPWebhookController, und wählen Sie Hinzufügen aus, um den API-Controller zu Ihrem Projekt hinzuzufügen.

  6. Ersetzen Sie die Anweisungen des Typs using durch den folgenden Code:

    using Newtonsoft.Json;
    using SPWebhooksReceiver.Models;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
    using System.Web.Http.Tracing;
    
  7. Ersetzen Sie den Code in der Klasse SPWebhookController durch den folgenden Code:

    [HttpPost]
    public HttpResponseMessage HandleRequest()
    {
        HttpResponseMessage httpResponse = new HttpResponseMessage(HttpStatusCode.BadRequest);
        var traceWriter = Configuration.Services.GetTraceWriter();
        string validationToken = string.Empty;
        IEnumerable<string> clientStateHeader = new List<string>();
        string webhookClientState = ConfigurationManager.AppSettings["webhookclientstate"].ToString();
    
        if (Request.Headers.TryGetValues("ClientState", out clientStateHeader))
        {
            string clientStateHeaderValue = clientStateHeader.FirstOrDefault() ?? string.Empty;
    
            if (!string.IsNullOrEmpty(clientStateHeaderValue) && clientStateHeaderValue.Equals(webhookClientState))
            {
                traceWriter.Trace(Request, "SPWebhooks",
                    TraceLevel.Info,
                    string.Format("Received client state: {0}", clientStateHeaderValue));
    
                var queryStringParams = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    
                if (queryStringParams.AllKeys.Contains("validationtoken"))
                {
                    httpResponse = new HttpResponseMessage(HttpStatusCode.OK);
                    validationToken = queryStringParams.GetValues("validationtoken")[0].ToString();
                    httpResponse.Content = new StringContent(validationToken);
    
                    traceWriter.Trace(Request, "SPWebhooks",
                        TraceLevel.Info,
                        string.Format("Received validation token: {0}", validationToken));
                    return httpResponse;
                }
                else
                {
                    var requestContent = Request.Content.ReadAsStringAsync().Result;
    
                    if (!string.IsNullOrEmpty(requestContent))
                    {
                        SPWebhookNotification notification = null;
    
                        try
                        {
                            var objNotification = JsonConvert.DeserializeObject<SPWebhookContent>(requestContent);
                            notification = objNotification.Value[0];
                        }
                        catch (JsonException ex)
                        {
                            traceWriter.Trace(Request, "SPWebhooks",
                                TraceLevel.Error,
                                string.Format("JSON deserialization error: {0}", ex.InnerException));
                            return httpResponse;
                        }
    
                        if (notification != null)
                        {
                            Task.Factory.StartNew(() =>
                            {
                                  //handle the notification here
                                  //you can send this to an Azure queue to be processed later
                                //for this sample, we just log to the trace
    
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("Resource: {0}", notification.Resource));
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("SubscriptionId: {0}", notification.SubscriptionId));
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("TenantId: {0}", notification.TenantId));
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("SiteUrl: {0}", notification.SiteUrl));
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("WebId: {0}", notification.WebId));
                                traceWriter.Trace(Request, "SPWebhook Notification",
                                    TraceLevel.Info, string.Format("ExpirationDateTime: {0}", notification.ExpirationDateTime));
    
                            });
    
                            httpResponse = new HttpResponseMessage(HttpStatusCode.OK);
                        }
                    }
                }
            }
            else
            {
                httpResponse = new HttpResponseMessage(HttpStatusCode.Forbidden);
            }
        }
    
        return httpResponse;
    }
    
  8. Speichern Sie die Datei.

Schritt 3: Debuggen des Webhook-Empfängers

  1. Wählen Sie F5 aus, um den Webhook-Empfänger zu debuggen.
  2. Kopieren Sie die Portnummer aus der Adressleiste, sobald sich der Browser öffnet. Beispiel: http://localhost:<_port-number_>

Schritt 4: Ausführen des ngrok-Proxys

  1. Öffnen Sie ein Konsolenterminal.

  2. Wechseln Sie zum extrahierten ngrok-Ordner.

  3. Geben Sie Folgendes mit der Portnummern-URL aus dem vorherigen Schritt ein, um ngrok zu starten:

    ./ngrok http port-number --host-header=localhost:port-number
    

    ngrok sollte jetzt ausgeführt werden.

  4. Kopieren Sie die HTTPS-Adresse unter Forwarding. Diese Adresse wird der Dienstproxy, an den SharePoint Anforderungen sendet.

Schritt 5: Hinzufügen eines Webhook-Abonnements mit Postman

Abrufen eines neuen Zugriffstokens

Postman macht die Arbeit mit APIs sehr einfach. Im ersten Schritt konfigurieren Sie Postman für die Azure AD-Authentifizierung, damit Sie API-Anforderungen an SharePoint senden können. Dazu verwenden Sie die Azure AD-App, die Sie in Schritt 1 registriert haben.

  1. Öffnen Sie Postman. Sie sehen die Sidebar und den Request Editor.

  2. Wählen Sie die Registerkarte Authorization im Request Editor aus.

  3. Wählen Sie OAuth 2.0 in der Liste Typ aus.

  4. Wählen Sie die Schaltfläche Get New Access Token aus.

  5. Geben Sie im Dialogfenster Folgendes ein:

    • Auth URL:
      • https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2F<_your-sharepoint-tenant-url-without-https_>
      • Ersetzen Sie your-sharepoint-tenant-url-without-https mit Ihrer Mandanten-URL ohne das Präfix Https.
    • Zugriffstoken-URL: https://login.microsoftonline.com/common/oauth2/token
    • Client-ID: Client-ID der App, die Sie zuvor in Schritt 1 registriert haben.
    • Geheimer Clientschlüssel: Geheimer Clientschlüssel der App, den Sie zuvor in Schritt 1 registriert haben.
    • Tokenname: sp_webhooks_token
    • Autorisierungstyp: Autorisierungscode
  6. Wählen Sie Request Token aus, um sich anzumelden, zuzustimmen und das Token für die Sitzung abzurufen.

  7. Wenn das Token erfolgreich abgerufen wurde, sollte access_token Variable angezeigt werden, die der Registerkarte Autorisierung hinzugefügt wurde.

  8. Wählen Sie die Option Add token to header aus.

  9. Doppelklicken Sie auf die variable access_token , um das Token dem Header für die Anforderung hinzuzufügen.

    Abrufen eines neuen Zugriffstokens von Postman

Abrufen der ID der Liste „Dokumente“

Sie müssen die Webhooks für die Standarddokumentbibliothek verwalten, die in Ihrer Standardwebsitesammlung unter dem Namen Dokumente bereitgestellt wird. Senden Sie zum Abrufen der ID dieser Liste eine GET-Anforderung:

  1. Geben Sie die folgende Anforderungs-URL ein:

    https://site-collection/_api/web/lists/getbytitle('Documents')?$select=Title,Id
    
  2. Tragen Sie für site-collection Ihre Websitesammlung ein.

    Postman führt nun Ihre Anforderung aus. Ist die Ausführung erfolgreich, wird das Ergebnis angezeigt.

  3. Kopieren Sie aus den Ergebnissen den Wert für Id. Den Wert Id verwenden Sie später zur Erstellung von Webhook-Anforderungen.

Hinzufügen eines Webhook-Abonnements

Da Sie nun alle erforderlichen Informationen haben, können Sie die Abfrage und die Anforderung zum Hinzufügen eines Webhook-Abonnements erstellen. Führen Sie im Request Editor die folgenden Schritte durch:

  1. Ändern Sie die Anforderung in POST statt GET.

  2. Geben Sie die folgende Anforderungs-URL ein:

    https://site-collection/_api/web/lists('list-id')/subscriptions
    
  3. Tragen Sie für site-collection Ihre Websitesammlung ein.

  4. Wechseln Sie zur Registerkarte Headers.

  5. Vergewissern Sie sich, dass der Authorization-Header übernommen wurde. Ist das nicht der Fall, müssen Sie ein neues Zugriffstoken anfordern.

  6. Fügen Sie die folgenden Paare des Typs key>value für den Header hinzu:

    • Akzeptieren:application/json;odata=nometadata
    • Inhaltstyp: application/json
  7. Wechseln Sie zur Registerkarte Body, und wählen Sie als Format raw aus.

  8. Fügen Sie den folgenden JSON-Text als Body ein:

    {
      "resource": "https://site-collection/_api/web/lists('list-id')",
      "notificationUrl": "https://ngrok-forwarding-address/api/spwebhook/handlerequest",
      "expirationDateTime": "2016-10-27T16:17:57+00:00",
      "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449"
    }
    

    Hinzufügen eines Webhook-Bodys in Postman

  9. Stellen Sie sicher, dass der Wert expirationDateTime höchstens 6 Monate in der Zukunft liegt, gerechnet vom aktuellen Datum.

  10. Stellen Sie sicher, dass Sie den Webhook-Empfänger wie in Schritt 4 beschrieben debuggen.

  11. Wählen Sie Send aus, um die Anforderung auszuführen.

    Kann die Anforderung ausgeführt werden, sollten Sie eine Antwort von SharePoint mit den Abonnementdetails sehen. Hier ein Beispiel einer Antwort für ein neu erstelltes Abonnement:

    {
      "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449",
      "expirationDateTime": "2016-10-27T16:17:57Z",
      "id": "32b95d9-4d20-4a17-bfa3-2957cb38ead8",
      "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest",
      "resource": "c34420f9-2ad7-4e54-94c9-b67798d2299b"
    }
    
  12. Kopieren Sie den Wert id des Abonnements. Sie benötigen ihn für die nächsten Anforderungen.

  13. Wechseln Sie zum Webhook-Empfängerprojekt in Visual Studio, und überprüfen Sie das Fenster Ausgabe . Die Ablaufverfolgungsprotokolle, die der folgenden Ablaufverfolgung ähneln, sollten zusammen mit anderen Meldungen angezeigt werden:

    iisexpress.exe Information: 0 : Message='Received client state: A0A354EC-97D4-4D83-9DDB-144077ADB449'
    iisexpress.exe Information: 0 : Message='Received validation token: daf2803c-43cf-44c7-8dff-7066eaa40f13'
    

    Die Ablaufverfolgung meldet, dass der anfänglich empfangene Webhook eine Prüfungsanforderung empfangen hat. Sie sehen im Code, dass das Prüfungstoken sofort zurückgegeben wird, so dass SharePoint die Anforderungen überprüfen kann:

    if (queryStringParams.AllKeys.Contains("validationtoken"))
    {
      httpResponse = new HttpResponseMessage(HttpStatusCode.OK);
      validationToken = queryStringParams.GetValues("validationtoken")[0].ToString();
      httpResponse.Content = new StringContent(validationToken);
    
      traceWriter.Trace(Request, "SPWebhooks",
        TraceLevel.Info,
        string.Format("Received validation token: {0}", validationToken));
      return httpResponse;
    }
    

Schritt 6: Abrufen der Abonnementdetails

Jetzt führen Sie Abfragen in Postman aus, um die Abonnementdetails abzurufen.

  1. Öffnen Sie den Postman-Client.

  2. Ändern Sie die Anforderung in GET statt POST.

  3. Geben Sie Folgendes als Anforderung ein:

    https://site-collection/_api/web/lists('list-id')/subscriptions
    
  4. Tragen Sie für site-collection Ihre Websitesammlung ein.

  5. Wählen Sie Send aus, um die Anforderung auszuführen.

    Kann die Anforderung ausgeführt werden, gibt SharePoint die Abonnements für diese Listenressource zurück. Da Sie gerade eins hinzugefügt haben, sollte mindestens ein Abonnement zurückgegeben werden. Hier ein Beispiel für eine Antwort mit einem Abonnement:

    {
      "value": [
        {
          "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449",
          "expirationDateTime": "2016-10-27T16:17:57Z",
          "id": "32b95add-4d20-4a17-bfa3-2957cb38ead8",
          "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest",
          "resource": "c34420f9-2a67-4e54-94c9-b67798229f9b"
        }
      ]
    }
    
  6. Rufen Sie die Details dieses Abonnements mit der folgenden Abfrage ab:

    https://site-collection/_api/web/lists('list-id')/subscriptions('subscription-id')
    
  7. Ersetzen Sie subscription-id durch Ihre Abonnement-ID.

Schritt 7: Testen der Webhook-Benachrichtigungen

Nun fügen Sie eine Datei zur Bibliothek „Dokumente“ hinzu und testen, ob Sie im Webhook-Empfänger eine Benachrichtigung von SharePoint erhalten.

  1. Wechseln Sie zu Visual Studio.

  2. Platzieren Sie im SPWebhookController einen Breakpoint in der folgenden Codezeile:

    var requestContent = Request.Content.ReadAsStringAsync().Result;
    
  3. Gehen Sie zur Bibliothek Dokumente. In Ihrer Standardwebsitesammlung ist dies die Bibliothek Freigegebene Dokumente.

  4. Fügen Sie eine neue Datei hinzu.

  5. Gehen Sie zu Visual Studio, und warten Sie, bis der Breakpoint erreicht wird.

    Die Wartezeit kann zwischen einigen Sekunden und 5 Minuten betragen. In dem Moment, in dem der Breakpoint erreicht ist, hat der Webhook-Empfänger eine Benachrichtigung von SharePoint erhalten.

  6. Wählen Sie F5 aus, um fortzufahren.

  7. Die Benachrichtigungsdaten finden Sie im Fenster Ausgabe in den folgenden Einträgen, da Sie sie zum Ablaufprotokoll hinzugefügt haben:

    iisexpress.exe Information: 0 : Message='Resource: c34420f9-2a67-4e54-94c9-b6770892299b'
    iisexpress.exe Information: 0 : Message='SubscriptionId: 32b95ad9-4d20-4a17-bfa3-2957cb38ead8'
    iisexpress.exe Information: 0 : Message='TenantId: 7a17cb7d-6898-423f-8839-45f363076f06'
    iisexpress.exe Information: 0 : Message='SiteUrl: /'
    iisexpress.exe Information: 0 : Message='WebId: 62b80e0b-f889-4974-a519-cc138413be40'
    iisexpress.exe Information: 0 : Message='ExpirationDateTime: 2016-10-27T16:17:57.0000000Z'
    

Dieses Projekt schreibt die Informationen nur ins Ablaufprotokoll. Im Empfänger werden die Informationen jedoch an eine Tabelle oder eine Warteschlange gesendet, die die empfangenen Daten verarbeiten und die von SharePoint gesendeten Informationen auswerten kann.

Mit diesen Daten können Sie die URL erstellen und über die GetChanges-API die neuesten Änderungen abrufen.

Nächste Schritte

In diesem Artikel haben Sie mithilfe des Postman-Clients und einer einfachen Web-API Webhook-Benachrichtigungen von SharePoint abonniert und empfangen.

Sehen Sie sich als nächstes die Beispielreferenzimplementierung für SharePoint-Webhooks an. Sie gibt ein End-to-End-Beispiel, das Azure-Speicherwarteschlangen verwendet, um die Informationen zu verarbeiten, Änderungen von SharePoint abzurufen und diese Änderungen an eine SharePoint-Liste zurückzusenden.