first_page

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

How to get tweet’s HTML with LinqToTwitter?

I will need something like TwitterExtensions for a WPF version of my little project.

How to get HTML instead of plain text (Status.Text)

“There’s an Entities property that contains metadata for various parts of a tweet, including the Start and End character positions. One of those is UrlEntities, which you can use to determine where the URLs are in the tweet. With that, you can write code to arrange the entities and work backwards through the tweet to transform the text into HTML.”

Implementing Single User Authorization

“The SingleUserAuthorizer allows you to fill in all of your credentials at one time, bypassing the user-centric authorization process. It's designed for application-only operations…”

How do I tweet, using the DotNetOpenAuth library?

“…it would probably be much easier for you to download LinqToTwitter, which uses DotNetOpenAuth and offers an extensive Twitter library to do most/all the operations Twitter supports.”

TwitterConsumer.cs

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 LinqToTwitter and SingleUserAuthorizer, I assumed that I needed Session State support on Windows Azure to properly handle Twitter authentication and authorization. I thought that manually logging in to Twitter was the *only *way to access the REST API.

How to maintain session state in Window Azure

It turns out that I was quite pleased with my success with implementing session state with TableStorageSessionStateProvider. So this digression from my Twitter problems should pay off later.

Session State Provider for Windows Azure Cache

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 LinqToTwitter people it was total fail for me. I assume that I could not get it to work because I am running MVC on Windows Azure.

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. Nope. By the way, there is no official answer to this StackOverflow.com question. Also: it was this question that really helped me to distinguish between authentication and authorization: “The DotNetOpenAuth.AspNet.Clients.TwitterClient class only allows authentication, not authorization. So you wouldn't be able to post tweets as that user if you use that class. Instead, you can use DotNetOpenAuth.ApplicationBlock.TwitterConsumer [http://nuget.org/packages/DotNetOpenAuth.ApplicationBlock], which does not share this limitation and you can even copy the source code for this type into your application and extend it as necessary.”

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.

OAuth with Verification in .NET

“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 DotNetOpenAuth?), poorly designed (look at the methods with 10 string parameters in the OAuthBase.cs module from that google link you provided—there’s no state management at all), or otherwise unsatisfactory.”

How to Connect in Twitter API Using PHP

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.

https://github.com/BryanWilhite/