using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Discord.Logging;
using Discord.Rest;
namespace Discord.Webhook
{
/// A client responsible for connecting as a 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(string webhookUrl)
: this(webhookUrl, new DiscordRestConfig()) { }
// regex pattern to match webhook urls
private static Regex WebhookUrlRegex = new Regex(@"^.*discordapp\.com\/api\/webhooks\/([\d]+)\/([a-z0-9_-]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
/// 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;
}
///
/// Creates a new Webhook Discord client.
///
/// The url of the webhook.
/// The configuration options to use for this client.
/// Thrown if the is an invalid format.
/// Thrown if the is null or whitespace.
public DiscordWebhookClient(string webhookUrl, DiscordRestConfig config) : this(config)
{
string token;
ParseWebhookUrl(webhookUrl, out _webhookId, out token);
ApiClient.LoginAsync(TokenType.Webhook, token).GetAwaiter().GetResult();
Webhook = WebhookClientHelper.GetWebhookAsync(this, _webhookId).GetAwaiter().GetResult();
}
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 = null, bool isTTS = false, IEnumerable