using System.Collections.Specialized; using System.Net.Http.Headers; using System.Text.Json; using yawaflua.Discord.Net.Interfaces.Models; namespace yawaflua.Discord.Net.Entities; internal class DiscordSession (IToken token, HttpClient httpClient, ScopesBuilder scopes, ulong clientId, string clientSecret, string redirectUri, bool prompt) : ISession { private async Task _req(string endpoint, HttpMethod? method = null) where T : class { using var request = new HttpRequestMessage(method ?? HttpMethod.Get, $"https://discord.com/api/{endpoint}"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); var response = await httpClient.SendAsync(request); if (!response.IsSuccessStatusCode) { return null; } var responseString = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize(responseString) ?? null; } public async Task?> GetGuildsAsync(CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return await _req("users/@me/guilds"); } public async Task GetGuildMemberAsync(ulong guildId, CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return await _req($"users/@me/guilds/{guildId}/member"); } public async Task AddMemberToGuildAsync(ulong guildId, ulong userId, CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return await _req($"guilds/{guildId}/members/{userId}", HttpMethod.Put); } public async Task GetCurrentUserAsync(CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return await _req("users/@me"); } public async Task GetConnectionAsync(CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return await _req("users/@me/connections"); } public string GetAuthorizationUrl(string state) { NameValueCollection query = new() { ["client_id"] = clientId.ToString(), ["redirect_uri"] = redirectUri, ["response_type"] = "code", ["scope"] = scopes.ToString(), ["state"] = state, ["prompt"] = prompt ? "consent" : "none" }; var uriBuilder = new UriBuilder("https://discord.com/api/oauth2/authorize") { Query = query.ToString() }; return uriBuilder.ToString(); } public IToken GetToken(CancellationToken cancellationToken = default) { if (token.AccessToken is null) { throw new ArgumentNullException(nameof(token), "Token cannot be null."); } return token; } }