Condividi tramite


Creare una sottoscrizione dell'hook del servizio in modo programmatico

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Usando le API REST delle sottoscrizioni , è possibile creare a livello di codice una sottoscrizione che esegue un'azione su un servizio esterno/consumer quando si verifica un evento specifico in un progetto Azure DevOps. Ad esempio, è possibile creare una sottoscrizione per notificare al servizio quando una compilazione ha esito negativo.

Eventi supportati:

  • Compilazione completata
  • Push del codice (per i progetti Git)
  • Creazione o aggiornamento della richiesta pull (per i progetti Git)
  • Codice archiviato (progetti Controllo della versione di Team Foundation)
  • Elemento di lavoro creato, aggiornato, eliminato, ripristinato o commentato

È possibile configurare i filtri nelle sottoscrizioni per controllare gli eventi che attivano un'azione. Ad esempio, è possibile filtrare un evento di compilazione completato in base allo stato di compilazione. Per un set completo di eventi e opzioni di filtro supportate, vedere Riferimento all'evento.

Per un set completo di servizi e azioni consumer supportati, vedere Riferimento al consumer.

Prerequisiti

Per creare una sottoscrizione, sono necessari i dati seguenti:

  • ID progetto. Usare l'API REST del progetto per ottenere l'ID progetto.
  • ID evento e impostazioni. Vedere riferimento all'evento.
  • ID e impostazioni di consumer e azione. Vedere le informazioni di riferimento sul consumer.

Creare la richiesta

Costruire il corpo della richiesta HTTP POST per creare la sottoscrizione in base all'ID progetto, all'evento, al consumer e all'azione.

Vedere la richiesta di esempio seguente per la creazione di una sottoscrizione che causa un evento di compilazione su POST quando https://myservice/event la compilazione WebSite.CI ha esito negativo.

Richiedi

{
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "projectId": "56479caf-1eeb-4bca-86ab-aaa6f29399d9",
    },
    "consumerInputs": {
        "url": " https://myservice/event"
    },
}

È consigliabile usare URL HTTPS sicuri per la sicurezza dei dati privati nell'oggetto JSON.

Risposta Vedere la risposta seguente alla richiesta di creazione della sottoscrizione:

{
    "id": "74aeeed0-bf5d-48dc-893f-f862b80987e9",
    "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/hooks/subscriptions/74aeeed0-bf5d-48dc-893f-f862b80987e9",
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "createdBy": {
        "id": "00ca946b-2fe9-4f2a-ae2f-40d5c48001bc"
    },
    "createdDate": "2014-03-28T16:10:06.523Z",
    "modifiedBy": {
        "id": "1c4978ae-7cc9-4efa-8649-5547304a8438"
    },
    "modifiedDate": "2014-04-25T18:15:26.053Z",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "hostId": "17f27955-99bb-4861-9550-f2c669d64fc9",
        "projectId": "56479caf-1eeb-4bca-86ab-aaa6f29399d9",
        "tfsSubscriptionId": "29cde8b4-f37e-4ef9-a6d4-d57d526d82cc"
    },
    "consumerInputs": {
        "url": "http://myservice/event"
    }
}

Se la richiesta di sottoscrizione non riesce, viene visualizzato un codice di risposta HTTP pari a 400 con un messaggio con altri dettagli.

Cosa accade quando si verifica l'evento?

Quando si verifica un evento, vengono valutate tutte le sottoscrizioni abilitate nel progetto e l'azione consumer viene eseguita per tutte le sottoscrizioni corrispondenti.

Versioni delle risorse (avanzate)

Il controllo delle versioni delle risorse è applicabile quando un'API è in anteprima. Per la maggior parte degli scenari, specificare 1.0 come versione della risorsa è la route più sicura.

Il payload dell'evento inviato a determinati consumer, ad esempio webhook, bus di servizio di Azure e Archiviazione di Azure, include una rappresentazione JSON della risorsa oggetto (ad esempio, una compilazione o un elemento di lavoro). La rappresentazione di questa risorsa può avere forme o versioni diverse.

È possibile specificare la versione della risorsa che si vuole inviare al servizio consumer tramite il resourceVersion campo nella sottoscrizione. La versione della risorsa corrisponde alla versione dell'API. Se non si specifica una versione della risorsa, significa "ultima versione rilasciata". È consigliabile specificare sempre una versione della risorsa, che garantisce un payload di eventi coerente nel tempo.

Domande frequenti

D: Sono disponibili servizi che è possibile sottoscrivere manualmente?

R: Sì. Per altre informazioni sui servizi a cui è possibile effettuare la sottoscrizione dalla pagina di amministrazione di un progetto, vedere Panoramica.

D: Sono disponibili librerie C# che è possibile usare per creare sottoscrizioni?

R: No, ma ecco un esempio per iniziare.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Mvc;

namespace Microsoft.Samples.VisualStudioOnline
{
    public class ServiceHookEventController : Controller
    {

        // POST: /ServiceHookEvent/workitemcreated
        [HttpPost]
        public HttpResponseMessage WorkItemCreated(Content workItemEvent)
        {
            //Grabbing the title for the new workitem
            var value = RetrieveFieldValue("System.field", workItemEvent.Resource.Fields);

            //Acknowledge event receipt
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Gets the value for a specified work item field.
        /// </summary>
        /// <param name="key">Key used to retrieve matching value</param>
        /// <param name="fields">List of fields for a work item</param>
        /// <returns></returns>
        public String RetrieveFieldValue(String key, IList<FieldInfo> fields)
        {
            if (String.IsNullOrEmpty(key))
                return String.Empty;

            var result = fields.Single(s => s.Field.RefName == key);

            return result.Value;
        }

	}

    public class Content
    {
        public String SubscriptionId { get; set; }

        public int NotificationId { get; set; }

        public String EventType { get; set; }

        public WorkItemResource Resource { get; set; }

    }

    public class WorkItemResource
    {
        public String UpdatesUrl { get; set; }

        public IList<FieldInfo> Fields { get; set;}

        public int Id { get; set; }

        public int Rev { get; set; }

        public String Url { get; set; }

        public String WebUrl { get; set; }
    }

    public class FieldInfo
    {
        public FieldDetailedInfo Field { get; set; }

        public String Value { get; set; }

    }

    public class FieldDetailedInfo
    {
        public int Id { get; set; }

        public String Name { get; set; }

        public String RefName { get; set; }
    }
}