From ea3b089b47d431c2fe0ecd084362c913b10ee2a4 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Fri, 8 May 2026 09:55:33 -0500 Subject: [PATCH] =?UTF-8?q?Fix=20#944=20=E2=80=94=20snooze=20hint=20in=20e?= =?UTF-8?q?mail=20and=20Teams/Slack=20payloads?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a one-line discoverability footer to alert delivery channels other than the desktop popup, since neither email nor webhooks can round-trip a click back to a desktop process: "To silence this alert: open Performance Monitor Lite → Settings → Manage Mute Rules" Placed in the email HTML footer (under the cooldown line), the plain-text body tail, the Teams MessageCard (a small section after the facts), and the Slack context block at the bottom of the message. Suppressed on test deliveries so the test card stays minimal. Pairs with the snooze popup from #946 to close out #944. Co-Authored-By: Claude Opus 4.7 (1M context) --- Lite/Services/EmailTemplateBuilder.cs | 7 +++++++ Lite/Services/WebhookAlertService.cs | 20 ++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Lite/Services/EmailTemplateBuilder.cs b/Lite/Services/EmailTemplateBuilder.cs index 744d24de..f745a952 100644 --- a/Lite/Services/EmailTemplateBuilder.cs +++ b/Lite/Services/EmailTemplateBuilder.cs @@ -20,6 +20,7 @@ internal static class EmailTemplateBuilder { private const string EditionName = "Performance Monitor Lite"; private const string FontStack = "-apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif"; + private const string SnoozeHint = "To silence this alert: open Performance Monitor Lite → Settings → Manage Mute Rules"; /// /// Builds both HTML and plain-text bodies for an alert email. @@ -174,6 +175,10 @@ private static string BuildHtmlBody( sb.Append($" · {emailCooldownMinutes}-minute cooldown between repeat alerts"); } sb.Append(""); + if (!isTest) + { + sb.Append($"
{WebUtility.HtmlEncode(SnoozeHint)}"); + } sb.Append(""); /* Close inner table */ @@ -282,6 +287,8 @@ private static string BuildPlainTextBody( sb.Append($"\r\nAttached: {context.AttachmentFileName}\r\n"); } + sb.Append($"\r\n{SnoozeHint}\r\n"); + return sb.ToString(); } } diff --git a/Lite/Services/WebhookAlertService.cs b/Lite/Services/WebhookAlertService.cs index 7e54ea58..8dbee9f4 100644 --- a/Lite/Services/WebhookAlertService.cs +++ b/Lite/Services/WebhookAlertService.cs @@ -24,6 +24,7 @@ namespace PerformanceMonitorLite.Services; public class WebhookAlertService { private const string EditionName = "Performance Monitor Lite"; + private const string SnoozeHint = "To silence this alert: open Performance Monitor Lite → Settings → Manage Mute Rules"; private static readonly JsonSerializerOptions s_jsonOptions = new() { PropertyNamingPolicy = null }; private readonly ConcurrentDictionary _cooldowns = new(); @@ -221,6 +222,11 @@ internal static string BuildTeamsPayload( } }; + if (!isTest) + { + sections.Add(new { text = SnoozeHint }); + } + var card = new { @type = "MessageCard", @@ -346,13 +352,19 @@ internal static string BuildSlackPayload( } } + var contextElements = new List + { + new { type = "mrkdwn", text = $"Sent by {EditionName}" } + }; + if (!isTest) + { + contextElements.Add(new { type = "mrkdwn", text = SnoozeHint }); + } + blocks.Add(new { type = "context", - elements = new object[] - { - new { type = "mrkdwn", text = $"Sent by {EditionName}" } - } + elements = contextElements }); var payload = new