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:
And the API key could be found in your account’s settings:
Listening to Webhooks
To test the script you could now send a POST request with a json payload e.g. using Postman:
The script now identifies the „data“ keyword in the payload and writes it to the console:
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!
Great, thank you so much. I’ve corrected it.