Skip to content

Instantly share code, notes, and snippets.

@jasongaylord
Created November 5, 2018 21:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasongaylord/df33fe4cd4bc7d253a10c3cdccc41104 to your computer and use it in GitHub Desktop.
Save jasongaylord/df33fe4cd4bc7d253a10c3cdccc41104 to your computer and use it in GitHub Desktop.
Twitter View Component
@model List<TwitterViewComponent.Tweet>
<h3>Recent Tweets</h3>
<ul>
@foreach (var tweet in Model)
{
<li>
@tweet.Message<br/>
<a href="http://twitter.com/@tweet.Username/statuses/@tweet.Id">@(tweet.Timestamp)</a>
</li>
</ul>
public interface ITwitterService
{
string ObtainBearerToken(string consumerKey, string consumerSecret);
Task<List<Tweet>> RetrieveTweetsAsync(TwitterOptions options);
}
public class RetrieveTweetsViewComponent : ViewComponent
{
protected TwitterOptions TwitterOptions { get; private set; }
public RetrieveTweetsViewComponent(IOptions<TwitterOptions> options = null)
{
if (options != null)
TwitterOptions = options.Value;
else
TwitterOptions = new TwitterOptions();
}
public async Task<IViewComponentResult> InvokeAsync()
{
var service = new TwitterService();
var tweets = await service.RetrieveTweetsAsync(TwitterOptions);
return View("Default", tweets);
}
}
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddTwitter(this IServiceCollection services, IConfiguration configuration = null)
{
if (configuration != null)
services.Configure<TwitterOptions>(configuration);
else
services.TryAddSingleton<TwitterOptions, TwitterOptions>();
services.TryAddScoped<ITwitterService, TwitterService>();
return services;
}
}
public class Token
{
public string access_token { get; set; }
}
public class Tweet
{
public string Username { get; set; }
public string Message { get; set; }
public string Avatar { get; set; }
public string Timestamp { get; set; }
public string Id { get; set; }
}
public class TweetRaw
{
public string id_str { get; set; }
public string text { get; set; }
public string created_at { get; set; }
public string in_reply_to_screen_name { get; set; }
public UserRaw user { get; set; }
}
public class UserRaw
{
public string id_str { get; set; }
public string profile_image_url { get; set; }
public string screen_name { get; set; }
}
public class TwitterOptions
{
[Required]
public string ConsumerKey { get; set; } = "";
[Required]
public string ConsumerSecret { get; set; } = "";
public string Username { get; set; }
}
public class TwitterService : ITwitterService
{
public string ObtainBearerToken(string consumerKey, string consumerSecret)
{
var applicationAuthorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", Uri.EscapeDataString(consumerKey), Uri.EscapeDataString(consumerSecret))));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth2/token");
request.Headers.Add("Authorization", "Basic " + applicationAuthorization);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
request.AutomaticDecompression = DecompressionMethods.GZip;
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write("grant_type=client_credentials");
}
WebResponse response = request.GetResponse();
var token = "";
using (var reader = new StreamReader(response.GetResponseStream()))
{
token = reader.ReadToEnd();
}
return JsonConvert.DeserializeObject<Token>(token).access_token;
}
public async Task<List<Tweet>> RetrieveTweetsAsync(TwitterOptions options)
{
var tweets = new List<Tweet>();
if (!string.IsNullOrEmpty(options.Username) && !string.IsNullOrEmpty(options.ConsumerKey) && !string.IsNullOrEmpty(options.ConsumerSecret))
{
var bearerToken = ObtainBearerToken(options.ConsumerKey, options.ConsumerSecret);
var timelineUrl =
string.Format("https://api.twitter.com/1.1/statuses/user_timeline.json?exclude_replies={0}&screen_name={1}",
"false",
Uri.EscapeDataString(options.Username));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(timelineUrl);
request.Headers.Add("Authorization", "Bearer " + bearerToken);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
request.AutomaticDecompression = DecompressionMethods.GZip;
WebResponse response = await request.GetResponseAsync();
string responseData = await new StreamReader(response.GetResponseStream()).ReadToEndAsync();
var jsonResponse = JsonConvert.DeserializeObject<IEnumerable<TweetRaw>>(responseData);
tweets = jsonResponse.Select(t =>
new Tweet() { Message = t.text,
Username = t.user.screen_name,
Avatar = t.user.profile_image_url,
Timestamp = DateTime.ParseExact(t.created_at, "ddd MMM dd HH:mm:ss %zzzz yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal).ToFriendlyDate(),
Id = t.id_str
}).ToList();
}
return tweets;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment