Don't ignore next pages of archived threads

This commit is contained in:
masmc05 2025-04-20 00:25:35 +03:00 committed by GitHub
parent 6fb197cf0b
commit 7ddd55951c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -438,43 +438,63 @@ public class DiscordClient(string token)
foreach (var channel in channels)
{
// Public archived threads
{
// Can be null on certain channels
var response = await TryGetJsonResponseAsync(
$"channels/{channel.Id}/threads/archived/public",
cancellationToken
);
if (response is null)
continue;
foreach (
var threadJson in response.Value.GetProperty("threads").EnumerateArray()
)
yield return Channel.Parse(threadJson, channel);
}
await foreach (
var th in GetAllArchivedThreadsAsync(channel, "public", cancellationToken)
)
yield return th;
// Private archived threads
{
// Can be null on certain channels
var response = await TryGetJsonResponseAsync(
$"channels/{channel.Id}/threads/archived/private",
cancellationToken
);
if (response is null)
continue;
foreach (
var threadJson in response.Value.GetProperty("threads").EnumerateArray()
)
yield return Channel.Parse(threadJson, channel);
}
await foreach (
var th in GetAllArchivedThreadsAsync(channel, "private", cancellationToken)
)
yield return th;
}
}
}
}
private async IAsyncEnumerable<Channel> GetAllArchivedThreadsAsync(
Channel channel,
string archiveType,
[EnumeratorCancellation] CancellationToken cancellationToken
)
{
// Base endpoint: "public" or "private"
var endpointBase = $"channels/{channel.Id}/threads/archived/{archiveType}";
// Cursor parameter: ISO8601 timestamp string
string? beforeTimestamp = null;
bool hasMorePages = true;
while (hasMorePages && !cancellationToken.IsCancellationRequested)
{
// Build URL with optional before= parameter
var url = beforeTimestamp is null
? endpointBase
: $"{endpointBase}?before={Uri.EscapeDataString(beforeTimestamp)}";
var response = await TryGetJsonResponseAsync(url, cancellationToken);
if (response is null)
yield break;
// Parse out the threads array
var threadsJson = response.Value.GetProperty("threads").EnumerateArray().ToList();
foreach (var threadJson in threadsJson)
{
yield return Channel.Parse(threadJson, channel);
}
// Check pagination flag
hasMorePages = response.Value.GetProperty("has_more").GetBoolean();
if (hasMorePages && threadsJson.Count > 0)
{
// Prepare next cursor: the archived timestamp of the last thread
var lastThreadMeta = threadsJson.Last().GetProperty("thread_metadata");
beforeTimestamp = lastThreadMeta.GetProperty("archive_timestamp").GetString();
}
}
}
public async IAsyncEnumerable<Role> GetGuildRolesAsync(
Snowflake guildId,
[EnumeratorCancellation] CancellationToken cancellationToken = default