Skip to content

Commit c4d90cd

Browse files
authored
[Feature] Message Forwards (#2918)
* code * no guild * iTS ALIVE (THANKS aDVAITH)
1 parent 623a457 commit c4d90cd

File tree

14 files changed

+96
-7
lines changed

14 files changed

+96
-7
lines changed

src/Discord.Net.Core/Entities/Messages/IUserMessage.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public interface IUserMessage : IMessage
3030
/// </remarks>
3131
IMessageInteractionMetadata InteractionMetadata { get; }
3232

33+
/// <summary>
34+
/// Gets a collection of partial messages that were forwarded with this message.
35+
/// </summary>
36+
IReadOnlyCollection<MessageSnapshot> ForwardedMessages { get; }
37+
3338
/// <summary>
3439
/// Gets the poll sent with this message.
3540
/// </summary>

src/Discord.Net.Core/Entities/Messages/MessageReference.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public class MessageReference
3333
/// </summary>
3434
public Optional<bool> FailIfNotExists { get; internal set; }
3535

36+
/// <summary>
37+
/// Gets the type of message reference.
38+
/// </summary>
39+
public Optional<MessageReferenceType> ReferenceType { get; internal set; }
40+
3641
/// <summary>
3742
/// Initializes a new instance of the <see cref="MessageReference"/> class.
3843
/// </summary>
@@ -48,12 +53,14 @@ public class MessageReference
4853
/// <param name="failIfNotExists">
4954
/// Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message. Defaults to true.
5055
/// </param>
51-
public MessageReference(ulong? messageId = null, ulong? channelId = null, ulong? guildId = null, bool? failIfNotExists = null)
56+
public MessageReference(ulong? messageId = null, ulong? channelId = null, ulong? guildId = null, bool? failIfNotExists = null,
57+
MessageReferenceType referenceType = MessageReferenceType.Default)
5258
{
5359
MessageId = messageId ?? Optional.Create<ulong>();
5460
InternalChannelId = channelId ?? Optional.Create<ulong>();
5561
GuildId = guildId ?? Optional.Create<ulong>();
5662
FailIfNotExists = failIfNotExists ?? Optional.Create<bool>();
63+
ReferenceType = referenceType;
5764
}
5865

5966
private string DebuggerDisplay
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Discord;
2+
3+
/// <summary>
4+
/// Determines how associated data is populated.
5+
/// </summary>
6+
public enum MessageReferenceType
7+
{
8+
/// <summary>
9+
/// A standard reference used by replies.
10+
/// </summary>
11+
Default = 0,
12+
13+
/// <summary>
14+
/// Reference used to point to a message at a point in time.
15+
/// </summary>
16+
Forward = 1,
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Discord;
2+
3+
/// <summary>
4+
/// Represents a snapshot of a message.
5+
/// </summary>
6+
public readonly struct MessageSnapshot
7+
{
8+
/// <summary>
9+
/// Gets the partial message that was forwarded.
10+
/// </summary>
11+
public readonly IMessage Message;
12+
13+
internal MessageSnapshot(IMessage message)
14+
{
15+
Message = message;
16+
}
17+
}

src/Discord.Net.Core/Utils/Preconditions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static void WebhookMessageAtLeastOneOf(string text = null, MessageCompone
9898
}
9999

100100
public static void MessageAtLeastOneOf(string text = null, MessageComponent components = null, ICollection<IEmbed> embeds = null,
101-
ICollection<ISticker> stickers = null, IEnumerable<FileAttachment> attachments = null, PollProperties poll = null)
101+
ICollection<ISticker> stickers = null, IEnumerable<FileAttachment> attachments = null, PollProperties poll = null, MessageReference messageReference = null)
102102
{
103103
if (!string.IsNullOrEmpty(text))
104104
return;
@@ -118,6 +118,9 @@ public static void MessageAtLeastOneOf(string text = null, MessageComponent comp
118118
if (poll is not null)
119119
return;
120120

121+
if (messageReference?.ReferenceType.GetValueOrDefault(MessageReferenceType.Default) is MessageReferenceType.Forward)
122+
return;
123+
121124
throw new ArgumentException($"At least one of 'Content', 'Embeds', 'Components', 'Stickers', 'Attachments' or 'Poll' must be specified.");
122125
}
123126

src/Discord.Net.Rest/API/Common/Message.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ internal class Message
102102
[JsonProperty("interaction_metadata")]
103103
public Optional<MessageInteractionMetadata> InteractionMetadata { get; set; }
104104

105+
[JsonProperty("message_snapshots")]
106+
public Optional<MessageSnapshot[]> MessageSnapshots { get; set; }
107+
105108
[JsonProperty("poll")]
106109
public Optional<Poll> Poll { get; set; }
107110

src/Discord.Net.Rest/API/Common/MessageReference.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ namespace Discord.API
44
{
55
internal class MessageReference
66
{
7+
[JsonProperty("type")]
8+
public Optional<MessageReferenceType> Type { get; set; }
9+
710
[JsonProperty("message_id")]
811
public Optional<ulong> MessageId { get; set; }
912

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Discord.API;
4+
5+
internal class MessageSnapshot
6+
{
7+
[JsonProperty("message")]
8+
public Message Message { get; set; }
9+
}

src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public static async Task<RestUserMessage> SendMessageAsync(IMessageChannel chann
284284
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
285285
Preconditions.AtMost(embeds.Length, DiscordConfig.MaxEmbedsPerMessage, nameof(embeds), $"A max of {DiscordConfig.MaxEmbedsPerMessage} Embeds are allowed.");
286286

287-
Preconditions.MessageAtLeastOneOf(text, components, embeds, stickers, poll: poll);
287+
Preconditions.MessageAtLeastOneOf(text, components, embeds, stickers, poll: poll, messageReference: messageReference);
288288
Preconditions.ValidatePoll(poll);
289289

290290
// check that user flag and user Id list are exclusive, same with role flag and role Id list
@@ -400,7 +400,7 @@ public static async Task<RestUserMessage> SendFilesAsync(IMessageChannel channel
400400
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
401401
Preconditions.AtMost(embeds.Length, DiscordConfig.MaxEmbedsPerMessage, nameof(embeds), $"A max of {DiscordConfig.MaxEmbedsPerMessage} Embeds are allowed.");
402402

403-
Preconditions.MessageAtLeastOneOf(text, components, embeds, stickers, attachments, poll);
403+
Preconditions.MessageAtLeastOneOf(text, components, embeds, stickers, attachments, poll, messageReference);
404404
Preconditions.ValidatePoll(poll);
405405

406406
foreach (var attachment in attachments)

src/Discord.Net.Rest/Entities/Messages/RestMessage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ internal virtual void Update(Model model)
165165
GuildId = model.Reference.Value.GuildId,
166166
InternalChannelId = model.Reference.Value.ChannelId,
167167
MessageId = model.Reference.Value.MessageId,
168-
FailIfNotExists = model.Reference.Value.FailIfNotExists
168+
FailIfNotExists = model.Reference.Value.FailIfNotExists,
169+
ReferenceType = model.Reference.Value.Type
169170
};
170171
}
171172

0 commit comments

Comments
 (0)