using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Discord.Logging; using Discord.Rest; namespace Discord.Webhook { public class DiscordWebhookClient : IDisposable { public event Func Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } } internal readonly AsyncEvent> _logEvent = new AsyncEvent>(); private readonly ulong _webhookId; internal IWebhook Webhook; internal readonly Logger _restLogger; internal API.DiscordRestApiClient ApiClient { get; } internal LogManager LogManager { get; } /// Creates a new Webhook discord client. public DiscordWebhookClient(IWebhook webhook) : this(webhook.Id, webhook.Token, new DiscordRestConfig()) { } /// Creates a new Webhook discord client. public DiscordWebhookClient(ulong webhookId, string webhookToken) : this(webhookId, webhookToken, new DiscordRestConfig()) { } /// Creates a new Webhook discord client. public DiscordWebhookClient(ulong webhookId, string webhookToken, DiscordRestConfig config) : this(config) { _webhookId = webhookId; ApiClient.LoginAsync(TokenType.Webhook, webhookToken).GetAwaiter().GetResult(); Webhook = WebhookClientHelper.GetWebhookAsync(this, webhookId).GetAwaiter().GetResult(); } /// Creates a new Webhook discord client. public DiscordWebhookClient(IWebhook webhook, DiscordRestConfig config) : this(config) { Webhook = webhook; _webhookId = Webhook.Id; } private DiscordWebhookClient(DiscordRestConfig config) { ApiClient = CreateApiClient(config); LogManager = new LogManager(config.LogLevel); LogManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false); _restLogger = LogManager.CreateLogger("Rest"); ApiClient.RequestQueue.RateLimitTriggered += async (id, info) => { if (info == null) await _restLogger.VerboseAsync($"Preemptive Rate limit triggered: {id ?? "null"}").ConfigureAwait(false); else await _restLogger.WarningAsync($"Rate limit triggered: {id ?? "null"}").ConfigureAwait(false); }; ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false); } private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config) => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent); /// Sends a message using to the channel for this webhook. Returns the ID of the created message. public Task SendMessageAsync(string text, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendMessageAsync(this, text, isTTS, embeds, username, avatarUrl, options); /// Send a message to the channel for this webhook with an attachment. Returns the ID of the created message. public Task SendFileAsync(string filePath, string text, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendFileAsync(this, filePath, text, isTTS, embeds, username, avatarUrl, options); /// Send a message to the channel for this webhook with an attachment. Returns the ID of the created message. public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, IEnumerable embeds = null, string username = null, string avatarUrl = null, RequestOptions options = null) => WebhookClientHelper.SendFileAsync(this, stream, filename, text, isTTS, embeds, username, avatarUrl, options); /// Modifies the properties of this webhook. public Task ModifyWebhookAsync(Action func, RequestOptions options = null) => Webhook.ModifyAsync(func, options); /// Deletes this webhook from Discord and disposes the client. public async Task DeleteWebhookAsync(RequestOptions options = null) { await Webhook.DeleteAsync(options).ConfigureAwait(false); Dispose(); } public void Dispose() { ApiClient?.Dispose(); } } }