diff --git a/src/Discord.Net.Commands/ModuleBase.cs b/src/Discord.Net.Commands/ModuleBase.cs
index ec1722c70..6ec2db54d 100644
--- a/src/Discord.Net.Commands/ModuleBase.cs
+++ b/src/Discord.Net.Commands/ModuleBase.cs
@@ -35,9 +35,10 @@ namespace Discord.Commands
/// Specifies if notifications are sent for mentioned users and roles in the .
/// If null, all mentioned roles and users will be notified.
///
- protected virtual async Task ReplyAsync(string message = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null)
+ /// The message references to be included. Used to reply to specific messages.
+ protected virtual async Task ReplyAsync(string message = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null)
{
- return await Context.Channel.SendMessageAsync(message, isTTS, embed, options, allowedMentions).ConfigureAwait(false);
+ return await Context.Channel.SendMessageAsync(message, isTTS, embed, options, allowedMentions, messageReference).ConfigureAwait(false);
}
///
/// The method to execute before executing the command.
diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
index 030a278bc..abd20e4f0 100644
--- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -27,11 +27,12 @@ namespace Discord
/// Specifies if notifications are sent for mentioned users and roles in the message .
/// If null, all mentioned roles and users will be notified.
///
+ /// The message references to be included. Used to reply to specific messages.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
///
- Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null);
+ Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null);
///
/// Sends a file to this message channel with an optional caption.
///
@@ -63,11 +64,12 @@ namespace Discord
/// Specifies if notifications are sent for mentioned users and roles in the message .
/// If null, all mentioned roles and users will be notified.
///
+ /// The message references to be included. Used to reply to specific messages.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
///
- Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null);
+ Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null);
///
/// Sends a file to this message channel with an optional caption.
///
@@ -96,11 +98,12 @@ namespace Discord
/// Specifies if notifications are sent for mentioned users and roles in the message .
/// If null, all mentioned roles and users will be notified.
///
+ /// The message references to be included. Used to reply to specific messages.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
///
- Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null);
+ Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null);
///
/// Gets a message from this message channel.
diff --git a/src/Discord.Net.Core/Entities/Messages/AllowedMentions.cs b/src/Discord.Net.Core/Entities/Messages/AllowedMentions.cs
index d52feaa7d..0206ad7b1 100644
--- a/src/Discord.Net.Core/Entities/Messages/AllowedMentions.cs
+++ b/src/Discord.Net.Core/Entities/Messages/AllowedMentions.cs
@@ -49,6 +49,14 @@ namespace Discord
///
public List UserIds { get; set; } = new List();
+ ///
+ /// Gets or sets whether to mention the author of the message you are replying to or not.
+ ///
+ ///
+ /// Specifically for inline replies.
+ ///
+ public bool? MentionRepliedUser { get; set; } = null;
+
///
/// Initializes a new instance of the class.
///
diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
index b74e333c1..35458d87d 100644
--- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
@@ -148,11 +148,11 @@ namespace Discord
MessageApplication Application { get; }
///
- /// Gets the reference to the original message if it was crossposted.
+ /// Gets the reference to the original message if it is a crosspost, channel follow add, pin, or reply message.
///
///
- /// Sent with Cross-posted messages, meaning they were published from news channels
- /// and received by subscriber channels.
+ /// Sent with cross-posted messages, meaning they were published from news channels
+ /// and received by subscriber channels, channel follow adds, pins, and message replies.
///
///
/// A message's reference, if any is associated.
diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
index e2fb25aae..1589e2ae5 100644
--- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Threading.Tasks;
namespace Discord
@@ -9,6 +8,14 @@ namespace Discord
///
public interface IUserMessage : IMessage
{
+ ///
+ /// Gets the referenced message if it is a crosspost, channel follow add, pin, or reply message.
+ ///
+ ///
+ /// The referenced message, if any is associated and still exists.
+ ///
+ IUserMessage ReferencedMessage { get; }
+
///
/// Modifies this message.
///
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageReference.cs b/src/Discord.Net.Core/Entities/Messages/MessageReference.cs
index 57a508a7c..029910e56 100644
--- a/src/Discord.Net.Core/Entities/Messages/MessageReference.cs
+++ b/src/Discord.Net.Core/Entities/Messages/MessageReference.cs
@@ -3,7 +3,7 @@ using System.Diagnostics;
namespace Discord
{
///
- /// Contains the IDs sent from a crossposted message.
+ /// Contains the IDs sent from a crossposted message or inline reply.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class MessageReference
@@ -16,13 +16,36 @@ namespace Discord
///
/// Gets the Channel ID of the original message.
///
- public ulong ChannelId { get; internal set; }
+ ///
+ /// It only will be the default value (zero) if it was instantiated with a in the constructor.
+ ///
+ public ulong ChannelId { get => InternalChannelId.GetValueOrDefault(); }
+ internal Optional InternalChannelId;
///
/// Gets the Guild ID of the original message.
///
public Optional GuildId { get; internal set; }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The ID of the message that will be referenced. Used to reply to specific messages and the only parameter required for it.
+ ///
+ ///
+ /// The ID of the channel that will be referenced. It will be validated if sent.
+ ///
+ ///
+ /// The ID of the guild that will be referenced. It will be validated if sent.
+ ///
+ public MessageReference(ulong? messageId = null, ulong? channelId = null, ulong? guildId = null)
+ {
+ MessageId = messageId ?? Optional.Create();
+ InternalChannelId = channelId ?? Optional.Create();
+ GuildId = guildId ?? Optional.Create();
+ }
+
private string DebuggerDisplay
=> $"Channel ID: ({ChannelId}){(GuildId.IsSpecified ? $", Guild ID: ({GuildId.Value})" : "")}" +
$"{(MessageId.IsSpecified ? $", Message ID: ({MessageId.Value})" : "")}";
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageType.cs b/src/Discord.Net.Core/Entities/Messages/MessageType.cs
index ee5f4fb4d..ad1f3a3cd 100644
--- a/src/Discord.Net.Core/Entities/Messages/MessageType.cs
+++ b/src/Discord.Net.Core/Entities/Messages/MessageType.cs
@@ -57,5 +57,12 @@ namespace Discord
/// The message for when a news channel subscription is added to a text channel.
///
ChannelFollowAdd = 12,
+ ///
+ /// The message is an inline reply.
+ ///
+ ///
+ /// Only available in API v8.
+ ///
+ Reply = 19,
}
}
diff --git a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
index 92b146e05..0e4004c46 100644
--- a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
+++ b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
@@ -73,7 +73,7 @@ namespace Discord
///
///
/// The following example checks if the current user has the ability to send a message with attachment in
- /// this channel; if so, uploads a file via .
+ /// this channel; if so, uploads a file via .
///
/// if (currentUser?.GetPermissions(targetChannel)?.AttachFiles)
/// await targetChannel.SendFileAsync("fortnite.png");
diff --git a/src/Discord.Net.Core/Extensions/MessageExtensions.cs b/src/Discord.Net.Core/Extensions/MessageExtensions.cs
index e44e397fa..b043d7b77 100644
--- a/src/Discord.Net.Core/Extensions/MessageExtensions.cs
+++ b/src/Discord.Net.Core/Extensions/MessageExtensions.cs
@@ -71,5 +71,25 @@ namespace Discord
foreach (var rxn in reactions)
await msg.RemoveReactionAsync(rxn, user, options).ConfigureAwait(false);
}
+
+ ///
+ /// Sends an inline reply that references a message.
+ ///
+ /// The message to be sent.
+ /// Determines whether the message should be read aloud by Discord or not.
+ /// The to be sent.
+ ///
+ /// Specifies if notifications are sent for mentioned users and roles in the message .
+ /// If null, all mentioned roles and users will be notified.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public static async Task ReplyAsync(this IUserMessage msg, string text = null, bool isTTS = false, Embed embed = null, AllowedMentions allowedMentions = null, RequestOptions options = null)
+ {
+ return await msg.Channel.SendMessageAsync(text, isTTS, embed, options, allowedMentions, new MessageReference(messageId: msg.Id)).ConfigureAwait(false);
+ }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/Message.cs b/src/Discord.Net.Rest/API/Common/Message.cs
index b4529d457..b781de346 100644
--- a/src/Discord.Net.Rest/API/Common/Message.cs
+++ b/src/Discord.Net.Rest/API/Common/Message.cs
@@ -56,5 +56,7 @@ namespace Discord.API
public Optional Flags { get; set; }
[JsonProperty("allowed_mentions")]
public Optional AllowedMentions { get; set; }
+ [JsonProperty("referenced_message")]
+ public Optional ReferencedMessage { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/MessageReference.cs b/src/Discord.Net.Rest/API/Common/MessageReference.cs
index 8c0f8fe14..6cc7603e0 100644
--- a/src/Discord.Net.Rest/API/Common/MessageReference.cs
+++ b/src/Discord.Net.Rest/API/Common/MessageReference.cs
@@ -8,7 +8,7 @@ namespace Discord.API
public Optional MessageId { get; set; }
[JsonProperty("channel_id")]
- public ulong ChannelId { get; set; }
+ public Optional ChannelId { get; set; } // Optional when sending, always present when receiving
[JsonProperty("guild_id")]
public Optional GuildId { get; set; }
diff --git a/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs b/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
index 4b56658d6..e64532864 100644
--- a/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
@@ -17,6 +17,8 @@ namespace Discord.API.Rest
public Optional