[Feature] Guild Onboarding support (#2616)

* api models

* moar models

* complete models

* modelsss

* forgot to push

* oh lol forgot this too

* api & rest guild method

* revert VS being VS & formatting to file scoped namespace

* socket entities

* yup

* fix xml doc

* changes
This commit is contained in:
Misha133
2023-04-15 02:08:30 +03:00
committed by GitHub
parent 84431decfd
commit 3a8f76c4b1
18 changed files with 574 additions and 3 deletions

View File

@@ -0,0 +1,18 @@
using Newtonsoft.Json;
namespace Discord.API;
internal class GuildOnboarding
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("prompts")]
public GuildOnboardingPrompt[] Prompts { get; set; }
[JsonProperty("default_channel_ids")]
public ulong[] DefaultChannelIds { get; set; }
[JsonProperty("enabled")]
public bool Enabled { get; set; }
}

View File

@@ -0,0 +1,27 @@
using Newtonsoft.Json;
namespace Discord.API;
internal class GuildOnboardingPrompt
{
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("options")]
public GuildOnboardingPromptOption[] Options { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("single_select")]
public bool IsSingleSelect { get; set; }
[JsonProperty("required")]
public bool IsRequired { get; set; }
[JsonProperty("in_onboarding")]
public bool IsInOnboarding { get; set; }
[JsonProperty("type")]
public GuildOnboardingPromptType Type { get; set; }
}

View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
namespace Discord.API;
internal class GuildOnboardingPromptOption
{
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("channel_ids")]
public ulong[] ChannelIds { get; set; }
[JsonProperty("role_ids")]
public ulong[] RoleIds { get; set; }
[JsonProperty("emoji")]
public Emoji Emoji { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public Optional<string> Description { get; set; }
}

View File

@@ -2239,6 +2239,19 @@ namespace Discord.API
#endregion
#region Guild Onboarding
public async Task<GuildOnboarding> GetGuildOnboardingAsync(ulong guildId, RequestOptions options)
{
Preconditions.NotEqual(guildId, 0, nameof(guildId));
options = RequestOptions.CreateOrClone(options);
return await SendAsync<GuildOnboarding>("GET", () => $"guilds/{guildId}/onboarding", new BucketIds(guildId: guildId), options: options);
}
#endregion
#region Users
public async Task<User> GetUserAsync(ulong userId, RequestOptions options = null)
{

View File

@@ -193,7 +193,7 @@ namespace Discord.Rest
},
start: fromUserId,
count: limit
);
);
}
public static async Task<RestBan> GetBanAsync(IGuild guild, BaseDiscordClient client, ulong userId, RequestOptions options)
@@ -427,7 +427,7 @@ namespace Discord.Rest
}
public static async Task DeleteIntegrationAsync(IGuild guild, BaseDiscordClient client, ulong id,
RequestOptions options) =>
await client.ApiClient.DeleteIntegrationAsync(guild.Id, id, options).ConfigureAwait(false);
await client.ApiClient.DeleteIntegrationAsync(guild.Id, id, options).ConfigureAwait(false);
#endregion
#region Interactions
@@ -810,7 +810,7 @@ namespace Discord.Rest
}
public static IAsyncEnumerable<IReadOnlyCollection<RestUser>> GetEventUsersAsync(BaseDiscordClient client, IGuildScheduledEvent guildEvent,
ulong? fromUserId, int? limit, RequestOptions options)
ulong? fromUserId, int? limit, RequestOptions options)
{
return new PagedAsyncEnumerable<RestUser>(
DiscordConfig.MaxGuildEventUsersPerBatch,
@@ -1254,5 +1254,12 @@ namespace Discord.Rest
public static Task DeleteRuleAsync(BaseDiscordClient client, IAutoModRule rule, RequestOptions options)
=> client.ApiClient.DeleteGuildAutoModRuleAsync(rule.GuildId, rule.Id, options);
#endregion
#region Onboarding
public static async Task<GuildOnboarding> GetGuildOnboardingAsync(IGuild guild, BaseDiscordClient client, RequestOptions options)
=> await client.ApiClient.GetGuildOnboardingAsync(guild.Id, options);
#endregion
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Model = Discord.API.GuildOnboarding;
namespace Discord.Rest;
/// <inheritdoc />
public class RestGuildOnboarding : IGuildOnboarding
{
/// <inheritdoc />
public ulong GuildId { get; private set; }
/// <inheritdoc cref="IGuildOnboarding.Guild" />
public RestGuild Guild { get; private set; }
/// <inheritdoc />
public IReadOnlyCollection<ulong> DefaultChannelIds { get; private set; }
/// <inheritdoc />
public bool IsEnabled { get; private set; }
/// <inheritdoc cref="IGuildOnboarding.Prompts"/>
public IReadOnlyCollection<RestGuildOnboardingPrompt> Prompts { get; private set; }
internal RestGuildOnboarding(BaseDiscordClient discord, Model model, RestGuild guild = null)
{
GuildId = model.GuildId;
DefaultChannelIds = model.DefaultChannelIds.ToImmutableArray();
IsEnabled = model.Enabled;
Guild = guild;
Prompts = model.Prompts.Select(prompt => new RestGuildOnboardingPrompt(discord, prompt.Id, prompt)).ToImmutableArray();
}
#region IGuildOnboarding
/// <inheritdoc />
IReadOnlyCollection<IGuildOnboardingPrompt> IGuildOnboarding.Prompts => Prompts;
/// <inheritdoc />
IGuild IGuildOnboarding.Guild => Guild;
#endregion
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Model = Discord.API.GuildOnboardingPrompt;
namespace Discord.Rest;
/// <inheritdoc cref="IGuildOnboardingPrompt"/>
public class RestGuildOnboardingPrompt : RestEntity<ulong>, IGuildOnboardingPrompt
{
/// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
/// <inheritdoc cref="IGuildOnboardingPrompt.Options"/>
public IReadOnlyCollection<RestGuildOnboardingPromptOption> Options { get; private set; }
/// <inheritdoc />
public string Title { get; private set; }
/// <inheritdoc />
public bool IsSingleSelect { get; private set; }
/// <inheritdoc />
public bool IsRequired { get; private set; }
/// <inheritdoc />
public bool IsInOnboarding { get; private set; }
/// <inheritdoc />
public GuildOnboardingPromptType Type { get; private set; }
internal RestGuildOnboardingPrompt(BaseDiscordClient discord, ulong id, Model model) : base(discord, id)
{
Title = model.Title;
IsSingleSelect = model.IsSingleSelect;
IsInOnboarding = model.IsInOnboarding;
IsRequired = model.IsRequired;
Type = model.Type;
Options = model.Options.Select(option => new RestGuildOnboardingPromptOption(discord, option.Id, option)).ToImmutableArray();
}
#region IGuildOnboardingPrompt
/// <inheritdoc />
IReadOnlyCollection<IGuildOnboardingPromptOption> IGuildOnboardingPrompt.Options => Options;
#endregion
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Model = Discord.API.GuildOnboardingPromptOption;
namespace Discord.Rest;
/// <inheritdoc cref="IGuildOnboardingPromptOption"/>
public class RestGuildOnboardingPromptOption : RestEntity<ulong>, IGuildOnboardingPromptOption
{
/// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
/// <inheritdoc />
public IReadOnlyCollection<ulong> ChannelIds { get; private set; }
/// <inheritdoc />
public IReadOnlyCollection<ulong> RoleIds { get; private set; }
/// <inheritdoc />
public IEmote Emoji { get; private set; }
/// <inheritdoc />
public string Title { get; private set; }
/// <inheritdoc />
public string Description { get; private set; }
internal RestGuildOnboardingPromptOption(BaseDiscordClient discord, ulong id, Model model) : base(discord, id)
{
ChannelIds = model.ChannelIds.ToImmutableArray();
RoleIds = model.RoleIds.ToImmutableArray();
Title = model.Title;
Description = model.Description.IsSpecified ? model.Description.Value : null;
if (model.Emoji.Id.HasValue)
{
Emoji = new Emote(model.Emoji.Id.Value, model.Emoji.Name, model.Emoji.Animated ?? false);
}
else if (!string.IsNullOrWhiteSpace(model.Emoji.Name))
{
Emoji = new Emoji(model.Emoji.Name);
}
else
{
Emoji = null;
}
}
}

View File

@@ -1234,6 +1234,18 @@ namespace Discord.Rest
}
#endregion
#region Onboarding
/// <inheritdoc cref="IGuild.GetOnboardingAsync"/>
public async Task<RestGuildOnboarding> GetOnboardingAsync(RequestOptions options = null)
{
var model = await GuildHelper.GetGuildOnboardingAsync(this, Discord, options);
return new RestGuildOnboarding(Discord, model, this);
}
#endregion
#region IGuild
@@ -1592,6 +1604,10 @@ namespace Discord.Rest
/// <inheritdoc/>
async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options)
=> await CreateAutoModRuleAsync(props, options).ConfigureAwait(false);
/// <inheritdoc/>
async Task<IGuildOnboarding> IGuild.GetOnboardingAsync(RequestOptions options)
=> await GetOnboardingAsync(options);
#endregion
}