diff --git a/src/Discord.Net.Core/Entities/Guilds/ExplicitContentFilterLevel.cs b/src/Discord.Net.Core/Entities/Guilds/ExplicitContentFilterLevel.cs
new file mode 100644
index 000000000..54c0bdafe
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/ExplicitContentFilterLevel.cs
@@ -0,0 +1,13 @@
+namespace Discord
+{
+ public enum ExplicitContentFilterLevel
+ {
+ /// No messages will be scanned.
+ Disabled = 0,
+ /// Scans messages from all guild members that do not have a role.
+ /// Recommented option for servers that use roles for trusted membership.
+ MembersWithoutRoles = 1,
+ /// Scan messages sent by all guild members.
+ AllMembers = 2
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs
index 0ffe8db35..e6d21a463 100644
--- a/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs
@@ -66,5 +66,9 @@ namespace Discord
/// Gets or sets the ID of the owner of this guild.
///
public Optional OwnerId { get; set; }
+ ///
+ /// Gets or sets the explicit content filter level of this guild.
+ ///
+ public Optional ExplicitContentFilter { get; set; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 9b91b9440..c321cd2e3 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -53,6 +53,13 @@ namespace Discord
///
VerificationLevel VerificationLevel { get; }
///
+ /// Gets the level of content filtering applied to user's content in a Guild.
+ ///
+ ///
+ /// The level of explicit content filtering.
+ ///
+ ExplicitContentFilterLevel ExplicitContentFilter { get; }
+ ///
/// Gets the ID of this guild's icon.
///
///
@@ -141,6 +148,13 @@ namespace Discord
///
ulong OwnerId { get; }
///
+ /// Gets the application ID of the guild creator if it is bot-created.
+ ///
+ ///
+ /// A representing the snowflake identifier of the application ID that created this guild, or null if it was not bot-created.
+ ///
+ ulong? ApplicationId { get; }
+ ///
/// Gets the ID of the region hosting this guild's voice channels.
///
///
diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
index 87754eecd..33e019419 100644
--- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
@@ -100,5 +100,25 @@ namespace Discord
/// A read-only collection of user IDs.
///
IReadOnlyCollection MentionedUserIds { get; }
+ ///
+ /// Returns the Activity associated with a message.
+ ///
+ ///
+ /// Sent with Rich Presence-related chat embeds.
+ ///
+ ///
+ /// A message's activity, if any is associated.
+ ///
+ MessageActivity Activity { get; }
+ ///
+ /// Returns the Application associated with a messsage.
+ ///
+ ///
+ /// Sent with Rich-Presence-related chat embeds.
+ ///
+ ///
+ /// A message's application, if any is associated.
+ ///
+ MessageApplication Application { get; }
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs b/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs
new file mode 100644
index 000000000..d19e6a8e9
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/MessageActivity.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
+ public class MessageActivity
+ {
+ ///
+ /// Gets the type of activity of this message.
+ ///
+ public MessageActivityType Type { get; set; }
+ ///
+ /// Gets the party ID of this activity, if any.
+ ///
+ public string PartyId { get; set; }
+
+ private string DebuggerDisplay
+ => $"{Type}{(string.IsNullOrWhiteSpace(PartyId) ? "" : $" {PartyId}")}";
+
+ public override string ToString() => DebuggerDisplay;
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageActivityType.cs b/src/Discord.Net.Core/Entities/Messages/MessageActivityType.cs
new file mode 100644
index 000000000..68b99a9c1
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/MessageActivityType.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ public enum MessageActivityType
+ {
+ Join = 1,
+ Spectate = 2,
+ Listen = 3,
+ JoinRequest = 5
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs b/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs
new file mode 100644
index 000000000..960d1700f
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/MessageApplication.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
+ public class MessageApplication
+ {
+ ///
+ /// Gets the snowflake ID of the application.
+ ///
+ public ulong Id { get; set; }
+ ///
+ /// Gets the ID of the embed's image asset.
+ ///
+ public string CoverImage { get; set; }
+ ///
+ /// Gets the application's description.
+ ///
+ public string Description { get; set; }
+ ///
+ /// Gets the ID of the application's icon.
+ ///
+ public string Icon { get; set; }
+ ///
+ /// Gets the Url of the application's icon.
+ ///
+ public string IconUrl
+ => $"https://cdn.discordapp.com/app-icons/{Id}/{Icon}";
+ ///
+ /// Gets the name of the application.
+ ///
+ public string Name { get; set; }
+ private string DebuggerDisplay
+ => $"{Name} ({Id}): {Description}";
+ public override string ToString()
+ => DebuggerDisplay;
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/Guild.cs b/src/Discord.Net.Rest/API/Common/Guild.cs
index 0ca1bc236..a84b55a93 100644
--- a/src/Discord.Net.Rest/API/Common/Guild.cs
+++ b/src/Discord.Net.Rest/API/Common/Guild.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API
@@ -25,10 +25,12 @@ namespace Discord.API
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("default_message_notifications")]
+ public DefaultMessageNotifications DefaultMessageNotifications { get; set; }
+ [JsonProperty("explicit_content_filter")]
+ public ExplicitContentFilterLevel ExplicitContentFilter { get; set; }
[JsonProperty("voice_states")]
public VoiceState[] VoiceStates { get; set; }
[JsonProperty("roles")]
@@ -39,7 +41,9 @@ namespace Discord.API
public string[] Features { get; set; }
[JsonProperty("mfa_level")]
public MfaLevel MfaLevel { get; set; }
- [JsonProperty("default_message_notifications")]
- public DefaultMessageNotifications DefaultMessageNotifications { get; set; }
+ [JsonProperty("application_id")]
+ public ulong? ApplicationId { get; set; }
+ [JsonProperty("system_channel_id")]
+ public ulong? SystemChannelId { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/Message.cs b/src/Discord.Net.Rest/API/Common/Message.cs
index 229249ccf..10bdbe568 100644
--- a/src/Discord.Net.Rest/API/Common/Message.cs
+++ b/src/Discord.Net.Rest/API/Common/Message.cs
@@ -44,5 +44,11 @@ namespace Discord.API
public Optional Pinned { get; set; }
[JsonProperty("reactions")]
public Optional Reactions { get; set; }
+ // sent with Rich Presence-related chat embeds
+ [JsonProperty("activity")]
+ public Optional Activity { get; set; }
+ // sent with Rich Presence-related chat embeds
+ [JsonProperty("application")]
+ public Optional Application { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/MessageActivity.cs b/src/Discord.Net.Rest/API/Common/MessageActivity.cs
new file mode 100644
index 000000000..701f6fc03
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/MessageActivity.cs
@@ -0,0 +1,17 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ public class MessageActivity
+ {
+ [JsonProperty("type")]
+ public Optional Type { get; set; }
+ [JsonProperty("party_id")]
+ public Optional PartyId { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/MessageApplication.cs b/src/Discord.Net.Rest/API/Common/MessageApplication.cs
new file mode 100644
index 000000000..7302185ad
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/MessageApplication.cs
@@ -0,0 +1,38 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ public class MessageApplication
+ {
+ ///
+ /// Gets the snowflake ID of the application.
+ ///
+ [JsonProperty("id")]
+ public ulong Id { get; set; }
+ ///
+ /// Gets the ID of the embed's image asset.
+ ///
+ [JsonProperty("cover_image")]
+ public string CoverImage { get; set; }
+ ///
+ /// Gets the application's description.
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+ ///
+ /// Gets the ID of the application's icon.
+ ///
+ [JsonProperty("icon")]
+ public string Icon { get; set; }
+ ///
+ /// Gets the name of the application.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs
index 8de10f534..ba70c58d6 100644
--- a/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Rest
@@ -28,5 +28,7 @@ namespace Discord.API.Rest
public Optional AfkChannelId { get; set; }
[JsonProperty("owner_id")]
public Optional OwnerId { get; set; }
+ [JsonProperty("explicit_content_filter")]
+ public Optional ExplicitContentFilter { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index b8b66f802..7b77dafc7 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -32,7 +32,8 @@ namespace Discord.Rest
Icon = args.Icon.IsSpecified ? args.Icon.Value?.ToModel() : Optional.Create(),
Name = args.Name,
Splash = args.Splash.IsSpecified ? args.Splash.Value?.ToModel() : Optional.Create(),
- VerificationLevel = args.VerificationLevel
+ VerificationLevel = args.VerificationLevel,
+ ExplicitContentFilter = args.ExplicitContentFilter
};
if (args.AfkChannel.IsSpecified)
@@ -60,6 +61,9 @@ namespace Discord.Rest
if (!apiArgs.Icon.IsSpecified && guild.IconId != null)
apiArgs.Icon = new ImageModel(guild.IconId);
+ if (args.ExplicitContentFilter.IsSpecified)
+ apiArgs.ExplicitContentFilter = args.ExplicitContentFilter.Value;
+
return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
}
/// is null.
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index 9c4ecd848..8cd81f218 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -32,6 +32,8 @@ namespace Discord.Rest
public MfaLevel MfaLevel { get; private set; }
///
public DefaultMessageNotifications DefaultMessageNotifications { get; private set; }
+ ///
+ public ExplicitContentFilterLevel ExplicitContentFilter { get; private set; }
///
public ulong? AFKChannelId { get; private set; }
@@ -48,6 +50,8 @@ namespace Discord.Rest
///
public string SplashId { get; private set; }
internal bool Available { get; private set; }
+ ///
+ public ulong? ApplicationId { get; private set; }
///
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -98,6 +102,8 @@ namespace Discord.Rest
VerificationLevel = model.VerificationLevel;
MfaLevel = model.MfaLevel;
DefaultMessageNotifications = model.DefaultMessageNotifications;
+ ExplicitContentFilter = model.ExplicitContentFilter;
+ ApplicationId = model.ApplicationId;
if (model.Emojis != null)
{
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
index a4ecf3647..fae1aff99 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
@@ -55,6 +55,10 @@ namespace Discord.Rest
///
public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks);
+ ///
+ public MessageActivity Activity { get; private set; }
+ ///
+ public MessageApplication Application { get; private set; }
internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
: base(discord, id)
@@ -77,6 +81,29 @@ namespace Discord.Rest
if (model.Content.IsSpecified)
Content = model.Content.Value;
+
+ if (model.Application.IsSpecified)
+ {
+ // create a new Application from the API model
+ Application = new MessageApplication()
+ {
+ Id = model.Application.Value.Id,
+ CoverImage = model.Application.Value.CoverImage,
+ Description = model.Application.Value.Description,
+ Icon = model.Application.Value.Icon,
+ Name = model.Application.Value.Name
+ };
+ }
+
+ if (model.Activity.IsSpecified)
+ {
+ // create a new Activity from the API model
+ Activity = new MessageActivity()
+ {
+ Type = model.Activity.Value.Type.Value,
+ PartyId = model.Activity.Value.PartyId.Value
+ };
+ }
}
///
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index b4f87e12a..ce8cd08de 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -50,6 +50,8 @@ namespace Discord.WebSocket
public MfaLevel MfaLevel { get; private set; }
///
public DefaultMessageNotifications DefaultMessageNotifications { get; private set; }
+ ///
+ public ExplicitContentFilterLevel ExplicitContentFilter { get; private set; }
///
/// Gets the number of members.
///
@@ -73,6 +75,8 @@ namespace Discord.WebSocket
internal bool IsAvailable { get; private set; }
/// Indicates whether the client is connected to this guild.
public bool IsConnected { get; internal set; }
+ ///
+ public ulong? ApplicationId { get; internal set; }
internal ulong? AFKChannelId { get; private set; }
internal ulong? EmbedChannelId { get; private set; }
@@ -346,6 +350,8 @@ namespace Discord.WebSocket
VerificationLevel = model.VerificationLevel;
MfaLevel = model.MfaLevel;
DefaultMessageNotifications = model.DefaultMessageNotifications;
+ ExplicitContentFilter = model.ExplicitContentFilter;
+ ApplicationId = model.ApplicationId;
if (model.Emojis != null)
{
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
index 0767f2ad7..2cfcee270 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
@@ -43,6 +43,13 @@ namespace Discord.WebSocket
public virtual bool IsPinned => false;
///
public virtual DateTimeOffset? EditedTimestamp => null;
+
+ ///
+ public MessageActivity Activity { get; private set; }
+
+ ///
+ public MessageApplication Application { get; private set; }
+
///
/// Returns all attachments included in this message.
///
@@ -105,6 +112,29 @@ namespace Discord.WebSocket
if (model.Content.IsSpecified)
Content = model.Content.Value;
+
+ if (model.Application.IsSpecified)
+ {
+ // create a new Application from the API model
+ Application = new MessageApplication()
+ {
+ Id = model.Application.Value.Id,
+ CoverImage = model.Application.Value.CoverImage,
+ Description = model.Application.Value.Description,
+ Icon = model.Application.Value.Icon,
+ Name = model.Application.Value.Name
+ };
+ }
+
+ if (model.Activity.IsSpecified)
+ {
+ // create a new Activity from the API model
+ Activity = new MessageActivity()
+ {
+ Type = model.Activity.Value.Type.Value,
+ PartyId = model.Activity.Value.PartyId.Value
+ };
+ }
}
///
diff --git a/test/Discord.Net.Tests/Tests.GuildPermissions.cs b/test/Discord.Net.Tests/Tests.Guilds.cs
similarity index 94%
rename from test/Discord.Net.Tests/Tests.GuildPermissions.cs
rename to test/Discord.Net.Tests/Tests.Guilds.cs
index f49f431b5..09e3d044d 100644
--- a/test/Discord.Net.Tests/Tests.GuildPermissions.cs
+++ b/test/Discord.Net.Tests/Tests.Guilds.cs
@@ -5,8 +5,25 @@ using Xunit;
namespace Discord
{
- public class GuidPermissionsTests
+ public partial class Tests
{
+ ///
+ /// Tests the behavior of modifying the ExplicitContentFilter property of a Guild.
+ ///
+ [Fact]
+ public async Task TestExplicitContentFilter()
+ {
+ foreach (var level in Enum.GetValues(typeof(ExplicitContentFilterLevel)))
+ {
+ await _guild.ModifyAsync(x => x.ExplicitContentFilter = (ExplicitContentFilterLevel)level);
+ await _guild.UpdateAsync();
+ Assert.Equal(level, _guild.ExplicitContentFilter);
+ }
+ }
+
+ ///
+ /// Tests the behavior of the GuildPermissions class.
+ ///
[Fact]
public Task TestGuildPermission()
{