Use alternative endpoint to retrieve threads when requested by a bot (#1037)

Co-authored-by: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com>
pull/1040/head
William Unsworth 2 years ago committed by GitHub
parent 6bbde4ccdc
commit 41b4e47d0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,6 +36,12 @@ public class GetChannelsCommand : DiscordCommandBase
.ThenBy(c => c.Name) .ThenBy(c => c.Name)
.ToArray(); .ToArray();
var threads = IncludeThreads
? (await Discord.GetGuildThreadsAsync(GuildId, cancellationToken))
.OrderBy(c => c.Name)
.ToArray()
: Array.Empty<ChannelThread>();
foreach (var channel in channels) foreach (var channel in channels)
{ {
// Channel ID // Channel ID
@ -51,31 +57,24 @@ public class GetChannelsCommand : DiscordCommandBase
using (console.WithForegroundColor(ConsoleColor.White)) using (console.WithForegroundColor(ConsoleColor.White))
await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}"); await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}");
if (IncludeThreads) foreach (var thread in threads.Where(t => t.ParentId == channel.Id))
{ {
var threads = (await Discord.GetChannelThreadsAsync(channel.Id, cancellationToken)) // Indent
.OrderBy(c => c.Name) await console.Output.WriteAsync('\t');
.ToArray();
foreach (var thread in threads)
{
// Indent
await console.Output.WriteAsync('\t');
// Thread ID // Thread ID
await console.Output.WriteAsync( await console.Output.WriteAsync(
thread.Id.ToString().PadRight(18, ' ') thread.Id.ToString().PadRight(18, ' ')
); );
// Separator // Separator
using (console.WithForegroundColor(ConsoleColor.DarkGray)) using (console.WithForegroundColor(ConsoleColor.DarkGray))
await console.Output.WriteAsync(" | "); await console.Output.WriteAsync(" | ");
// Thread name // Thread name
using (console.WithForegroundColor(ConsoleColor.White)) using (console.WithForegroundColor(ConsoleColor.White))
await console.Output.WriteLineAsync($"Thread / {thread.Name}"); await console.Output.WriteLineAsync($"Thread / {thread.Name}");
} }
}
} }
} }
} }

@ -10,6 +10,7 @@ public record ChannelThread(
Snowflake Id, Snowflake Id,
ChannelKind Kind, ChannelKind Kind,
Snowflake GuildId, Snowflake GuildId,
Snowflake ParentId,
string Name, string Name,
Snowflake? LastMessageId) : IHasId Snowflake? LastMessageId) : IHasId
{ {
@ -18,6 +19,7 @@ public record ChannelThread(
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var kind = (ChannelKind)json.GetProperty("type").GetInt32(); var kind = (ChannelKind)json.GetProperty("type").GetInt32();
var guildId = json.GetProperty("guild_id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var guildId = json.GetProperty("guild_id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var parentId = json.GetProperty("parent_id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var name = json.GetProperty("name").GetNonWhiteSpaceString(); var name = json.GetProperty("name").GetNonWhiteSpaceString();
var lastMessageId = json var lastMessageId = json
@ -29,6 +31,7 @@ public record ChannelThread(
id, id,
kind, kind,
guildId, guildId,
parentId,
name, name,
lastMessageId lastMessageId
); );

@ -311,30 +311,68 @@ public class DiscordClient
return Channel.Parse(response, category); return Channel.Parse(response, category);
} }
public async IAsyncEnumerable<ChannelThread> GetChannelThreadsAsync( public async IAsyncEnumerable<ChannelThread> GetGuildThreadsAsync(
Snowflake channelId, Snowflake guildId,
[EnumeratorCancellation] CancellationToken cancellationToken = default) [EnumeratorCancellation] CancellationToken cancellationToken = default)
{ {
var currentOffset = 0; var channels = (await GetGuildChannelsAsync(guildId, cancellationToken))
while (true) .ToArray();
{ var tokenKind = _resolvedTokenKind ??= await GetTokenKindAsync(cancellationToken);
var url = new UrlBuilder()
.SetPath($"channels/{channelId}/threads/search")
.SetQueryParameter("offset", currentOffset.ToString())
.Build();
var response = await TryGetJsonResponseAsync(url, cancellationToken);
if (response is null)
break;
foreach (var threadJson in response.Value.GetProperty("threads").EnumerateArray()) if (tokenKind == TokenKind.Bot)
{
var response = await GetJsonResponseAsync($"guilds/{guildId}/threads/active", cancellationToken);
foreach (var threadJson in response.GetProperty("threads").EnumerateArray())
{ {
yield return ChannelThread.Parse(threadJson); yield return ChannelThread.Parse(threadJson);
currentOffset++;
} }
}
foreach (var channel in channels)
{
if (tokenKind == TokenKind.User)
{
var currentOffset = 0;
while (true)
{
var url = new UrlBuilder()
.SetPath($"channels/{channel.Id}/threads/search")
.SetQueryParameter("offset", currentOffset.ToString())
.Build();
var response = await TryGetJsonResponseAsync(url, cancellationToken);
if (response is null)
break;
foreach (var threadJson in response.Value.GetProperty("threads").EnumerateArray())
{
yield return ChannelThread.Parse(threadJson);
currentOffset++;
}
if (!response.Value.GetProperty("has_more").GetBoolean())
break;
}
}
else
{
var responsePublic = await TryGetJsonResponseAsync($"channels/{channel.Id}/threads/archived/public", cancellationToken);
var responsePrivate = await TryGetJsonResponseAsync($"channels/{channel.Id}/threads/archived/private", cancellationToken);
if (!response.Value.GetProperty("has_more").GetBoolean()) if (responsePublic is not null)
break; {
foreach (var threadJson in responsePublic.Value.GetProperty("threads").EnumerateArray())
{
yield return ChannelThread.Parse(threadJson);
}
}
if (responsePrivate is not null)
{
foreach (var threadJson in responsePrivate.Value.GetProperty("threads").EnumerateArray())
{
yield return ChannelThread.Parse(threadJson);
}
}
}
} }
} }

Loading…
Cancel
Save