Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
using System.Text.Json.Serialization;
using RestSharp.Authenticators;
namespace RestSharp.Tests.External.Twitter;
public interface ITwitterClient
{
Task<TwitterUser> GetUser(string user);
}
public class TwitterClient : ITwitterClient, IDisposable
{
readonly RestClient _client;
public TwitterClient(string apiKey, string apiKeySecret)
{
var options = new RestClientOptions("https://api.twitter.com/2");
_client = new RestClient(options)
{
Authenticator = new TwitterAuthenticator("https://api.twitter.com", apiKey, apiKeySecret)
};
}
public async Task<TwitterUser> GetUser(string user)
{
var response = await _client.GetJsonAsync<TwitterSingleObject<TwitterUser>>(
"users/by/username/{user}",
new { user }
);
return response!.Data;
}
record TwitterSingleObject<T>(T Data);
public void Dispose()
{
_client?.Dispose();
GC.SuppressFinalize(this);
}
}
public class TwitterAuthenticator : AuthenticatorBase
{
readonly string _baseUrl;
readonly string _clientId;
readonly string _clientSecret;
protected DateTime Expiration { get; private set; } = DateTime.MinValue;
public TwitterAuthenticator(string baseUrl, string clientId, string clientSecret) : base("")
{
_baseUrl = baseUrl;
_clientId = clientId;
_clientSecret = clientSecret;
}
protected override async ValueTask<Parameter> GetAuthenticationParameter(string accessToken)
{
if (string.IsNullOrEmpty(Token) || DateTime.UtcNow >= Expiration)
{
var tokenResponse = await GetToken();
Token = $"{tokenResponse!.TokenType} {tokenResponse!.AccessToken}";
Expiration = tokenResponse.GetExpirationDate(DateTime.UtcNow);
}
return new HeaderParameter(KnownHeaders.Authorization, Token);
}
async Task<TokenResponse> GetToken()
{
var options = new RestClientOptions(_baseUrl);
using var client = new RestClient(options)
{
Authenticator = new HttpBasicAuthenticator(_clientId, _clientSecret),
};
var request = new RestRequest("oauth2/token")
.AddParameter("grant_type", "client_credentials");
return await client.PostAsync<TokenResponse>(request);
}
record TokenResponse
{
[JsonPropertyName("token_type")]
public string TokenType { get; init; }
[JsonPropertyName("access_token")]
public string AccessToken { get; init; }
[JsonPropertyName("expires_in")]
public int ExpiresIn { get; init; }
public DateTime GetExpirationDate(DateTime baseDateTime, int toleranceInMinutes = 1)
{
return baseDateTime.AddSeconds(ExpiresIn).AddMinutes(-toleranceInMinutes);
}
}
}
public record TwitterUser(string Id, string Name, string Username);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment