diff --git a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs index ebec03e0b2..1b406ef7f7 100644 --- a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs +++ b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs @@ -60,6 +60,14 @@ public class GuildProperties /// public Optional AfkChannelId { get; set; } /// + /// The ITextChannel where System messages should be sent. + /// + public Optional SystemChannel { get; set; } + /// + /// The ID of the ITextChannel where System messages should be sent. + /// + public Optional SystemChannelId { get; set; } + /// /// The owner of this guild. /// public Optional Owner { get; set; } diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index be9f7b4668..07f01a06ba 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -36,6 +36,8 @@ public interface IGuild : IDeletable, ISnowflakeEntity ulong DefaultChannelId { get; } /// Gets the id of the embed channel for this guild if set, or null if not. ulong? EmbedChannelId { get; } + /// Gets the id of the channel where randomized welcome messages are sent, or null if not. + ulong? SystemChannelId { get; } /// Gets the id of the user that created this guild. ulong OwnerId { get; } /// Gets the id of the region hosting this guild's voice channels. @@ -84,6 +86,7 @@ public interface IGuild : IDeletable, ISnowflakeEntity Task> GetVoiceChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetAFKChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); + Task GetSystemChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetDefaultChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); /// Creates a new text channel. diff --git a/src/Discord.Net.Rest/API/Common/Guild.cs b/src/Discord.Net.Rest/API/Common/Guild.cs index b69ba1293e..0ca1bc2364 100644 --- a/src/Discord.Net.Rest/API/Common/Guild.cs +++ b/src/Discord.Net.Rest/API/Common/Guild.cs @@ -25,6 +25,8 @@ internal class Guild public bool EmbedEnabled { get; set; } [JsonProperty("embed_channel_id")] public ulong? EmbedChannelId { get; set; } + [JsonProperty("system_channel_id")] + public ulong? SystemChannelId { get; set; } [JsonProperty("verification_level")] public VerificationLevel VerificationLevel { get; set; } [JsonProperty("voice_states")] diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs index 2c7d840872..8de10f5349 100644 --- a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs +++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs @@ -18,6 +18,8 @@ internal class ModifyGuildParams public Optional DefaultMessageNotifications { get; set; } [JsonProperty("afk_timeout")] public Optional AfkTimeout { get; set; } + [JsonProperty("system_channel_id")] + public Optional SystemChannelId { get; set; } [JsonProperty("icon")] public Optional Icon { get; set; } [JsonProperty("splash")] diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index f0b376c2e8..a1871db5f5 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -26,6 +26,7 @@ internal static class GuildHelper { AfkChannelId = args.AfkChannelId, AfkTimeout = args.AfkTimeout, + SystemChannelId = args.SystemChannelId, DefaultMessageNotifications = args.DefaultMessageNotifications, Icon = args.Icon.IsSpecified ? args.Icon.Value?.ToModel() : Optional.Create(), Name = args.Name, @@ -39,6 +40,11 @@ internal static class GuildHelper else if (args.AfkChannelId.IsSpecified) apiArgs.AfkChannelId = args.AfkChannelId.Value; + if (args.SystemChannel.IsSpecified) + apiArgs.SystemChannelId = args.SystemChannel.Value.Id; + else if (args.SystemChannelId.IsSpecified) + apiArgs.SystemChannelId = args.SystemChannelId.Value; + if (args.Owner.IsSpecified) apiArgs.OwnerId = args.Owner.Value.Id; else if (args.OwnerId.IsSpecified) diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 86c63de08c..bff893d035 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -26,6 +26,7 @@ public class RestGuild : RestEntity, IGuild, IUpdateable public ulong? AFKChannelId { get; private set; } public ulong? EmbedChannelId { get; private set; } + public ulong? SystemChannelId { get; private set; } public ulong OwnerId { get; private set; } public string VoiceRegionId { get; private set; } public string IconId { get; private set; } @@ -58,6 +59,7 @@ internal void Update(Model model) { AFKChannelId = model.AFKChannelId; EmbedChannelId = model.EmbedChannelId; + SystemChannelId = model.SystemChannelId; AFKTimeout = model.AFKTimeout; IsEmbeddable = model.EmbedEnabled; IconId = model.Icon; @@ -201,6 +203,16 @@ public async Task GetEmbedChannelAsync(RequestOptions options return await GuildHelper.GetChannelAsync(this, Discord, embedId.Value, options).ConfigureAwait(false); return null; } + public async Task GetSystemChannelAsync(RequestOptions options = null) + { + var systemId = SystemChannelId; + if (systemId.HasValue) + { + var channel = await GuildHelper.GetChannelAsync(this, Discord, systemId.Value, options).ConfigureAwait(false); + return channel as RestTextChannel; + } + return null; + } public Task CreateTextChannelAsync(string name, RequestOptions options = null) => GuildHelper.CreateTextChannelAsync(this, Discord, name, options); public Task CreateVoiceChannelAsync(string name, RequestOptions options = null) @@ -324,6 +336,13 @@ async Task IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOpt else return null; } + async Task IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) + { + if (mode == CacheMode.AllowDownload) + return await GetSystemChannelAsync(options).ConfigureAwait(false); + else + return null; + } async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options) => await CreateTextChannelAsync(name, options).ConfigureAwait(false); async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options) diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index 999beef93e..4f43d44140 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -47,6 +47,7 @@ public class SocketGuild : SocketEntity, IGuild internal ulong? AFKChannelId { get; private set; } internal ulong? EmbedChannelId { get; private set; } + internal ulong? SystemChannelId { get; private set; } public ulong OwnerId { get; private set; } public SocketGuildUser Owner => GetUser(OwnerId); public string VoiceRegionId { get; private set; } @@ -81,6 +82,14 @@ public SocketGuildChannel EmbedChannel return id.HasValue ? GetChannel(id.Value) : null; } } + public SocketTextChannel SystemChannel + { + get + { + var id = SystemChannelId; + return id.HasValue ? GetTextChannel(id.Value) : null; + } + } public IReadOnlyCollection TextChannels => Channels.Select(x => x as SocketTextChannel).Where(x => x != null).ToImmutableArray(); public IReadOnlyCollection VoiceChannels @@ -191,6 +200,7 @@ internal void Update(ClientState state, Model model) { AFKChannelId = model.AFKChannelId; EmbedChannelId = model.EmbedChannelId; + SystemChannelId = model.SystemChannelId; AFKTimeout = model.AFKTimeout; IsEmbeddable = model.EmbedEnabled; IconId = model.Icon; @@ -611,6 +621,7 @@ internal async Task RepopulateAudioStreamsAsync() bool IGuild.Available => true; ulong IGuild.DefaultChannelId => DefaultChannel?.Id ?? 0; ulong? IGuild.EmbedChannelId => EmbedChannelId; + ulong? IGuild.SystemChannelId => SystemChannelId; IRole IGuild.EveryoneRole => EveryoneRole; IReadOnlyCollection IGuild.Roles => Roles; @@ -635,6 +646,8 @@ Task IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions => Task.FromResult(DefaultChannel); Task IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) => Task.FromResult(EmbedChannel); + Task IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) + => Task.FromResult(SystemChannel); async Task IGuild.CreateTextChannelAsync(string name, RequestOptions options) => await CreateTextChannelAsync(name, options).ConfigureAwait(false); async Task IGuild.CreateVoiceChannelAsync(string name, RequestOptions options)