| @@ -1239,5 +1239,13 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| Task<IReadOnlyCollection<IApplicationCommand>> BulkOverwriteApplicationCommandsAsync(ApplicationCommandProperties[] properties, | Task<IReadOnlyCollection<IApplicationCommand>> BulkOverwriteApplicationCommandsAsync(ApplicationCommandProperties[] properties, | ||||
| RequestOptions options = null); | RequestOptions options = null); | ||||
| /// <summary> | |||||
| /// Gets the welcome screen of the guild. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous creation operation. The task result contains a <see cref="WelcomeScreen"/>. | |||||
| /// </returns> | |||||
| Task<WelcomeScreen> GetWelcomeScreenAsync(RequestOptions options = null); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,24 @@ | |||||
| using System.Collections.Generic; | |||||
| namespace Discord; | |||||
| public class WelcomeScreen | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the server description shown in the welcome screen. Null if not set. | |||||
| /// </summary> | |||||
| public string Description { get; } | |||||
| /// <summary> | |||||
| /// Gets the channels shown in the welcome screen, up to 5 channels. | |||||
| /// </summary> | |||||
| public IReadOnlyCollection<WelcomeScreenChannel> Channels { get; } | |||||
| internal WelcomeScreen(string description, IReadOnlyCollection<WelcomeScreenChannel> channels) | |||||
| { | |||||
| Description = description; | |||||
| Channels = channels; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,43 @@ | |||||
| using System; | |||||
| using System.Xml.Linq; | |||||
| namespace Discord; | |||||
| public class WelcomeScreenChannel : ISnowflakeEntity | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the channel's id. | |||||
| /// </summary> | |||||
| public ulong Id { get; } | |||||
| /// <summary> | |||||
| /// Gets the description shown for the channel. | |||||
| /// </summary> | |||||
| public string Description { get; } | |||||
| /// <summary> | |||||
| /// Gets the emoji for this channel. <see cref="Emoji"/> if it is unicode emoji, <see cref="Emote"/> if it is a custom one and <see langword="null"/> if none is set. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// If the emoji is <see cref="Emote"/> only the <see cref="Emote.Id"/> will be populated. | |||||
| /// Use <see cref="IGuild.GetEmoteAsync"/> to get the emoji. | |||||
| /// </remarks> | |||||
| public IEmote Emoji { get; } | |||||
| /// <inheritdoc/> | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -8,5 +8,5 @@ internal class WelcomeScreen | |||||
| public Optional<string> Description { get; set; } | public Optional<string> Description { get; set; } | ||||
| [JsonProperty("welcome_channels")] | [JsonProperty("welcome_channels")] | ||||
| public Optional<WelcomeScreenChannel[]> WelcomeChannels { get; set; } | |||||
| public WelcomeScreenChannel[] WelcomeChannels { get; set; } | |||||
| } | } | ||||
| @@ -11,8 +11,8 @@ internal class WelcomeScreenChannel | |||||
| public string Description { get; set; } | public string Description { get; set; } | ||||
| [JsonProperty("emoji_id")] | [JsonProperty("emoji_id")] | ||||
| public Optional<ulong> EmojiId { get; set; } | |||||
| public Optional<ulong?> EmojiId { get; set; } | |||||
| [JsonProperty("emoji_name")] | [JsonProperty("emoji_name")] | ||||
| public Optional<string> UserId { get; set; } | |||||
| public Optional<string> EmojiName{ get; set; } | |||||
| } | } | ||||
| @@ -1589,6 +1589,18 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); | return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<WelcomeScreen> 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<WelcomeScreen>("GET", () => $"guilds/{guildId}/welcome-screen", ids, options: options).ConfigureAwait(false); | |||||
| } | |||||
| catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | |||||
| } | |||||
| #endregion | #endregion | ||||
| #region Guild Bans | #region Guild Bans | ||||
| @@ -392,6 +392,17 @@ namespace Discord.Rest | |||||
| inviteModel.Uses = vanityModel.Uses; | inviteModel.Uses = vanityModel.Uses; | ||||
| return RestInviteMetadata.Create(client, guild, null, inviteModel); | return RestInviteMetadata.Create(client, guild, null, inviteModel); | ||||
| } | } | ||||
| public static async Task<WelcomeScreen> 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 | #endregion | ||||
| #region Roles | #region Roles | ||||
| @@ -1518,6 +1518,11 @@ namespace Discord.Rest | |||||
| else | else | ||||
| return null; | return null; | ||||
| } | } | ||||
| /// <inheritdoc/> | |||||
| public Task<WelcomeScreen> GetWelcomeScreenAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetWelcomeScreenAsync(this, Discord, options); | |||||
| #endregion | #endregion | ||||
| } | } | ||||
| } | } | ||||
| @@ -2011,6 +2011,10 @@ namespace Discord.WebSocket | |||||
| RequestOptions options) | RequestOptions options) | ||||
| => await BulkOverwriteApplicationCommandAsync(properties, options); | => await BulkOverwriteApplicationCommandAsync(properties, options); | ||||
| /// <inheritdoc/> | |||||
| public Task<WelcomeScreen> GetWelcomeScreenAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetWelcomeScreenAsync(this, Discord, options); | |||||
| void IDisposable.Dispose() | void IDisposable.Dispose() | ||||
| { | { | ||||
| DisconnectAudioAsync().GetAwaiter().GetResult(); | DisconnectAudioAsync().GetAwaiter().GetResult(); | ||||