Skip to content

Instantly share code, notes, and snippets.

@alexeyzimarev
Last active September 14, 2023 12:40
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alexeyzimarev/62d77bb25d7aa5bb4b9685461f8aabdd to your computer and use it in GitHub Desktop.
Save alexeyzimarev/62d77bb25d7aa5bb4b9685461f8aabdd to your computer and use it in GitHub Desktop.
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;
public TwitterAuthenticator(string baseUrl, string clientId, string clientSecret) : base("") {
_baseUrl = baseUrl;
_clientId = clientId;
_clientSecret = clientSecret;
}
protected override async ValueTask<Parameter> GetAuthenticationParameter(string accessToken) {
var token = string.IsNullOrEmpty(Token) ? await GetToken() : Token;
return new HeaderParameter(KnownHeaders.Authorization, token);
}
async Task<string> 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");
var response = await client.PostAsync<TokenResponse>(request);
return $"{response!.TokenType} {response!.AccessToken}";
}
record TokenResponse {
[JsonPropertyName("token_type")]
public string TokenType { get; init; }
[JsonPropertyName("access_token")]
public string AccessToken { get; init; }
}
}
public record TwitterUser(string Id, string Name, string Username);
@PedroNetto404
Copy link

PedroNetto404 commented Jul 17, 2023

@keyse just inform during the creation of the RestClientOptions instance:

 async Task<TokenResponse> GetToken() 
{
        //here
       var options = new RestClientOptions(_baseUrl){ Authenticator = new HttpBasicAuthenticator(_clientId, _clientSecret) };
        //not here
        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); 
} 

@alexeyzimarev thanks for your example, it was a great help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment