diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
index 757c3e4a03..ca37d56618 100644
--- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
namespace Discord
@@ -29,6 +30,11 @@ public interface IUserMessage : IMessage
///
IMessageInteractionMetadata InteractionMetadata { get; }
+ ///
+ /// Gets a collection of partial messages that were forwarded with this message.
+ ///
+ IReadOnlyCollection ForwardedMessages { 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 7fdc448ad6..032879a0a2 100644
--- a/src/Discord.Net.Core/Entities/Messages/MessageReference.cs
+++ b/src/Discord.Net.Core/Entities/Messages/MessageReference.cs
@@ -33,6 +33,11 @@ public class MessageReference
///
public Optional FailIfNotExists { get; internal set; }
+ ///
+ /// Gets the type of message reference.
+ ///
+ public Optional ReferenceType { get; internal set; }
+
///
/// Initializes a new instance of the class.
///
@@ -48,12 +53,14 @@ public class MessageReference
///
/// Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message. Defaults to true.
///
- public MessageReference(ulong? messageId = null, ulong? channelId = null, ulong? guildId = null, bool? failIfNotExists = null)
+ public MessageReference(ulong? messageId = null, ulong? channelId = null, ulong? guildId = null, bool? failIfNotExists = null,
+ MessageReferenceType referenceType = MessageReferenceType.Default)
{
MessageId = messageId ?? Optional.Create();
InternalChannelId = channelId ?? Optional.Create();
GuildId = guildId ?? Optional.Create();
FailIfNotExists = failIfNotExists ?? Optional.Create();
+ ReferenceType = referenceType;
}
private string DebuggerDisplay
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageReferenceType.cs b/src/Discord.Net.Core/Entities/Messages/MessageReferenceType.cs
new file mode 100644
index 0000000000..4fed6f4151
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/MessageReferenceType.cs
@@ -0,0 +1,17 @@
+namespace Discord;
+
+///
+/// Determines how associated data is populated.
+///
+public enum MessageReferenceType
+{
+ ///
+ /// A standard reference used by replies.
+ ///
+ Default = 0,
+
+ ///
+ /// Reference used to point to a message at a point in time.
+ ///
+ Forward = 1,
+}
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageSnapshot.cs b/src/Discord.Net.Core/Entities/Messages/MessageSnapshot.cs
new file mode 100644
index 0000000000..dc1322615a
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/MessageSnapshot.cs
@@ -0,0 +1,23 @@
+namespace Discord;
+
+///
+/// Represents a snapshot of a message.
+///
+public readonly struct MessageSnapshot
+{
+ ///
+ /// Gets the partial message that was forwarded.
+ ///
+ public readonly IMessage Message;
+
+ ///
+ /// Gets the id of the originating message's guild
+ ///
+ public readonly ulong? GuildId;
+
+ internal MessageSnapshot(IMessage message, ulong? guildId)
+ {
+ Message = message;
+ GuildId = guildId;
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/Message.cs b/src/Discord.Net.Rest/API/Common/Message.cs
index c9cc61a203..a5da3f85aa 100644
--- a/src/Discord.Net.Rest/API/Common/Message.cs
+++ b/src/Discord.Net.Rest/API/Common/Message.cs
@@ -101,4 +101,7 @@ internal class Message
[JsonProperty("interaction_metadata")]
public Optional InteractionMetadata { get; set; }
+
+ [JsonProperty("message_snapshot")]
+ public Optional MessageSnapshots { get; set; }
}
diff --git a/src/Discord.Net.Rest/API/Common/MessageReference.cs b/src/Discord.Net.Rest/API/Common/MessageReference.cs
index 70ef4e678e..3e582b2f28 100644
--- a/src/Discord.Net.Rest/API/Common/MessageReference.cs
+++ b/src/Discord.Net.Rest/API/Common/MessageReference.cs
@@ -4,6 +4,9 @@ namespace Discord.API
{
internal class MessageReference
{
+ [JsonProperty("type")]
+ public Optional Type { get; set; }
+
[JsonProperty("message_id")]
public Optional MessageId { get; set; }
diff --git a/src/Discord.Net.Rest/API/Common/MessageSnapshot.cs b/src/Discord.Net.Rest/API/Common/MessageSnapshot.cs
new file mode 100644
index 0000000000..cb880845f0
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/MessageSnapshot.cs
@@ -0,0 +1,12 @@
+using Newtonsoft.Json;
+
+namespace Discord.API;
+
+internal class MessageSnapshot
+{
+ [JsonProperty("message")]
+ public Message Message { get; set; }
+
+ [JsonProperty("guild_id")]
+ public Optional GuildId { get; set; }
+}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
index fd9aa07c96..d6ecc0771c 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
@@ -158,7 +158,8 @@ internal virtual void Update(Model model)
GuildId = model.Reference.Value.GuildId,
InternalChannelId = model.Reference.Value.ChannelId,
MessageId = model.Reference.Value.MessageId,
- FailIfNotExists = model.Reference.Value.FailIfNotExists
+ FailIfNotExists = model.Reference.Value.FailIfNotExists,
+ ReferenceType = model.Reference.Value.Type
};
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
index 2312f92c44..56e8fae623 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
@@ -54,6 +54,9 @@ public class RestUserMessage : RestMessage, IUserMessage
///
public MessageResolvedData ResolvedData { get; internal set; }
+ ///
+ public IReadOnlyCollection ForwardedMessages { get; internal set; }
+
internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
: base(discord, id, channel, author, source)
{
@@ -167,6 +170,15 @@ internal override void Update(Model model)
}
if (model.InteractionMetadata.IsSpecified)
InteractionMetadata = model.InteractionMetadata.Value.ToInteractionMetadata();
+
+ if (model.MessageSnapshots.IsSpecified)
+ {
+ ForwardedMessages = model.MessageSnapshots.Value.Select(x =>
+ new MessageSnapshot(RestMessage.Create(Discord, null, null, x.Message),
+ x.GuildId.IsSpecified ? x.GuildId.Value : null)).ToImmutableArray();
+ }
+ else
+ ForwardedMessages = ImmutableArray.Empty;
}
///
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
index 930c6ca177..8ca06b3b0f 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
@@ -192,7 +192,8 @@ internal virtual void Update(ClientState state, Model model)
GuildId = model.Reference.Value.GuildId,
InternalChannelId = model.Reference.Value.ChannelId,
MessageId = model.Reference.Value.MessageId,
- FailIfNotExists = model.Reference.Value.FailIfNotExists
+ FailIfNotExists = model.Reference.Value.FailIfNotExists,
+ ReferenceType = model.Reference.Value.Type
};
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
index 74d82fdb58..a0eb755708 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
@@ -55,6 +55,9 @@ public class SocketUserMessage : SocketMessage, IUserMessage
///
public MessageResolvedData ResolvedData { get; internal set; }
+ ///
+ public IReadOnlyCollection ForwardedMessages { get; internal set; }
+
internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source)
: base(discord, id, channel, author, source)
{
@@ -209,6 +212,16 @@ internal override void Update(ClientState state, Model model)
if (model.InteractionMetadata.IsSpecified)
InteractionMetadata = model.InteractionMetadata.Value.ToInteractionMetadata();
+
+
+ if (model.MessageSnapshots.IsSpecified)
+ {
+ ForwardedMessages = model.MessageSnapshots.Value.Select(x =>
+ new MessageSnapshot(RestMessage.Create(Discord, null, null, x.Message),
+ x.GuildId.IsSpecified ? x.GuildId.Value : null)).ToImmutableArray();
+ }
+ else
+ ForwardedMessages = ImmutableArray.Empty;
}
///