Listening to Webhooks using PowerShell

Recently I’ve listened to a genuinely nice and interesting session at Directions EMEA concerning usage of webhooks in Azure Devops. The idea of Kamil Sacek was to create e.g., a docker container with a certain Business Central version for local development. If the developer is creating a new workitem and adding a new branch to it, a DevOps webhook should be fired containing some specific information (customer’s Business Central version, OnPrem or SaaS, …).

To this point this is no problem at all. We might send this webhook to a requestbin and see the events content. But how could we use this on a simple and effortless way in your local environment? Sure, you could also use some Azure Functions or Node.JS Scripts to capture and process or store the data… but what about a simple PowerShell script listening directly to server-sent events?

Server-Sent Events are some kind of stream that you could listen to. As requestbin respectively pipedream supports this kind of SSE, I tried it and searched a bit.

The result is a quick and dirty little PowerShell script which is listening to webhooks and the event stream and lets you react to it, e.g., create the mentioned docker container using the information in the webhook’s payload.

#####################################
# Listening to Webhooks in PowerShell
#####################################
function StartListener() {
    #Your requestbin's id and api_key
    $id = "dc_6Rxxxxx"
    $api_key = "607b2415f31e17f09156axxxxxxxxxx"
    $url = "https://api.pipedream.com/sources/$id/sse"
 
    try
    {   
        $request = [System.Net.WebRequest]::CreateHttp($url)
        $request.Headers.Add("Authorization", "Bearer $api_key")
        $request.AllowReadStreamBuffering = $false
        $response = $request.GetResponse()

        $stream = $response.GetResponseStream()

        while ($true) {
            $encoding = [System.Text.Encoding]::UTF8
            [byte[]]$buffer = New-Object byte[] 2048
            $length = $Stream.Read($buffer, 0, 2048)
            $responsetext = $encoding.GetString($buffer, 0, $length)
        
            if(![string]::IsNullOrEmpty($responsetext)) {
                #Quick'n dirty, lookup if there‘s „data“ keyword in the payload/stream
                if (($responsetext.ToCharArray()) -contains [char]'{') {
                    ReadJsonReponse -responsetext $responsetext.SubString($responsetext.IndexOf("data"))
                }
            }
        }
    }
    catch
    {
        $errorStatus = "Exception Message: " + $_.Exception.Message;
        Write-Host $errorStatus;
    }
}

function ReadJsonReponse($responsetext) {
    $json = $responsetext.Substring("data :".Length) | ConvertFrom-Json
    
    #Process your data here
    Write-Host $json.event
}

StartListener

You can find the requestbin’s id e.g. in its URL:

 the requestbin's id

And the API key could be found in your account’s settings:

Listening to Webhooks

Listening to Webhooks

To test the script you could now send a POST request with a json payload e.g. using Postman:

Listening to Webhooks in Powershell Postman

The script now identifies the „data“ keyword in the payload and writes it to the console:

Listening to Webshooks

... is a technical consultant and developer at Comsol Unternehmenslösungen AG in Kronberg/Taunus. Major tasks are the architecture and implementation of complex, usually cross-system applications in and around Microsoft Dynamics 365 Business Central.

2 comments

  1. Spellingmistake in line 38 – it should be $reponsetext instead of $reponsetest.
    Thank you very much for sharing your code! Much appreciated and helped me a lot!

    Reply

Leave a Reply

Your email address will not be published.