using System.Net.Http; using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace Content.Server.Discord; public sealed class DiscordWebhook : IPostInjectInit { [Dependency] private readonly ILogManager _log = default!; private const string BaseUrl = "https://discord.com/api/v10/webhooks"; private readonly HttpClient _http = new(); private ISawmill _sawmill = default!; private string GetUrl(WebhookIdentifier identifier) { return $"{BaseUrl}/{identifier.Id}/{identifier.Token}"; } /// /// Gets the webhook data from the given webhook url. /// /// The url to get the data from. /// The webhook data returned from the url. public async Task GetWebhook(string url) { try { return await _http.GetFromJsonAsync(url); } catch { _sawmill.Error($"Error getting discord webhook data. Stack trace:\n{Environment.StackTrace}"); return null; } } /// /// Gets the webhook data from the given webhook url. /// /// The url to get the data from. /// The delegate to invoke with the obtained data, if any. public async void GetWebhook(string url, Action onComplete) { if (await GetWebhook(url) is { } data) onComplete(data); } /// /// Tries to get the webhook data from the given webhook url if it is not null or whitespace. /// /// The url to get the data from. /// The delegate to invoke with the obtained data, if any. public async void TryGetWebhook(string url, Action onComplete) { if (await GetWebhook(url) is { } data) onComplete(data); } /// /// Creates a new webhook message with the given identifier and payload. /// /// The identifier for the webhook url. /// The payload to create the message from. /// The response from Discord's API. 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 }); } /// /// Deletes a webhook message with the given identifier and message id. /// /// The identifier for the webhook url. /// The message id to delete. /// The response from Discord's API. public async Task DeleteMessage(WebhookIdentifier identifier, ulong messageId) { var url = $"{GetUrl(identifier)}/messages/{messageId}"; return await _http.DeleteAsync(url); } /// /// Creates a new webhook message with the given identifier, message id and payload. /// /// The identifier for the webhook url. /// The message id to edit. /// The payload used to edit the message. /// The response from Discord's API. 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 }); } void IPostInjectInit.PostInject() { _sawmill = _log.GetSawmill("DISCORD"); } }