Files
donetick-notifier/Start-DoneTickConsumer.ps1
kelly 075c6079c3
Security / security (push) Successful in 58s
resolving #10
completing #8
2026-06-02 20:35:10 -05:00

153 lines
3.9 KiB
PowerShell

[string] $ListenUrl = "http://+:8080/"
Import-Module ./AppriseNotification.psm1
function Write-JsonResponse
{
param(
[Parameter(Mandatory=$true)]
[System.Net.HttpListenerResponse]
$Response,
[Parameter(Mandatory=$true)]
[int]
$StatusCode,
[Parameter(Mandatory=$true)]
[hashtable]
$Body
)
$json = $Body | ConvertTo-Json -Depth 10
$bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
$Response.StatusCode = $StatusCode
$Response.ContentType = "application/json"
$Response.ContentEncoding = [System.Text.Encoding]::UTF8
$Response.ContentLength64 = $bytes.Length
$Response.OutputStream.Write($bytes, 0, $bytes.Length)
$Response.OutputStream.Close()
}
function Read-RequestBody
{
param(
[Parameter(Mandatory=$true)]
[System.Net.HttpListenerRequest]
$Request
)
$reader = [System.IO.StreamReader]::new($Request.InputStream, $Request.ContentEncoding)
try {
return $reader.ReadToEnd()
}
finally {
$reader.Close()
}
}
function Receive-Webhook
{
param(
[Parameter(Mandatory=$true)]
[System.Net.HttpListenerContext]
$Context
)
$request = $Context.Request
$response = $Context.Response
if ($request.HttpMethod -ne "POST") {
Write-JsonResponse -Response $response -StatusCode 405 -Body @{
ok = $false
error = "Only POST requests are supported."
}
return
}
$rawBody = Read-RequestBody -Request $request
$payload = $null
try {
if ($rawBody) {
$payload = $rawBody | ConvertFrom-Json
}
}
catch {
Write-JsonResponse -Response $response -StatusCode 400 -Body @{
ok = $false
error = "Request body was not valid JSON."
}
return
}
Write-Host "Webhook received at $(Get-Date -Format o)"
Write-Host "From: $($request.RemoteEndPoint)"
Write-Host "Path: $($request.Url.AbsolutePath)"
if ($payload) {
Write-Host "Payload:"
Write-Host ($payload | ConvertTo-Json -Depth 20)
}
else {
Write-Host "Payload: <empty>"
}
$notificationTitle = ""
$notificationContent = ""
switch($payload.type)
{
"task.completed" {
$notificationTitle = "Donetick Task Completed"
$notificationContent = "$($payload.data.chore.name) marked completed!"
}
"task.reminder" {
$notificationTitle = "Donetick Task Reminder"
$notificationContent = "$($payload.data.name) is due at $((Get-Date $payload.data.due_date).ToLocalTime())"
}
"task.created" {
$notificationTitle = "Donetick Task Created"
if ($null -eq $payload.data.chore.nextDueDate)
{
$notificationContent = "$($payload.data.chore.name) created"
}
else
{
$notificationContent = "$($payload.data.chore.name) created with due date of $((Get-Date $payload.data.chore.nextDueDate).ToLocalTime())"
}
}
default {
$notificationTitle = "Donetick Notification"
$notificationContent = "Donetick event of type $($payload.type) received"
}
}
Send-AppriseNotification -title $notificationTitle -content $notificationContent
Write-JsonResponse -Response $response -StatusCode 200 -Body @{
ok = $true
message = "Webhook accepted."
receivedAt = (Get-Date -Format o)
}
}
$listener = [System.Net.HttpListener]::new()
$listener.Prefixes.Add($ListenUrl)
try {
$listener.Start()
Write-Host "Webhook consumer listening on $ListenUrl"
Write-Host "Press Ctrl+C to stop."
while ($listener.IsListening) {
$context = $listener.GetContext()
Receive-Webhook -Context $context
}
}
finally {
if ($listener.IsListening) {
$listener.Stop()
}
$listener.Close()
}