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;
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);
@miai-demant
Copy link

Bad example. Token is empty every request so if forces to get new one.

@miai-demant
Copy link

And what about refreshing token ?

@alexeyzimarev
Copy link
Author

@miai-demant feel free to provide a better example. I never claimed that it should be considered as production code. It is, as described, an example.

@alexeyzimarev
Copy link
Author

@lcordy

means every client request will get a new token

Adding one line after line 49 solves it, I am not sure why it's such a big issue

        Token = token;

@vanderlei-dev
Copy link

vanderlei-dev commented Jan 31, 2023

I created a updated version that handle expiration date, for anyway interested is over here:
https://gist.github.com/vanderlei-dev/665d7cd7c90aee0bf3e38e83dad5c7d2

Thanks @alexeyzimarev for the base example.

@alexeyzimarev
Copy link
Author

Cool! Thanks @vanderlei-dev

@keyse
Copy link

keyse commented May 9, 2023

v107 documentation is not correct.
_client = new RestClient(options)
{
Authenticator = new TwitterAuthenticator("https://api.twitter.com", apiKey, apiKeySecret)
};

The above code will NOT compile because Authenticator is getter and can not be set.

@alexeyzimarev
Copy link
Author

I appreciate the report, but it would've been better to open an issue in the RestSharp repository rather than commenting on my old gist.

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