[Feature] Get current bot application information (#2619)
* initial commit * Add support for modifying current bot's app
This commit is contained in:
@@ -14,10 +14,12 @@ namespace Discord.API
|
||||
public ulong Id { get; set; }
|
||||
[JsonProperty("icon")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
[JsonProperty("bot_public")]
|
||||
public bool IsBotPublic { get; set; }
|
||||
public Optional<bool> IsBotPublic { get; set; }
|
||||
[JsonProperty("bot_require_code_grant")]
|
||||
public bool BotRequiresCodeGrant { get; set; }
|
||||
public Optional<bool> BotRequiresCodeGrant { get; set; }
|
||||
|
||||
[JsonProperty("install_params")]
|
||||
public Optional<InstallParams> InstallParams { get; set; }
|
||||
[JsonProperty("team")]
|
||||
@@ -28,8 +30,20 @@ namespace Discord.API
|
||||
public Optional<User> Owner { get; set; }
|
||||
[JsonProperty("tags")]
|
||||
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")]
|
||||
public string TermsOfService { get; set; }
|
||||
|
||||
[JsonProperty("privacy_policy_url")]
|
||||
public string PrivacyPolicy { get; set; }
|
||||
|
||||
@@ -39,7 +53,11 @@ namespace Discord.API
|
||||
[JsonProperty("role_connections_verification_url")]
|
||||
public Optional<string> RoleConnectionsUrl { get; set; }
|
||||
|
||||
[JsonProperty("verify_key")]
|
||||
public string VerifyKey { get; set; }
|
||||
[JsonProperty("interactions_endpoint_url")]
|
||||
public Optional<string> InteractionsEndpointUrl { get; set; }
|
||||
|
||||
[JsonProperty("redirect_uris")]
|
||||
public Optional<string[]> RedirectUris { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Discord.API
|
||||
public string Code { get; set; }
|
||||
|
||||
[JsonProperty("guild")]
|
||||
public Optional<InviteGuild> Guild { get; set; }
|
||||
public Optional<PartialGuild> Guild { get; set; }
|
||||
|
||||
[JsonProperty("channel")]
|
||||
public InviteChannel Channel { get; set; }
|
||||
|
||||
@@ -2,7 +2,7 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
{
|
||||
internal class InviteGuild
|
||||
internal class PartialGuild
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
@@ -23,10 +23,10 @@ namespace Discord.API
|
||||
public Optional<string> IconHash { get; set; }
|
||||
|
||||
[JsonProperty("features")]
|
||||
public GuildFeatures Features { get; set; }
|
||||
public Optional<GuildFeatures> Features { get; set; }
|
||||
|
||||
[JsonProperty("verification_level")]
|
||||
public VerificationLevel VerificationLevel { get; set; }
|
||||
public Optional<VerificationLevel> VerificationLevel { get; set; }
|
||||
|
||||
[JsonProperty("vanity_url_code")]
|
||||
public Optional<string> VanityUrlCode { get; set; }
|
||||
@@ -38,9 +38,16 @@ namespace Discord.API
|
||||
public Optional<bool?> Nsfw { get; set; }
|
||||
|
||||
[JsonProperty("nsfw_level")]
|
||||
public NsfwLevel NsfwLevel { get; set; }
|
||||
public Optional<NsfwLevel> NsfwLevel { get; set; }
|
||||
|
||||
[JsonProperty("welcome_screen")]
|
||||
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; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -17,6 +17,34 @@ namespace Discord.Rest
|
||||
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,
|
||||
ulong id, RequestOptions options)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
public async Task<Application> GetMyApplicationAsync(RequestOptions options = null)
|
||||
{
|
||||
options = RequestOptions.CreateOrClone(options);
|
||||
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)
|
||||
{
|
||||
Preconditions.NotNull(args, nameof(args));
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace Discord.Rest
|
||||
{
|
||||
#region DiscordRestClient
|
||||
private RestApplication _applicationInfo;
|
||||
private RestApplication _currentBotApplication;
|
||||
|
||||
internal static JsonSerializer Serializer = new JsonSerializer() { ContractResolver = new DiscordContractResolver(), NullValueHandling = NullValueHandling.Include };
|
||||
|
||||
/// <summary>
|
||||
@@ -170,6 +172,22 @@ namespace Discord.Rest
|
||||
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)
|
||||
=> ClientHelper.GetChannelAsync(this, id, options);
|
||||
public Task<IReadOnlyCollection<IRestPrivateChannel>> GetPrivateChannelsAsync(RequestOptions options = null)
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Discord.Rest
|
||||
/// <returns>
|
||||
/// A partial guild object representing the guild that the invite points to.
|
||||
/// </returns>
|
||||
public InviteGuild InviteGuild { get; private set; }
|
||||
public PartialGuild PartialGuild { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IInvite.Application" />
|
||||
public RestApplication Application { get; private set; }
|
||||
@@ -85,28 +85,7 @@ namespace Discord.Rest
|
||||
|
||||
if (model.Guild.IsSpecified)
|
||||
{
|
||||
InviteGuild = new InviteGuild
|
||||
(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);
|
||||
PartialGuild = PartialGuildExtensions.Create(model.Guild.Value);
|
||||
}
|
||||
|
||||
if(model.Application.IsSpecified)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Model = Discord.API.Application;
|
||||
|
||||
namespace Discord.Rest
|
||||
@@ -24,9 +25,9 @@ namespace Discord.Rest
|
||||
/// <inheritdoc />
|
||||
public ApplicationFlags Flags { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool IsBotPublic { get; private set; }
|
||||
public bool? IsBotPublic { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool BotRequiresCodeGrant { get; private set; }
|
||||
public bool? BotRequiresCodeGrant { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public ITeam Team { get; private set; }
|
||||
/// <inheritdoc />
|
||||
@@ -48,6 +49,18 @@ namespace Discord.Rest
|
||||
/// <inheritdoc />
|
||||
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 IReadOnlyCollection<string> Tags { get; private set; }
|
||||
@@ -68,13 +81,13 @@ namespace Discord.Rest
|
||||
RPCOrigins = model.RPCOrigins.IsSpecified ? model.RPCOrigins.Value.ToImmutableArray() : ImmutableArray<string>.Empty;
|
||||
Name = model.Name;
|
||||
_iconId = model.Icon;
|
||||
IsBotPublic = model.IsBotPublic;
|
||||
BotRequiresCodeGrant = model.BotRequiresCodeGrant;
|
||||
IsBotPublic = model.IsBotPublic.IsSpecified ? model.IsBotPublic.Value : null;
|
||||
BotRequiresCodeGrant = model.BotRequiresCodeGrant.IsSpecified ? model.BotRequiresCodeGrant.Value : null;
|
||||
Tags = model.Tags.GetValueOrDefault(null)?.ToImmutableArray() ?? ImmutableArray<string>.Empty;
|
||||
PrivacyPolicy = model.PrivacyPolicy;
|
||||
TermsOfService = model.TermsOfService;
|
||||
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)
|
||||
Flags = model.Flags.Value;
|
||||
@@ -86,6 +99,16 @@ namespace Discord.Rest
|
||||
CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null;
|
||||
RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null;
|
||||
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>
|
||||
|
||||
35
src/Discord.Net.Rest/Extensions/PartialGuildExtensions.cs
Normal file
35
src/Discord.Net.Rest/Extensions/PartialGuildExtensions.cs
Normal 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
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user