using System.Net.Http.Headers; using Foxcord.Serialization; namespace Foxcord.Rest; public partial class DiscordRestClient { public string UserAgent { get; private init; } = "DiscordBot (https://codeberg.org/u1f320/Foxcord, v1)"; private readonly HttpClient _client = new(); private readonly string _token; private readonly string _baseUrl = "https://discord.com/api/v10"; public DiscordRestClient(string token, string? userAgent = null, string? baseUrl = null) { _token = token; if (userAgent != null) UserAgent = userAgent; if (baseUrl != null) _baseUrl = baseUrl; } public async Task RequestAsync(HttpMethod method, string path, IReadOnlyDictionary? extraHeaders = null) where TResponse : class { var request = CreateRequest(method, path, body: null, extraHeaders); var resp = await Send(request); return await resp.Content.ReadAsJsonAsync() ?? throw new FoxcordException("HTTP response was unexpectedly null"); } public async Task RequestAsync(HttpMethod method, string path, TRequest body, IReadOnlyDictionary? extraHeaders = null) where TRequest : class where TResponse : class { var request = CreateRequest(method, path, body, extraHeaders); var resp = await Send(request); return await resp.Content.ReadAsJsonAsync() ?? throw new FoxcordException("HTTP response was unexpectedly null"); } public async Task RequestAsync(HttpMethod method, string path, TRequest body, IReadOnlyDictionary? extraHeaders = null) where TRequest : class => await Send(CreateRequest(method, path, body, extraHeaders)); public async Task RequestAsync(HttpMethod method, string path, IReadOnlyDictionary? extraHeaders = null) => await Send(CreateRequest(method, path, body: null, extraHeaders)); // TODO: rate limits private async Task Send(HttpRequestMessage request) { var resp = await _client.SendAsync(request); if (!resp.IsSuccessStatusCode) { var error = await resp.Content.ReadAsJsonAsync(); throw new RestException(resp.StatusCode, error!); } return resp; } private HttpRequestMessage CreateRequest(HttpMethod method, string path, object? body, IReadOnlyDictionary? extraHeaders = null) { var request = new HttpRequestMessage(method, _baseUrl + path); request.Headers.Add("Authorization", _token); if (body != null) { request.Content = new ReadOnlyMemoryContent(JsonSerializer.SerializeToUtf8Bytes(body)); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json", "utf-8"); } if (extraHeaders != null) foreach (var (k, v) in extraHeaders) request.Headers.Add(k, v); return request; } }