Introdução a webhooks do SharePoint

Este artigo descreve como criar um aplicativo que adiciona e gerencia solicitações de webhook do SharePoint. Você aprenderá a usar o cliente Postman para criar e executar solicitações de webhook do SharePoint rapidamente durante a interação com uma API Web do ASP.NET simples como destinatário de webhook.

Você usará solicitações HTTP simples, o que é útil para entender como os webhooks funcionam.

Para concluir as instruções passo a passo deste artigo, baixe e instale as seguintes ferramentas:

Etapa 1: registrar um aplicativo do Azure AD para o cliente Postman

Para que o cliente Postman se comunique com o SharePoint, você precisa registrar um aplicativo do Microsoft Azure Active Directory (Azure AD) no locatário do Azure AD associado ao locatário do Office 365.

  1. Registre o aplicativo como um Aplicativo Web.

  2. Para acessar o SharePoint Online, é importante conceder permissões de aplicativo Azure AD ao aplicativo do Office 365 SharePoint Online e selecionar a permissão ler e gravar listas e itens em todos os conjuntos de sites.

    Observação

    Confira mais informações sobre como adicionar um aplicativo do Azure AD e conceder permissões a aplicativos em Adicionar um aplicativo.

  3. Insira o seguinte ponto de extremidade como a URL de Resposta (Redirecionar) para o aplicativo. Esse é o ponto de extremidade para o qual o Azure AD enviará a resposta de autenticação, inclusive o token de acesso, se a autenticação for bem-sucedida.

    https://www.getpostman.com/oauth2/callback
    
  4. Gere uma Chave, que será o segredo do cliente.

  5. Copie as seguintes propriedades em um local seguro porque elas serão necessárias nas etapas posteriores:

    • ID do cliente
    • Segredo de Cliente

Etapa 2: Criar um receptor de webhook

Para este projeto, use o projeto de API Web do Visual Studio para criar o receptor de webhook.

Criar um novo projeto de API Web do ASP.NET

  1. Abra o Visual Studio.
  2. Selecione Arquivo>Novo>Projeto.
  3. No painel Modelos, selecione Modelos Instalados e expanda o nó Visual C#.
  4. Em Visual C#, selecione Web.
  5. Na lista de modelos de projeto, selecione Aplicativo Web ASP.NET.
  6. Nomeie o projeto como SPWebhooksReceiver e selecione OK.
  7. Na caixa de diálogo Novo Projeto ASP.NET, selecione o modelo API Web do grupo ASP.NET 4.5..
  8. Altere a autenticação para Sem Autenticação selecionando o botão Alterar Autenticação.
  9. Selecione OK para criar o projeto de API Web.

Observação

Você pode desmarcar a caixa de seleção Hospedar na nuvem, pois esse projeto não será implantado na nuvem.

O Visual Studio cria seu projeto.

Criar o receptor de webhook

Instalar pacotes NuGet

Use o Rastreamento de API Web ASP.NET para registrar as solicitações que vêm do SharePoint. As seguintes etapas instalam o pacote de rastreamento:

  1. Vá para o Gerenciador de Soluções no Visual Studio.
  2. Abra o menu de contexto (clique com o botão direito do mouse) do projeto e selecione Gerenciar Pacotes do NuGet.
  3. Na caixa de pesquisa, insira Microsoft.AspNet.WebApi.Tracing.
  4. Nos resultados da pesquisa, selecione o pacote Microsoft.AspNet.WebApi.Tracing e selecione Instalar para instalar o pacote.

Criar um modelo de SPWebhookNotification

Cada notificação gerada pelo serviço é serializada em uma instância de webhookNotification. Você precisa criar um modelo simples que representa essa instância de notificação.

  1. Vá para o Gerenciador de Soluções no Visual Studio.

  2. Abra o menu de contexto (clique com o botão direito do mouse) da pasta Modelos e selecione Adicionar>Classe.

  3. Insira SPWebhookNotification como o nome da classe e selecione Adicionar para adicionar a classe ao projeto.

  4. Adicione o seguinte código ao corpo da classe SPWebhookNotification:

    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; }
    

Criar um modelo de SPWebhookContent

Como várias notificações podem ser enviadas ao receptor de webhook em uma única solicitação, são combinadas em um objeto com um valor de matriz único. Crie um modelo simples que representa a matriz.

  1. Vá para o Gerenciador de Soluções no Visual Studio.

  2. Abra o menu de contexto (clique com o botão direito do mouse) da pasta Modelos e selecione Adicionar>Classe.

  3. Insira SPWebhookContent como o nome da classe e selecione Adicionar para adicionar a classe ao projeto.

  4. Adicione o seguinte código ao corpo da classe SPWebhookContent:

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

Adicionar um estado do cliente de webhook do SharePoint

Os webhooks fornecem a capacidade de usar um valor de cadeia de caracteres opcional que é passado novamente na mensagem de notificação para sua assinatura. Isso pode ser usado para confirmar que a solicitação realmente vem da fonte de confiável, que, nesse caso, é o SharePoint.

Adicione um valor de estado do cliente com o qual o aplicativo pode verificar as solicitações de entrada.

  1. Vá para o Gerenciador de Soluções no Visual Studio.

  2. Abra o arquivo Web.config e adicione a seguinte chave como o estado do cliente para a seção <appSettings>:

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

Habilitar o rastreamento

No arquivo Web.config, habilite o rastreamento, adicionando a seguinte chave no elemento <system.web> na seção <configuration>:

<trace enabled="true"/>

Um gravador de rastreamento é necessário. Portanto, você deve adicionar um gravador de rastreamento à configuração do controlador (nesse caso, use o de System.Diagnostics).

  1. Vá para o Gerenciador de Soluções no Visual Studio.

  2. Abra WebApiConfig.cs na pasta App_Start.

  3. Adicione a seguinte linha no método Registrar:

    config.EnableSystemDiagnosticsTracing();
    

Criar um controlador de webhook do SharePoint

Agora, crie o controlador de receptor de webhook que lida com as solicitações de entrada do SharePoint e executa a ação adequada.

  1. Vá para o Gerenciador de Soluções no Visual Studio.

  2. Abra o menu de contexto (clique com o botão direito do mouse) para a pasta Controladores e selecione Adicionar>Controlador.

  3. Na caixa de diálogo Adicionar Scaffold, selecione Controlador de API Web 2 - Vazio.

  4. Selecione Adicionar.

  5. Nomeie o controlador SPWebhookController e selecione Adicionar para adicionar o controlador de API ao projeto.

  6. Substitua as instruções using pelo seguinte código:

    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. Substitua o código na classe SPWebhookController pelo seguinte código:

    [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. Salve o arquivo.

Etapa 3: Depurar o receptor de webhook

  1. Selecione F5 para depurar o receptor de webhook.
  2. Depois de abrir o navegador, copie o número da porta da barra de endereços. Por exemplo: http://localhost:<_port-number_>

Etapa 4: Executar proxy ngrok

  1. Abra um terminal de console.

  2. Vá para a pasta do ngrok extraída.

  3. Insira o seguinte com a URL do número da porta da etapa anterior para iniciar ngrok:

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

    Você deve ver o ngrok em execução.

  4. Copie o endereço HTTPS de Encaminhamento. Você usará esse endereço como o proxy de serviço para que o SharePoint envie solicitações.

Etapa 5: Adicionar assinatura de webhook usando o Postman

Obter novo token de acesso

O Postman facilita muito o trabalho com APIs. A primeira etapa é configurar o Postman para se autenticar com o Azure AD para que você possa enviar solicitações de API ao SharePoint. Você usará o aplicativo do Azure AD que registrou na Etapa 1.

  1. Abra o Postman. Você verá uma Barra lateral e um Editor de Solicitação.

  2. Selecione a guia Autorização no Editor de Solicitação.

  3. Selecione OAuth 2.0 na lista Tipo.

  4. Selecione o botão Obter Novo Token de Acesso.

  5. Na janela de diálogo, insira o seguinte:

    • URL de autenticação:
      • https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2F<_your-sharepoint-tenant-url-without-https_>
      • Substitua your-sharepoint-tenant-url-without-https pela URL do seu locatário sem o prefixo https.
    • URL do Token de Acesso: https://login.microsoftonline.com/common/oauth2/token
    • Id do Cliente: Id do Cliente do aplicativo que você registrou anteriormente na Etapa um.
    • Segredo do Cliente: Segredo do Cliente do aplicativo que você registrou anteriormente na Etapa um.
    • Nome do token: sp_webhooks_token
    • Tipo de Concessão: código de autorização
  6. Selecione o Token de Solicitação para entrar, consentir e obter o token para a sessão.

  7. Quando o token for recuperado com êxito, você deverá ver access_token variável adicionada à guia Autorização .

  8. Seleciona a opção Adicionar token ao cabeçalho.

  9. Clique duas vezes na variável access_token para adicionar o token ao cabeçalho da solicitação.

    O Postman obterá um novo token de acesso

Obter Id de lista de Documentos

É necessário gerenciar webhooks para a biblioteca de documentos padrão, que é provisionada no conjunto de sites padrão sob o nome Documentos. Obtenha a Id dessa lista emitindo uma solicitação GET:

  1. Insira a seguinte URL de solicitação:

    https://site-collection/_api/web/lists/getbytitle('Documents')?$select=Title,Id
    
  2. Substitua site-collection por seu conjunto de sites.

    O Postman executa a solicitação e, se ela tiver êxito, você deverá ver o resultado.

  3. Copie a Id dos resultados. Mais tarde, você usará a Id para fazer solicitações de webhook.

Adicionar assinatura de webhook

Agora que você tem as informações necessárias, crie a consulta e a solicitação para adicionar uma assinatura de webhook. Use o editor de solicitação para as seguintes etapas:

  1. Altere a solicitação para POST de GET.

  2. Insira o seguinte como a URL de solicitação:

    https://site-collection/_api/web/lists('list-id')/subscriptions
    
  3. Substitua site-collection por seu conjunto de sites.

  4. Vá para a guia Cabeçalhos.

  5. Verifique se você ainda tem o cabeçalho de Autorização. Caso contrário, será necessário solicitar um novo token de acesso.

  6. Adicione os seguintes pares de cabeçalho chave>valor:

    • Aceitar: application/json;odata=nometadata
    • Tipo de conteúdo: application/json
  7. Vá para a guia Corpo e selecione o formato bruto.

  8. Cole o seguinte JSON como o corpo:

    {
      "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"
    }
    

    postman add webhook body

  9. Verifique se expirationDateTime é de, no máximo, seis meses a contar de hoje.

  10. Verifique se está depurando o receptor de webhook como na Etapa 4.

  11. Selecione Enviar para executar a solicitação.

    Se a solicitação for bem-sucedida, você deverá ver a resposta do SharePoint que fornece os detalhes da assinatura. O seguinte exemplo mostra uma resposta para uma assinatura recém-criada:

    {
      "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. Copie a id de assinatura. Você precisará dela para o próximo conjunto de solicitações.

  13. Vá para o projeto de receptor de webhook no Visual Studio e examine a janela Saída. Você deve ver logs de rastreamento semelhantes ao seguinte rastreamento, juntamente com outras mensagens:

    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'
    

    O rastreamento indica que o webhook recebeu inicialmente uma solicitação de validação. Se examinar o código, você verá que ele retorna o token de validação imediatamente, para que o SharePoint possa validar a solicitação:

    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;
    }
    

Etapa 6: Editar detalhes da assinatura

Agora, você executará consultas no Postman para obter os detalhes da assinatura.

  1. Abra o cliente Postman.

  2. Altere a solicitação para GET de POST.

  3. Insira o seguinte como a solicitação:

    https://site-collection/_api/web/lists('list-id')/subscriptions
    
  4. Substitua site-collection por seu conjunto de sites.

  5. Selecione Enviar para executar a solicitação.

    Se ela tiver êxito, o SharePoint deverá retornar as assinaturas para esse recurso de lista. Como acabamos de adicionar um, pelo menos uma assinatura deverá ser retornada. O exemplo a seguir mostra uma resposta com uma assinatura:

    {
      "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. Execute a seguinte consulta para obter detalhes da assinatura específica:

    https://site-collection/_api/web/lists('list-id')/subscriptions('subscription-id')
    
  7. Substitua subscription-id por sua id da assinatura.

Etapa 7: Notificação de webhook de teste

Agora, adicione um arquivo à biblioteca de documentos e teste se você receberá uma notificação do SharePoint no receptor de webhook.

  1. Vá para o Visual Studio.

  2. Em SPWebhookController, coloque um ponto de interrupção na seguinte linha de código:

    var requestContent = Request.Content.ReadAsStringAsync().Result;
    
  3. Vá para a biblioteca Documentos. Ela será nomeada como a biblioteca Documentos Compartilhados no conjunto de sites padrão.

  4. Adicione um novo arquivo.

  5. Vá para o Visual Studio e espere até que o ponto de interrupção seja atingido.

    O tempo de espera pode variar de alguns segundos até cinco minutos. Quando o ponto de interrupção é alcançado, o receptor de webhook acabou de receber uma notificação do SharePoint.

  6. Selecione F5 para continuar.

  7. Para ver os dados de notificação, examine a janela Saída das seguintes entradas, pois você adicionou os dados de notificação no log de rastreamento:

    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'
    

Esse projeto apenas grava as informações no log de rastreamento. No entanto, no receptor, você envia essas informações a uma tabela ou uma fila que pode processar os dados recebidos para obter informações do SharePoint.

Com esses dados, você pode criar a URL e usar a API GetChanges para obter as alterações mais recentes.

Próximas etapas

Neste artigo, você usou o cliente Postman e uma API Web simples para assinar e receber notificações de webhook do SharePoint.

Em seguida, confira Implementação de referência de exemplo de webhooks do SharePoint, que mostra um exemplo de ponta a ponta que usa Filas de Armazenamento do Azure para processar as informações, obter alterações do SharePoint e enviar as alterações de volta para uma lista do SharePoint.