The Ornery Twitter API 1.1: Struggling with the Lack of Fresh Documentation
The abstract “personality” of Twitter matches the curt, blunt tone coming from the current “leader” of Twitter, CEO Dick Costolo in “Twitter’s CEO says a leader doesn’t care what people think and shouldn’t copy others” (by Ken Yeung). It took me a ridiculously large time to solve my problem with the Twitter API (version 1.1) because of Twitter culture not caring what I think (especially as a .NET developer).
I am not alone. Collectively, Twitter doesn’t care what Tom Scott of the “dead” KloucheBag thinks either:
They’re steadily squeezing out third-party clients like Tweetbot, Echofon and Dabr, and they’re removing unauthenticated API calls. The latter means that every Twitter app, no matter how minor, will require a “Sign in with Twitter” button.
What Tom is saying here is not exactly true: what he might say after a little Twitter-soul searching is every Twitter app that matters will require a Twitter button. You see folks my app does not matter because it is built for me, alone. I am a registered developer with Twitter. I have registered my application with Twitter—and for my troubles I was given keys and secrets that I can send to Twitter and pretty much do what I want as long as I am working with my own Twitter account.
So: for a .NET developer like me who make apps that don’t matter I recommend installing the NuGet Package LinqToTwitter
and then doing a little something like this (in ASP.NET MVC space):
[HttpPost]
public ActionResult TwitterItems()
{
var authorizer = this.GetLinqToTwitterCredentialsAndAuthorizer();
var ctx = new TwitterContext(authorizer);
var query = ctx.Favorites
.Where(i => i.Type == FavoritesType.Favorites)
.Where(i => i.Count == 50)
.Where(i => i.IncludeEntities == true);
var count = query.Count();
if (count == 0) throw new TwitterQueryException("No items were found.");
var favorites = query.ToList();
if (favorites == null) throw new TwitterQueryException("No items were found.");
return this.Json(favorites);
}
I make it look so easy after all of my unknowns are known. But I can assure you it was a ridiculously comical nightmare to get to this level of simplicity—and it is all for an app that does not really matter (because it is designed for one Twitter account—my account).
Twitter Documentation ‘Misleading’
The Twitter REST API documentation should introduce itself to newbies by prioritizing “Authentication & Authorization.” The opinion here is that it is ‘misleading’ to visually position this subject below or next to other REST API subjects. It should be made clear that, in the 1.1 API world, you can do nothing unless you get authentication and authorization working. The academic subtlety of a statement like “Be sure and read about Authentication & Authorization” does not suggest that it is a prerequisite instead of an optional detail.
Once a Twitter application is defined I suggest starting with cURL by selecting the OAuth Tool for the application and press the See OAuth signature for this request button. Greg Williams details this in “Using Twitter’s OAuth Tool.” From my Ubuntu command line, we have verification that Twitter is working with your account:
curl ^
--get 'https://api.twitter.com/1.1/favorites/list.json' ^
--data 'count=2&screen_name=BryanWilhite' ^
--header 'Authorization: OAuth oauth_consumer_key="[your key]", oauth_nonce="[nonce]", oauth_signature="[signature]", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1373088858", oauth_token="[token]", oauth_version="1.0"' ^
–verbose
This cURL statement is altered from the one provided by Twitter as it is retrieving just two of my Favorites from my account with get operation, --get 'https://api.twitter.com/1.1/favorites/list.json'
, with data parameter, --data 'count=2&screen_name=BryanWilhite'
. The rest of the cURL statement comes from Twitter.
This cURL command represents a request for a Twitter app that ‘does not matter’—it represents what Twitter calls an “application-only auth” request opposed to an “OAuth signed” request. But this classification feels ‘misleading’ to me because both requests use OAuth—right? No?
“Authorizers” in LinqToTwitter
Most of the ‘comical’ misery with Twitter comes in generating the Authorization header. You can literally see this by measuring how much our cURL command above is dominated by authorization data. In the world of LinqToTwitter
, the ‘seed’ that generates the header is the authorizer.
It took me months to find that the authorizer for my limited needs is the SingleUserAuthorizer
(which should be called—according to Twitter documentation—“application-only-authorizer”?) From my ASP.NET MVC example above we have:
ITwitterAuthorizer GetLinqToTwitterCredentialsAndAuthorizer()
{
var data = new OpenAuthorizationData(ConfigurationManager.AppSettings);
var authorizer = new SingleUserAuthorizer
{
Credentials = new InMemoryCredentials
{
ConsumerKey = data.ConsumerKey,
ConsumerSecret = data.ConsumerSecret,
OAuthToken = data.Token,
AccessToken = data.TokenSecret
},
};
return authorizer;
}
The OpenAuthorizationData
instance is of a little housekeeping class I use to clearly define my keys and secrets.
Related Links
I will need something like | |
“There’s an | |
“The | |
“…it would probably be much easier for you to download | |
I tried and failed to get something like this working on a Windows Azure Websites server (see also: “2-legged OAuth with DotNetOpenAuth and Twitter. Getting a 401 error”). | |
“Two tastes better together: Combining OpenID and OAuth with OpenID Connect” |
“OpenID, by design, favors the user rather than the relying party. In contrast, technologies like Facebook and Twitter Connect emphasize the benefits to relying parties. So while it might seem like an inconvenience to custom-tailor your personal privacy settings on Facebook, the liberal defaults are meant to make Facebook users’ accounts more valuable to relying parties than other, more privacy-preserving account configurations.” |
“Managing session state in Windows Azure: What are the options?” |
When I was ignorant of the usefulness of |
It turns out that I was quite pleased with my success with implementing session state with | |
Table Storage worked for me: I do not recall getting this cache-based stuff up and running (see also: “Introducing Windows Azure Caching”). | |
“[Implementing OAuth for MVC Applications](http://linqtotwitter.codeplex.com/wikipage?title=Implementing OAuth for ASP.NET MVC&referringTitle=Learning to use OAuth)” |
Even though this documentation is from |
“Getting Twitter Access Secret using DotNetOpenAuth in MVC4” |
For a very large time I assumed that I could get things to working solely with |
“DotNetOpenAuth.AspNet Twitter,Facebook,Google,Microsoft,LinkedIn Authentication” |
I could not get this example to work on Windows Azure. I kept getting that 401 unauthorized error. This may be the right to mention that Twitter folk should save detailed error messages for developers available for viewing on dev.twitter.com. |
“I agree with you. The open-source OAuth support classes available for .NET apps are hard to understand, overly complicated (how many methods are exposed by | |
Okay here is the punch line: the PHP code in this article modified slightly for my Windows Azure Websites server ran flawlessly. No problems whatsoever! | |
“Multi-service Authentication the Easy Way” “Enabling Twitter OAuth For An Azure Mobile Service (Zumo) in a Windows 8 Game” |
A bunch of Windows 8 and Windows Azure links related to OAuth. |
“Parsing Twitter Usernames, Hashtags and URLs with JavaScript” |
I am using these techniques for the MVC version of my little app. |