Skip to content

Instantly share code, notes, and snippets.

@SnowCait
Last active April 3, 2022 03:24
Show Gist options
  • Save SnowCait/5b48c2ef73a1b79a711a18d88334ab7a to your computer and use it in GitHub Desktop.
Save SnowCait/5b48c2ef73a1b79a711a18d88334ab7a to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace MauiLib1
{
public class Api
{
public string AccessToken { get; private set; }
protected static readonly HttpClient HttpClient = new HttpClient();
public Api(string accessToken)
{
AccessToken = accessToken;
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
}
public async Task<string> GetTweet(long id)
{
var response = await HttpClient.GetAsync($"https://api.twitter.com/2/tweets/{id}").ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
public async Task<string> PostTweet(string text)
{
var parameters = new Dictionary<string, string>()
{
{ "text", text },
};
var json = JsonSerializer.Serialize(parameters);
var content = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);
var response = await HttpClient.PostAsync("https://api.twitter.com/2/tweets", content).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace MauiLib1
{
public class Client
{
protected static readonly HttpClient HttpClient = new HttpClient();
public ClientType ClientType { get; private set; }
public string ClientId { get; private set; }
public string ClientSecret { get; private set; }
public Client(string clientId, string clientSecret = null)
{
ClientType = clientSecret == null ? ClientType.Public : ClientType.Confidential;
ClientId = clientId;
ClientSecret = clientSecret;
}
public string ConstructAuthorizeUrl(string redirectUri, IEnumerable<Scope> scopes, string state, string challenge, string challengeMethod = "S256")
{
var query = HttpUtility.ParseQueryString("");
query.Add("response_type", "code");
query.Add("client_id", ClientId);
query.Add("redirect_uri", redirectUri);
query.Add("scope", string.Join(" ", scopes.Select(x => x.GetValue())));
query.Add("state", state);
query.Add("code_challenge", challenge);
query.Add("code_challenge_method", challengeMethod);
var uriBuilder = new UriBuilder("https://twitter.com/i/oauth2/authorize")
{
Query = query.ToString(),
};
return uriBuilder.Uri.AbsoluteUri;
}
public string RetrieveAuthorizationCode(string callbackedUri, string state)
{
var uri = new Uri(callbackedUri);
var query = HttpUtility.ParseQueryString(uri.Query);
if (query.Get("state") != state)
{
throw new InvalidDataException("state is not valid.");
}
return query.Get("code");
}
public async Task<string> GetAccessToken(string redirectUri, string code, string verifier)
{
var parameters = new Dictionary<string, string>()
{
{ "code", code },
{ "grant_type", "authorization_code" },
{ "redirect_uri", redirectUri },
{ "code_verifier", verifier },
};
if (ClientType == ClientType.Public)
{
parameters.Add("client_id", ClientId);
}
var content = new FormUrlEncodedContent(parameters);
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/2/oauth2/token");
if (ClientType == ClientType.Confidential)
{
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{ClientId}:{ClientSecret}"))
);
}
request.Content = content;
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
public async Task<string> RefreshToken(string refreshToken)
{
var parameters = new Dictionary<string, string>()
{
{ "refresh_token", refreshToken },
{ "grant_type", "refresh_token" },
};
if (ClientType == ClientType.Public)
{
parameters.Add("client_id", ClientId);
}
var content = new FormUrlEncodedContent(parameters);
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/2/oauth2/token");
if (ClientType == ClientType.Confidential)
{
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{ClientId}:{ClientSecret}"))
);
}
request.Content = content;
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
public async Task<string> RevokeToken(string accessToken)
{
var parameters = new Dictionary<string, string>()
{
{ "token", accessToken },
{ "token_type_hint", "access_token" }
};
if (ClientType == ClientType.Public)
{
parameters.Add("client_id", ClientId);
}
var content = new FormUrlEncodedContent(parameters);
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/2/oauth2/revoke");
if (ClientType == ClientType.Confidential)
{
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{ClientId}:{ClientSecret}"))
);
}
request.Content = content;
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
public enum ClientType
{
Confidential,
Public,
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MauiLib1
{
public enum Scope
{
TweetRead,
TweetWrite,
TweetModerateWrite,
UsersRead,
FollowRead,
FollowWrite,
OfflineAccess,
SpaceRead,
MuteRead,
MuteWrite,
LikeRead,
LikeWrite,
ListRead,
ListWrite,
BlockRead,
BlockWrite,
BookmarkRead,
BookmarkWrite,
}
public static class ScopeExtension
{
private static Dictionary<Scope, string> Values = new Dictionary<Scope, string>()
{
{ Scope.TweetRead, "tweet.read" },
{ Scope.TweetWrite, "tweet.write" },
{ Scope.TweetModerateWrite, "tweet.moderate.write" },
{ Scope.UsersRead, "users.read" },
{ Scope.FollowRead, "follow.read" },
{ Scope.FollowWrite, "follow.write" },
{ Scope.OfflineAccess, "offline.access" },
{ Scope.SpaceRead, "space.read" },
{ Scope.MuteRead, "mute.read" },
{ Scope.MuteWrite, "mute.write" },
{ Scope.LikeRead, "like.read" },
{ Scope.LikeWrite, "like.write" },
{ Scope.ListRead, "list.read" },
{ Scope.ListWrite, "list.write" },
{ Scope.BlockRead, "block.read" },
{ Scope.BlockWrite, "block.write" },
{ Scope.BookmarkRead, "bookmark.read" },
{ Scope.BookmarkWrite, "bookmark.write" },
};
public static string GetValue(this Scope scope)
{
return Values[scope];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment