feature: Add MessageFlags and AllowedMentions to message modify (#1724)
* feature: Add MessageFlags and AllowedMentions to Modify * Change exception message
This commit is contained in:
@@ -164,6 +164,17 @@ namespace Discord
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions { get; }
|
IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the flags related to this message.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This value is determined by bitwise OR-ing <see cref="MessageFlags"/> values together.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// A message's flags, if any is associated.
|
||||||
|
/// </returns>
|
||||||
|
MessageFlags? Flags { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a reaction to this message.
|
/// Adds a reaction to this message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
36
src/Discord.Net.Core/Entities/Messages/MessageFlags.cs
Normal file
36
src/Discord.Net.Core/Entities/Messages/MessageFlags.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum MessageFlags
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default value for flags, when none are given to a message.
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Flag given to messages that have been published to subscribed
|
||||||
|
/// channels (via Channel Following).
|
||||||
|
/// </summary>
|
||||||
|
Crossposted = 1 << 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Flag given to messages that originated from a message in another
|
||||||
|
/// channel (via Channel Following).
|
||||||
|
/// </summary>
|
||||||
|
IsCrosspost = 1 << 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Flag given to messages that do not display any embeds.
|
||||||
|
/// </summary>
|
||||||
|
SuppressEmbeds = 1 << 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Flag given to messages that the source message for this crosspost
|
||||||
|
/// has been deleted (via Channel Following).
|
||||||
|
/// </summary>
|
||||||
|
SourceMessageDeleted = 1 << 3,
|
||||||
|
/// <summary>
|
||||||
|
/// Flag given to messages that came from the urgent message system.
|
||||||
|
/// </summary>
|
||||||
|
Urgent = 1 << 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,5 +21,17 @@ namespace Discord
|
|||||||
/// Gets or sets the embed the message should display.
|
/// Gets or sets the embed the message should display.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Optional<Embed> Embed { get; set; }
|
public Optional<Embed> Embed { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the flags of the message.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Only <see cref="MessageFlags.SuppressEmbeds"/> can be set/unset and you need to be
|
||||||
|
/// the author of the message.
|
||||||
|
/// </remarks>
|
||||||
|
public Optional<MessageFlags?> Flags { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the allowed mentions of the message.
|
||||||
|
/// </summary>
|
||||||
|
public Optional<AllowedMentions> AllowedMentions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Discord.API
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
internal enum MessageFlags : byte // probably safe to constrain this to 8 values, if not, it's internal so who cares
|
|
||||||
{
|
|
||||||
Suppressed = 0x04,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Discord.API.Rest
|
namespace Discord.API.Rest
|
||||||
@@ -10,5 +10,9 @@ namespace Discord.API.Rest
|
|||||||
public Optional<string> Content { get; set; }
|
public Optional<string> Content { get; set; }
|
||||||
[JsonProperty("embed")]
|
[JsonProperty("embed")]
|
||||||
public Optional<Embed> Embed { get; set; }
|
public Optional<Embed> Embed { get; set; }
|
||||||
|
[JsonProperty("flags")]
|
||||||
|
public Optional<MessageFlags?> Flags { get; set; }
|
||||||
|
[JsonProperty("allowed_mentions")]
|
||||||
|
public Optional<AllowedMentions> AllowedMentions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,21 +27,46 @@ namespace Discord.Rest
|
|||||||
public static async Task<Model> ModifyAsync(IMessage msg, BaseDiscordClient client, Action<MessageProperties> func,
|
public static async Task<Model> ModifyAsync(IMessage msg, BaseDiscordClient client, Action<MessageProperties> func,
|
||||||
RequestOptions options)
|
RequestOptions options)
|
||||||
{
|
{
|
||||||
if (msg.Author.Id != client.CurrentUser.Id)
|
|
||||||
throw new InvalidOperationException("Only the author of a message may modify the message.");
|
|
||||||
|
|
||||||
var args = new MessageProperties();
|
var args = new MessageProperties();
|
||||||
func(args);
|
func(args);
|
||||||
|
|
||||||
|
if (msg.Author.Id != client.CurrentUser.Id && (args.Content.IsSpecified || args.Embed.IsSpecified || args.AllowedMentions.IsSpecified))
|
||||||
|
throw new InvalidOperationException("Only the author of a message may modify the message content, embed, or allowed mentions.");
|
||||||
|
|
||||||
bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(msg.Content);
|
bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(msg.Content);
|
||||||
bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : msg.Embeds.Any();
|
bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : msg.Embeds.Any();
|
||||||
if (!hasText && !hasEmbed)
|
if (!hasText && !hasEmbed)
|
||||||
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
|
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
|
||||||
|
|
||||||
|
if (args.AllowedMentions.IsSpecified)
|
||||||
|
{
|
||||||
|
AllowedMentions allowedMentions = args.AllowedMentions.Value;
|
||||||
|
Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
|
||||||
|
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
|
||||||
|
|
||||||
|
// check that user flag and user Id list are exclusive, same with role flag and role Id list
|
||||||
|
if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
|
||||||
|
{
|
||||||
|
if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users) &&
|
||||||
|
allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(allowedMentions));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles) &&
|
||||||
|
allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(allowedMentions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var apiArgs = new API.Rest.ModifyMessageParams
|
var apiArgs = new API.Rest.ModifyMessageParams
|
||||||
{
|
{
|
||||||
Content = args.Content,
|
Content = args.Content,
|
||||||
Embed = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create<API.Embed>()
|
Embed = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create<API.Embed>(),
|
||||||
|
Flags = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create<MessageFlags?>(),
|
||||||
|
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create<API.AllowedMentions>(),
|
||||||
};
|
};
|
||||||
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
|
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ namespace Discord.Rest
|
|||||||
public MessageApplication Application { get; private set; }
|
public MessageApplication Application { get; private set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public MessageReference Reference { get; private set; }
|
public MessageReference Reference { get; private set; }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public MessageFlags? Flags { get; private set; }
|
||||||
|
|
||||||
internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
|
internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
|
||||||
: base(discord, id)
|
: base(discord, id)
|
||||||
@@ -124,6 +126,9 @@ namespace Discord.Rest
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model.Flags.IsSpecified)
|
||||||
|
Flags = model.Flags.Value;
|
||||||
|
|
||||||
if (model.Reactions.IsSpecified)
|
if (model.Reactions.IsSpecified)
|
||||||
{
|
{
|
||||||
var value = model.Reactions.Value;
|
var value = model.Reactions.Value;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Discord.Rest
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class RestUserMessage : RestMessage, IUserMessage
|
public class RestUserMessage : RestMessage, IUserMessage
|
||||||
{
|
{
|
||||||
private bool _isMentioningEveryone, _isTTS, _isPinned, _isSuppressed;
|
private bool _isMentioningEveryone, _isTTS, _isPinned;
|
||||||
private long? _editedTimestampTicks;
|
private long? _editedTimestampTicks;
|
||||||
private IUserMessage _referencedMessage;
|
private IUserMessage _referencedMessage;
|
||||||
private ImmutableArray<Attachment> _attachments = ImmutableArray.Create<Attachment>();
|
private ImmutableArray<Attachment> _attachments = ImmutableArray.Create<Attachment>();
|
||||||
@@ -27,7 +27,7 @@ namespace Discord.Rest
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsPinned => _isPinned;
|
public override bool IsPinned => _isPinned;
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsSuppressed => _isSuppressed;
|
public override bool IsSuppressed => Flags.HasValue && Flags.Value.HasFlag(MessageFlags.SuppressEmbeds);
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -70,10 +70,6 @@ namespace Discord.Rest
|
|||||||
_editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
|
_editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
|
||||||
if (model.MentionEveryone.IsSpecified)
|
if (model.MentionEveryone.IsSpecified)
|
||||||
_isMentioningEveryone = model.MentionEveryone.Value;
|
_isMentioningEveryone = model.MentionEveryone.Value;
|
||||||
if (model.Flags.IsSpecified)
|
|
||||||
{
|
|
||||||
_isSuppressed = model.Flags.Value.HasFlag(API.MessageFlags.Suppressed);
|
|
||||||
}
|
|
||||||
if (model.RoleMentions.IsSpecified)
|
if (model.RoleMentions.IsSpecified)
|
||||||
_roleMentionIds = model.RoleMentions.Value.ToImmutableArray();
|
_roleMentionIds = model.RoleMentions.Value.ToImmutableArray();
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ namespace Discord.WebSocket
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public MessageReference Reference { get; private set; }
|
public MessageReference Reference { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public MessageFlags? Flags { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all attachments included in this message.
|
/// Returns all attachments included in this message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -156,6 +159,9 @@ namespace Discord.WebSocket
|
|||||||
MessageId = model.Reference.Value.MessageId
|
MessageId = model.Reference.Value.MessageId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model.Flags.IsSpecified)
|
||||||
|
Flags = model.Flags.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Discord.WebSocket
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class SocketUserMessage : SocketMessage, IUserMessage
|
public class SocketUserMessage : SocketMessage, IUserMessage
|
||||||
{
|
{
|
||||||
private bool _isMentioningEveryone, _isTTS, _isPinned, _isSuppressed;
|
private bool _isMentioningEveryone, _isTTS, _isPinned;
|
||||||
private long? _editedTimestampTicks;
|
private long? _editedTimestampTicks;
|
||||||
private IUserMessage _referencedMessage;
|
private IUserMessage _referencedMessage;
|
||||||
private ImmutableArray<Attachment> _attachments = ImmutableArray.Create<Attachment>();
|
private ImmutableArray<Attachment> _attachments = ImmutableArray.Create<Attachment>();
|
||||||
@@ -29,7 +29,7 @@ namespace Discord.WebSocket
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsPinned => _isPinned;
|
public override bool IsPinned => _isPinned;
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsSuppressed => _isSuppressed;
|
public override bool IsSuppressed => Flags.HasValue && Flags.Value.HasFlag(MessageFlags.SuppressEmbeds);
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -74,10 +74,6 @@ namespace Discord.WebSocket
|
|||||||
_editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
|
_editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
|
||||||
if (model.MentionEveryone.IsSpecified)
|
if (model.MentionEveryone.IsSpecified)
|
||||||
_isMentioningEveryone = model.MentionEveryone.Value;
|
_isMentioningEveryone = model.MentionEveryone.Value;
|
||||||
if (model.Flags.IsSpecified)
|
|
||||||
{
|
|
||||||
_isSuppressed = model.Flags.Value.HasFlag(API.MessageFlags.Suppressed);
|
|
||||||
}
|
|
||||||
if (model.RoleMentions.IsSpecified)
|
if (model.RoleMentions.IsSpecified)
|
||||||
_roleMentions = model.RoleMentions.Value.Select(x => guild.GetRole(x)).ToImmutableArray();
|
_roleMentions = model.RoleMentions.Value.Select(x => guild.GetRole(x)).ToImmutableArray();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user