66 lines
2.3 KiB
C#
66 lines
2.3 KiB
C#
|
using System.Net;
|
||
|
using System.Net.Http.Json;
|
||
|
using System.Text.Json;
|
||
|
using Foxcord.Models;
|
||
|
using Foxcord.Rest.Rate;
|
||
|
using Foxcord.Rest.Types;
|
||
|
using Foxcord.Serialization;
|
||
|
using Polly;
|
||
|
using Serilog;
|
||
|
|
||
|
namespace Foxcord.Rest;
|
||
|
|
||
|
public class DiscordRestClient : BaseRestClient
|
||
|
{
|
||
|
public DiscordRestClient(ILogger logger, DiscordRestClientOptions options) : base(logger, new RestClientOptions
|
||
|
{
|
||
|
JsonSerializerOptions = JsonSerializerOptions,
|
||
|
ApiBaseUrl = options.ApiBaseUrl ?? DefaultApiBaseUrl,
|
||
|
UserAgent = options.UserAgent ?? DefaultUserAgent,
|
||
|
TokenFactory = () => $"Bot {options.Token}",
|
||
|
ErrorHandler = HandleError,
|
||
|
})
|
||
|
{
|
||
|
Pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
|
||
|
.AddDiscordStrategy(new RateLimiter(logger.ForContext<DiscordRestClient>()))
|
||
|
.Build();
|
||
|
}
|
||
|
|
||
|
public const string DefaultUserAgent = "DiscordBot (https://code.vulpine.solutions/sam/Foxcord, v1)";
|
||
|
public const string DefaultApiBaseUrl = "https://discord.com/api/v10";
|
||
|
|
||
|
public async Task<GetGatewayBotResponse> GatewayBotAsync(CancellationToken ct = default) =>
|
||
|
await RequestAsync<GetGatewayBotResponse>(HttpMethod.Get, "/gateway/bot", ct);
|
||
|
|
||
|
public async Task<Message> CreateMessageAsync(Snowflake channelId, CreateMessageParams message,
|
||
|
CancellationToken ct = default) =>
|
||
|
await RequestAsync<CreateMessageParams, Message>(HttpMethod.Post, $"/channels/{channelId}/messages", message,
|
||
|
ct);
|
||
|
|
||
|
#region BaseRestClient parameters
|
||
|
|
||
|
private static readonly JsonSerializerOptions JsonSerializerOptions = JsonSerializerExtensions.CreateSerializer();
|
||
|
|
||
|
private static async Task HandleError(HttpResponseMessage resp, CancellationToken ct)
|
||
|
{
|
||
|
if (resp.IsSuccessStatusCode) return;
|
||
|
|
||
|
if (resp.StatusCode == HttpStatusCode.TooManyRequests)
|
||
|
{
|
||
|
throw new RateLimitError(resp.Headers);
|
||
|
}
|
||
|
|
||
|
var error = await resp.Content.ReadFromJsonAsync<DiscordRestError>(JsonSerializerOptions, ct);
|
||
|
if (error == null) throw new ArgumentNullException(nameof(resp), "Response was deserialized as null");
|
||
|
throw error;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
public class DiscordRestClientOptions
|
||
|
{
|
||
|
public required string Token { get; init; }
|
||
|
public string? UserAgent { get; init; }
|
||
|
public string? ApiBaseUrl { get; init; }
|
||
|
}
|