From edd5c5f401de30df285440d5ee0431602006972c Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 29 Apr 2026 19:06:20 +0100 Subject: [PATCH] Fix watchdog Discord DM payloads --- scripts/check-voidbot-operations.ps1 | 50 +++++++++++++++++++--------- state/evidence.jsonl | 1 + 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/scripts/check-voidbot-operations.ps1 b/scripts/check-voidbot-operations.ps1 index 746478a..adcf2d8 100644 --- a/scripts/check-voidbot-operations.ps1 +++ b/scripts/check-voidbot-operations.ps1 @@ -424,6 +424,38 @@ function Invoke-WatchdogExtension { & $extensionCommand -Context $Context } +function Invoke-DiscordJsonRequest { + param( + [Parameter(Mandatory = $true)] + [string] $Method, + [Parameter(Mandatory = $true)] + [string] $Url, + [Parameter(Mandatory = $true)] + [string] $BotToken, + [Parameter(Mandatory = $true)] + [string] $JsonBody + ) + + $bodyPath = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName() + ".json") + + try { + $utf8NoBom = New-Object System.Text.UTF8Encoding($false) + [System.IO.File]::WriteAllText($bodyPath, $JsonBody, $utf8NoBom) + $response = & curl.exe -fsS -X $Method $Url ` + -H "Authorization: Bot $BotToken" ` + -H "Content-Type: application/json" ` + --data-binary "@$bodyPath" + + if ($LASTEXITCODE -ne 0) { + throw "Request failed for $Url" + } + + return $response + } finally { + Remove-Item -LiteralPath $bodyPath -Force -ErrorAction SilentlyContinue + } +} + function Open-OwnerDmChannel { param( [Parameter(Mandatory = $true)] @@ -433,14 +465,7 @@ function Open-OwnerDmChannel { ) $payload = @{ recipient_id = $OwnerDiscordId } | ConvertTo-Json -Compress - $response = & curl.exe -fsS -X POST "https://discord.com/api/v10/users/@me/channels" ` - -H "Authorization: Bot $BotToken" ` - -H "Content-Type: application/json" ` - --data-raw $payload - - if ($LASTEXITCODE -ne 0) { - throw "Failed to open the owner DM channel." - } + $response = Invoke-DiscordJsonRequest -Method "POST" -Url "https://discord.com/api/v10/users/@me/channels" -BotToken $BotToken -JsonBody $payload $parsed = $response | ConvertFrom-Json @@ -469,14 +494,7 @@ function Send-OwnerDm { } } | ConvertTo-Json -Depth 4 -Compress - & curl.exe -fsS -X POST "https://discord.com/api/v10/channels/$dmChannelId/messages" ` - -H "Authorization: Bot $BotToken" ` - -H "Content-Type: application/json" ` - --data-raw $payload *> $null - - if ($LASTEXITCODE -ne 0) { - throw "Failed to send the owner DM." - } + [void](Invoke-DiscordJsonRequest -Method "POST" -Url "https://discord.com/api/v10/channels/$dmChannelId/messages" -BotToken $BotToken -JsonBody $payload) } function Build-OwnerNotificationMessage { diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 121c220..4502108 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -7,3 +7,4 @@ {"ts":"2026-04-26T16:25:00+01:00","type":"architecture","status":"ok","note":"State storage was split into a thin factory, bootstrap/migration helper, per-domain Postgres stores, and dedicated rate-limit stores; behavior stayed stable, but one persistence omnibus had become the likelier future failure surface."} {"ts":"2026-04-29T17:36:43Z","type":"implementation","status":"ok","note":"Operations watchdog now checks Repixelizer public health plus recent Yggdrasil journald pressure signals and routes queue-full, job-failed, stale-cancel, and slow-job issues through the existing owner DM notification path."} {"ts":"2026-04-29T18:20:00+01:00","type":"architecture","status":"ok","note":"Adjacent-service fire signals now load through an ignored local watchdog extension script instead of living in tracked VoidBot code, so the owner alert path stays useful without baking private cross-project monitoring into the public repo."} +{"ts":"2026-04-29T19:06:00+01:00","type":"implementation","status":"ok","note":"The watchdog owner-DM path was failing on Windows because Discord JSON bodies were being shoved through curl command-line quoting and arriving malformed; writing the JSON to a temp file and posting it with --data-binary fixed the alert path."}