Delen via


Programmatisch een servicehookabonnement maken

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

U kunt een abonnement gebruiken om een actie uit te voeren op een externe of consumentenservice wanneer een specifieke gebeurtenis plaatsvindt in een Azure DevOps-project. Een abonnement kan bijvoorbeeld uw service waarschuwen wanneer een build mislukt.

Als u programmatisch een abonnement wilt maken, kunt u de REST API's van Abonnementen gebruiken. Dit artikel bevat een voorbeeldaanvraag en voorbeeldcode voor het maken van een abonnement.

Voorwaarden

Categorie Eisen
projecttoegang het projectlid.
Gegevens - Project-id. Gebruik de Project REST API om de project-id op te halen.
- Gebeurtenis-id en -instellingen. Zie Servicehookgebeurtenissen.
- Consumenten- en actie-id's en -instellingen. Zie Service hook consumers.

Ondersteunde gebeurtenissen

Azure DevOps biedt ondersteuning voor tal van trigger-gebeurtenissen. Voorbeelden hiervan zijn de volgende gebeurtenissen:

  • Build voltooid
  • Code geplaatst (voor Git-projecten)
  • Pull-aanvraag gemaakt of bijgewerkt (voor Git-projecten)
  • Code ingecheckt (voor Team Foundation Version Control-projecten)
  • Werkitem gemaakt, bijgewerkt, verwijderd, hersteld of van een opmerking voorzien

Als u wilt bepalen welke gebeurtenissen een actie activeren, kunt u filters voor uw abonnementen configureren. U kunt bijvoorbeeld de voltooide build-gebeurtenis filteren op basis van de buildstatus.

Een aanvraag maken

Wanneer u een abonnement maakt, gebruikt u de hoofdtekst van een HTTP POST-aanvraag om de project-id, gebeurtenis, consument, actie en gerelateerde instellingen op te geven.

U kunt de volgende aanvraag gebruiken om een abonnement te maken voor een voltooide build-gebeurtenis. In dit voorbeeld, wanneer de WebSite.CI build mislukt, verzendt het abonnement een POST-aanvraag naar https://myservice/event.

aanvraag

{
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "projectId": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff",
    },
    "consumerInputs": {
        "url": " https://myservice/event"
    },
}

We raden u ten zeerste aan beveiligde HTTPS-URL's te gebruiken voor de beveiliging van de persoonlijke gegevens in het JSON-object.

Antwoord

De aanvraag voor het maken van het abonnement genereert een antwoord dat vergelijkbaar is met de volgende:

{
    "id": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
    "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/hooks/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "createdBy": {
        "id": "22cc22cc-dd33-ee44-ff55-66aa66aa66aa"
    },
    "createdDate": "2014-03-28T16:10:06.523Z",
    "modifiedBy": {
        "id": "22cc22cc-dd33-ee44-ff55-66aa66aa66aa"
    },
    "modifiedDate": "2014-04-25T18:15:26.053Z",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "hostId": "d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4",
        "projectId": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff",
        "tfsSubscriptionId": "ffff5f5f-aa6a-bb7b-cc8c-dddddd9d9d9d"
    },
    "consumerInputs": {
        "url": "http://myservice/event"
    }
}

Als de abonnementsaanvraag mislukt, krijgt u een HTTP-antwoordcode van 400 met een bericht met meer informatie.

Wat gebeurt er wanneer de gebeurtenis plaatsvindt?

Wanneer er een gebeurtenis plaatsvindt, worden alle ingeschakelde abonnementen in het project geƫvalueerd. Vervolgens wordt de consumentenactie uitgevoerd voor alle overeenkomende abonnementen.

Resourceversies (geavanceerd)

Versiebeheer van resources is van toepassing wanneer een API in preview is. Voor de meeste scenario's geeft u 1.0 op omdat de resourceversie de veiligste route is.

De nettolading van de gebeurtenis die naar bepaalde consumenten wordt verzonden, bevat een JSON-weergave van een onderwerpresource. De payload die wordt verzonden naar webhooks, Azure Service Bus en Azure Storage omvat bijvoorbeeld informatie over een build of werkitem. De weergave van deze resource kan verschillende formulieren of versies hebben.

U kunt de versie opgeven van de resource die u naar de consumentenservice wilt verzenden via het resourceVersion veld in het abonnement.

De resource-versie is hetzelfde als de API-versie. Als u geen resourceversie opgeeft, wordt de meest recente versie gebruikt latest released. Geef altijd een ressourceversie op om ervoor te zorgen dat de gegevenslading van een gebeurtenis in de loop van de tijd consistent blijft.

Veelgestelde vragen

V: Zijn er services waarop ik me handmatig kan abonneren?

A: Ja. Zie Integreren met servicehook voor meer informatie over de services waarop u zich kunt abonneren vanaf een projectbeheerpagina.

V: Zijn er C#-bibliotheken die ik kan gebruiken om abonnementen te maken?

A: Nee, maar hier volgt een voorbeeld om u te helpen aan de slag te gaan. Voor verificatie bij Azure DevOps gebruikt de volgende code een persoonlijk toegangstoken (PAT) dat is opgeslagen in Azure Key Vault. Gebruik in een productieomgeving een veiligere verificatiemethode. Zie Het juiste verificatiemechanisme kiezen voor meer informatie.

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.ServiceHooks.WebApi;
using Microsoft.VisualStudio.Services.WebApi;

namespace CreateServiceHookSubscription
{
    internal class Program
    {
        // Create a service hook subscription to send a message to an Azure Service Bus queue when code is pushed to a Git repository.

        static async Task Main(string[] args)
        {
            // Get the secrets from the key vault.
            string keyVaultURI = "https://<key-vault-name>.vault.azure.net/";
            var secretClient = new SecretClient(new Uri(keyVaultURI), new DefaultAzureCredential());
            string personalAccessTokenSecretName = "<personal-access-token-secret-name>";
            string serviceBusConnectionStringSecretName = "<Service-Bus-connection-string-secret-name>";
            KeyVaultSecret personalAccessTokenSecret = await secretClient.GetSecretAsync(personalAccessTokenSecretName);
            KeyVaultSecret serviceBusConnectionStringSecret = await secretClient.GetSecretAsync(serviceBusConnectionStringSecretName);

            // Set up the connection parameters for Azure DevOps.
            var azureDevOpsOrganizationURL = new Uri("https://dev.azure.com/<Azure-DevOps-organization-name>/");
            string azureDevOpsTeamProjectID = "<Azure-DevOps-team-project-ID>";
            string azureDevOpsPersonalAccessToken = personalAccessTokenSecret.Value;

            // Set up the event parameters.
            string eventPublisherID = "tfs";
            string eventID = "git.push";
            string eventDescription = "Any stage in any release";
            string resourceVersion = "1.0";

            // Set up the consumer parameters.
            string consumerID = "azureServiceBus";
            string consumerActionID = "serviceBusQueueSend";
            string serviceBusNamespace = "<Service-Bus-namespace>";
            string serviceBusQueueName = "<Service-Bus-queue-name>";
            string consumerActionDescription = $"Send a message to the Service Bus {serviceBusQueueName} queue in the {serviceBusNamespace} namespace.";
            string serviceBusConnectionString = serviceBusConnectionStringSecret.Value;

            // Configure the subscription.
            var subscription = new Subscription()
            {
                PublisherId = eventPublisherID,
                PublisherInputs = new Dictionary<string, string>
                {
                    ["projectId"] = azureDevOpsTeamProjectID
                },
                EventType = eventID,
                EventDescription = eventDescription,
                ResourceVersion = resourceVersion,
                ActionDescription = consumerActionDescription,
                ConsumerActionId = consumerActionID,
                ConsumerId = consumerID,
                ConsumerInputs = new Dictionary<string, string>
                {
                    ["connectionString"] = serviceBusConnectionString,
                    ["queueName"] = serviceBusQueueName
                }
            };

            // Connect to the Azure DevOps organization and get a service hook client.
            var azureDevOpsCredentials = new VssBasicCredential(azureDevOpsPersonalAccessToken, string.Empty);
            var azureDevOpsConnection = new VssConnection(azureDevOpsOrganizationURL, azureDevOpsCredentials);
            var serviceHookClient = azureDevOpsConnection.GetClient<ServiceHooksPublisherHttpClient>();

            // Create the subscription.
            var createdSubscription = await serviceHookClient.CreateSubscriptionAsync(subscription);
            Console.WriteLine($"A subscription was created that has ID {createdSubscription.Id}.");
        }
    }
}