diff --git a/Content.Server/Discord/DiscordWebhook.cs b/Content.Server/Discord/DiscordWebhook.cs index ace5766764..878cd5975a 100644 --- a/Content.Server/Discord/DiscordWebhook.cs +++ b/Content.Server/Discord/DiscordWebhook.cs @@ -68,7 +68,11 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task CreateMessage(WebhookIdentifier identifier, WebhookPayload payload) { var url = $"{GetUrl(identifier)}?wait=true"; - return await _http.PostAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + var response = await _http.PostAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + + LogResponse(response, "Create"); + + return response; } /// @@ -80,7 +84,11 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task DeleteMessage(WebhookIdentifier identifier, ulong messageId) { var url = $"{GetUrl(identifier)}/messages/{messageId}"; - return await _http.DeleteAsync(url); + var response = await _http.DeleteAsync(url); + + LogResponse(response, "Delete"); + + return response; } /// @@ -93,11 +101,40 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task EditMessage(WebhookIdentifier identifier, ulong messageId, WebhookPayload payload) { var url = $"{GetUrl(identifier)}/messages/{messageId}"; - return await _http.PatchAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + var response = await _http.PatchAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + + LogResponse(response, "Edit"); + + return response; } void IPostInjectInit.PostInject() { _sawmill = _log.GetSawmill("DISCORD"); } + + /// + /// Logs detailed information about the HTTP response received from a Discord webhook request. + /// If the response status code is non-2XX it logs the status code, relevant rate limit headers. + /// + /// The HTTP response received from the Discord API. + /// The name (constant) of the method that initiated the webhook request (e.g., "Create", "Edit", "Delete"). + private void LogResponse(HttpResponseMessage response, string methodName) + { + if (!response.IsSuccessStatusCode) + { + _sawmill.Error($"Failed to {methodName} message. Status code: {response.StatusCode}."); + + if (response.Headers.TryGetValues("Retry-After", out var retryAfter)) + _sawmill.Debug($"Failed webhook response Retry-After: {string.Join(", ", retryAfter)}"); + + if (response.Headers.TryGetValues("X-RateLimit-Global", out var globalRateLimit)) + _sawmill.Debug($"Failed webhook response X-RateLimit-Global: {string.Join(", ", globalRateLimit)}"); + + if (response.Headers.TryGetValues("X-RateLimit-Scope", out var rateLimitScope)) + _sawmill.Debug($"Failed webhook response X-RateLimit-Scope: {string.Join(", ", rateLimitScope)}"); + } + } + + }