using System.Diagnostics; namespace Aeshnidae.Trials; /// /// The award post. A webhook URL in the deployed Settings.json (set-webhook.sh puts /// it there; never source) is posted to directly, as Aeshnidae.Leaderboard does. /// Without one, the VPS's notify-discord.sh is run with Settings.Discord.Channel - /// the same script the ops scripts use, which falls back to the audit channel until /// the channel key is wired - so the line still lands somewhere staff read. With /// neither, the log has it. Fire-and-forget on the thread pool; the world thread /// never waits on Discord. /// public static class Discord { private static readonly HttpClient _http = new() { Timeout = TimeSpan.FromSeconds(15) }; public static string LastResult { get; private set; } = "never posted"; public static void Post(string text) { var d = Mod.Settings.Discord; if (!string.IsNullOrWhiteSpace(d.WebhookUrl)) { _ = Task.Run(async () => { try { var payload = JsonSerializer.Serialize(new { content = text, username = d.Username }); using var body = new StringContent(payload, Encoding.UTF8, "application/json"); using var response = await _http.PostAsync(d.WebhookUrl, body); LastResult = response.IsSuccessStatusCode ? $"posted {DateTime.UtcNow:yyyy-MM-dd HH:mm} UTC (webhook)" : $"HTTP {(int)response.StatusCode} at {DateTime.UtcNow:HH:mm} UTC"; } catch (Exception ex) { LastResult = $"failed: {ex.Message}"; } ModManager.Log($"[{Mod.Name}] Discord: {LastResult}"); }); return; } var script = (d.NotifyScript ?? "").Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); if (!string.IsNullOrWhiteSpace(script) && File.Exists(script)) { _ = Task.Run(() => { try { var psi = new ProcessStartInfo { FileName = "/bin/bash", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, }; psi.ArgumentList.Add(script); psi.ArgumentList.Add(string.IsNullOrWhiteSpace(d.Channel) ? "audit" : d.Channel); psi.ArgumentList.Add(text); using var proc = Process.Start(psi); if (proc is null) { LastResult = "notify script did not start"; } else { proc.WaitForExit(20000); LastResult = proc.ExitCode == 0 ? $"posted {DateTime.UtcNow:yyyy-MM-dd HH:mm} UTC (notify-discord.sh {d.Channel})" : $"notify-discord.sh exited {proc.ExitCode}: {proc.StandardError.ReadToEnd().Trim()}"; } } catch (Exception ex) { LastResult = $"notify script failed: {ex.Message}"; } ModManager.Log($"[{Mod.Name}] Discord: {LastResult}"); }); return; } LastResult = "no webhook and no notify script - logged only"; ModManager.Log($"[{Mod.Name}] Discord ({LastResult}): {text.Replace('\n', ' ')}"); } }