- Add missing guild properties: `discovery_splash`, `widget_enabled`, `widget_channel_id`, `rules_channel_id`, `max_presences`, `max_presences`, `max_members`, `public_updates_channel_id`, `max_video_channel_users`, `approximate_member_count`, `approximate_presence_count` - Update guild properties: `embed_enabled`, `embed_channel_id` - Add `GetGuildDiscoverySplashUrl` to `CDN` - Add classes related to the guild widget - Add `withCounts` parameter to `GetGuild(s)Async` - Make GuildEmbed related methods obsolete with a message redirecting to widget onespull/1573/head
@@ -62,11 +62,21 @@ namespace Discord | |||||
/// <param name="guildId">The guild snowflake identifier.</param> | /// <param name="guildId">The guild snowflake identifier.</param> | ||||
/// <param name="splashId">The splash icon identifier.</param> | /// <param name="splashId">The splash icon identifier.</param> | ||||
/// <returns> | /// <returns> | ||||
/// A URL pointing to the guild's icon. | |||||
/// A URL pointing to the guild's splash. | |||||
/// </returns> | /// </returns> | ||||
public static string GetGuildSplashUrl(ulong guildId, string splashId) | public static string GetGuildSplashUrl(ulong guildId, string splashId) | ||||
=> splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null; | => splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null; | ||||
/// <summary> | /// <summary> | ||||
/// Returns a guild discovery splash URL. | |||||
/// </summary> | |||||
/// <param name="guildId">The guild snowflake identifier.</param> | |||||
/// <param name="discoverySplashId">The discovery splash icon identifier.</param> | |||||
/// <returns> | |||||
/// A URL pointing to the guild's discovery splash. | |||||
/// </returns> | |||||
public static string GetGuildDiscoverySplashUrl(ulong guildId, string discoverySplashId) | |||||
=> discoverySplashId != null ? $"{DiscordConfig.CDNUrl}discovery-splashes/{guildId}/{discoverySplashId}.jpg" : null; | |||||
/// <summary> | |||||
/// Returns a channel icon URL. | /// Returns a channel icon URL. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="channelId">The channel snowflake identifier.</param> | /// <param name="channelId">The channel snowflake identifier.</param> | ||||
@@ -0,0 +1,21 @@ | |||||
namespace Discord | |||||
{ | |||||
/// <summary> | |||||
/// Provides properties that are used to modify the widget of an <see cref="IGuild" /> with the specified changes. | |||||
/// </summary> | |||||
public class GuildWidgetProperties | |||||
{ | |||||
/// <summary> | |||||
/// Sets whether the widget should be enabled. | |||||
/// </summary> | |||||
public Optional<bool> Enabled { get; set; } | |||||
/// <summary> | |||||
/// Sets the channel that the invite should place its users in, if not <c>null</c>. | |||||
/// </summary> | |||||
public Optional<IChannel> Channel { get; set; } | |||||
/// <summary> | |||||
/// Sets the channel the invite should place its users in, if not <c>null</c>. | |||||
/// </summary> | |||||
public Optional<ulong?> ChannelId { get; set; } | |||||
} | |||||
} |
@@ -35,6 +35,13 @@ namespace Discord | |||||
/// </returns> | /// </returns> | ||||
bool IsEmbeddable { get; } | bool IsEmbeddable { get; } | ||||
/// <summary> | /// <summary> | ||||
/// Gets a value that indicates whether this guild has the widget enabled. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// <c>true</c> if this guild has a widget enabled; otherwise <c>false</c>. | |||||
/// </returns> | |||||
bool IsWidgetEnabled { get; } | |||||
/// <summary> | |||||
/// Gets the default message notifications for users who haven't explicitly set their notification settings. | /// Gets the default message notifications for users who haven't explicitly set their notification settings. | ||||
/// </summary> | /// </summary> | ||||
DefaultMessageNotifications DefaultMessageNotifications { get; } | DefaultMessageNotifications DefaultMessageNotifications { get; } | ||||
@@ -89,6 +96,20 @@ namespace Discord | |||||
/// </returns> | /// </returns> | ||||
string SplashUrl { get; } | string SplashUrl { get; } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the ID of this guild's discovery splash image. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// An identifier for the discovery splash image; <c>null</c> if none is set. | |||||
/// </returns> | |||||
string DiscoverySplashId { get; } | |||||
/// <summary> | |||||
/// Gets the URL of this guild's discovery splash image. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A URL pointing to the guild's discovery splash image; <c>null</c> if none is set. | |||||
/// </returns> | |||||
string DiscoverySplashUrl { get; } | |||||
/// <summary> | |||||
/// Determines if this guild is currently connected and ready to be used. | /// Determines if this guild is currently connected and ready to be used. | ||||
/// </summary> | /// </summary> | ||||
/// <remarks> | /// <remarks> | ||||
@@ -134,6 +155,14 @@ namespace Discord | |||||
/// </returns> | /// </returns> | ||||
ulong? EmbedChannelId { get; } | ulong? EmbedChannelId { get; } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the ID of the channel assigned to the widget of this guild. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel assigned to the widget found | |||||
/// within the widget settings of this guild; <c>null</c> if none is set. | |||||
/// </returns> | |||||
ulong? WidgetChannelId { get; } | |||||
/// <summary> | |||||
/// Gets the ID of the channel where randomized welcome messages are sent. | /// Gets the ID of the channel where randomized welcome messages are sent. | ||||
/// </summary> | /// </summary> | ||||
/// <returns> | /// <returns> | ||||
@@ -142,6 +171,23 @@ namespace Discord | |||||
/// </returns> | /// </returns> | ||||
ulong? SystemChannelId { get; } | ulong? SystemChannelId { get; } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the ID of the channel with the rules. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel that contains the rules; | |||||
/// <c>null</c> if none is set. | |||||
/// </returns> | |||||
ulong? RulesChannelId { get; } | |||||
/// <summary> | |||||
/// Gets the ID of the channel where admins and moderators of guilds with the "PUBLIC" feature | |||||
/// receive notices from Discord. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel where admins and moderators | |||||
/// of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set. | |||||
/// </returns> | |||||
ulong? PublicUpdatesChannelId { get; } | |||||
/// <summary> | |||||
/// Gets the ID of the user that owns this guild. | /// Gets the ID of the user that owns this guild. | ||||
/// </summary> | /// </summary> | ||||
/// <returns> | /// <returns> | ||||
@@ -249,6 +295,47 @@ namespace Discord | |||||
/// The number of premium subscribers of this guild. | /// The number of premium subscribers of this guild. | ||||
/// </returns> | /// </returns> | ||||
int PremiumSubscriptionCount { get; } | int PremiumSubscriptionCount { get; } | ||||
/// <summary> | |||||
/// Gets the maximum number of presences for the guild. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// The maximum number of presences for the guild. | |||||
/// </returns> | |||||
int? MaxPresences { get; } | |||||
/// <summary> | |||||
/// Gets the maximum number of members for the guild. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// The maximum number of members for the guild. | |||||
/// </returns> | |||||
int? MaxMembers { get; } | |||||
/// <summary> | |||||
/// Gets the maximum amount of users in a video channel. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// The maximum amount of users in a video channel. | |||||
/// </returns> | |||||
int? MaxVideoChannelUsers { get; } | |||||
/// <summary> | |||||
/// Gets the approximate number of members in this guild. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Only available when getting a guild via REST when `with_counts` is true. | |||||
/// </remarks> | |||||
/// <returns> | |||||
/// The approximate number of members in this guild. | |||||
/// </returns> | |||||
int? ApproximateMemberCount { get; } | |||||
/// <summary> | |||||
/// Gets the approximate number of non-offline members in this guild. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Only available when getting a guild via REST when `with_counts` is true. | |||||
/// </remarks> | |||||
/// <returns> | |||||
/// The approximate number of non-offline members in this guild. | |||||
/// </returns> | |||||
int? ApproximatePresenceCount { get; } | |||||
/// <summary> | /// <summary> | ||||
/// Gets the preferred locale of this guild in IETF BCP 47 | /// Gets the preferred locale of this guild in IETF BCP 47 | ||||
@@ -285,8 +372,18 @@ namespace Discord | |||||
/// <returns> | /// <returns> | ||||
/// A task that represents the asynchronous modification operation. | /// A task that represents the asynchronous modification operation. | ||||
/// </returns> | /// </returns> | ||||
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")] | |||||
Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null); | Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null); | ||||
/// <summary> | /// <summary> | ||||
/// Modifies this guild's widget. | |||||
/// </summary> | |||||
/// <param name="func">The delegate containing the properties to modify the guild widget with.</param> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous modification operation. | |||||
/// </returns> | |||||
Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null); | |||||
/// <summary> | |||||
/// Bulk-modifies the order of channels in this guild. | /// Bulk-modifies the order of channels in this guild. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="args">The properties used to modify the channel positions with.</param> | /// <param name="args">The properties used to modify the channel positions with.</param> | ||||
@@ -504,7 +601,38 @@ namespace Discord | |||||
/// A task that represents the asynchronous get operation. The task result contains the embed channel set | /// A task that represents the asynchronous get operation. The task result contains the embed channel set | ||||
/// within the server's widget settings; <c>null</c> if none is set. | /// within the server's widget settings; <c>null</c> if none is set. | ||||
/// </returns> | /// </returns> | ||||
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")] | |||||
Task<IGuildChannel> GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | Task<IGuildChannel> GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | ||||
/// <summary> | |||||
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild. | |||||
/// </summary> | |||||
/// <param name="mode">The <see cref="CacheMode" /> that determines whether the object should be fetched from cache.</param> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the widget channel set | |||||
/// within the server's widget settings; <c>null</c> if none is set. | |||||
/// </returns> | |||||
Task<IGuildChannel> GetWidgetChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||||
/// <summary> | |||||
/// Gets the text channel where guilds with the "PUBLIC" feature can display rules and/or guidelines. | |||||
/// </summary> | |||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the text channel | |||||
/// where guilds with the "PUBLIC" feature can display rules and/or guidelines; <c>null</c> if none is set. | |||||
/// </returns> | |||||
Task<ITextChannel> GetRulesChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||||
/// <summary> | |||||
/// Gets the text channel channel where admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord. | |||||
/// </summary> | |||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the text channel channel where | |||||
/// admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set. | |||||
/// </returns> | |||||
Task<ITextChannel> GetPublicUpdatesChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||||
/// <summary> | /// <summary> | ||||
/// Creates a new text channel in this guild. | /// Creates a new text channel in this guild. | ||||
@@ -10,6 +10,7 @@ namespace Discord | |||||
/// <summary> | /// <summary> | ||||
/// Updates this object's properties with its current state. | /// Updates this object's properties with its current state. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
Task UpdateAsync(RequestOptions options = null); | Task UpdateAsync(RequestOptions options = null); | ||||
} | } | ||||
} | } |
@@ -13,6 +13,8 @@ namespace Discord.API | |||||
public string Icon { get; set; } | public string Icon { get; set; } | ||||
[JsonProperty("splash")] | [JsonProperty("splash")] | ||||
public string Splash { get; set; } | public string Splash { get; set; } | ||||
[JsonProperty("discovery_splash")] | |||||
public string DiscoverySplash { get; set; } | |||||
[JsonProperty("owner_id")] | [JsonProperty("owner_id")] | ||||
public ulong OwnerId { get; set; } | public ulong OwnerId { get; set; } | ||||
[JsonProperty("region")] | [JsonProperty("region")] | ||||
@@ -22,9 +24,9 @@ namespace Discord.API | |||||
[JsonProperty("afk_timeout")] | [JsonProperty("afk_timeout")] | ||||
public int AFKTimeout { get; set; } | public int AFKTimeout { get; set; } | ||||
[JsonProperty("embed_enabled")] | [JsonProperty("embed_enabled")] | ||||
public bool EmbedEnabled { get; set; } | |||||
public Optional<bool> EmbedEnabled { get; set; } | |||||
[JsonProperty("embed_channel_id")] | [JsonProperty("embed_channel_id")] | ||||
public ulong? EmbedChannelId { get; set; } | |||||
public Optional<ulong?> EmbedChannelId { get; set; } | |||||
[JsonProperty("verification_level")] | [JsonProperty("verification_level")] | ||||
public VerificationLevel VerificationLevel { get; set; } | public VerificationLevel VerificationLevel { get; set; } | ||||
[JsonProperty("default_message_notifications")] | [JsonProperty("default_message_notifications")] | ||||
@@ -43,6 +45,10 @@ namespace Discord.API | |||||
public MfaLevel MfaLevel { get; set; } | public MfaLevel MfaLevel { get; set; } | ||||
[JsonProperty("application_id")] | [JsonProperty("application_id")] | ||||
public ulong? ApplicationId { get; set; } | public ulong? ApplicationId { get; set; } | ||||
[JsonProperty("widget_enabled")] | |||||
public Optional<bool> WidgetEnabled { get; set; } | |||||
[JsonProperty("widget_channel_id")] | |||||
public Optional<ulong?> WidgetChannelId { get; set; } | |||||
[JsonProperty("system_channel_id")] | [JsonProperty("system_channel_id")] | ||||
public ulong? SystemChannelId { get; set; } | public ulong? SystemChannelId { get; set; } | ||||
[JsonProperty("premium_tier")] | [JsonProperty("premium_tier")] | ||||
@@ -56,9 +62,23 @@ namespace Discord.API | |||||
// this value is inverted, flags set will turn OFF features | // this value is inverted, flags set will turn OFF features | ||||
[JsonProperty("system_channel_flags")] | [JsonProperty("system_channel_flags")] | ||||
public SystemChannelMessageDeny SystemChannelFlags { get; set; } | public SystemChannelMessageDeny SystemChannelFlags { get; set; } | ||||
[JsonProperty("rules_channel_id")] | |||||
public ulong? RulesChannelId { get; set; } | |||||
[JsonProperty("max_presences")] | |||||
public Optional<int?> MaxPresences { get; set; } | |||||
[JsonProperty("max_members")] | |||||
public Optional<int> MaxMembers { get; set; } | |||||
[JsonProperty("premium_subscription_count")] | [JsonProperty("premium_subscription_count")] | ||||
public int? PremiumSubscriptionCount { get; set; } | public int? PremiumSubscriptionCount { get; set; } | ||||
[JsonProperty("preferred_locale")] | [JsonProperty("preferred_locale")] | ||||
public string PreferredLocale { get; set; } | public string PreferredLocale { get; set; } | ||||
[JsonProperty("public_updates_channel_id")] | |||||
public ulong? PublicUpdatesChannelId { get; set; } | |||||
[JsonProperty("max_video_channel_users")] | |||||
public Optional<int> MaxVideoChannelUsers { get; set; } | |||||
[JsonProperty("approximate_member_count")] | |||||
public Optional<int> ApproximateMemberCount { get; set; } | |||||
[JsonProperty("approximate_presence_count")] | |||||
public Optional<int> ApproximatePresenceCount { get; set; } | |||||
} | } | ||||
} | } |
@@ -1,4 +1,4 @@ | |||||
#pragma warning disable CS1591 | |||||
#pragma warning disable CS1591 | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
namespace Discord.API | namespace Discord.API | ||||
@@ -8,6 +8,6 @@ namespace Discord.API | |||||
[JsonProperty("enabled")] | [JsonProperty("enabled")] | ||||
public bool Enabled { get; set; } | public bool Enabled { get; set; } | ||||
[JsonProperty("channel_id")] | [JsonProperty("channel_id")] | ||||
public ulong ChannelId { get; set; } | |||||
public ulong? ChannelId { get; set; } | |||||
} | } | ||||
} | } |
@@ -0,0 +1,13 @@ | |||||
#pragma warning disable CS1591 | |||||
using Newtonsoft.Json; | |||||
namespace Discord.API | |||||
{ | |||||
internal class GuildWidget | |||||
{ | |||||
[JsonProperty("enabled")] | |||||
public bool Enabled { get; set; } | |||||
[JsonProperty("channel_id")] | |||||
public ulong? ChannelId { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
#pragma warning disable CS1591 | |||||
using Newtonsoft.Json; | |||||
namespace Discord.API.Rest | |||||
{ | |||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)] | |||||
internal class ModifyGuildWidgetParams | |||||
{ | |||||
[JsonProperty("enabled")] | |||||
public Optional<bool> Enabled { get; set; } | |||||
[JsonProperty("channel")] | |||||
public Optional<ulong?> ChannelId { get; set; } | |||||
} | |||||
} |
@@ -62,9 +62,9 @@ namespace Discord.Rest | |||||
} | } | ||||
public static async Task<RestGuild> GetGuildAsync(BaseDiscordClient client, | public static async Task<RestGuild> GetGuildAsync(BaseDiscordClient client, | ||||
ulong id, RequestOptions options) | |||||
ulong id, bool withCounts, RequestOptions options) | |||||
{ | { | ||||
var model = await client.ApiClient.GetGuildAsync(id, options).ConfigureAwait(false); | |||||
var model = await client.ApiClient.GetGuildAsync(id, withCounts, options).ConfigureAwait(false); | |||||
if (model != null) | if (model != null) | ||||
return RestGuild.Create(client, model); | return RestGuild.Create(client, model); | ||||
return null; | return null; | ||||
@@ -77,6 +77,14 @@ namespace Discord.Rest | |||||
return RestGuildEmbed.Create(model); | return RestGuildEmbed.Create(model); | ||||
return null; | return null; | ||||
} | } | ||||
public static async Task<RestGuildWidget?> GetGuildWidgetAsync(BaseDiscordClient client, | |||||
ulong id, RequestOptions options) | |||||
{ | |||||
var model = await client.ApiClient.GetGuildWidgetAsync(id, options).ConfigureAwait(false); | |||||
if (model != null) | |||||
return RestGuildWidget.Create(model); | |||||
return null; | |||||
} | |||||
public static IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(BaseDiscordClient client, | public static IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(BaseDiscordClient client, | ||||
ulong? fromGuildId, int? limit, RequestOptions options) | ulong? fromGuildId, int? limit, RequestOptions options) | ||||
{ | { | ||||
@@ -106,13 +114,13 @@ namespace Discord.Rest | |||||
count: limit | count: limit | ||||
); | ); | ||||
} | } | ||||
public static async Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(BaseDiscordClient client, RequestOptions options) | |||||
public static async Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(BaseDiscordClient client, bool withCounts, RequestOptions options) | |||||
{ | { | ||||
var summaryModels = await GetGuildSummariesAsync(client, null, null, options).FlattenAsync().ConfigureAwait(false); | var summaryModels = await GetGuildSummariesAsync(client, null, null, options).FlattenAsync().ConfigureAwait(false); | ||||
var guilds = ImmutableArray.CreateBuilder<RestGuild>(); | var guilds = ImmutableArray.CreateBuilder<RestGuild>(); | ||||
foreach (var summaryModel in summaryModels) | foreach (var summaryModel in summaryModels) | ||||
{ | { | ||||
var guildModel = await client.ApiClient.GetGuildAsync(summaryModel.Id).ConfigureAwait(false); | |||||
var guildModel = await client.ApiClient.GetGuildAsync(summaryModel.Id, withCounts).ConfigureAwait(false); | |||||
if (guildModel != null) | if (guildModel != null) | ||||
guilds.Add(RestGuild.Create(client, guildModel)); | guilds.Add(RestGuild.Create(client, guildModel)); | ||||
} | } | ||||
@@ -140,7 +148,7 @@ namespace Discord.Rest | |||||
public static async Task<RestGuildUser> GetGuildUserAsync(BaseDiscordClient client, | public static async Task<RestGuildUser> GetGuildUserAsync(BaseDiscordClient client, | ||||
ulong guildId, ulong id, RequestOptions options) | ulong guildId, ulong id, RequestOptions options) | ||||
{ | { | ||||
var guild = await GetGuildAsync(client, guildId, options).ConfigureAwait(false); | |||||
var guild = await GetGuildAsync(client, guildId, false, options).ConfigureAwait(false); | |||||
if (guild == null) | if (guild == null) | ||||
return null; | return null; | ||||
@@ -789,7 +789,7 @@ namespace Discord.API | |||||
} | } | ||||
//Guilds | //Guilds | ||||
public async Task<Guild> GetGuildAsync(ulong guildId, RequestOptions options = null) | |||||
public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null) | |||||
{ | { | ||||
Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
@@ -797,7 +797,7 @@ namespace Discord.API | |||||
try | try | ||||
{ | { | ||||
var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}", ids, options: options).ConfigureAwait(false); | |||||
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}?with_counts={(withCounts ? "true" : "false")}", ids, options: options).ConfigureAwait(false); | |||||
} | } | ||||
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | ||||
} | } | ||||
@@ -935,6 +935,32 @@ namespace Discord.API | |||||
return await SendJsonAsync<GuildEmbed>("PATCH", () => $"guilds/{guildId}/embed", args, ids, options: options).ConfigureAwait(false); | return await SendJsonAsync<GuildEmbed>("PATCH", () => $"guilds/{guildId}/embed", args, ids, options: options).ConfigureAwait(false); | ||||
} | } | ||||
//Guild Widget | |||||
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | |||||
public async Task<GuildWidget> GetGuildWidgetAsync(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<GuildWidget>("GET", () => $"guilds/{guildId}/widget", ids, options: options).ConfigureAwait(false); | |||||
} | |||||
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | |||||
} | |||||
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | |||||
/// <exception cref="ArgumentNullException"><paramref name="args"/> must not be <see langword="null"/>.</exception> | |||||
public async Task<GuildWidget> ModifyGuildWidgetAsync(ulong guildId, Rest.ModifyGuildWidgetParams args, RequestOptions options = null) | |||||
{ | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||||
options = RequestOptions.CreateOrClone(options); | |||||
var ids = new BucketIds(guildId: guildId); | |||||
return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false); | |||||
} | |||||
//Guild Integrations | //Guild Integrations | ||||
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | ||||
public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) | public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) | ||||
@@ -1,3 +1,4 @@ | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
using System.IO; | using System.IO; | ||||
@@ -76,15 +77,22 @@ namespace Discord.Rest | |||||
=> ClientHelper.GetInviteAsync(this, inviteId, options); | => ClientHelper.GetInviteAsync(this, inviteId, options); | ||||
public Task<RestGuild> GetGuildAsync(ulong id, RequestOptions options = null) | public Task<RestGuild> GetGuildAsync(ulong id, RequestOptions options = null) | ||||
=> ClientHelper.GetGuildAsync(this, id, options); | |||||
=> ClientHelper.GetGuildAsync(this, id, false, options); | |||||
public Task<RestGuild> GetGuildAsync(ulong id, bool withCounts, RequestOptions options = null) | |||||
=> ClientHelper.GetGuildAsync(this, id, withCounts, options); | |||||
[Obsolete("This endpoint is deprecated, use GetGuildWidgetAsync instead.")] | |||||
public Task<RestGuildEmbed?> GetGuildEmbedAsync(ulong id, RequestOptions options = null) | public Task<RestGuildEmbed?> GetGuildEmbedAsync(ulong id, RequestOptions options = null) | ||||
=> ClientHelper.GetGuildEmbedAsync(this, id, options); | => ClientHelper.GetGuildEmbedAsync(this, id, options); | ||||
public Task<RestGuildWidget?> GetGuildWidgetAsync(ulong id, RequestOptions options = null) | |||||
=> ClientHelper.GetGuildWidgetAsync(this, id, options); | |||||
public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(RequestOptions options = null) | public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(RequestOptions options = null) | ||||
=> ClientHelper.GetGuildSummariesAsync(this, null, null, options); | => ClientHelper.GetGuildSummariesAsync(this, null, null, options); | ||||
public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(ulong fromGuildId, int limit, RequestOptions options = null) | public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(ulong fromGuildId, int limit, RequestOptions options = null) | ||||
=> ClientHelper.GetGuildSummariesAsync(this, fromGuildId, limit, options); | => ClientHelper.GetGuildSummariesAsync(this, fromGuildId, limit, options); | ||||
public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(RequestOptions options = null) | ||||
=> ClientHelper.GetGuildsAsync(this, options); | |||||
=> ClientHelper.GetGuildsAsync(this, false, options); | |||||
public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(bool withCounts, RequestOptions options = null) | |||||
=> ClientHelper.GetGuildsAsync(this, withCounts, options); | |||||
public Task<RestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null) | public Task<RestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null) | ||||
=> ClientHelper.CreateGuildAsync(this, name, region, jpegIcon, options); | => ClientHelper.CreateGuildAsync(this, name, region, jpegIcon, options); | ||||
@@ -5,6 +5,7 @@ using System.Collections.Immutable; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using EmbedModel = Discord.API.GuildEmbed; | using EmbedModel = Discord.API.GuildEmbed; | ||||
using WidgetModel = Discord.API.GuildWidget; | |||||
using Model = Discord.API.Guild; | using Model = Discord.API.Guild; | ||||
using RoleModel = Discord.API.Role; | using RoleModel = Discord.API.Role; | ||||
using ImageModel = Discord.API.Image; | using ImageModel = Discord.API.Image; | ||||
@@ -99,6 +100,27 @@ namespace Discord.Rest | |||||
return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | ||||
} | } | ||||
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | |||||
public static async Task<WidgetModel> ModifyWidgetAsync(IGuild guild, BaseDiscordClient client, | |||||
Action<GuildWidgetProperties> func, RequestOptions options) | |||||
{ | |||||
if (func == null) | |||||
throw new ArgumentNullException(nameof(func)); | |||||
var args = new GuildWidgetProperties(); | |||||
func(args); | |||||
var apiArgs = new API.Rest.ModifyGuildWidgetParams | |||||
{ | |||||
Enabled = args.Enabled | |||||
}; | |||||
if (args.Channel.IsSpecified) | |||||
apiArgs.ChannelId = args.Channel.Value?.Id; | |||||
else if (args.ChannelId.IsSpecified) | |||||
apiArgs.ChannelId = args.ChannelId.Value; | |||||
return await client.ApiClient.ModifyGuildWidgetAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | |||||
} | |||||
public static async Task ReorderChannelsAsync(IGuild guild, BaseDiscordClient client, | public static async Task ReorderChannelsAsync(IGuild guild, BaseDiscordClient client, | ||||
IEnumerable<ReorderChannelProperties> args, RequestOptions options) | IEnumerable<ReorderChannelProperties> args, RequestOptions options) | ||||
{ | { | ||||
@@ -7,6 +7,7 @@ using System.Globalization; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using EmbedModel = Discord.API.GuildEmbed; | using EmbedModel = Discord.API.GuildEmbed; | ||||
using WidgetModel = Discord.API.GuildWidget; | |||||
using Model = Discord.API.Guild; | using Model = Discord.API.Guild; | ||||
namespace Discord.Rest | namespace Discord.Rest | ||||
@@ -28,6 +29,8 @@ namespace Discord.Rest | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public bool IsEmbeddable { get; private set; } | public bool IsEmbeddable { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public bool IsWidgetEnabled { get; private set; } | |||||
/// <inheritdoc /> | |||||
public VerificationLevel VerificationLevel { get; private set; } | public VerificationLevel VerificationLevel { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public MfaLevel MfaLevel { get; private set; } | public MfaLevel MfaLevel { get; private set; } | ||||
@@ -41,8 +44,14 @@ namespace Discord.Rest | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong? EmbedChannelId { get; private set; } | public ulong? EmbedChannelId { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong? WidgetChannelId { get; private set; } | |||||
/// <inheritdoc /> | |||||
public ulong? SystemChannelId { get; private set; } | public ulong? SystemChannelId { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong? RulesChannelId { get; private set; } | |||||
/// <inheritdoc /> | |||||
public ulong? PublicUpdatesChannelId { get; private set; } | |||||
/// <inheritdoc /> | |||||
public ulong OwnerId { get; private set; } | public ulong OwnerId { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string VoiceRegionId { get; private set; } | public string VoiceRegionId { get; private set; } | ||||
@@ -50,6 +59,8 @@ namespace Discord.Rest | |||||
public string IconId { get; private set; } | public string IconId { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string SplashId { get; private set; } | public string SplashId { get; private set; } | ||||
/// <inheritdoc /> | |||||
public string DiscoverySplashId { get; private set; } | |||||
internal bool Available { get; private set; } | internal bool Available { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong? ApplicationId { get; private set; } | public ulong? ApplicationId { get; private set; } | ||||
@@ -67,6 +78,16 @@ namespace Discord.Rest | |||||
public int PremiumSubscriptionCount { get; private set; } | public int PremiumSubscriptionCount { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string PreferredLocale { get; private set; } | public string PreferredLocale { get; private set; } | ||||
/// <inheritdoc /> | |||||
public int? MaxPresences { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? MaxMembers { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? MaxVideoChannelUsers { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? ApproximateMemberCount { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? ApproximatePresenceCount { get; private set; } | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public CultureInfo PreferredCulture { get; private set; } | public CultureInfo PreferredCulture { get; private set; } | ||||
@@ -81,6 +102,8 @@ namespace Discord.Rest | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); | public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string DiscoverySplashUrl => CDN.GetGuildDiscoverySplashUrl(Id, DiscoverySplashId); | |||||
/// <inheritdoc /> | |||||
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); | public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); | ||||
/// <summary> | /// <summary> | ||||
@@ -110,15 +133,24 @@ namespace Discord.Rest | |||||
internal void Update(Model model) | internal void Update(Model model) | ||||
{ | { | ||||
AFKChannelId = model.AFKChannelId; | AFKChannelId = model.AFKChannelId; | ||||
EmbedChannelId = model.EmbedChannelId; | |||||
if (model.EmbedChannelId.IsSpecified) | |||||
EmbedChannelId = model.EmbedChannelId.Value; | |||||
if (model.WidgetChannelId.IsSpecified) | |||||
WidgetChannelId = model.WidgetChannelId.Value; | |||||
SystemChannelId = model.SystemChannelId; | SystemChannelId = model.SystemChannelId; | ||||
RulesChannelId = model.RulesChannelId; | |||||
PublicUpdatesChannelId = model.PublicUpdatesChannelId; | |||||
AFKTimeout = model.AFKTimeout; | AFKTimeout = model.AFKTimeout; | ||||
IsEmbeddable = model.EmbedEnabled; | |||||
if (model.EmbedEnabled.IsSpecified) | |||||
IsEmbeddable = model.EmbedEnabled.Value; | |||||
if (model.WidgetEnabled.IsSpecified) | |||||
IsWidgetEnabled = model.WidgetEnabled.Value; | |||||
IconId = model.Icon; | IconId = model.Icon; | ||||
Name = model.Name; | Name = model.Name; | ||||
OwnerId = model.OwnerId; | OwnerId = model.OwnerId; | ||||
VoiceRegionId = model.Region; | VoiceRegionId = model.Region; | ||||
SplashId = model.Splash; | SplashId = model.Splash; | ||||
DiscoverySplashId = model.DiscoverySplash; | |||||
VerificationLevel = model.VerificationLevel; | VerificationLevel = model.VerificationLevel; | ||||
MfaLevel = model.MfaLevel; | MfaLevel = model.MfaLevel; | ||||
DefaultMessageNotifications = model.DefaultMessageNotifications; | DefaultMessageNotifications = model.DefaultMessageNotifications; | ||||
@@ -130,8 +162,18 @@ namespace Discord.Rest | |||||
SystemChannelFlags = model.SystemChannelFlags; | SystemChannelFlags = model.SystemChannelFlags; | ||||
Description = model.Description; | Description = model.Description; | ||||
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); | PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); | ||||
if (model.MaxPresences.IsSpecified) | |||||
MaxPresences = model.MaxPresences.Value ?? 25000; | |||||
if (model.MaxMembers.IsSpecified) | |||||
MaxMembers = model.MaxMembers.Value; | |||||
if (model.MaxVideoChannelUsers.IsSpecified) | |||||
MaxVideoChannelUsers = model.MaxVideoChannelUsers.Value; | |||||
PreferredLocale = model.PreferredLocale; | PreferredLocale = model.PreferredLocale; | ||||
PreferredCulture = new CultureInfo(PreferredLocale); | PreferredCulture = new CultureInfo(PreferredLocale); | ||||
if (model.ApproximateMemberCount.IsSpecified) | |||||
ApproximateMemberCount = model.ApproximateMemberCount.Value; | |||||
if (model.ApproximatePresenceCount.IsSpecified) | |||||
ApproximatePresenceCount = model.ApproximatePresenceCount.Value; | |||||
if (model.Emojis != null) | if (model.Emojis != null) | ||||
{ | { | ||||
@@ -163,11 +205,30 @@ namespace Discord.Rest | |||||
EmbedChannelId = model.ChannelId; | EmbedChannelId = model.ChannelId; | ||||
IsEmbeddable = model.Enabled; | IsEmbeddable = model.Enabled; | ||||
} | } | ||||
internal void Update(WidgetModel model) | |||||
{ | |||||
WidgetChannelId = model.ChannelId; | |||||
IsWidgetEnabled = model.Enabled; | |||||
} | |||||
//General | //General | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public async Task UpdateAsync(RequestOptions options = null) | public async Task UpdateAsync(RequestOptions options = null) | ||||
=> Update(await Discord.ApiClient.GetGuildAsync(Id, options).ConfigureAwait(false)); | |||||
=> Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false)); | |||||
/// <summary> | |||||
/// Updates this object's properties with its current state. | |||||
/// </summary> | |||||
/// <param name="withCounts"> | |||||
/// If true, <see cref="ApproximateMemberCount"/> and <see cref="ApproximatePresenceCount"/> | |||||
/// will be updated as well. | |||||
/// </param> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <remarks> | |||||
/// If <paramref name="withCounts"/> is true, <see cref="ApproximateMemberCount"/> and | |||||
/// <see cref="ApproximatePresenceCount"/> will be updated as well. | |||||
/// </remarks> | |||||
public async Task UpdateAsync(bool withCounts, RequestOptions options = null) | |||||
=> Update(await Discord.ApiClient.GetGuildAsync(Id, withCounts, options).ConfigureAwait(false)); | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public Task DeleteAsync(RequestOptions options = null) | public Task DeleteAsync(RequestOptions options = null) | ||||
=> GuildHelper.DeleteAsync(this, Discord, options); | => GuildHelper.DeleteAsync(this, Discord, options); | ||||
@@ -182,12 +243,21 @@ namespace Discord.Rest | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | ||||
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")] | |||||
public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) | public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) | ||||
{ | { | ||||
var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false); | var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false); | ||||
Update(model); | Update(model); | ||||
} | } | ||||
/// <inheritdoc /> | |||||
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | |||||
public async Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null) | |||||
{ | |||||
var model = await GuildHelper.ModifyWidgetAsync(this, Discord, func, options).ConfigureAwait(false); | |||||
Update(model); | |||||
} | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
/// <exception cref="ArgumentNullException"><paramref name="args" /> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="args" /> is <c>null</c>.</exception> | ||||
public async Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) | public async Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) | ||||
@@ -401,6 +471,7 @@ namespace Discord.Rest | |||||
/// A task that represents the asynchronous get operation. The task result contains the embed channel set | /// A task that represents the asynchronous get operation. The task result contains the embed channel set | ||||
/// within the server's widget settings; <c>null</c> if none is set. | /// within the server's widget settings; <c>null</c> if none is set. | ||||
/// </returns> | /// </returns> | ||||
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")] | |||||
public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null) | public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null) | ||||
{ | { | ||||
var embedId = EmbedChannelId; | var embedId = EmbedChannelId; | ||||
@@ -410,12 +481,28 @@ namespace Discord.Rest | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the first viewable text channel in this guild. | |||||
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild. | |||||
/// </summary> | /// </summary> | ||||
/// <param name="options">The options to be used when sending the request.</param> | /// <param name="options">The options to be used when sending the request.</param> | ||||
/// <returns> | /// <returns> | ||||
/// A task that represents the asynchronous get operation. The task result contains the first viewable text | |||||
/// channel in this guild; <c>null</c> if none is found. | |||||
/// A task that represents the asynchronous get operation. The task result contains the widget channel set | |||||
/// within the server's widget settings; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public async Task<RestGuildChannel> GetWidgetChannelAsync(RequestOptions options = null) | |||||
{ | |||||
var widgetChannelId = WidgetChannelId; | |||||
if (widgetChannelId.HasValue) | |||||
return await GuildHelper.GetChannelAsync(this, Discord, widgetChannelId.Value, options).ConfigureAwait(false); | |||||
return null; | |||||
} | |||||
/// <summary> | |||||
/// Gets the text channel where guild notices such as welcome messages and boost events are posted. | |||||
/// </summary> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the text channel | |||||
/// where guild notices such as welcome messages and boost events are poste; <c>null</c> if none is found. | |||||
/// </returns> | /// </returns> | ||||
public async Task<RestTextChannel> GetSystemChannelAsync(RequestOptions options = null) | public async Task<RestTextChannel> GetSystemChannelAsync(RequestOptions options = null) | ||||
{ | { | ||||
@@ -427,6 +514,45 @@ namespace Discord.Rest | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/// <summary> | |||||
/// Gets the text channel where guilds with the "PUBLIC" feature can display rules and/or guidelines. | |||||
/// </summary> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the text channel | |||||
/// where guilds with the "PUBLIC" feature can display rules and/or guidelines; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public async Task<RestTextChannel> GetRulesChannelAsync(RequestOptions options = null) | |||||
{ | |||||
var rulesChannelId = RulesChannelId; | |||||
if (rulesChannelId.HasValue) | |||||
{ | |||||
var channel = await GuildHelper.GetChannelAsync(this, Discord, rulesChannelId.Value, options).ConfigureAwait(false); | |||||
return channel as RestTextChannel; | |||||
} | |||||
return null; | |||||
} | |||||
/// <summary> | |||||
/// Gets the text channel channel where admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord. | |||||
/// </summary> | |||||
/// <param name="options">The options to be used when sending the request.</param> | |||||
/// <returns> | |||||
/// A task that represents the asynchronous get operation. The task result contains the text channel channel where | |||||
/// admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public async Task<RestTextChannel> GetPublicUpdatesChannelAsync(RequestOptions options = null) | |||||
{ | |||||
var publicUpdatesChannelId = PublicUpdatesChannelId; | |||||
if (publicUpdatesChannelId.HasValue) | |||||
{ | |||||
var channel = await GuildHelper.GetChannelAsync(this, Discord, publicUpdatesChannelId.Value, options).ConfigureAwait(false); | |||||
return channel as RestTextChannel; | |||||
} | |||||
return null; | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Creates a new text channel in this guild. | /// Creates a new text channel in this guild. | ||||
/// </summary> | /// </summary> | ||||
@@ -808,6 +934,7 @@ namespace Discord.Rest | |||||
return null; | return null; | ||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")] | |||||
async Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) | async Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) | ||||
{ | { | ||||
if (mode == CacheMode.AllowDownload) | if (mode == CacheMode.AllowDownload) | ||||
@@ -816,6 +943,14 @@ namespace Discord.Rest | |||||
return null; | return null; | ||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
async Task<IGuildChannel> IGuild.GetWidgetChannelAsync(CacheMode mode, RequestOptions options) | |||||
{ | |||||
if (mode == CacheMode.AllowDownload) | |||||
return await GetWidgetChannelAsync(options).ConfigureAwait(false); | |||||
else | |||||
return null; | |||||
} | |||||
/// <inheritdoc /> | |||||
async Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) | async Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) | ||||
{ | { | ||||
if (mode == CacheMode.AllowDownload) | if (mode == CacheMode.AllowDownload) | ||||
@@ -824,6 +959,22 @@ namespace Discord.Rest | |||||
return null; | return null; | ||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
async Task<ITextChannel> IGuild.GetRulesChannelAsync(CacheMode mode, RequestOptions options) | |||||
{ | |||||
if (mode == CacheMode.AllowDownload) | |||||
return await GetRulesChannelAsync(options).ConfigureAwait(false); | |||||
else | |||||
return null; | |||||
} | |||||
/// <inheritdoc /> | |||||
async Task<ITextChannel> IGuild.GetPublicUpdatesChannelAsync(CacheMode mode, RequestOptions options) | |||||
{ | |||||
if (mode == CacheMode.AllowDownload) | |||||
return await GetPublicUpdatesChannelAsync(options).ConfigureAwait(false); | |||||
else | |||||
return null; | |||||
} | |||||
/// <inheritdoc /> | |||||
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) | async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) | ||||
=> await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); | => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
@@ -0,0 +1,25 @@ | |||||
using System.Diagnostics; | |||||
using Model = Discord.API.GuildWidget; | |||||
namespace Discord.Rest | |||||
{ | |||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
public struct RestGuildWidget | |||||
{ | |||||
public bool IsEnabled { get; private set; } | |||||
public ulong? ChannelId { get; private set; } | |||||
internal RestGuildWidget(bool isEnabled, ulong? channelId) | |||||
{ | |||||
ChannelId = channelId; | |||||
IsEnabled = isEnabled; | |||||
} | |||||
internal static RestGuildWidget Create(Model model) | |||||
{ | |||||
return new RestGuildWidget(model.Enabled, model.ChannelId); | |||||
} | |||||
public override string ToString() => ChannelId?.ToString() ?? "Unknown"; | |||||
private string DebuggerDisplay => $"{ChannelId} ({(IsEnabled ? "Enabled" : "Disabled")})"; | |||||
} | |||||
} |
@@ -48,6 +48,8 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public bool IsEmbeddable { get; private set; } | public bool IsEmbeddable { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public bool IsWidgetEnabled { get; private set; } | |||||
/// <inheritdoc /> | |||||
public VerificationLevel VerificationLevel { get; private set; } | public VerificationLevel VerificationLevel { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public MfaLevel MfaLevel { get; private set; } | public MfaLevel MfaLevel { get; private set; } | ||||
@@ -83,7 +85,10 @@ namespace Discord.WebSocket | |||||
internal ulong? AFKChannelId { get; private set; } | internal ulong? AFKChannelId { get; private set; } | ||||
internal ulong? EmbedChannelId { get; private set; } | internal ulong? EmbedChannelId { get; private set; } | ||||
internal ulong? WidgetChannelId { get; private set; } | |||||
internal ulong? SystemChannelId { get; private set; } | internal ulong? SystemChannelId { get; private set; } | ||||
internal ulong? RulesChannelId { get; private set; } | |||||
internal ulong? PublicUpdatesChannelId { get; private set; } | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong OwnerId { get; private set; } | public ulong OwnerId { get; private set; } | ||||
/// <summary> Gets the user that owns this guild. </summary> | /// <summary> Gets the user that owns this guild. </summary> | ||||
@@ -95,6 +100,8 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string SplashId { get; private set; } | public string SplashId { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string DiscoverySplashId { get; private set; } | |||||
/// <inheritdoc /> | |||||
public PremiumTier PremiumTier { get; private set; } | public PremiumTier PremiumTier { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string BannerId { get; private set; } | public string BannerId { get; private set; } | ||||
@@ -108,6 +115,12 @@ namespace Discord.WebSocket | |||||
public int PremiumSubscriptionCount { get; private set; } | public int PremiumSubscriptionCount { get; private set; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string PreferredLocale { get; private set; } | public string PreferredLocale { get; private set; } | ||||
/// <inheritdoc /> | |||||
public int? MaxPresences { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? MaxMembers { get; private set; } | |||||
/// <inheritdoc /> | |||||
public int? MaxVideoChannelUsers { get; private set; } | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public CultureInfo PreferredCulture { get; private set; } | public CultureInfo PreferredCulture { get; private set; } | ||||
@@ -119,6 +132,8 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); | public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string DiscoverySplashUrl => CDN.GetGuildDiscoverySplashUrl(Id, DiscoverySplashId); | |||||
/// <inheritdoc /> | |||||
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); | public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); | ||||
/// <summary> Indicates whether the client has all the members downloaded to the local guild cache. </summary> | /// <summary> Indicates whether the client has all the members downloaded to the local guild cache. </summary> | ||||
public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted; | public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted; | ||||
@@ -168,6 +183,7 @@ namespace Discord.WebSocket | |||||
/// <returns> | /// <returns> | ||||
/// A channel set within the server's widget settings; <c>null</c> if none is set. | /// A channel set within the server's widget settings; <c>null</c> if none is set. | ||||
/// </returns> | /// </returns> | ||||
[Obsolete("This property is deprecated, use WidgetChannel instead.")] | |||||
public SocketGuildChannel EmbedChannel | public SocketGuildChannel EmbedChannel | ||||
{ | { | ||||
get | get | ||||
@@ -177,6 +193,20 @@ namespace Discord.WebSocket | |||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A channel set within the server's widget settings; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public SocketGuildChannel WidgetChannel | |||||
{ | |||||
get | |||||
{ | |||||
var id = WidgetChannelId; | |||||
return id.HasValue ? GetChannel(id.Value) : null; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Gets the system channel where randomized welcome messages are sent in this guild. | /// Gets the system channel where randomized welcome messages are sent in this guild. | ||||
/// </summary> | /// </summary> | ||||
/// <returns> | /// <returns> | ||||
@@ -191,6 +221,36 @@ namespace Discord.WebSocket | |||||
} | } | ||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Gets the channel with the guild rules. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A text channel with the guild rules; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public SocketTextChannel RulesChannel | |||||
{ | |||||
get | |||||
{ | |||||
var id = RulesChannelId; | |||||
return id.HasValue ? GetTextChannel(id.Value) : null; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Gets the channel where admins and moderators of guilds with the "PUBLIC" | |||||
/// feature receive notices from Discord. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// A text channel where admins and moderators of guilds with the "PUBLIC" | |||||
/// feature receive notices from Discord; <c>null</c> if none is set. | |||||
/// </returns> | |||||
public SocketTextChannel PublicUpdatesChannel | |||||
{ | |||||
get | |||||
{ | |||||
var id = PublicUpdatesChannelId; | |||||
return id.HasValue ? GetTextChannel(id.Value) : null; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Gets a collection of all text channels in this guild. | /// Gets a collection of all text channels in this guild. | ||||
/// </summary> | /// </summary> | ||||
/// <returns> | /// <returns> | ||||
@@ -360,15 +420,24 @@ namespace Discord.WebSocket | |||||
internal void Update(ClientState state, Model model) | internal void Update(ClientState state, Model model) | ||||
{ | { | ||||
AFKChannelId = model.AFKChannelId; | AFKChannelId = model.AFKChannelId; | ||||
EmbedChannelId = model.EmbedChannelId; | |||||
if (model.EmbedChannelId.IsSpecified) | |||||
EmbedChannelId = model.EmbedChannelId.Value; | |||||
if (model.WidgetChannelId.IsSpecified) | |||||
WidgetChannelId = model.WidgetChannelId.Value; | |||||
SystemChannelId = model.SystemChannelId; | SystemChannelId = model.SystemChannelId; | ||||
RulesChannelId = model.RulesChannelId; | |||||
PublicUpdatesChannelId = model.PublicUpdatesChannelId; | |||||
AFKTimeout = model.AFKTimeout; | AFKTimeout = model.AFKTimeout; | ||||
IsEmbeddable = model.EmbedEnabled; | |||||
if (model.EmbedEnabled.IsSpecified) | |||||
IsEmbeddable = model.EmbedEnabled.Value; | |||||
if (model.WidgetEnabled.IsSpecified) | |||||
IsWidgetEnabled = model.WidgetEnabled.Value; | |||||
IconId = model.Icon; | IconId = model.Icon; | ||||
Name = model.Name; | Name = model.Name; | ||||
OwnerId = model.OwnerId; | OwnerId = model.OwnerId; | ||||
VoiceRegionId = model.Region; | VoiceRegionId = model.Region; | ||||
SplashId = model.Splash; | SplashId = model.Splash; | ||||
DiscoverySplashId = model.DiscoverySplash; | |||||
VerificationLevel = model.VerificationLevel; | VerificationLevel = model.VerificationLevel; | ||||
MfaLevel = model.MfaLevel; | MfaLevel = model.MfaLevel; | ||||
DefaultMessageNotifications = model.DefaultMessageNotifications; | DefaultMessageNotifications = model.DefaultMessageNotifications; | ||||
@@ -380,6 +449,12 @@ namespace Discord.WebSocket | |||||
SystemChannelFlags = model.SystemChannelFlags; | SystemChannelFlags = model.SystemChannelFlags; | ||||
Description = model.Description; | Description = model.Description; | ||||
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); | PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); | ||||
if (model.MaxPresences.IsSpecified) | |||||
MaxPresences = model.MaxPresences.Value ?? 25000; | |||||
if (model.MaxMembers.IsSpecified) | |||||
MaxMembers = model.MaxMembers.Value; | |||||
if (model.MaxVideoChannelUsers.IsSpecified) | |||||
MaxVideoChannelUsers = model.MaxVideoChannelUsers.Value; | |||||
PreferredLocale = model.PreferredLocale; | PreferredLocale = model.PreferredLocale; | ||||
PreferredCulture = new CultureInfo(PreferredLocale); | PreferredCulture = new CultureInfo(PreferredLocale); | ||||
@@ -453,9 +528,14 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | ||||
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")] | |||||
public Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) | public Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) | ||||
=> GuildHelper.ModifyEmbedAsync(this, Discord, func, options); | => GuildHelper.ModifyEmbedAsync(this, Discord, func, options); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | |||||
public Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null) | |||||
=> GuildHelper.ModifyWidgetAsync(this, Discord, func, options); | |||||
/// <inheritdoc /> | |||||
public Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) | public Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) | ||||
=> GuildHelper.ReorderChannelsAsync(this, Discord, args, options); | => GuildHelper.ReorderChannelsAsync(this, Discord, args, options); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
@@ -1133,11 +1213,21 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
ulong? IGuild.EmbedChannelId => EmbedChannelId; | ulong? IGuild.EmbedChannelId => EmbedChannelId; | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
ulong? IGuild.WidgetChannelId => WidgetChannelId; | |||||
/// <inheritdoc /> | |||||
ulong? IGuild.SystemChannelId => SystemChannelId; | ulong? IGuild.SystemChannelId => SystemChannelId; | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
ulong? IGuild.RulesChannelId => RulesChannelId; | |||||
/// <inheritdoc /> | |||||
ulong? IGuild.PublicUpdatesChannelId => PublicUpdatesChannelId; | |||||
/// <inheritdoc /> | |||||
IRole IGuild.EveryoneRole => EveryoneRole; | IRole IGuild.EveryoneRole => EveryoneRole; | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
IReadOnlyCollection<IRole> IGuild.Roles => Roles; | IReadOnlyCollection<IRole> IGuild.Roles => Roles; | ||||
/// <inheritdoc /> | |||||
int? IGuild.ApproximateMemberCount => null; | |||||
/// <inheritdoc /> | |||||
int? IGuild.ApproximatePresenceCount => null; | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync(RequestOptions options) | async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync(RequestOptions options) | ||||
@@ -1177,12 +1267,22 @@ namespace Discord.WebSocket | |||||
Task<ITextChannel> IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions options) | Task<ITextChannel> IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions options) | ||||
=> Task.FromResult<ITextChannel>(DefaultChannel); | => Task.FromResult<ITextChannel>(DefaultChannel); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
[Obsolete("This method is deprecated, use GetWidgetChannelAsync instead.")] | |||||
Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) | Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) | ||||
=> Task.FromResult<IGuildChannel>(EmbedChannel); | => Task.FromResult<IGuildChannel>(EmbedChannel); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
Task<IGuildChannel> IGuild.GetWidgetChannelAsync(CacheMode mode, RequestOptions options) | |||||
=> Task.FromResult<IGuildChannel>(WidgetChannel); | |||||
/// <inheritdoc /> | |||||
Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) | Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) | ||||
=> Task.FromResult<ITextChannel>(SystemChannel); | => Task.FromResult<ITextChannel>(SystemChannel); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
Task<ITextChannel> IGuild.GetRulesChannelAsync(CacheMode mode, RequestOptions options) | |||||
=> Task.FromResult<ITextChannel>(RulesChannel); | |||||
/// <inheritdoc /> | |||||
Task<ITextChannel> IGuild.GetPublicUpdatesChannelAsync(CacheMode mode, RequestOptions options) | |||||
=> Task.FromResult<ITextChannel>(PublicUpdatesChannel); | |||||
/// <inheritdoc /> | |||||
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) | async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) | ||||
=> await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); | => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||