[Feature] Get current bot application information (#2619)

* initial commit

* Add support for modifying current bot's app
This commit is contained in:
Misha133
2023-03-31 14:36:26 +03:00
committed by GitHub
parent 898ee56557
commit 9ef5a768e0
16 changed files with 281 additions and 84 deletions

View File

@@ -222,5 +222,15 @@ namespace Discord
/// The maximum number of thread members that can be gotten per-batch. /// The maximum number of thread members that can be gotten per-batch.
/// </returns> /// </returns>
public const int MaxThreadMembersPerBatch = 100; public const int MaxThreadMembersPerBatch = 100;
/// <summary>
/// Returns the max length of an application tag.
/// </summary>
public const int MaxApplicationTagLength = 20;
/// <summary>
/// Returns the max length of an application description.
/// </summary>
public const int MaxApplicationDescriptionLength = 400;
} }
} }

View File

@@ -36,13 +36,13 @@ namespace Discord
/// </summary> /// </summary>
string IconUrl { get; } string IconUrl { get; }
/// <summary> /// <summary>
/// Gets if the bot is public. /// Gets if the bot is public. <see langword="null" /> if not set.
/// </summary> /// </summary>
bool IsBotPublic { get; } bool? IsBotPublic { get; }
/// <summary> /// <summary>
/// Gets if the bot requires code grant. /// Gets if the bot requires code grant. <see langword="null" /> if not set.
/// </summary> /// </summary>
bool BotRequiresCodeGrant { get; } bool? BotRequiresCodeGrant { get; }
/// <summary> /// <summary>
/// Gets the team associated with this application if there is one. /// Gets the team associated with this application if there is one.
/// </summary> /// </summary>
@@ -75,5 +75,24 @@ namespace Discord
/// </summary> /// </summary>
public string VerifyKey { get; } public string VerifyKey { get; }
/// <summary>
/// Gets the partial guild object of the application's developer's support server. <see langword="null" /> if not set.
/// </summary>
public PartialGuild Guild { get; }
/// <summary>
/// Gets the redirect uris configured for the application.
/// </summary>
public IReadOnlyCollection<string> RedirectUris { get;}
/// <summary>
/// Gets application's interactions endpoint url. <see langword="null" /> if not set.
/// </summary>
public string InteractionsEndpointUrl { get; }
/// <summary>
/// Gets the approximate count of the guild the application was added to. <see langword="null" /> if not returned.
/// </summary>
public int? ApproximateGuildCount { get; }
} }
} }

View File

@@ -0,0 +1,32 @@
namespace Discord;
/// <summary>
/// Represents properties used to modify current application's bot.
/// </summary>
public class ModifyApplicationProperties
{
/// <summary>
/// Gets or sets the http interactions endpoint configured for the application.
/// </summary>
public Optional<string> InteractionsEndpointUrl { get; set; }
/// <summary>
/// Gets or sets the role connections verification endpoint configured for the application.
/// </summary>
public Optional<string> RoleConnectionsEndpointUrl { get; set; }
/// <summary>
/// Gets or sets the description of the application.
/// </summary>
public Optional<string> Description { get; set; }
/// <summary>
/// Gets or sets application's tags
/// </summary>
public Optional<string[]> Tags { get; set; }
/// <summary>
/// Gets or sets the icon of the application.
/// </summary>
public Optional<Image?> Icon { get; set; }
}

View File

@@ -2,13 +2,19 @@ using System;
namespace Discord; namespace Discord;
public class InviteGuild : ISnowflakeEntity /// <summary>
/// Represents a partial guild object.
/// </summary>
/// <remarks>
/// Most of the fields can have <see langword="null" /> value.
/// </remarks>
public class PartialGuild : ISnowflakeEntity
{ {
/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
/// <inheritdoc/> /// <inheritdoc/>
public ulong Id { get; private set; } public ulong Id { get; internal set; }
/// <summary> /// <summary>
/// Gets the name of this guild. /// Gets the name of this guild.
@@ -16,7 +22,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// A string containing the name of this guild. /// A string containing the name of this guild.
/// </returns> /// </returns>
public string Name { get; private set; } public string Name { get; internal set; }
/// <summary> /// <summary>
/// Gets the description for the guild. /// Gets the description for the guild.
@@ -24,7 +30,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// The description for the guild; <see langword="null" /> if none is set. /// The description for the guild; <see langword="null" /> if none is set.
/// </returns> /// </returns>
public string Description { get; private set; } public string Description { get; internal set; }
/// <summary> /// <summary>
/// Gets the ID of this guild's splash image. /// Gets the ID of this guild's splash image.
@@ -32,7 +38,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// An identifier for the splash image; <see langword="null" /> if none is set. /// An identifier for the splash image; <see langword="null" /> if none is set.
/// </returns> /// </returns>
public string SplashId { get; private set; } public string SplashId { get; internal set; }
/// <summary> /// <summary>
/// Gets the URL of this guild's splash image. /// Gets the URL of this guild's splash image.
@@ -48,7 +54,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// An identifier for the banner image; <see langword="null" /> if none is set. /// An identifier for the banner image; <see langword="null" /> if none is set.
/// </returns> /// </returns>
public string BannerId { get; private set; } public string BannerId { get; internal set; }
/// <summary> /// <summary>
/// Gets the URL of this guild's banner image. /// Gets the URL of this guild's banner image.
@@ -64,7 +70,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// A flags enum containing all the features for the guild. /// A flags enum containing all the features for the guild.
/// </returns> /// </returns>
public GuildFeatures Features { get; private set; } public GuildFeatures Features { get; internal set; }
/// <summary> /// <summary>
/// Gets the ID of this guild's icon. /// Gets the ID of this guild's icon.
@@ -72,7 +78,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// An identifier for the splash image; <see langword="null" /> if none is set. /// An identifier for the splash image; <see langword="null" /> if none is set.
/// </returns> /// </returns>
public string IconId { get; private set; } public string IconId { get; internal set; }
/// <summary> /// <summary>
/// Gets the URL of this guild's icon. /// Gets the URL of this guild's icon.
@@ -87,9 +93,9 @@ public class InviteGuild : ISnowflakeEntity
/// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. /// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// The level of requirements. /// The level of requirements. <see langword="null" /> if none is was returned.
/// </returns> /// </returns>
public VerificationLevel VerificationLevel { get; private set; } public VerificationLevel? VerificationLevel { get; internal set; }
/// <summary> /// <summary>
/// Gets the code for this guild's vanity invite URL. /// Gets the code for this guild's vanity invite URL.
@@ -97,7 +103,7 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// A string containing the vanity invite code for this guild; <see langword="null" /> if none is set. /// A string containing the vanity invite code for this guild; <see langword="null" /> if none is set.
/// </returns> /// </returns>
public string VanityURLCode { get; private set; } public string VanityURLCode { get; internal set; }
/// <summary> /// <summary>
/// Gets the number of premium subscribers of this guild. /// Gets the number of premium subscribers of this guild.
@@ -106,17 +112,17 @@ public class InviteGuild : ISnowflakeEntity
/// This is the number of users who have boosted this guild. /// This is the number of users who have boosted this guild.
/// </remarks> /// </remarks>
/// <returns> /// <returns>
/// The number of premium subscribers of this guild; /// The number of premium subscribers of this guild; <see langword="null" /> if none was returned.
/// </returns> /// </returns>
public int PremiumSubscriptionCount { get; private set; } public int? PremiumSubscriptionCount { get; internal set; }
/// <summary> /// <summary>
/// Gets the NSFW level of this guild. /// Gets the NSFW level of this guild.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// The NSFW level of this guild. /// The NSFW level of this guild. <see langword="null" /> if none was returned.
/// </returns> /// </returns>
public NsfwLevel NsfwLevel { get; private set; } public NsfwLevel? NsfwLevel { get; internal set; }
/// <summary> /// <summary>
/// Gets the Welcome Screen of this guild /// Gets the Welcome Screen of this guild
@@ -124,33 +130,18 @@ public class InviteGuild : ISnowflakeEntity
/// <returns> /// <returns>
/// The welcome screen of this guild. <see langword="null" /> if none is set. /// The welcome screen of this guild. <see langword="null" /> if none is set.
/// </returns> /// </returns>
public WelcomeScreen WelcomeScreen { get; private set; } public WelcomeScreen WelcomeScreen { get; internal set; }
/// <summary>
/// Gets the approximate member count in the guild. <see langword="null" /> if none was returned.
/// </summary>
public int? ApproximateMemberCount { get; internal set; }
/// <summary>
/// Gets the approximate presence count in the guild.<see langword="null" /> if none was returned.
/// </summary>
public int? ApproximatePresenceCount { get; internal set; }
internal PartialGuild() { }
internal InviteGuild(
ulong id,
string name,
string description,
string splashId,
string bannerId,
GuildFeatures features,
string iconId,
VerificationLevel verificationLevel,
string vanityURLCode,
int premiumSubscriptionCount,
NsfwLevel nsfwLevel,
WelcomeScreen welcomeScreen)
{
Id = id;
Name = name;
Description = description;
SplashId = splashId;
BannerId = bannerId;
Features = features;
IconId = iconId;
VerificationLevel = verificationLevel;
VanityURLCode = vanityURLCode;
PremiumSubscriptionCount = premiumSubscriptionCount;
NsfwLevel = nsfwLevel;
WelcomeScreen = welcomeScreen;
}
} }

View File

@@ -14,10 +14,12 @@ namespace Discord.API
public ulong Id { get; set; } public ulong Id { get; set; }
[JsonProperty("icon")] [JsonProperty("icon")]
public string Icon { get; set; } public string Icon { get; set; }
[JsonProperty("bot_public")] [JsonProperty("bot_public")]
public bool IsBotPublic { get; set; } public Optional<bool> IsBotPublic { get; set; }
[JsonProperty("bot_require_code_grant")] [JsonProperty("bot_require_code_grant")]
public bool BotRequiresCodeGrant { get; set; } public Optional<bool> BotRequiresCodeGrant { get; set; }
[JsonProperty("install_params")] [JsonProperty("install_params")]
public Optional<InstallParams> InstallParams { get; set; } public Optional<InstallParams> InstallParams { get; set; }
[JsonProperty("team")] [JsonProperty("team")]
@@ -28,8 +30,20 @@ namespace Discord.API
public Optional<User> Owner { get; set; } public Optional<User> Owner { get; set; }
[JsonProperty("tags")] [JsonProperty("tags")]
public Optional<string[]> Tags { get; set; } public Optional<string[]> Tags { get; set; }
[JsonProperty("verify_key")]
public string VerifyKey { get; set; }
[JsonProperty("approximate_guild_count")]
public Optional<int> ApproximateGuildCount { get; set; }
[JsonProperty("guild")]
public Optional<PartialGuild> PartialGuild { get; set; }
/// Urls
[JsonProperty("terms_of_service_url")] [JsonProperty("terms_of_service_url")]
public string TermsOfService { get; set; } public string TermsOfService { get; set; }
[JsonProperty("privacy_policy_url")] [JsonProperty("privacy_policy_url")]
public string PrivacyPolicy { get; set; } public string PrivacyPolicy { get; set; }
@@ -39,7 +53,11 @@ namespace Discord.API
[JsonProperty("role_connections_verification_url")] [JsonProperty("role_connections_verification_url")]
public Optional<string> RoleConnectionsUrl { get; set; } public Optional<string> RoleConnectionsUrl { get; set; }
[JsonProperty("verify_key")] [JsonProperty("interactions_endpoint_url")]
public string VerifyKey { get; set; } public Optional<string> InteractionsEndpointUrl { get; set; }
[JsonProperty("redirect_uris")]
public Optional<string[]> RedirectUris { get; set; }
} }
} }

View File

@@ -9,7 +9,7 @@ namespace Discord.API
public string Code { get; set; } public string Code { get; set; }
[JsonProperty("guild")] [JsonProperty("guild")]
public Optional<InviteGuild> Guild { get; set; } public Optional<PartialGuild> Guild { get; set; }
[JsonProperty("channel")] [JsonProperty("channel")]
public InviteChannel Channel { get; set; } public InviteChannel Channel { get; set; }

View File

@@ -2,7 +2,7 @@ using Newtonsoft.Json;
namespace Discord.API namespace Discord.API
{ {
internal class InviteGuild internal class PartialGuild
{ {
[JsonProperty("id")] [JsonProperty("id")]
public ulong Id { get; set; } public ulong Id { get; set; }
@@ -23,10 +23,10 @@ namespace Discord.API
public Optional<string> IconHash { get; set; } public Optional<string> IconHash { get; set; }
[JsonProperty("features")] [JsonProperty("features")]
public GuildFeatures Features { get; set; } public Optional<GuildFeatures> Features { get; set; }
[JsonProperty("verification_level")] [JsonProperty("verification_level")]
public VerificationLevel VerificationLevel { get; set; } public Optional<VerificationLevel> VerificationLevel { get; set; }
[JsonProperty("vanity_url_code")] [JsonProperty("vanity_url_code")]
public Optional<string> VanityUrlCode { get; set; } public Optional<string> VanityUrlCode { get; set; }
@@ -38,9 +38,16 @@ namespace Discord.API
public Optional<bool?> Nsfw { get; set; } public Optional<bool?> Nsfw { get; set; }
[JsonProperty("nsfw_level")] [JsonProperty("nsfw_level")]
public NsfwLevel NsfwLevel { get; set; } public Optional<NsfwLevel> NsfwLevel { get; set; }
[JsonProperty("welcome_screen")] [JsonProperty("welcome_screen")]
public Optional<WelcomeScreen> WelcomeScreen { get; set; } public Optional<WelcomeScreen> WelcomeScreen { get; set; }
[JsonProperty("approximate_member_count")]
public Optional<int> ApproximateMemberCount { get; set; }
[JsonProperty("approximate_presence_count")]
public Optional<int> ApproximatePresenceCount { get; set; }
} }
} }

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
namespace Discord.API.Rest;
internal class ModifyCurrentApplicationBotParams
{
[JsonProperty("interactions_endpoint_url")]
public Optional<string> InteractionsEndpointUrl { get; set; }
[JsonProperty("role_connections_verification_url")]
public Optional<string> RoleConnectionsEndpointUrl { get; set; }
[JsonProperty("description")]
public Optional<string> Description { get; set; }
[JsonProperty("tags")]
public Optional<string[]> Tags { get; set; }
[JsonProperty("icon")]
public Optional<Image?> Icon { get; set; }
}

View File

@@ -17,6 +17,34 @@ namespace Discord.Rest
return RestApplication.Create(client, model); return RestApplication.Create(client, model);
} }
public static async Task<RestApplication> GetCurrentBotApplicationAsync(BaseDiscordClient client, RequestOptions options)
{
var model = await client.ApiClient.GetCurrentBotApplicationAsync(options).ConfigureAwait(false);
return RestApplication.Create(client, model);
}
public static async Task<API.Application> ModifyCurrentBotApplicationAsync(BaseDiscordClient client, Action<ModifyApplicationProperties> func, RequestOptions options)
{
var args = new ModifyApplicationProperties();
func(args);
if(args.Tags.IsSpecified)
foreach (var tag in args.Tags.Value)
Preconditions.AtMost(tag.Length, DiscordConfig.MaxApplicationTagLength, nameof(args.Tags), $"An application tag must have length less or equal to {DiscordConfig.MaxApplicationTagLength}");
if(args.Description.IsSpecified)
Preconditions.AtMost(args.Description.Value.Length, DiscordConfig.MaxApplicationDescriptionLength, nameof(args.Description), $"An application description tag mus have length less or equal to {DiscordConfig.MaxApplicationDescriptionLength}");
return await client.ApiClient.ModifyCurrentBotApplicationAsync(new()
{
Description = args.Description,
Tags = args.Tags,
Icon = args.Icon.IsSpecified ? args.Icon.Value?.ToModel() : Optional<API.Image?>.Unspecified,
InteractionsEndpointUrl = args.InteractionsEndpointUrl,
RoleConnectionsEndpointUrl = args.RoleConnectionsEndpointUrl,
}, options);
}
public static async Task<RestChannel> GetChannelAsync(BaseDiscordClient client, public static async Task<RestChannel> GetChannelAsync(BaseDiscordClient client,
ulong id, RequestOptions options) ulong id, RequestOptions options)
{ {

View File

@@ -2282,11 +2282,27 @@ namespace Discord.API
return await SendAsync<IReadOnlyCollection<UserGuild>>("GET", () => $"users/@me/guilds?limit={limit}&after={afterGuildId}&with_counts=true", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<IReadOnlyCollection<UserGuild>>("GET", () => $"users/@me/guilds?limit={limit}&after={afterGuildId}&with_counts=true", new BucketIds(), options: options).ConfigureAwait(false);
} }
public async Task<Application> GetMyApplicationAsync(RequestOptions options = null) public async Task<Application> GetMyApplicationAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
return await SendAsync<Application>("GET", () => "oauth2/applications/@me", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<Application>("GET", () => "oauth2/applications/@me", new BucketIds(), options: options).ConfigureAwait(false);
} }
public async Task<Application> GetCurrentBotApplicationAsync(RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
return await SendAsync<Application>("GET", () => "applications/@me", new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task<Application> ModifyCurrentBotApplicationAsync(ModifyCurrentApplicationBotParams args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));
options = RequestOptions.CreateOrClone(options);
return await SendJsonAsync<Application>("PATCH", () => "applications/@me", args, new BucketIds(), options: options);
}
public async Task<User> ModifySelfAsync(Rest.ModifyCurrentUserParams args, RequestOptions options = null) public async Task<User> ModifySelfAsync(Rest.ModifyCurrentUserParams args, RequestOptions options = null)
{ {
Preconditions.NotNull(args, nameof(args)); Preconditions.NotNull(args, nameof(args));

View File

@@ -19,6 +19,8 @@ namespace Discord.Rest
{ {
#region DiscordRestClient #region DiscordRestClient
private RestApplication _applicationInfo; private RestApplication _applicationInfo;
private RestApplication _currentBotApplication;
internal static JsonSerializer Serializer = new JsonSerializer() { ContractResolver = new DiscordContractResolver(), NullValueHandling = NullValueHandling.Include }; internal static JsonSerializer Serializer = new JsonSerializer() { ContractResolver = new DiscordContractResolver(), NullValueHandling = NullValueHandling.Include };
/// <summary> /// <summary>
@@ -170,6 +172,22 @@ namespace Discord.Rest
return _applicationInfo ??= await ClientHelper.GetApplicationInfoAsync(this, options).ConfigureAwait(false); return _applicationInfo ??= await ClientHelper.GetApplicationInfoAsync(this, options).ConfigureAwait(false);
} }
public async Task<RestApplication> GetCurrentBotInfoAsync(RequestOptions options = null)
{
return _currentBotApplication = await ClientHelper.GetCurrentBotApplicationAsync(this, options);
}
public async Task<RestApplication> ModifyCurrentBotApplicationAsync(Action<ModifyApplicationProperties> args, RequestOptions options = null)
{
var model = await ClientHelper.ModifyCurrentBotApplicationAsync(this, args, options);
if (_currentBotApplication is null)
_currentBotApplication = RestApplication.Create(this, model);
else
_currentBotApplication.Update(model);
return _currentBotApplication;
}
public Task<RestChannel> GetChannelAsync(ulong id, RequestOptions options = null) public Task<RestChannel> GetChannelAsync(ulong id, RequestOptions options = null)
=> ClientHelper.GetChannelAsync(this, id, options); => ClientHelper.GetChannelAsync(this, id, options);
public Task<IReadOnlyCollection<IRestPrivateChannel>> GetPrivateChannelsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<IRestPrivateChannel>> GetPrivateChannelsAsync(RequestOptions options = null)

View File

@@ -36,7 +36,7 @@ namespace Discord.Rest
/// <returns> /// <returns>
/// A partial guild object representing the guild that the invite points to. /// A partial guild object representing the guild that the invite points to.
/// </returns> /// </returns>
public InviteGuild InviteGuild { get; private set; } public PartialGuild PartialGuild { get; private set; }
/// <inheritdoc cref="IInvite.Application" /> /// <inheritdoc cref="IInvite.Application" />
public RestApplication Application { get; private set; } public RestApplication Application { get; private set; }
@@ -85,28 +85,7 @@ namespace Discord.Rest
if (model.Guild.IsSpecified) if (model.Guild.IsSpecified)
{ {
InviteGuild = new InviteGuild PartialGuild = PartialGuildExtensions.Create(model.Guild.Value);
(model.Guild.Value.Id,
model.Guild.Value.Name,
model.Guild.Value.Description.IsSpecified ? model.Guild.Value.Description.Value : null,
model.Guild.Value.Splash.IsSpecified ? model.Guild.Value.Splash.Value : null,
model.Guild.Value.BannerHash.IsSpecified ? model.Guild.Value.BannerHash.Value : null,
model.Guild.Value.Features,
model.Guild.Value.IconHash.IsSpecified ? model.Guild.Value.IconHash.Value : null,
model.Guild.Value.VerificationLevel,
model.Guild.Value.VanityUrlCode.IsSpecified ? model.Guild.Value.VanityUrlCode.Value : null,
model.Guild.Value.PremiumSubscriptionCount.GetValueOrDefault(0),
model.Guild.Value.NsfwLevel,
model.Guild.Value.WelcomeScreen.IsSpecified
? new WelcomeScreen(
model.Guild.Value.WelcomeScreen.Value.Description.IsSpecified ? model.Guild.Value.WelcomeScreen.Value.Description.Value : null,
model.Guild.Value.WelcomeScreen.Value.WelcomeChannels.Select(ch =>
new WelcomeScreenChannel(
ch.ChannelId,
ch.Description,
ch.EmojiName.IsSpecified ? ch.EmojiName.Value : null,
ch.EmojiId.IsSpecified ? ch.EmojiId.Value : null)).ToImmutableArray())
: null);
} }
if(model.Application.IsSpecified) if(model.Application.IsSpecified)

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using Model = Discord.API.Application; using Model = Discord.API.Application;
namespace Discord.Rest namespace Discord.Rest
@@ -24,9 +25,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public ApplicationFlags Flags { get; private set; } public ApplicationFlags Flags { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool IsBotPublic { get; private set; } public bool? IsBotPublic { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool BotRequiresCodeGrant { get; private set; } public bool? BotRequiresCodeGrant { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ITeam Team { get; private set; } public ITeam Team { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -48,6 +49,18 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId); public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId);
/// <inheritdoc />
public PartialGuild Guild { get; private set; }
/// <inheritdoc />
public int? ApproximateGuildCount { get; private set; }
/// <inheritdoc />
public IReadOnlyCollection<string> RedirectUris { get; private set; }
/// <inheritdoc />
public string InteractionsEndpointUrl { get; private set; }
public ApplicationInstallParams InstallParams { get; private set; } public ApplicationInstallParams InstallParams { get; private set; }
public IReadOnlyCollection<string> Tags { get; private set; } public IReadOnlyCollection<string> Tags { get; private set; }
@@ -68,13 +81,13 @@ namespace Discord.Rest
RPCOrigins = model.RPCOrigins.IsSpecified ? model.RPCOrigins.Value.ToImmutableArray() : ImmutableArray<string>.Empty; RPCOrigins = model.RPCOrigins.IsSpecified ? model.RPCOrigins.Value.ToImmutableArray() : ImmutableArray<string>.Empty;
Name = model.Name; Name = model.Name;
_iconId = model.Icon; _iconId = model.Icon;
IsBotPublic = model.IsBotPublic; IsBotPublic = model.IsBotPublic.IsSpecified ? model.IsBotPublic.Value : null;
BotRequiresCodeGrant = model.BotRequiresCodeGrant; BotRequiresCodeGrant = model.BotRequiresCodeGrant.IsSpecified ? model.BotRequiresCodeGrant.Value : null;
Tags = model.Tags.GetValueOrDefault(null)?.ToImmutableArray() ?? ImmutableArray<string>.Empty; Tags = model.Tags.GetValueOrDefault(null)?.ToImmutableArray() ?? ImmutableArray<string>.Empty;
PrivacyPolicy = model.PrivacyPolicy; PrivacyPolicy = model.PrivacyPolicy;
TermsOfService = model.TermsOfService; TermsOfService = model.TermsOfService;
var installParams = model.InstallParams.GetValueOrDefault(null); var installParams = model.InstallParams.GetValueOrDefault(null);
InstallParams = new ApplicationInstallParams(installParams?.Scopes ?? new string[0], (GuildPermission?)installParams?.Permission ?? null); InstallParams = new ApplicationInstallParams(installParams?.Scopes ?? Array.Empty<string>(), (GuildPermission?)installParams?.Permission);
if (model.Flags.IsSpecified) if (model.Flags.IsSpecified)
Flags = model.Flags.Value; Flags = model.Flags.Value;
@@ -86,6 +99,16 @@ namespace Discord.Rest
CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null; CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null;
RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null; RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null;
VerifyKey = model.VerifyKey; VerifyKey = model.VerifyKey;
if (model.PartialGuild.IsSpecified)
Guild = PartialGuildExtensions.Create(model.PartialGuild.Value);
InteractionsEndpointUrl = model.InteractionsEndpointUrl.IsSpecified ? model.InteractionsEndpointUrl.Value : null;
if (model.RedirectUris.IsSpecified)
RedirectUris = model.RedirectUris.Value.ToImmutableArray();
ApproximateGuildCount = model.ApproximateGuildCount.IsSpecified ? model.ApproximateGuildCount.Value : null;
} }
/// <exception cref="InvalidOperationException">Unable to update this object from a different application token.</exception> /// <exception cref="InvalidOperationException">Unable to update this object from a different application token.</exception>

View File

@@ -0,0 +1,35 @@
using System.Collections.Immutable;
using System.Linq;
namespace Discord.Rest;
internal static class PartialGuildExtensions
{
public static PartialGuild Create(API.PartialGuild model)
=> new PartialGuild
{
Id = model.Id,
Name = model.Name,
Description = model.Description.IsSpecified ? model.Description.Value : null,
SplashId = model.Splash.IsSpecified ? model.Splash.Value : null,
BannerId = model.BannerHash.IsSpecified ? model.BannerHash.Value : null,
Features = model.Features.IsSpecified ? model.Features.Value : null,
IconId = model.IconHash.IsSpecified ? model.IconHash.Value : null,
VerificationLevel = model.VerificationLevel.IsSpecified ? model.VerificationLevel.Value : null,
VanityURLCode = model.VanityUrlCode.IsSpecified ? model.VanityUrlCode.Value : null,
PremiumSubscriptionCount = model.PremiumSubscriptionCount.IsSpecified ? model.PremiumSubscriptionCount.Value : null,
NsfwLevel = model.NsfwLevel.IsSpecified ? model.NsfwLevel.Value : null,
WelcomeScreen = model.WelcomeScreen.IsSpecified
? new WelcomeScreen(
model.WelcomeScreen.Value.Description.IsSpecified ? model.WelcomeScreen.Value.Description.Value : null,
model.WelcomeScreen.Value.WelcomeChannels.Select(ch =>
new WelcomeScreenChannel(
ch.ChannelId,
ch.Description,
ch.EmojiName.IsSpecified ? ch.EmojiName.Value : null,
ch.EmojiId.IsSpecified ? ch.EmojiId.Value : null)).ToImmutableArray())
: null,
ApproximateMemberCount = model.ApproximateMemberCount.IsSpecified ? model.ApproximateMemberCount.Value : null,
ApproximatePresenceCount = model.ApproximatePresenceCount.IsSpecified ? model.ApproximatePresenceCount.Value : null
};
}