mirror of
https://github.com/yawaflua/Discord.Net.git
synced 2025-12-09 03:49:36 +02:00
Refactor and rename project to yawaflua.Discord.Net; add core entities and interfaces for Discord OAuth2 integration
This commit is contained in:
12
Entities/AvatarDecoration.cs
Normal file
12
Entities/AvatarDecoration.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
internal class AvatarDecoration : IAvatarDecoration
|
||||
{
|
||||
[JsonPropertyName("asset")]
|
||||
public string AssetHash { get; set; }
|
||||
[JsonPropertyName("sku_id")]
|
||||
public ulong AssetArticular { get; set; }
|
||||
}
|
||||
@@ -1,48 +1,19 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Entities.Enums;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace x3rt.DiscordOAuth2.Entities;
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
public class DiscordConnection
|
||||
internal class DiscordConnection : IConnection
|
||||
{
|
||||
[JsonProperty("id")] public string Id { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("type")] public ConnectionType Type { get; set; }
|
||||
[JsonProperty("revoked")] public bool? Revoked { get; set; }
|
||||
[JsonProperty("integrations")] public object[] Integrations { get; set; }
|
||||
[JsonProperty("verified")] public bool? Verified { get; set; }
|
||||
[JsonProperty("friend_sync")] public bool? FriendSync { get; set; }
|
||||
[JsonProperty("show_activity")] public bool? ShowActivity { get; set; }
|
||||
[JsonProperty("two_way_link")] public bool? TwoWayLink { get; set; }
|
||||
[JsonProperty("visibility")] public ConnectionVisibility? Visibility { get; set; }
|
||||
|
||||
|
||||
public enum ConnectionVisibility
|
||||
{
|
||||
None,
|
||||
Everyone
|
||||
}
|
||||
|
||||
|
||||
public enum ConnectionType
|
||||
{
|
||||
BattleNet,
|
||||
Ebay,
|
||||
EpicGames,
|
||||
Facebook,
|
||||
GitHub,
|
||||
Instagram,
|
||||
LeagueOfLegends,
|
||||
PayPal,
|
||||
PlayStation,
|
||||
Reddit,
|
||||
RiotGames,
|
||||
Spotify,
|
||||
Skype,
|
||||
Steam,
|
||||
TikTok,
|
||||
Twitch,
|
||||
Twitter,
|
||||
Xbox,
|
||||
YouTube
|
||||
}
|
||||
[JsonPropertyName("id")] public string Id { get; set; }
|
||||
[JsonPropertyName("name")] public string Name { get; set; }
|
||||
[JsonPropertyName("type")] public ConnectionType Type { get; set; }
|
||||
[JsonPropertyName("revoked")] public bool? Revoked { get; set; }
|
||||
[JsonPropertyName("integrations")] public object[] Integrations { get; set; }
|
||||
[JsonPropertyName("verified")] public bool? Verified { get; set; }
|
||||
[JsonPropertyName("friend_sync")] public bool? FriendSync { get; set; }
|
||||
[JsonPropertyName("show_activity")] public bool? ShowActivity { get; set; }
|
||||
[JsonPropertyName("two_way_link")] public bool? TwoWayLink { get; set; }
|
||||
[JsonPropertyName("visibility")] public ConnectionVisibility? Visibility { get; set; }
|
||||
}
|
||||
@@ -1,24 +1,45 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Entities.Enums;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace x3rt.DiscordOAuth2.Entities;
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
public class DiscordGuild
|
||||
internal class DiscordGuild : IGuild
|
||||
{
|
||||
[JsonProperty("id")] public ulong Id { get; set; }
|
||||
[JsonPropertyName("id")] public ulong Id { get; set; }
|
||||
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonPropertyName("name")] public string Name { get; set; }
|
||||
|
||||
[JsonProperty("icon")] public string? Icon { get; set; }
|
||||
[JsonPropertyName("icon")] public string? IconHash { get; set; }
|
||||
[JsonPropertyName("banner")] public string? BannerHash { get; set; }
|
||||
|
||||
[JsonProperty("owner")] public bool Owner { get; set; }
|
||||
[JsonPropertyName("owner")] public bool IsOwner { get; set; }
|
||||
|
||||
[JsonProperty("permissions")] public string Permissions { get; set; }
|
||||
[JsonPropertyName("permissions")] public string Permissions { get; set; }
|
||||
|
||||
[JsonProperty("features")] public GuildFeatures Features { get; set; }
|
||||
[JsonPropertyName("features")] public IEnumerable<GuildFeature> Features { get; set; } = [];
|
||||
|
||||
[JsonPropertyName("approximate_member_count")] public int ApproximateMemberCount { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
[JsonPropertyName("approximate_presence_count")] public int ApproximatePresenceCount { get; set; }
|
||||
|
||||
public string GetIconUrl(int size = 128)
|
||||
{
|
||||
return
|
||||
$"Id: {Id}; Name: {Name}; Icon: {Icon}; Owner: {Owner}; Permissions: {Permissions}; Features: {Features}";
|
||||
if (string.IsNullOrEmpty(IconHash))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $"https://cdn.discordapp.com/icons/{Id}/{IconHash}.png?size={size}";
|
||||
}
|
||||
|
||||
public string GetBannerUrl(int size = 128)
|
||||
{
|
||||
if (string.IsNullOrEmpty(BannerHash))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $"https://cdn.discordapp.com/banners/{Id}/{BannerHash}.png?size={size}";
|
||||
}
|
||||
}
|
||||
39
Entities/DiscordGuildMember.cs
Normal file
39
Entities/DiscordGuildMember.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
internal class DiscordGuildMember : IGuildMember
|
||||
{
|
||||
private DiscordUser User { get; set; }
|
||||
public string? Nick { get; set; }
|
||||
[JsonPropertyName("avatar")]
|
||||
public string? AvatarHash { get; set; }
|
||||
[JsonPropertyName("banner")]
|
||||
public string? BannerHash { get; set; }
|
||||
public List<IRole> Roles { get; set; }
|
||||
public DateTime JoinedAt { get; set; }
|
||||
public DateTime? PremiumSince { get; set; }
|
||||
[JsonPropertyName("deaf")]
|
||||
public bool IsDeaf { get; set; }
|
||||
[JsonPropertyName("mute")]
|
||||
public bool IsMute { get; set; }
|
||||
public int Flags { get; set; }
|
||||
[JsonPropertyName("pending")]
|
||||
public bool IsPending { get; set; }
|
||||
[JsonPropertyName("communication_disabled_until")]
|
||||
public DateTime? CommunicationDisabledUntil { get; set; }
|
||||
private AvatarDecoration? AvatarDecoration { get; set; }
|
||||
|
||||
IUser IGuildMember.User
|
||||
{
|
||||
get => User;
|
||||
set => User = value as DiscordUser;
|
||||
}
|
||||
|
||||
IAvatarDecoration IGuildMember.AvatarDecoration
|
||||
{
|
||||
get => AvatarDecoration;
|
||||
set => AvatarDecoration = value as AvatarDecoration;
|
||||
}
|
||||
}
|
||||
26
Entities/DiscordRole.cs
Normal file
26
Entities/DiscordRole.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using yawaflua.Discord.Net.Entities.Enums;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
internal class DiscordRole : IRole
|
||||
{
|
||||
public ulong Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Color { get; set; }
|
||||
private RoleColor Colors { get; set; }
|
||||
public bool IsHoisted { get; set; }
|
||||
public bool IsManaged { get; set; }
|
||||
public bool IsMentionable { get; set; }
|
||||
public int Position { get; set; }
|
||||
public ulong? Permissions { get; set; }
|
||||
public string? IconHash { get; set; }
|
||||
public string? UnicodeEmoji { get; set; }
|
||||
public Dictionary<RoleTags, ulong?>? Tags { get; set; }
|
||||
|
||||
IRoleColor IRole.Colors
|
||||
{
|
||||
get => Colors;
|
||||
set => Colors = (RoleColor)value;
|
||||
}
|
||||
}
|
||||
103
Entities/DiscordSession.cs
Normal file
103
Entities/DiscordSession.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
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<T?> _req<T>(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<T?>(responseString) ?? null;
|
||||
}
|
||||
|
||||
public async Task<IList<IGuild>?> GetGuildsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (token.AccessToken is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(token), "Token cannot be null.");
|
||||
}
|
||||
|
||||
return await _req<DiscordGuild[]>("users/@me/guilds");
|
||||
}
|
||||
|
||||
public async Task<IGuildMember?> GetGuildMemberAsync(ulong guildId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (token.AccessToken is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(token), "Token cannot be null.");
|
||||
}
|
||||
|
||||
return await _req<DiscordGuildMember>($"users/@me/guilds/{guildId}/member");
|
||||
}
|
||||
|
||||
public async Task<IGuildMember?> 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<DiscordGuildMember>($"guilds/{guildId}/members/{userId}", HttpMethod.Put);
|
||||
}
|
||||
|
||||
public async Task<IUser?> GetCurrentUserAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (token.AccessToken is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(token), "Token cannot be null.");
|
||||
}
|
||||
|
||||
return await _req<DiscordUser>("users/@me");
|
||||
}
|
||||
|
||||
public async Task<IConnection?> GetConnectionAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (token.AccessToken is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(token), "Token cannot be null.");
|
||||
}
|
||||
return await _req<DiscordConnection>("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;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,85 @@
|
||||
using x3rt.DiscordOAuth2.Entities.Enums;
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Entities.Enums;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace x3rt.DiscordOAuth2.Entities;
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
public class DiscordUser
|
||||
internal class DiscordUser : IUser
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonPropertyName("username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
[JsonPropertyName("global_name")]
|
||||
public string GlobalName { get; set; }
|
||||
|
||||
[JsonPropertyName("discriminator")]
|
||||
public string Discriminator { get; set; }
|
||||
public string? Avatar { get; set; }
|
||||
|
||||
[JsonPropertyName("avatar")]
|
||||
public string? AvatarHash { get; set; }
|
||||
|
||||
[JsonPropertyName("bot")]
|
||||
public bool? Bot { get; set; }
|
||||
|
||||
[JsonPropertyName("system")]
|
||||
public bool? System { get; set; }
|
||||
|
||||
[JsonPropertyName("mfa_enabled")]
|
||||
public bool? MfaEnabled { get; set; }
|
||||
|
||||
[JsonPropertyName("banner")]
|
||||
public string? Banner { get; set; }
|
||||
|
||||
[JsonPropertyName("accent_color")]
|
||||
public int? AccentColor { get; set; }
|
||||
|
||||
[JsonPropertyName("locale")]
|
||||
public string? Locale { get; set; }
|
||||
|
||||
[JsonPropertyName("verified")]
|
||||
public bool? Verified { get; set; }
|
||||
|
||||
[JsonPropertyName("email")]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[JsonPropertyName("flags")]
|
||||
public UserFlag? Flags { get; set; }
|
||||
|
||||
[JsonPropertyName("premium_type")]
|
||||
public PremiumType? PremiumType { get; set; }
|
||||
|
||||
[JsonPropertyName("public_flags")]
|
||||
public UserFlag? PublicFlags { get; set; }
|
||||
|
||||
[JsonPropertyName("avatar_decoration")]
|
||||
public AvatarDecoration? AvatarDecoration { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
IAvatarDecoration IUser.AvatarDecoration
|
||||
{
|
||||
string result = "";
|
||||
foreach (var property in GetType().GetProperties())
|
||||
get => AvatarDecoration;
|
||||
set => AvatarDecoration = value as AvatarDecoration;
|
||||
}
|
||||
|
||||
public string GetAvatarUrl(int size = 128)
|
||||
{
|
||||
if (string.IsNullOrEmpty(AvatarHash))
|
||||
{
|
||||
var value = property.GetValue(this);
|
||||
if (value is not null)
|
||||
{
|
||||
result += $"{property.Name}: {value}; ";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
result = result.TrimEnd(' ', ';');
|
||||
return result;
|
||||
return $"https://cdn.discordapp.com/avatars/{Id}/{AvatarHash}.png?size={size}";
|
||||
}
|
||||
|
||||
public string GetBannerUrl(int size = 128)
|
||||
{
|
||||
if (string.IsNullOrEmpty(AvatarHash))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $"https://cdn.discordapp.com/banners/{Id}/{AvatarHash}.png?size={size}";
|
||||
}
|
||||
}
|
||||
24
Entities/Enums/ConnectionType.cs
Normal file
24
Entities/Enums/ConnectionType.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
public enum ConnectionType
|
||||
{
|
||||
BattleNet,
|
||||
Ebay,
|
||||
EpicGames,
|
||||
Facebook,
|
||||
GitHub,
|
||||
Instagram,
|
||||
LeagueOfLegends,
|
||||
PayPal,
|
||||
PlayStation,
|
||||
Reddit,
|
||||
RiotGames,
|
||||
Spotify,
|
||||
Skype,
|
||||
Steam,
|
||||
TikTok,
|
||||
Twitch,
|
||||
Twitter,
|
||||
Xbox,
|
||||
YouTube
|
||||
}
|
||||
7
Entities/Enums/ConnectionVisibility.cs
Normal file
7
Entities/Enums/ConnectionVisibility.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
public enum ConnectionVisibility
|
||||
{
|
||||
None,
|
||||
Everyone
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace x3rt.DiscordOAuth2.Entities.Enums;
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
[Flags]
|
||||
// Credit: Discord.Net
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace x3rt.DiscordOAuth2.Entities.Enums;
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the OAuth2 scopes available for a Discord application.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace x3rt.DiscordOAuth2.Entities.Enums;
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
public enum PremiumType
|
||||
{
|
||||
|
||||
11
Entities/Enums/RoleTags.cs
Normal file
11
Entities/Enums/RoleTags.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
public enum RoleTags
|
||||
{
|
||||
bot_id,
|
||||
integration_id,
|
||||
premium_subscriber,
|
||||
subscription_listing_id,
|
||||
available_for_purchase,
|
||||
guild_connections,
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace x3rt.DiscordOAuth2.Entities.Enums;
|
||||
namespace yawaflua.Discord.Net.Entities.Enums;
|
||||
|
||||
[Flags]
|
||||
public enum UserFlag : ulong
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using x3rt.DiscordOAuth2.Entities.Enums;
|
||||
|
||||
namespace x3rt.DiscordOAuth2.Entities;
|
||||
|
||||
public record GuildFeatures
|
||||
{
|
||||
IEnumerable<GuildFeature> Features { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Join(", ", Features);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,69 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace x3rt.DiscordOAuth2.Entities;
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
public class OAuthToken
|
||||
internal class OAuthToken (HttpClient client, ulong ClientId, string ClientSecret) : IToken
|
||||
{
|
||||
[JsonProperty("access_token")] public string AccessToken { get; set; }
|
||||
[JsonPropertyName("access_token")] public string AccessToken { get; set; }
|
||||
|
||||
[JsonProperty("expires_in")] public int ExpiresIn { get; set; }
|
||||
[JsonPropertyName("expires_in")] public int ExpiresIn { get; set; }
|
||||
|
||||
[JsonProperty("refresh_token")] public string RefreshToken { get; set; }
|
||||
[JsonPropertyName("refresh_token")] public string RefreshToken { get; set; }
|
||||
|
||||
[JsonProperty("scope")] public string Scope { get; set; }
|
||||
[JsonPropertyName("scope")] public string Scope { get; set; }
|
||||
|
||||
[JsonProperty("token_type")] public string TokenType { get; set; }
|
||||
[JsonPropertyName("token_type")] public string TokenType { get; set; }
|
||||
public Task RevokeAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, "https://discord.com/api/oauth2/token/revoke")
|
||||
{
|
||||
Content = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
{
|
||||
{ "token", AccessToken },
|
||||
{ "client_id", ClientId.ToString() },
|
||||
{ "client_secret", ClientSecret }
|
||||
})
|
||||
};
|
||||
return client.SendAsync(request, cancellationToken)
|
||||
.ContinueWith(task =>
|
||||
{
|
||||
if (!task.Result.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception("Failed to revoke token.");
|
||||
}
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task RefreshAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, "https://discord.com/api/oauth2/token")
|
||||
{
|
||||
Content = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
{
|
||||
{ "grant_type", "refresh_token" },
|
||||
{ "refresh_token", RefreshToken },
|
||||
})
|
||||
};
|
||||
var byteArray = System.Text.Encoding.ASCII.GetBytes($"{ClientId}:{ClientSecret}");
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
|
||||
var req = await client.SendAsync(request, cancellationToken);
|
||||
if (!req.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception("Failed to refresh token.");
|
||||
}
|
||||
var responseString = await req.Content.ReadAsStringAsync();
|
||||
var newToken = JsonSerializer.Deserialize<OAuthToken>(responseString);
|
||||
if (newToken is null)
|
||||
{
|
||||
throw new Exception("Failed to deserialize token.");
|
||||
}
|
||||
AccessToken = newToken.AccessToken;
|
||||
ExpiresIn = newToken.ExpiresIn;
|
||||
RefreshToken = newToken.RefreshToken;
|
||||
Scope = newToken.Scope;
|
||||
TokenType = newToken.TokenType;
|
||||
}
|
||||
}
|
||||
10
Entities/RoleColor.cs
Normal file
10
Entities/RoleColor.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using yawaflua.Discord.Net.Interfaces.Models;
|
||||
|
||||
namespace yawaflua.Discord.Net.Entities;
|
||||
|
||||
internal class RoleColor : IRoleColor
|
||||
{
|
||||
public int Primary { get; set; }
|
||||
public int? Secondary { get; set; }
|
||||
public int? Tertiary { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user