mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-23 11:16:59 -04:00
Simplify token kind resolution
Extra request which makes it less efficient, but much simpler code
This commit is contained in:
parent
b8cea0d140
commit
f8dac2c9d0
2 changed files with 44 additions and 43 deletions
|
@ -22,65 +22,67 @@ public class DiscordClient
|
||||||
private readonly string _token;
|
private readonly string _token;
|
||||||
private readonly Uri _baseUri = new("https://discord.com/api/v9/", UriKind.Absolute);
|
private readonly Uri _baseUri = new("https://discord.com/api/v9/", UriKind.Absolute);
|
||||||
|
|
||||||
private TokenKind _tokenKind = TokenKind.Unknown;
|
private TokenKind? _resolvedTokenKind;
|
||||||
|
|
||||||
public DiscordClient(string token) => _token = token;
|
public DiscordClient(string token) => _token = token;
|
||||||
|
|
||||||
private async ValueTask<HttpResponseMessage> GetResponseAsync(
|
private async ValueTask<HttpResponseMessage> GetResponseAsync(
|
||||||
string url,
|
string url,
|
||||||
bool isBot,
|
TokenKind tokenKind,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url));
|
return await Http.ResponseResiliencePolicy.ExecuteAsync(async innerCancellationToken =>
|
||||||
|
{
|
||||||
|
using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url));
|
||||||
|
|
||||||
// Don't validate because token can have invalid characters
|
// Don't validate because token can have invalid characters
|
||||||
// https://github.com/Tyrrrz/DiscordChatExporter/issues/828
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/828
|
||||||
request.Headers.TryAddWithoutValidation(
|
request.Headers.TryAddWithoutValidation(
|
||||||
"Authorization",
|
"Authorization",
|
||||||
isBot ? $"Bot {_token}" : _token
|
tokenKind == TokenKind.Bot
|
||||||
);
|
? $"Bot {_token}"
|
||||||
|
: _token
|
||||||
|
);
|
||||||
|
|
||||||
return await Http.Client.SendAsync(
|
return await Http.Client.SendAsync(
|
||||||
request,
|
request,
|
||||||
HttpCompletionOption.ResponseHeadersRead,
|
HttpCompletionOption.ResponseHeadersRead,
|
||||||
|
innerCancellationToken
|
||||||
|
);
|
||||||
|
}, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ValueTask<TokenKind> GetTokenKindAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
// Try authenticating as a user
|
||||||
|
using var userResponse = await GetResponseAsync(
|
||||||
|
"users/@me",
|
||||||
|
TokenKind.User,
|
||||||
cancellationToken
|
cancellationToken
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (userResponse.StatusCode != HttpStatusCode.Unauthorized)
|
||||||
|
return TokenKind.User;
|
||||||
|
|
||||||
|
// Try authenticating as a bot
|
||||||
|
using var botResponse = await GetResponseAsync(
|
||||||
|
"users/@me",
|
||||||
|
TokenKind.Bot,
|
||||||
|
cancellationToken
|
||||||
|
);
|
||||||
|
|
||||||
|
if (botResponse.StatusCode != HttpStatusCode.Unauthorized)
|
||||||
|
return TokenKind.Bot;
|
||||||
|
|
||||||
|
throw DiscordChatExporterException.Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask<HttpResponseMessage> GetResponseAsync(
|
private async ValueTask<HttpResponseMessage> GetResponseAsync(
|
||||||
string url,
|
string url,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await Http.ResponseResiliencePolicy.ExecuteAsync(async innerCancellationToken =>
|
var tokenKind = _resolvedTokenKind ??= await GetTokenKindAsync(cancellationToken);
|
||||||
{
|
return await GetResponseAsync(url, tokenKind, cancellationToken);
|
||||||
if (_tokenKind == TokenKind.User)
|
|
||||||
return await GetResponseAsync(url, false, innerCancellationToken);
|
|
||||||
|
|
||||||
if (_tokenKind == TokenKind.Bot)
|
|
||||||
return await GetResponseAsync(url, true, innerCancellationToken);
|
|
||||||
|
|
||||||
// Try to authenticate as user
|
|
||||||
var userResponse = await GetResponseAsync(url, false, innerCancellationToken);
|
|
||||||
if (userResponse.StatusCode != HttpStatusCode.Unauthorized)
|
|
||||||
{
|
|
||||||
_tokenKind = TokenKind.User;
|
|
||||||
return userResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
userResponse.Dispose();
|
|
||||||
|
|
||||||
// Otherwise, try to authenticate as bot
|
|
||||||
var botResponse = await GetResponseAsync(url, true, innerCancellationToken);
|
|
||||||
if (botResponse.StatusCode != HttpStatusCode.Unauthorized)
|
|
||||||
{
|
|
||||||
_tokenKind = TokenKind.Bot;
|
|
||||||
return botResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The token is probably invalid altogether.
|
|
||||||
// Return the last response anyway, upstream should handle the error.
|
|
||||||
return botResponse;
|
|
||||||
}, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask<JsonElement> GetJsonResponseAsync(
|
private async ValueTask<JsonElement> GetJsonResponseAsync(
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
public enum TokenKind
|
public enum TokenKind
|
||||||
{
|
{
|
||||||
Unknown,
|
|
||||||
User,
|
User,
|
||||||
Bot
|
Bot
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue