Created
April 23, 2015 23:20
-
-
Save jaredfaris/941e9176f371b7cd5bba to your computer and use it in GitHub Desktop.
A class I built for making Twitter requests with OAuth. Built around code I found on SO.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Text; | |
using System.Web.Script.Serialization; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace TwitterIntegration | |
{ | |
public class TwitterApiHelper | |
{ | |
private string _oAuthConsumerKey; | |
private string _oAuthConsumerSecret; | |
public TwitterApiHelper(string oAuthConsumerKey, string oAuthConsumerSecret) | |
{ | |
// You need to set your own keys and screen name | |
_oAuthConsumerKey = oAuthConsumerKey; | |
_oAuthConsumerSecret = oAuthConsumerSecret; | |
} | |
/// <summary> | |
/// Sends an OAuth request to Twitter with our app's tokens to get a bearer token. | |
/// See https://dev.twitter.com/oauth/application-only for more details. | |
/// Code originally from: http://stackoverflow.com/questions/17067996/authenticate-and-request-a-users-timeline-with-twitter-api-1-1-oauth | |
/// </summary> | |
/// <param name="oAuthConsumerKey"></param> | |
/// <param name="oAuthConsumerSecret"></param> | |
/// <returns></returns> | |
public TwitterBearerToken GetAuthenticatedToken() | |
{ | |
var oAuthUrl = "https://api.twitter.com/oauth2/token"; | |
// Do the Authenticate | |
var authHeaderFormat = "Basic {0}"; | |
var authHeader = string.Format(authHeaderFormat, | |
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(_oAuthConsumerKey) + ":" + | |
Uri.EscapeDataString((_oAuthConsumerSecret))) | |
)); | |
var postBody = "grant_type=client_credentials"; | |
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl); | |
authRequest.Headers.Add("Authorization", authHeader); | |
authRequest.Method = "POST"; | |
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8"; | |
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; | |
using (Stream stream = authRequest.GetRequestStream()) | |
{ | |
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody); | |
stream.Write(content, 0, content.Length); | |
} | |
authRequest.Headers.Add("Accept-Encoding", "gzip"); | |
WebResponse authResponse = authRequest.GetResponse(); | |
// deserialize into an object | |
TwitterBearerToken twitAuthResponse; | |
using (authResponse) | |
{ | |
using (var reader = new StreamReader(authResponse.GetResponseStream())) | |
{ | |
JavaScriptSerializer js = new JavaScriptSerializer(); | |
var objectText = reader.ReadToEnd(); | |
twitAuthResponse = JsonConvert.DeserializeObject<TwitterBearerToken>(objectText); | |
} | |
} | |
return twitAuthResponse; | |
} | |
/// <summary> | |
/// Sends a request to twitter to get a user's timeline | |
/// </summary> | |
/// <param name="screenname"></param> | |
/// <param name="authToken"></param> | |
/// <returns></returns> | |
public JArray GetTimelineForScreenname(string screenname, TwitterBearerToken authToken) | |
{ | |
// build a request to their restful api. it uses query strings to identify people/search terms | |
var timelineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts=1&exclude_replies=1&count=5"; | |
var timelineUrl = string.Format(timelineFormat, screenname); | |
var timeLineJson = MakeTwitterApiCall(authToken, timelineUrl); | |
return JArray.Parse(timeLineJson); | |
} | |
/// <summary> | |
/// Sends a request to twitter to get results for a hashtag | |
/// </summary> | |
/// <param name="hashtag"></param> | |
/// <param name="authToken"></param> | |
/// <returns></returns> | |
public List<TwitterTimelineModel> GetResultsForHashtag(string hashtag, TwitterBearerToken authToken, Int64? sinceId) | |
{ | |
const int count = 100; | |
var allTweets = new List<TwitterTimelineModel>(); | |
// build a request to their restful api. it uses query strings to identify people/search terms | |
const string initialHashtagFormat = "https://api.twitter.com/1.1/search/tweets.json?q=%23{0}&result_type=recent&count={1}"; | |
string hashtagUrlFormat = initialHashtagFormat; | |
//string sinceIdHashtagFormat = "https://api.twitter.com/1.1/search/tweets.json?q=%23{0}&result_type=recent&count={1}&since_id={2}"; | |
//string followupHashtagFormat = "https://api.twitter.com/1.1/search/tweets.json?q=%23{0}&result_type=recent&count={1}&max_id={2}"; | |
// if we're coming back to this, we'll attach the ID of last iteration's first tweet as our since_id | |
var hashtagUrl = string.Format(hashtagUrlFormat, hashtag, count); | |
if (sinceId != null) | |
hashtagUrl += "&since_id=" + sinceId.ToString(); | |
// 1) get the initial request | |
var iterationResult = SendTwitterTimelineRequest(authToken, hashtagUrl); | |
// 2) save the first tweet's ID for future queries | |
if (iterationResult.Any()) | |
allTweets.AddRange(iterationResult); | |
// 3) As long as their are more results available, keep looping | |
while (iterationResult.Count == count) | |
{ | |
var lastId = iterationResult.Last().TweetId; | |
var loopinghashtagUrl = hashtagUrl + "&max_id=" + lastId.ToString(); | |
iterationResult = SendTwitterTimelineRequest(authToken, loopinghashtagUrl); | |
allTweets.AddRange(iterationResult); | |
} | |
return allTweets; | |
} | |
private List<TwitterTimelineModel> SendTwitterTimelineRequest(TwitterBearerToken authToken, string hashtagUrl) | |
{ | |
var hashtagJson = MakeTwitterApiCall(authToken, hashtagUrl); | |
var jsonObject = JObject.Parse(hashtagJson); | |
var listResult = ((JArray) jsonObject.SelectToken("statuses")).Select(status => | |
{ | |
var res = new TwitterTimelineModel | |
{ | |
ProfileImageUrl = status["user"]["profile_image_url_https"].ToString(), | |
TwitterHandle = status["user"]["screen_name"].ToString(), | |
TwitterUserId = status["user"]["id_str"].ToString(), | |
Text = status["text"].ToString(), | |
TweetId = Int64.Parse(status["id"].ToString()) | |
}; | |
return res; | |
}).ToList(); | |
return listResult; | |
} | |
/// <summary> | |
/// Sends a request to twitter to get a user's profile and then pulls out the avatar and userid | |
/// </summary> | |
/// <param name="twitterHandle"></param> | |
/// <param name="twitterBearerToken"></param> | |
/// <returns></returns> | |
public TwitterProfileInformation GetProfileInformationForUser(string twitterHandle, TwitterBearerToken authToken) | |
{ | |
// build a request to their restful api. it uses query strings to identify people/search terms | |
var avatarFormat = "https://api.twitter.com/1.1/users/show.json?screen_name={0}"; | |
var avatarUrl = string.Format(avatarFormat, twitterHandle); | |
var avatarJson = MakeTwitterApiCall(authToken, avatarUrl); | |
var jsonObject = JObject.Parse(avatarJson); | |
return new TwitterProfileInformation | |
{ | |
AvatarUrl = jsonObject["profile_image_url_https"].ToString(), | |
TwitterUserId = jsonObject["id"].ToString() | |
}; | |
} | |
/// <summary> | |
/// Makes a call to the Twitter API to get the followers for a twitter handle | |
/// Follower userids are returned in blocks of 5000. Twitter cursor support is necessary | |
/// GET https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=sitestreams&count=5000 | |
/// </summary> | |
/// <param name="twitterHandle"></param> | |
/// <returns></returns> | |
public List<string> GetFollowerIdsForUser(string twitterHandle, TwitterBearerToken authToken) | |
{ | |
// build a request to their restful api. it uses query strings to identify people/search terms | |
var followersFormat = "https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name={0}&count=5000"; | |
var followersUrl = string.Format(followersFormat, twitterHandle); | |
var followerIdJson = MakeTwitterApiCall(authToken, followersUrl); | |
var jsonObject = JObject.Parse(followerIdJson); | |
return ((JArray) jsonObject.SelectToken("ids")).Select(id => id.ToString()).ToList(); | |
} | |
/// <summary> | |
/// Makes the request to Twitter and adds the token to the header | |
/// </summary> | |
/// <param name="authToken"></param> | |
/// <param name="requestUrl"></param> | |
/// <returns></returns> | |
private string MakeTwitterApiCall(TwitterBearerToken authToken, string requestUrl) | |
{ | |
// build and then add the token to a http request | |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl); | |
var headerFormat = "{0} {1}"; | |
request.Headers.Add("Authorization", string.Format(headerFormat, authToken.token_type, authToken.access_token)); | |
request.Method = "Get"; | |
WebResponse response = request.GetResponse(); | |
// pull out the json string. we'll pass it back as a JSON.NET array instead of a nasty string | |
string responseJson; | |
using (response) | |
{ | |
using (var reader = new StreamReader(response.GetResponseStream())) | |
{ | |
responseJson = reader.ReadToEnd(); | |
} | |
} | |
return responseJson; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment