mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-03-17 12:22:32 +00:00
Clean up after last PR
This commit is contained in:
@@ -27,10 +27,16 @@ public partial record Message(
|
||||
IReadOnlyList<User> MentionedUsers,
|
||||
MessageReference? Reference,
|
||||
Message? ReferencedMessage,
|
||||
Interaction? Interaction,
|
||||
MessageSnapshot? ForwardedMessage
|
||||
MessageSnapshot? ForwardedMessage,
|
||||
Interaction? Interaction
|
||||
) : IHasId
|
||||
{
|
||||
public bool IsEmpty { get; } =
|
||||
string.IsNullOrWhiteSpace(Content)
|
||||
&& !Attachments.Any()
|
||||
&& !Embeds.Any()
|
||||
&& !Stickers.Any();
|
||||
|
||||
public bool IsSystemNotification { get; } =
|
||||
Kind is >= MessageKind.RecipientAdd and <= MessageKind.ThreadCreated;
|
||||
|
||||
@@ -39,15 +45,8 @@ public partial record Message(
|
||||
// App interactions are rendered as replies in the Discord client, but they are not actually replies
|
||||
public bool IsReplyLike => IsReply || Interaction is not null;
|
||||
|
||||
// A message is a forward if its reference type is Forward
|
||||
public bool IsForwarded { get; } = Reference?.Kind == MessageReferenceKind.Forward;
|
||||
|
||||
public bool IsEmpty { get; } =
|
||||
string.IsNullOrWhiteSpace(Content)
|
||||
&& !Attachments.Any()
|
||||
&& !Embeds.Any()
|
||||
&& !Stickers.Any();
|
||||
|
||||
public IEnumerable<User> GetReferencedUsers()
|
||||
{
|
||||
yield return Author;
|
||||
@@ -175,16 +174,19 @@ public partial record Message
|
||||
|
||||
var messageReference = json.GetPropertyOrNull("message_reference")
|
||||
?.Pipe(MessageReference.Parse);
|
||||
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse);
|
||||
var interaction = json.GetPropertyOrNull("interaction")?.Pipe(Interaction.Parse);
|
||||
|
||||
// Parse message snapshots for forwarded messages
|
||||
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse);
|
||||
|
||||
// Currently Discord only supports 1 snapshot per forward
|
||||
var forwardedMessage = json.GetPropertyOrNull("message_snapshots")
|
||||
?.EnumerateArrayOrNull()
|
||||
?.Select(MessageSnapshot.Parse)
|
||||
?.Select(j => j.GetPropertyOrNull("message"))
|
||||
.WhereNotNull()
|
||||
.Select(MessageSnapshot.Parse)
|
||||
.FirstOrDefault();
|
||||
|
||||
var interaction = json.GetPropertyOrNull("interaction")?.Pipe(Interaction.Parse);
|
||||
|
||||
return new Message(
|
||||
id,
|
||||
kind,
|
||||
@@ -202,8 +204,8 @@ public partial record Message
|
||||
mentionedUsers,
|
||||
messageReference,
|
||||
referencedMessage,
|
||||
interaction,
|
||||
forwardedMessage
|
||||
forwardedMessage,
|
||||
interaction
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,17 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
||||
|
||||
// https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure
|
||||
public record MessageReference(
|
||||
MessageReferenceKind Kind,
|
||||
Snowflake? MessageId,
|
||||
Snowflake? ChannelId,
|
||||
Snowflake? GuildId,
|
||||
MessageReferenceKind Kind
|
||||
)
|
||||
Snowflake? GuildId)
|
||||
{
|
||||
public static MessageReference Parse(JsonElement json)
|
||||
{
|
||||
var kind =
|
||||
json.GetPropertyOrNull("type")?.GetInt32OrNull()?.Pipe(t => (MessageReferenceKind)t)
|
||||
?? MessageReferenceKind.Default;
|
||||
|
||||
var messageId = json.GetPropertyOrNull("message_id")
|
||||
?.GetNonWhiteSpaceStringOrNull()
|
||||
?.Pipe(Snowflake.Parse);
|
||||
@@ -26,10 +29,6 @@ public record MessageReference(
|
||||
?.GetNonWhiteSpaceStringOrNull()
|
||||
?.Pipe(Snowflake.Parse);
|
||||
|
||||
var kind =
|
||||
json.GetPropertyOrNull("type")?.GetInt32OrNull()?.Pipe(t => (MessageReferenceKind)t)
|
||||
?? MessageReferenceKind.Default;
|
||||
|
||||
return new MessageReference(messageId, channelId, guildId, kind);
|
||||
return new MessageReference(kind, messageId, channelId, guildId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,31 +3,34 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||
using DiscordChatExporter.Core.Utils.Extensions;
|
||||
using JsonExtensions.Reading;
|
||||
|
||||
namespace DiscordChatExporter.Core.Discord.Data;
|
||||
|
||||
// https://discord.com/developers/docs/resources/channel#message-snapshot-object
|
||||
// https://docs.discord.com/developers/resources/message#message-snapshot-object
|
||||
// Message snapshots contain a subset of message fields for forwarded messages
|
||||
public record MessageSnapshot(
|
||||
DateTimeOffset Timestamp,
|
||||
DateTimeOffset? EditedTimestamp,
|
||||
string Content,
|
||||
IReadOnlyList<Attachment> Attachments,
|
||||
IReadOnlyList<Embed> Embeds,
|
||||
IReadOnlyList<Sticker> Stickers,
|
||||
DateTimeOffset Timestamp,
|
||||
DateTimeOffset? EditedTimestamp
|
||||
)
|
||||
IReadOnlyList<Sticker> Stickers)
|
||||
{
|
||||
public static MessageSnapshot Parse(JsonElement json)
|
||||
{
|
||||
// The message snapshot has a "message" property containing the actual message data
|
||||
var messageJson = json.GetPropertyOrNull("message") ?? json;
|
||||
var timestamp =
|
||||
json.GetPropertyOrNull("timestamp")?.GetDateTimeOffsetOrNull()
|
||||
?? DateTimeOffset.MinValue;
|
||||
|
||||
var content = messageJson.GetPropertyOrNull("content")?.GetStringOrNull() ?? "";
|
||||
var editedTimestamp = json
|
||||
.GetPropertyOrNull("edited_timestamp")
|
||||
?.GetDateTimeOffsetOrNull();
|
||||
|
||||
var content = json.GetPropertyOrNull("content")?.GetStringOrNull() ?? "";
|
||||
|
||||
var attachments =
|
||||
messageJson
|
||||
json
|
||||
.GetPropertyOrNull("attachments")
|
||||
?.EnumerateArrayOrNull()
|
||||
?.Select(Attachment.Parse)
|
||||
@@ -35,7 +38,7 @@ public record MessageSnapshot(
|
||||
?? [];
|
||||
|
||||
var embeds =
|
||||
messageJson
|
||||
json
|
||||
.GetPropertyOrNull("embeds")
|
||||
?.EnumerateArrayOrNull()
|
||||
?.Select(Embed.Parse)
|
||||
@@ -43,28 +46,14 @@ public record MessageSnapshot(
|
||||
?? [];
|
||||
|
||||
var stickers =
|
||||
messageJson
|
||||
json
|
||||
.GetPropertyOrNull("sticker_items")
|
||||
?.EnumerateArrayOrNull()
|
||||
?.Select(Sticker.Parse)
|
||||
.ToArray()
|
||||
?? [];
|
||||
|
||||
var timestamp =
|
||||
messageJson.GetPropertyOrNull("timestamp")?.GetDateTimeOffsetOrNull()
|
||||
?? DateTimeOffset.MinValue;
|
||||
|
||||
var editedTimestamp = messageJson
|
||||
.GetPropertyOrNull("edited_timestamp")
|
||||
?.GetDateTimeOffsetOrNull();
|
||||
|
||||
return new MessageSnapshot(
|
||||
content,
|
||||
attachments,
|
||||
embeds,
|
||||
stickers,
|
||||
timestamp,
|
||||
editedTimestamp
|
||||
);
|
||||
return new MessageSnapshot(timestamp,
|
||||
editedTimestamp, content, attachments, embeds, stickers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,22 +539,20 @@ internal class JsonMessageWriter(Stream stream, ExportContext context)
|
||||
{
|
||||
_writer.WriteStartObject("forwardedMessage");
|
||||
|
||||
_writer.WriteString(
|
||||
"content",
|
||||
await FormatMarkdownAsync(message.ForwardedMessage.Content, cancellationToken)
|
||||
);
|
||||
|
||||
_writer.WriteString(
|
||||
"timestamp",
|
||||
message.ForwardedMessage.Timestamp != DateTimeOffset.MinValue
|
||||
? Context.NormalizeDate(message.ForwardedMessage.Timestamp)
|
||||
: null
|
||||
Context.NormalizeDate(message.ForwardedMessage.Timestamp)
|
||||
);
|
||||
|
||||
_writer.WriteString(
|
||||
"timestampEdited",
|
||||
message.ForwardedMessage.EditedTimestamp?.Pipe(Context.NormalizeDate)
|
||||
);
|
||||
|
||||
_writer.WriteString(
|
||||
"content",
|
||||
await FormatMarkdownAsync(message.ForwardedMessage.Content, cancellationToken)
|
||||
);
|
||||
|
||||
// Forwarded attachments
|
||||
_writer.WriteStartArray("attachments");
|
||||
|
||||
@@ -263,9 +263,8 @@
|
||||
}
|
||||
|
||||
@* Forwarded message content *@
|
||||
@if (message.IsForwarded && message.ForwardedMessage is not null)
|
||||
@if (message is { IsForwarded: true, ForwardedMessage: not null })
|
||||
{
|
||||
var fwd = message.ForwardedMessage;
|
||||
<div class="chatlog__forwarded">
|
||||
<div class="chatlog__forwarded-header">
|
||||
<svg class="chatlog__forwarded-icon">
|
||||
@@ -275,18 +274,18 @@
|
||||
</div>
|
||||
|
||||
@* Forwarded text content *@
|
||||
@if (!string.IsNullOrWhiteSpace(fwd.Content))
|
||||
@if (!string.IsNullOrWhiteSpace(message.ForwardedMessage.Content))
|
||||
{
|
||||
<div class="chatlog__forwarded-content chatlog__markdown">
|
||||
<span class="chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatMarkdownAsync(fwd.Content))<!--/wmm:ignore--></span>
|
||||
<span class="chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatMarkdownAsync(message.ForwardedMessage.Content))<!--/wmm:ignore--></span>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Forwarded attachments *@
|
||||
@if (fwd.Attachments.Any())
|
||||
@if (message.ForwardedMessage.Attachments.Any())
|
||||
{
|
||||
<div class="chatlog__forwarded-attachments">
|
||||
@foreach (var attachment in fwd.Attachments)
|
||||
@foreach (var attachment in message.ForwardedMessage.Attachments)
|
||||
{
|
||||
@if (attachment.IsImage)
|
||||
{
|
||||
@@ -327,7 +326,7 @@
|
||||
}
|
||||
|
||||
@* Forwarded stickers *@
|
||||
@foreach (var sticker in fwd.Stickers)
|
||||
@foreach (var sticker in message.ForwardedMessage.Stickers)
|
||||
{
|
||||
<div class="chatlog__sticker" title="@sticker.Name">
|
||||
@if (sticker.IsImage)
|
||||
@@ -343,10 +342,10 @@
|
||||
|
||||
@* Forwarded timestamp *@
|
||||
<div class="chatlog__forwarded-timestamp">
|
||||
<span title="@FormatDate(fwd.Timestamp, "f")">Originally sent: @FormatDate(fwd.Timestamp)</span>
|
||||
@if (fwd.EditedTimestamp is not null)
|
||||
<span title="@FormatDate(message.ForwardedMessage.Timestamp, "f")">Originally sent: @FormatDate(message.ForwardedMessage.Timestamp)</span>
|
||||
@if (message.ForwardedMessage.EditedTimestamp is not null)
|
||||
{
|
||||
<span title="@FormatDate(fwd.EditedTimestamp.Value, "f")"> (edited)</span>
|
||||
<span title="@FormatDate(message.ForwardedMessage.EditedTimestamp.Value, "f")"> (edited)</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -239,12 +239,9 @@ internal class PlainTextMessageWriter(Stream stream, ExportContext context)
|
||||
);
|
||||
}
|
||||
|
||||
if (forwardedMessage.Timestamp != DateTimeOffset.MinValue)
|
||||
{
|
||||
await _writer.WriteLineAsync(
|
||||
$"Originally sent: {Context.FormatDate(forwardedMessage.Timestamp)}"
|
||||
);
|
||||
}
|
||||
|
||||
await WriteAttachmentsAsync(forwardedMessage.Attachments, cancellationToken);
|
||||
await WriteEmbedsAsync(forwardedMessage.Embeds, cancellationToken);
|
||||
|
||||
@@ -24,4 +24,17 @@ public static class CollectionExtensions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension<T>(IEnumerable<T?> source)
|
||||
where T : struct
|
||||
{
|
||||
public IEnumerable<T> WhereNotNull()
|
||||
{
|
||||
foreach (var o in source)
|
||||
{
|
||||
if (o is not null)
|
||||
yield return o.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user