diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index 34a08f1e7..17fca275e 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -1239,5 +1239,13 @@ namespace Discord /// Task> BulkOverwriteApplicationCommandsAsync(ApplicationCommandProperties[] properties, RequestOptions options = null); + + /// + /// Gets the welcome screen of the guild. + /// + /// + /// A task that represents the asynchronous creation operation. The task result contains a . + /// + Task GetWelcomeScreenAsync(RequestOptions options = null); } } diff --git a/src/Discord.Net.Core/Entities/Guilds/WelcomeScreen.cs b/src/Discord.Net.Core/Entities/Guilds/WelcomeScreen.cs new file mode 100644 index 000000000..3bdebf825 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Guilds/WelcomeScreen.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace Discord; + +public class WelcomeScreen +{ + /// + /// Gets the server description shown in the welcome screen. Null if not set. + /// + public string Description { get; } + + /// + /// Gets the channels shown in the welcome screen, up to 5 channels. + /// + public IReadOnlyCollection Channels { get; } + + internal WelcomeScreen(string description, IReadOnlyCollection channels) + { + Description = description; + + Channels = channels; + } + +} diff --git a/src/Discord.Net.Core/Entities/Guilds/WelcomeScreenChannel.cs b/src/Discord.Net.Core/Entities/Guilds/WelcomeScreenChannel.cs new file mode 100644 index 000000000..0f4c9b060 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Guilds/WelcomeScreenChannel.cs @@ -0,0 +1,43 @@ +using System; +using System.Xml.Linq; + +namespace Discord; + +public class WelcomeScreenChannel : ISnowflakeEntity +{ + /// + /// Gets the channel's id. + /// + public ulong Id { get; } + + /// + /// Gets the description shown for the channel. + /// + public string Description { get; } + + /// + /// Gets the emoji for this channel. if it is unicode emoji, if it is a custom one and if none is set. + /// + /// + /// If the emoji is only the will be populated. + /// Use to get the emoji. + /// + public IEmote Emoji { get; } + + /// + public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); + + internal WelcomeScreenChannel(ulong id, string description, string emojiName = null, ulong? emoteId = null) + { + Id = id; + Description = description; + + if (emoteId.HasValue && emoteId.Value != 0) + Emoji = new Emote(emoteId.Value, emojiName, false); + else if (emojiName != null) + Emoji = new Emoji(emojiName); + else + Emoji = null; + + } +} diff --git a/src/Discord.Net.Rest/API/Common/WelcomeScreen.cs b/src/Discord.Net.Rest/API/Common/WelcomeScreen.cs index d14191b1e..a462eaec1 100644 --- a/src/Discord.Net.Rest/API/Common/WelcomeScreen.cs +++ b/src/Discord.Net.Rest/API/Common/WelcomeScreen.cs @@ -8,5 +8,5 @@ internal class WelcomeScreen public Optional Description { get; set; } [JsonProperty("welcome_channels")] - public Optional WelcomeChannels { get; set; } + public WelcomeScreenChannel[] WelcomeChannels { get; set; } } diff --git a/src/Discord.Net.Rest/API/Common/WelcomeScreenChannel.cs b/src/Discord.Net.Rest/API/Common/WelcomeScreenChannel.cs index 17bec0983..426883dc5 100644 --- a/src/Discord.Net.Rest/API/Common/WelcomeScreenChannel.cs +++ b/src/Discord.Net.Rest/API/Common/WelcomeScreenChannel.cs @@ -11,8 +11,8 @@ internal class WelcomeScreenChannel public string Description { get; set; } [JsonProperty("emoji_id")] - public Optional EmojiId { get; set; } + public Optional EmojiId { get; set; } [JsonProperty("emoji_name")] - public Optional UserId { get; set; } + public Optional EmojiName{ get; set; } } diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 615e5ac12..dd57dba51 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -1589,6 +1589,18 @@ namespace Discord.API var ids = new BucketIds(guildId: guildId); return await SendAsync("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); } + public async Task GetGuildWelcomeScreenAsync(ulong guildId, RequestOptions options = null) + { + Preconditions.NotEqual(guildId, 0, nameof(guildId)); + options = RequestOptions.CreateOrClone(options); + + try + { + var ids = new BucketIds(guildId: guildId); + return await SendAsync("GET", () => $"guilds/{guildId}/welcome-screen", ids, options: options).ConfigureAwait(false); + } + catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } + } #endregion #region Guild Bans diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index c4e3764d1..a4d0de0ee 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -392,6 +392,17 @@ namespace Discord.Rest inviteModel.Uses = vanityModel.Uses; return RestInviteMetadata.Create(client, guild, null, inviteModel); } + + public static async Task GetWelcomeScreenAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) + { + var model = await client.ApiClient.GetGuildWelcomeScreenAsync(guild.Id, options); + + return new WelcomeScreen(model.Description.GetValueOrDefault(null), model.WelcomeChannels.Select( + x => new WelcomeScreenChannel( + x.ChannelId, x.Description, + x.EmojiName.GetValueOrDefault(null), + x.EmojiId.GetValueOrDefault(0))).ToList()); + } #endregion #region Roles diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index eb3254619..1fbfa95de 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -1518,6 +1518,11 @@ namespace Discord.Rest else return null; } + + /// + public Task GetWelcomeScreenAsync(RequestOptions options = null) + => GuildHelper.GetWelcomeScreenAsync(this, Discord, options); + #endregion } } diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index 55f098b2f..e8c3184ff 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -2011,6 +2011,10 @@ namespace Discord.WebSocket RequestOptions options) => await BulkOverwriteApplicationCommandAsync(properties, options); + /// + public Task GetWelcomeScreenAsync(RequestOptions options = null) + => GuildHelper.GetWelcomeScreenAsync(this, Discord, options); + void IDisposable.Dispose() { DisconnectAudioAsync().GetAwaiter().GetResult();