mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-27 21:24:12 -04:00
Load mentions for users that left the guild
This commit is contained in:
parent
bbe18368fa
commit
8f40acdda7
6 changed files with 45 additions and 17 deletions
|
@ -23,19 +23,6 @@ public partial record Channel(
|
|||
|
||||
public partial record Channel
|
||||
{
|
||||
private static ChannelCategory GetFallbackCategory(ChannelKind channelKind) => new(
|
||||
Snowflake.Zero,
|
||||
channelKind switch
|
||||
{
|
||||
ChannelKind.GuildTextChat => "Text",
|
||||
ChannelKind.DirectTextChat => "Private",
|
||||
ChannelKind.DirectGroupTextChat => "Group",
|
||||
ChannelKind.GuildNews => "News",
|
||||
_ => "Default"
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
public static Channel Parse(JsonElement json, ChannelCategory? categoryHint = null, int? positionHint = null)
|
||||
{
|
||||
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
|
||||
|
@ -45,7 +32,7 @@ public partial record Channel
|
|||
json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse) ??
|
||||
Guild.DirectMessages.Id;
|
||||
|
||||
var category = categoryHint ?? GetFallbackCategory(kind);
|
||||
var category = categoryHint ?? ChannelCategory.CreateDefault(kind);
|
||||
|
||||
var name =
|
||||
// Guild channel
|
||||
|
|
|
@ -7,6 +7,19 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
|||
|
||||
public record ChannelCategory(Snowflake Id, string Name, int? Position) : IHasId
|
||||
{
|
||||
public static ChannelCategory CreateDefault(ChannelKind channelKind) => new(
|
||||
Snowflake.Zero,
|
||||
channelKind switch
|
||||
{
|
||||
ChannelKind.GuildTextChat => "Text",
|
||||
ChannelKind.DirectTextChat => "Private",
|
||||
ChannelKind.DirectGroupTextChat => "Group",
|
||||
ChannelKind.GuildNews => "News",
|
||||
_ => "Default"
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
public static ChannelCategory Parse(JsonElement json, int? positionHint = null)
|
||||
{
|
||||
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
|
||||
|
|
|
@ -20,6 +20,8 @@ public partial record Member(
|
|||
|
||||
public partial record Member
|
||||
{
|
||||
public static Member CreateDefault(User user) => new(user, null, null, Array.Empty<Snowflake>());
|
||||
|
||||
public static Member Parse(JsonElement json, Snowflake? guildId = null)
|
||||
{
|
||||
var user = json.GetProperty("user").Pipe(User.Parse);
|
||||
|
|
|
@ -150,6 +150,14 @@ public class DiscordClient
|
|||
: null;
|
||||
}
|
||||
|
||||
public async ValueTask<User?> TryGetUserAsync(
|
||||
Snowflake userId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await TryGetJsonResponseAsync($"users/{userId}", cancellationToken);
|
||||
return response?.Pipe(User.Parse);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<Guild> GetUserGuildsAsync(
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ChannelExporter
|
|||
{
|
||||
// Resolve members for referenced users
|
||||
foreach (var user in message.GetReferencedUsers())
|
||||
await context.PopulateMemberAsync(user.Id, cancellationToken);
|
||||
await context.PopulateMemberAsync(user, cancellationToken);
|
||||
|
||||
// Export the message
|
||||
if (request.MessageFilter.IsMatch(message))
|
||||
|
|
|
@ -20,6 +20,7 @@ internal class ExportContext
|
|||
private readonly ExportAssetDownloader _assetDownloader;
|
||||
|
||||
public DiscordClient Discord { get; }
|
||||
|
||||
public ExportRequest Request { get; }
|
||||
|
||||
public ExportContext(DiscordClient discord,
|
||||
|
@ -43,18 +44,35 @@ internal class ExportContext
|
|||
_roles[role.Id] = role;
|
||||
}
|
||||
|
||||
// Because members are not pulled in bulk, we need to populate them on demand
|
||||
public async ValueTask PopulateMemberAsync(Snowflake id, CancellationToken cancellationToken = default)
|
||||
// Because members cannot be pulled in bulk, we need to populate them on demand
|
||||
private async ValueTask PopulateMemberAsync(
|
||||
Snowflake id,
|
||||
User? fallbackUser,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_members.ContainsKey(id))
|
||||
return;
|
||||
|
||||
var member = await Discord.TryGetGuildMemberAsync(Request.Guild.Id, id, cancellationToken);
|
||||
|
||||
// User may have left the guild since they were mentioned
|
||||
if (member is null)
|
||||
{
|
||||
var user = fallbackUser ?? await Discord.TryGetUserAsync(id, cancellationToken);
|
||||
if (user is not null)
|
||||
member = Member.CreateDefault(user);
|
||||
}
|
||||
|
||||
// Store the result even if it's null, to avoid re-fetching non-existing members
|
||||
_members[id] = member;
|
||||
}
|
||||
|
||||
public async ValueTask PopulateMemberAsync(Snowflake id, CancellationToken cancellationToken = default) =>
|
||||
await PopulateMemberAsync(id, null, cancellationToken);
|
||||
|
||||
public async ValueTask PopulateMemberAsync(User user, CancellationToken cancellationToken = default) =>
|
||||
await PopulateMemberAsync(user.Id, user, cancellationToken);
|
||||
|
||||
public string FormatDate(DateTimeOffset instant) => Request.DateFormat switch
|
||||
{
|
||||
"unix" => instant.ToUnixTimeSeconds().ToString(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue