api – Page 2 – Stay N Alive

Facebook Launches Application Creation API

One of my biggest frustrations as a FacebookFacebook API developer of WordPress plugins has been the need to require my users to go out and create their own application in Facebook for their blog.  To do so they had to install a “developer app” on Facebook and know what forms to fill out after they did.  It was a lot of work and very difficult to explain to people!  Today Facebook launched a way to automate that process, their Create Application API.

According to the developers wiki, starting today developers of WordPress plugins and other 4th-party Facebook applications will be able to automate the process of creating applications on behalf of their users as “child applications”.  This means for the FBFoundations plugin I launched over the weekend I’ll be able to automatically register the user’s blog as an app in Facebook when they activate the plugin.  The user will only need to activate the plugin in WordPress, we’ll grab the API key and everything else, and there will be nothing more for that user to do.

Installing Facebook Connect WordPress plugins just got a whole lot more easy.  Can’t wait to play with this and see what others do with it.  Stay tuned for an FBFoundations plugin update that includes this.  Details are still vague on this, so I’ll update if anything changes – thus far we just have a few wiki articles talking about it.

UPDATE: See my version 2 of this post for an even more interesting perspective on this API.

Twitter Starts the Chatter on API Guidelines

TwitterOn the Twitter development mailing list today Twitter began discussion on rules developers should abide by when writing applications for the Twitter API.  Such terms come on the heels of a much broader Terms of Service launched for the general Twitter user today. I’ve long discussed the need for such guidelines, as many developers are embarking on an unknown adventure when writing apps for the platform, unable to tell when something they are doing is breaking rules for Twitter platform usage.  We’ve seen this get out of hand with the launch of many “get-rich-quick” applications, along with applications that Tweet on your behalf either in public or DM form without your knowledge.

Twitter’s initial platform guidelines include the following, stating that developers of Twitter applications must:

  • Identify the user that authored or provided the Tweet, unless you are providing Tweets in an aggregate form or in anonymous form in those exceptional cases where concerns over user security and anonymity are involved.
  • Maintain the integrity of Tweets and not edit or revise them. Tweets may be abbreviated for display purposes and as necessary due to technical limitations or requirements of any networks, devices, services or media.
  • Get each user’s consent before sending Tweets or other messages on their behalf. A user authenticating with your application does not constitute consent to send a message.
  • Get permission from the user that created the Tweet if you want to make their Tweet into a commercial good or product, like using a Tweet on a t-shirt or a poster or making a book based on someone’s Tweets.

The most significant of the 4 items is that apps will no longer be able to send Tweets on a user’s behalf without their permission, although this is unclear if this includes automated DMs, and if this permission must be on a “Tweet-by-Tweet” basis or not.  In addition, users can feel secure that their Tweets will not be used without their permission in a commercial endeavor, although I’m pretty sure Copyright law will protect this.

This is a great move by Twitter, and one I strongly welcome.  Even if it prevents some developers from building applications, it sets the record straight so they know what they can, and can’t be doing.  Keep in mind that this is only a proposal at the moment, and nothing is set in stone.  You can contribute to the discussion on the developers mailing list.

[youtube https://www.youtube.com/watch?v=jbhnRuJBHLs&hl=en&fs=1&]

Facebook Prepares to Compete With Gmail: Launches Messaging API

FacebookFacebook is moving too fast this week for me to keep up.  On the heels of the Acquisition of Gmail-creator-founded FriendFeed, along with the launch of their new search interface, Facebook just took it one step further today.  In an announcement on their blog along with associated documentation on their developers wiki, Facebook released a set of new APIs for developers to begin writing software that enables them to read and display a user’s inbox and messages from Facebook Platform.

While Facebook has offered a rich set of APIs since the launch of their developer platform in 2007, Facebook’s messaging system has remained stagnant and seemingly untouched during the entire period.  Developers have been itching to get into the messages of a user on their behalf to help fix this.  Not only is Facebook opening this up for developers, but they are also getting ready to launch an entirely new messaging system being tested by a small group of users currently, set to launch “in the coming weeks”.  Facebook also launched an interface into their notifications API enabling developers to read and notify users when they receive new notifications.  I expect this to be used in Desktop applications such as Seesmic.

While people are speculating the fate of FriendFeed after the new acquisition, there seems to be two things on the mind of Facebook recently: Messaging and Search.  With the creator of Gmail on their team and co-founder of one of the best real-time search engines on the internet (that just so happens to have a superior Direct Messaging system as well), you can bet Facebook is already putting him hard at work in helping them on such features.  I hope and expect to see this new API implemented into FriendFeed’s own messaging system, as well – hopefully enabling you to import your Facebook inbox into FriendFeed’s own DM box.  We’ll wait and see.

It’s no secret that E-mail is an old and out-dated technology.  It only goes to say that we’re in a race now for the fastest, most real-time, and responsive messaging system to replace e-mail.  While Google moves forward with Wave, you can bet Facebook will be doing the same with their own messaging.  With the ability to now truly identify individuals socially without need for an actual “address”, E-mail may actually be going by the wayside.

Gmail has yet to launch any sort of API into its own messaging (that I’m aware of) – this move by Facebook is unprecedented.  While Facebook will not allow developers to actually send messages on behalf of users (a wise and careful move, I’m sure), this makes Facebook even more “open” in my book.

Developers can sign up for the new messaging platform by signing up for the Inbox API whitelist.

FriendFeed Opens Up the Firehose to Developers

friendfeed-logo.jpgFriendFeed seems to be staying one (or two or three) step(s) ahead of Twitter in everything they do. Today FriendFeed released their real-time stream of data in beta to any and all developers wishing to write applications. Unlike Twitter, there is no application necessary, no NDA to sign, and all is controlled by simple OAuth. This also means users of FriendFeed-based applications will no longer need to get their special key to manually enter as was previously required.

The real-time stream is based on long-polling techniques to receive near-immediate updates of data from FriendFeed. With Long-polling, developers send a request to a given address, which the server holds open until data is ready for that request. The result is real-time data from the polled source, in this case FriendFeed. It is also less server-intensive as compared to the typical push updates similar to what Twitter is using for their /track and real-time streams, so in theory will scale better (and to me shows the maturity of the FriendFeed team as compared to Twitter’s).

In addition to their real-time stream, FriendFeed released an OAuth solution to developers, enabling users one-click access to the FriendFeed data stream for compatible apps using the platform. SocialToo, my service currently using the Twitter and Facebook platforms, will be using this authentication as well as we integrate FriendFeed into our environment. It will enable simple, one-click login and registration into our system, making it much easier for users to use socially-based applications.

My favorite addition is the integration of social graph data into the stream returned by FriendFeed. Previously, only the list of people a user subscribed to was available via the FriendFeed API. Now, both the list of those subscribed to, and those subscribed to a user are provided, enabling apps like my SocialToo to very soon be able to provide useful analytics around those following you on FriendFeed. Yes, this will also enable auto-follow and auto-unfollow (to keep out spammers) as well if users opt to do so.

Other features released in the API are the ability to upload almost any file attachment to a user’s FriendFeed stream, access to the powerful (and more than 140 character) direct message features of FriendFeed, sharing to multiple streams at once, and more. In addition, FriendFeed is returning the HTML for users and groups, so developers don’t have to differentiate between the two. Hopefully, this will also enable FriendFeed to maintain control of the API and, if you ask me, provide advertising and monetization opportunities via the API in the future as well, which Twitter has completely lost control over.

FriendFeed’s API has proven to have potential as a much more flexible option for developers than Twitter’s in the past, and I think they’re proving that with the new features. In addition to the features launched today, developers can also opt to customize the requests they send to FriendFeed, specifying query parameters about exactly what information they want to retrieve about users, allowing much smaller and much fewer requests to the platform. This is a welcome site as compared to the Twitter platform, which forces entire requests to pull information about a user and their friends, forcing much larger data requests, and higher costs for developers in the end.

FriendFeed is putting the pressure on Twitter with this release. My hope is that developers will see this, and try the platform out, giving Twitter more pressure to fix their own platform issues. If you haven’t tried it, today is the day for Social Platform developers to try FriendFeed’s API.

With No Notice, Twitter Adds More Limits – Password Trouble Ensues

twitter fail whaleTwitter is up to their old antics of adding limits again, changing the API, and not telling developers as they do so.  This morning Twitter released into production new limits around their verify_credentials() method in the API, only allowing users to verify their usernames and passwords through Twitter applications 15 times per hour.  The problem is they didn’t tell any of the developers.

Sure enough, searching Twitter (the issues are intermittent), users are having password issues across the Twittersphere, wondering what is going on.  It even affected my service, SocialToo, as we were using that method as a backup to verify users were indeed authenticated (and hence enabling us to notify them if they forgot to change their password with us).  I e-mailed Twitter, and while very respectful as always, they seemed surprised at the issues we were having.  When I asked if it had been announced anywhere they responded, “It wasn’t, no, because [we] assumed (apparently incorrectly) that people were only using this method occasionally.”   There has still been no announcement by Twitter on the new limits.

Apparently, on June 29th, new text was added to the Developer API Wiki stating (regarding the verify_credentials() method in the API), “Because this method can be a vector for a brute force dictionary attack to determine a user’s password, it is limited to 15 requests per 60 minute period (starting from your first request).”  The new limits don’t appear to have been put in place until this morning however, as that is when we noticed it at SocialToo.

So if you’re using the verify_credentials() method in your app, you may want to consider finding some other way to be sure your users are verified – I’m happy to announce it here.  It now only takes a few runs by only a few apps to hit that limit for each user, and then users are stuck in the water until the next hour is up until apps begin to adapt to these new limits.  That is why we’re seeing the issues across all of Twitter.  According to Twitter, the best way is to look for a 401 response code returned in your API calls, as unauthenticated users will return as such when using the API.  Twitter only suggests using verify_credentials() for new users.  My conversation with Twitter ended with the suggestion from them, “Migrating to OAuth avoids the risk of a user changing her password, FWIW.”

FWIW, OAuth is still in beta and not yet suggested for use in Production. In their exact words, “For us, ‘beta’ really means ‘still in testing, not suitable for production use’.” In other words, use the Twitter API at your own risk.

You can follow the password problems as they happen in real-time on FriendFeed below:

http://friendfeed.com/search?q=password+service%3Atwitter&embed=1

Social Coding: How to Code Twitter’s OAuth Using Net::OAuth and Perl

OAuthFor the non-developers in my readership, I’m going to get a little geeky on you here. So you can either tune this one out, or pass it onto your IT staff for use in their applications. I promise much more on the “Social” side here shortly. Or, maybe you’ll learn a little Perl.

For those not in the loop, my company, SocialToo.com codes in Perl, a powerful language that gives me the ability to abstract what I need at a very high level, or get down to the nitty-gritty if needed to in order to improve speed or communicate with other core Unix libraries and tools. To me, it’s a very powerful and important language that enables me to get done what I need to do without having to hire developers that know multiple languages. It’s also an amazing scripting language, and powers many of the scripts we run on the backend of SocialToo.

One of Perl’s weaknesses however is that it has never been very strong in the marketing department. For this reason, it is some times (and some times not) one of the last on the priority list for companies like Twitter when developing libraries to integrate with their API. Fortunately it has a very strong group of developers contributing to its very unique directory of open source libraries, CPAN.

Recently we launched a beta OAuth implementation on our Forgot Password page on SocialToo, which uses Twitter OAuth to identify a user and allow them to change their password based on their Twitter authentication. Fortunately with Twitter, we were able to use Net::OAuth, Perl’s OAuth libraries on CPAN, to connect with Twitter’s OAuth implementation. There were some tricks, so I’d like to share that here. It’s my hope that maybe at some point I can package this up at a much higher level to make the process even easier for Perl developers to use Twitter’s OAuth to authenticate.

Perl and OAuth – the basics

First of all, you need to understand the basic flow of the Twitter OAuth process. There are official OAuth terms for this (consumer, service provider, etc.) supposedly to make understanding the process easier, but for our purposes those terms really don’t matter. If you really want to learn more about that stuff, go over to OAuth.net and take the tutorials. What matters is that you get the Access Token you need, which you can use any time later to make requests to Twitter, such as authenticating the user, getting the user’s timeline, their profile info, friends, followers, and more. The entire goal of Twitter OAuth from a development standpoint is to get that Access Token. So here are some basic terms you need to know:

Token – a string of hashed data given to you as a unique ID to identify your application, and the user trying to use your application by Twitter. See below for the types of tokens you’ll need to get from Twitter and when.

Request Token – The token you get from Twitter before redirecting the user to authenticate with Twitter. If the user’s authentication is successful, Twitter creates an access token which identifies the user and associates them with your application. You can then access that access token later by sending another request after the user has authenticated with the request token and the request token secret key (defined below).

Request Token Secret – A string of hashed text, which only you (the developer) will ever see or use. You retrieve this when you get your Request Token, and will need to pass it with your request token when you request to get an access token. Consider this your password when trying to get an access token. Your Request Token is your ID for Twitter to identify your request with to verify the user authenticated successfully and your application has permission to access Twitter.

Access Token – Once you have your Request Token, your Request Token secret, and the user has authenticated successfully, and assuming your application has been given permission by Twitter to access the Twitter API, you can then make a request to Twitter to get your Access Token. You send Twitter your Request Token and your Request Token Secret, and the response returns your Access Token and an Access Token Secret Key for access to the Twitter API. This is a permanent key at the moment that you can use any time later. Store this in your database or a file or elsewhere once the user has authenticated and you’ll be able to authenticate on their behalf from that point on (assuming you have set your app up to do such on Twitter.com). After you have your Access Token, you can make requests to Twitter, via Net::OAuth, which perform any of the methods found via the API by sending Twitter your Access Token and Access Token Secret with the request. Use JSON::Any to parse the resulting JSON returned.

Access Token Secret – The secret key to pass with an Access Token when making API calls to Twitter. Consider this the password that goes along with the ID, which is the Access Token. Twitter looks up the Access Token ID, verifies the user is authenticated, and then checks that you also have a valid Access Token Secret Key. If both are correct and valid Twitter will send back the data you need to access the Twitter API.

Twitter Consumer Key – The unique ID of your application as identified by Twitter – you can get this in your OAuth set up on Twitter. You use this when asking for your Request Token.

Twitter Consumer Key Secret – The “password” to go with your Twitter Consumer Key when asking for your Request Token from Twitter. Twitter looks up your application by it’s ID (Consumer Key), and verifies it’s you by checking your Consumer Key Secret.

Flow of a Simple Twitter OAuth App in Perl

To understand what we’re doing, you’ll need to understand the order of things you’ll need to do in order to fully access the Twitter API through OAuth. This Flow, in plain english, should outline that process, and from here you should be able to adapt the code I provide for any use:

  1. Send a GET request to http://twitter.com/oauth/request_token asking for a request token from Twitter, and passing your appropriate Consumer Key and Consumer Key Secret to identify your application.
  2. If Twitter identifies the Application as legit (and isn’t down), parse out the request token and request token secret from the content of the returned page by Twitter. Here you’ll want to store that request token and request token secret somewhere, as you’ll need to access it again after the user returns back to your site from Twitter.
  3. Redirect to http://twitter.com/oauth/authorize, appending “?oauth_token=YOUR_REQUEST_TOKEN_GOES_HERE” to the URL, replacing YOUR_REQUEST_TOKEN_GOES_HERE with the request token you just got from Twitter. There is no need to send the Request Token secret at this point – this is simply to identify that you have received a request token from Twitter, and so Twitter can identify the user’s authentication (successful or not) with that Request Token.
  4. The user authenticates on Twitter (if not already authenticated through Twitter – if they want to authenticate through a different user they can do so here as well by logging out and re-authenticating).
  5. The user is given the option to “Allow” or “Deny” the request by the Application to access their account information on Twitter.
  6. Twitter then redirects back to the Callback URL you set up in your OAuth set up on Twitter.com – you’ll want to note this so you can write code at the location Twitter redirects to that gets the response token.
  7. Your Callback URL takes the Request Token from earlier, and Request Token Secret from earlier, and sends them to http://twitter.com/oauth/access_token to try and get an Access token. Twitter verifies that the user has authenticated successfully, that they have allowed your application to access their account, and that your Application is valid. If so, you’re returned a successful response from Twitter.
  8. You’ll want to parse out the Access Token, and Access Token Secret from the returned page, and store them somewhere with that user so you can access Twitter on their behalf later. Or, do something right then and there! You have all you need now to use the Twitter API for that user under OAuth.
  9. At this time is when I would authenticate the user if needed, making an OAuth request to access http://twitter.com/account/verify_credentials.json. To do so just send the request via Net::OAuth, along with that user’s Access Key and Access Key Secret (which hopefully you can retrieve from somewhere since you stored it somewhere earlier), and Twitter returns the data back as JSON-formatted data (or XML if you specified verify_credentials.xml) you can then parse out as necessary. You can do the same with any method in the Twitter API.

Example Code

Alright, now onto the juicy details. Assuming you’ve already set up an OAuth Twitter App under your settings tab on Twitter.com, and have your Consumer Key and Secret, you should be set to go. You’ll need to install Perl’s Net::OAuth (and any dependencies) via:

perl -MCPAN -e "install Net::OAuth"

Now, let’s get the Request Token. To do so, I’ve created a simple OAuth Accessor method to do all my OAuth handling. I use Catalyst as my MVC Framework, so all the $c and $self references refer back to the Catalyst environment. I’ll leave that up to you to figure out, or you could always try out Catalyst! So first, let’s set up this method:

=head2 oauth_request

Sends a generic request to the specified url

=cut

sub oauth_request : Private {

my $self = shift;
my $c = shift;
my $i = {
'type' => '',
'url' => '',
'extra_params' => {},
'token' => '',
'token_secret' => '',
'method' => 'GET',
@_,
};

my $request = Net::OAuth->request($i->{'type'})->new(
consumer_key => $c->config->{'twitter_consumer_key'},
consumer_secret => $c->config->{'twitter_consumer_secret'},
token => $i->{'token'},
token_secret => $i->{'token_secret'},
request_url => $i->{'url'},
request_method => $i->{'method'},
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => join('', rand_chars(size=>16, set=>'alphanumeric')),
extra_params => $i->{'extra_params'},
);

$request->sign;
$c->log->debug("URL: ".$request->to_url);

$c->log->debug("Request: ".Dumper($request));

my $ua = LWP::UserAgent->new;
my $response = '';
if ($i->{'method'} eq 'GET') {
$response = $ua->get($request->to_url);
}
else {
$response = $ua->post($request->to_url);
}
$c->log->debug("Response: ".Dumper($response));

return $response;

}

Basically, all this does is create a new Net::OAuth request object, signs it, and then sends it via a GET or POST request (via LWP) back to the specified URL. This method will handle all our OAuth requests. You’ll need to modify it to match your environment and configuration variables (like the consumer key and secret).

The token and token_secret variables can be either a request token, or access token (and secret), or neither. You won’t need to pass either when you’re trying to get your request token obviously. “type” will define what type of request it is you’re making – it can be either “request token” (to ask for a request token), “access token” (to ask for an access token), or “protected resource” (when accessing private data for a user from the Twitter API on their behalf). The “url” variable specifies the Twitter URL to request, based on the type of the request. You can get these from your OAuth settings page for your app on Twitter.com. Dont’ worry about the rest – that’s all used to generate the signature sent to Twitter with all the data you just gave it.

Now that we have that, we can make our requests to Twitter.  We’ll need to start with getting our Request Token.  We’re of course assuming this is the user’s first time authenticating through your App.  Here’s how we’ll do that using the above method:


$c->log->debug("getting request token...");

my $res = $self->oauth_request($c,
'url'       => $c->config->{'twitter_request_url'},
'type'      => "request token",
);

$c->user_session->{'oauth_redirect_url'} = uri_escape($c->req->param("redirect_url"));

if ($res->is_success) {
my $response = Net::OAuth->response('request token')->from_post_body($res->content);
if (defined $response->token) {
$c->user_session->{'request_token'} = $response->token;
$c->user_session->{'request_token_secret'} = $response->token_secret;
my $auth_url = $c->config->{'twitter_authorize_token_url'}."?oauth_token=" . $response->token;
$c->res->redirect($auth_url);
$c->detach;
return;
}
}
else {
$c->log->fatal("Something went wrong.");
# expire request tokens each time they are used
$c->user_session->{'request_token'} = '';
$c->user_session->{'request_token_secret'} = '';
}

In this example, we ask for a simple request token from Twitter to the request token URL we were given by Twitter in our OAuth settings. In this particular example (it may not be needed by yours), we allow the user to pass a redirect URL to our application via a “redirect_url” parameter in the URL. We store that in the session for later use so we can pass the user onto somewhere else if needed. You could store this in a cookie, a session, a file, or database – it’s up to you, and won’t be necessary if you never need to redirect the user later.

Assuming your app has been authorized to connect to Twitter with the Consumer Key specified, you should get a successful (200 OK) response back from Twitter. You’ll then need to parse out the Request Token and Request Token Secret keys from the response. You can do so by passing the returned content through Net::OAuth->response(‘request token’)->from_post_body() as specified.

Once you’ve got that token and a secret key for it, you’ll want to store it somewhere for later use. Twitter doesn’t give it back to your app later, so you’ll need to put it somewhere. In this example we store it in the Catalyst Session for the particular user’s session. You could store them in a cookie, session, file, or database, but you’ll need to put them somewhere. You’ll need this later.

Finally, we need to redirect the user to authenticate and authorize your App on Twitter. You send them to the authorize URL Twitter gives you in your App settings page when you set up OAuth, and append, “?oauth_token=”, followed by the Request Token you just received. Also note the error checking we do – don’t forget to cover your bases!

The user will get sent to Twitter, authenticate, and authorize your App. Finally Twitter will redirect the user back to your callback URL that you specified in your App’s settings when you set up OAuth on Twitter.com. In that URL’s logic, you’ll need to do something like the following:


$c->log->debug("request_token: ".$c->user_session->{'request_token'});
$c->log->debug("request_token_secret: ".$c->user_session->{'request_token_secret'});

my $res = $self->oauth_request($c,
'url' => $c->config->{'twitter_access_token_url'},
 'type' => "access token",
'token' => $c->user_session->{'request_token'},
'token_secret' => $c->user_session->{'request_token_secret'},
);

if ($res->is_success) {
my $response = Net::OAuth->response('access token')->from_post_body($res->content);
$c->user_session->{'access_token'} = $response->token;
$c->user_session->{'access_token_secret'} = $response->token_secret;

$c->log->debug("redirect_url: ".$c->user_session->{'oauth_redirect_url'});
$c->res->redirect(uri_unescape($c->user_session->{'oauth_redirect_url'}));
}
else {
$c->log->fatal("Could not get an Access Token: " . $res->as_string);
}

# expire request tokens each time they are used
$c->user_session->{'request_token'} = '';
$c->user_session->{'request_token_secret'} = '';

At our callback URL, our main goal now is to get that Access Token. We’re assuming the user has authenticated and approved the app. We know the request token and request token secret, but do not yet have an Access Token for the user. Let’s hope you stored the Request Token and Request Token Secret for that user somewhere. You’ll need it here.

To get the Access Token, you’ll need to send an access token request to Twitter, to the URL specified in your settings where you set up OAuth for your App on Twitter.com. In addition, you’ll want to pass into it the Request Token, and Request Token Secret we stored earlier. In this case we stored it in the session, but you’ll need to retrieve it from wherever you stored it earlier.

If your request is successful, you’ll then need to parse the Access Token and Access Token secret from Twitter by passing the returned content to the Net::OAuth->response(‘access token’)->from_post_body() method. You can then get your Access Token and Access Token Secret from the returned response, as shown in the example. You’ll then want to store those somewhere, often some place permanent to be accessed later on behalf of the user. In our specific case, since this is just a forgot password form, we only need to store it in the session for access later, which we do in the example.

Now, remember that redirect_url parameter we passed and stored in the session? Now we can retrieve that, and redirect the user wherever you intended them to go after starting the authentication process. In this case, we’ll probably pass them onto the Forgot password page for authentication verification and identification of the user. The code on the forgot password page will look something like this:


=head2 verify_credentials

Verifies the user's Twitter credentials and returns a user hashref if successful

=cut

sub verify_credentials : Private {

my ($self, $c) = @_;

if (!$c->user_session->{'access_token'}) {
return q{Access token must be retrieved from Twitter before we can run verify_credentials.};
}

my $response = $self->oauth_request($c,
'url' => 'http://twitter.com/account/verify_credentials.json',
'token' => $c->user_session->{'access_token'},
'token_secret' => $c->user_session->{'access_token_secret'},
'type' => "protected resource",
);

my $retval = '';
if ($response->is_success) {
$retval = eval { JSON::Any->jsonToObj( $response->content ) };
if ( !defined $retval ) {
return q{Twitter returned success but parsing of the response failed: }.$response->content;
}
}
else {
return $response->code;
}

return $retval;

}

In this example we simply send a protected resource request to Twitter’s verify_credentials call. We parse out the returned JSON response, and voila, we have an authenticated user and all their information! This particular method will return the full user’s data if they are authenticated. We can then use that on the forgot password form to identify who the user is, if they’re a SocialToo user, and it will work regardless if we even have their Twitter username correct, because it relies on the Twitter user id.

So, the final full code you’ll want to use will look something like this (again, I’m using the Catalyst framework):


=head2 authenticate_twitter

Redirects to Twitter to get OAuth Token

=cut

sub authenticate_twitter : Local {

my ($self, $c) = @_;

#This ensures we only run the following code the first time they authenticate - pass it ?init=1 in the "sign in to Twitter" link
unless ($c->user_session->{'request_token'} && $c->user_session->{'request_token_secret'} && !$c->req->param('init')) {
$c->log->debug("getting request token...");

my $res = $self->oauth_request($c,
'url' => $c->config->{'twitter_request_url'},
'type' => "request token",
);

$c->user_session->{'oauth_redirect_url'} = uri_escape($c->req->param("redirect_url"));

if ($res->is_success) {
my $response = Net::OAuth->response('request token')->from_post_body($res->content);
if (defined $response->token) {
$c->user_session->{'request_token'} = $response->token;
$c->user_session->{'request_token_secret'} = $response->token_secret;
my $auth_url = $c->config->{'twitter_authorize_token_url'}."?oauth_token=" . $response->token;
$c->res->redirect($auth_url);
$c->detach;
return;
}
}
else {
$c->log->fatal("Something went wrong.");
# expire request tokens each time they are used
$c->user_session->{'request_token'} = '';
$c->user_session->{'request_token_secret'} = '';
}
}
else {
$c->log->debug("request_token: ".$c->user_session->{'request_token'});
$c->log->debug("request_token_secret: ".$c->user_session->{'request_token_secret'});

my $res = $self->oauth_request($c,
'url' => $c->config->{'twitter_access_token_url'},
 'type' => "access token",
'token' => $c->user_session->{'request_token'},
'token_secret' => $c->user_session->{'request_token_secret'},
);

if ($res->is_success) {
my $response = Net::OAuth->response('access token')->from_post_body($res->content);
$c->user_session->{'access_token'} = $response->token;
$c->user_session->{'access_token_secret'} = $response->token_secret;

$c->log->debug("redirect_url: ".$c->user_session->{'oauth_redirect_url'});
$c->res->redirect(uri_unescape($c->user_session->{'oauth_redirect_url'}));
}
else {
$c->log->fatal("Could not get an Access Token: " . $res->as_string);
}

# expire request tokens each time they are used
$c->user_session->{'request_token'} = '';
$c->user_session->{'request_token_secret'} = '';
}

}

=head2 oauth_request

Sends a generic request to the specified url

=cut

sub oauth_request : Private {

my $self = shift;
my $c = shift;
my $i = {
'type' => '',
'url' => '',
'extra_params' => {},
'token' => '',
'token_secret' => '',
'method' => 'GET',
@_,
};

my $request = Net::OAuth->request($i->{'type'})->new(
consumer_key => $c->config->{'twitter_consumer_key'},
consumer_secret => $c->config->{'twitter_consumer_secret'},
token => $i->{'token'},
token_secret => $i->{'token_secret'},
request_url => $i->{'url'},
request_method => $i->{'method'},
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => join('', rand_chars(size=>16, set=>'alphanumeric')),
extra_params => $i->{'extra_params'},
);

$request->sign;
$c->log->debug("URL: ".$request->to_url);

$c->log->debug("Request: ".Dumper($request));

my $ua = LWP::UserAgent->new;
my $response = '';
if ($i->{'method'} eq 'GET') {
$response = $ua->get($request->to_url);
}
else {
$response = $ua->post($request->to_url);
}
$c->log->debug("Response: ".Dumper($response));

return $response;

}

=head2 verify_credentials

Verifies the user's Twitter credentials and returns a user hashref if successful

=cut

sub verify_credentials : Private {

my ($self, $c) = @_;

if (!$c->user_session->{'access_token'}) {
return q{Access token must be retrieved from Twitter before we can run verify_credentials.};
}

my $response = $self->oauth_request($c,
'url' => 'http://twitter.com/account/verify_credentials.json',
'token' => $c->user_session->{'access_token'},
'token_secret' => $c->user_session->{'access_token_secret'},
'type' => "protected resource",
);

my $retval = '';
if ($response->is_success) {
$retval = eval { JSON::Any->jsonToObj( $response->content ) };
if ( !defined $retval ) {
return q{Twitter returned success but parsing of the response failed: }.$response->content;
}
}
else {
return $response->code;
}

return $retval;

}

To run it, you’ll (assuming this is Catalyst) point your “Sign in With Twitter” link to /authenticate_twitter?init=1&redirect_url=http://yourdomain.com/forgot on your domain. Note that “init=1” identifies the user is not yet authenticated. That gets the request token, and redirects the user to Twitter to authenticate. Twitter then sends the user back to /authenticate_twitter on your domain. You detect that the request_token session variable has been set along with the secret key, so then run the code to get an access token. You get the access token from Twitter, store that in the session, and then redirect the user to http://yourdomain.com/forgot (identified by the redirect_url parameter in your original sign in link). http://yourdomain.com/forgot accesses the verify_credentials() method above, which takes the user session variable with the access token, verifies the user’s Twitter credentials, and returns user data for the individual. You can then display user data appropriately, and in this case allow the user to reset their password because you have officially confirmed it is them.

SocialToo Forgot Password Form

Like on Socialtoo, your forgot password form, or other OAuth instance will have a “Sign in With Twitter” link like this one that points to code similar to what I featured.

If you want to learn more, the documentation is pretty scarce at the moment. Hopefully myself or someone else will put together a much more abstract set of libraries targeting the Twitter platform soon surrounding this. I do recommend checking out OAuth.net and understanding the OAuth protocol a little more, along with the Net::OAuth documentation. Hopefully many more of you can share your experiences in the comments, or in your own blogs as you come across new experiences with Twitter’s OAuth in a Perl environment.

UPDATE: Looks like someone already has added an abstraction layer around all this. To simplify things even further, check out Net::Twitter::OAuth. It might be helpful to read this first anyway so you know what’s going on there.

Oops, Twitter Does it Again

Oops I did it again - Britney SpearsI don’t think Twitter is listening. In fact, I remember a few of them mentioning they don’t read the news or blogs so that it doesn’t affect their work. Perhaps it’s about time they start. Today I blogged over on LouisGray about a cool new change to the e-mail notifications on Twitter where they now show a user’s profile image and follower/friend data along with the new follower e-mails they send to you. (and dang it – MG beat me to the news. He’s good!)

What is scary though is what actually happened behind the scenes in this change. Today Twitter, again without notice to developers, completely changed the format of both their new follower and DM e-mails from plain text, to HTML multi-part format, completely breaking any app that was relying on those formats to parse and process new follows or direct messages.

What’s funny is that the very apps I was saying Twitter was venturing into competing ground with, Topify, and Twimailer, are the very types of apps that would have been broken by this change. In addition, apps like Greg Lavallee’s addNetflix app are now broken because they were relying on the plain-text format of the new DM e-mails. In my previous post about Twitter doing this, Greg commented, stating, “When I first read this post last month I thought, “well, if you code your application well, it should take into account potential changes from Twitter.” I also thought that Twitter would warn us about bigger changes. Wrong on both counts.” Many apps are relying on these e-mails, some of them probably completely unaware their apps are broken at the moment.

This issue was brought up on the Twitter developers list this afternoon by TwitReport developer, “TjL” (“Can Twitter Please Pick a From, and Stick With It?”). Evidently the new format also broke the new follower statistics for his app, and has happened multiple times causing him to have to re-educate his users to re-do their filters every time. Matt Sanford, Twitter API Team member responded explaining,

“We had changed the from address to try and improve bounce reporting and prevent being marked as spam by major ISPs. When we added the HTML formatting we found that we needed a consistent address for the ‘always display images’ option in many clients so we changed things around again. Hopefully this will be the last change as it causes us a bunch of work as well. I’ll keep an eye out for future changes and try and let people know.”

The conversation went on to discuss further elements of the e-mail, and Sanford suggested they were going to change the e-mails again after the discussion. I think TjL reflected the developer community’s frustration exactly when he responded to the further changes,

“Seriously? I’ve already started telling people to change their filters
and now they’re going to break *again*.

This is why daddy drinks.

All kidding aside, I don’t understand how a change like this gets
pushed out without the left hand knowing WTF the right hand is doing —
which is what it looks like (from an outsider’s perspective) happened.

IMO/FWIW: You’ve gotten too big to make these sorts of changes without
more consideration and communication. It makes me look bad as a
developer, and it makes Twitter look bad.

The irony is that you’re a company built around communication.”

Twitter has got to change their ways – on my blog posts about this I’m seeing comment after comment of developers now refusing to develop on the Twitter development platform because of their lack of warning during changes like this. The thing is I’m not complaining about rate limits or Twitter scalability or anything like that at all when I’m complaining. As developers, we simply want a little bit of communication before changes go out. I actually like Twitter. I have a business with components built on it so I want it to succeed. I also think the Twitter dev team has done an outstanding job building out this amazing API. The only area they’re failing in right now is communication. We need a) a clear developer ToS, and b) warning before changes go in, or come out. Developers have been amazingly patient for the most part regarding this, but I know there is frustration.

I want to be clear that I love what the Twitter API team is doing. I really like and respect Alex and Matt and the rest of the team working extremely hard, often to the late hours of the night working on this stuff. I’m not sure where the fault lies, but I do hope they are listening. We need some warning on this stuff guys.

There is still no official announcement on the Developer mailing list, nor any official blog post by Twitter on the e-mail changes.

Facebook Developers See 20-50% Drop From URL Change

Picture 8.pngFacebook developers are reporting 20-50% drops in their Application traffic due to an unannounced deprecation of the old apps.new.facebook.com URL by Facebook. Over the weekend, Facebook appears to have deprecated the apps.new.facebook.com domain, but some developers are reporting that users aren’t recognizing the new domain, apps.facebook.com, causing the drop in traffic.

The apps.facebook.com domain is the central location for all applications on Facebook. Developers are given a unique suffix to the apps.facebook.com domain, giving apps.facebook.com/appname a unique location for every application on the Facebook platform. Facebook created the domain, apps.new.facebook.com to accommodate apps trying to test in the new design as it was in the process of being released. Now that all users should be transitioned to the new design, it appears that Facebook has decided that the two URLs are no longer necessary.

Facebook (perhaps not as often as Twitter) is known for changes like this. While it’s been awhile, the early days of the Facebook Platform were prone to frequent changes by Facebook with little notification by the company. For this reason, Facebook implemented a beta testing ground before pushing changes so bugs like this would be revealed, but it appears Facebook is not using this testing ground in all cases. As one developer put it, “I was planning to go on a sailing trip today, but when I noticed all the problems had to cancel that to fix all the absolute urls I had.” Unannounced changes like this, with little testing, are bound to cause developer frustration and angst as we’re seeing now.

Facebook has put in place a Status Feed to announce such things, and just last week announced that over the weekend the new “api.new.facebook.com” would point to the same place as “api.facebook.com”. Being a backend process, Facebook mentioned nothing about a deprecation of the apps.new.facebook.com domain. Also, any user that previously had an apps.new.facebook.com domain bookmarked will now be sent to a 404 not found page.

We have yet to hear an announcement by Facebook on this matter.

UPDATE: For some reason the link to the forums above has been removed and the post is gone. The text of the main link is below (written by crimson), followed by a long list of other developers seeing the same thing:

I’ve been doing some testing with the recent DNS errors and it seems that for most users, apps.new.facebook is broken. It’s sporadic though, and only affects certain user accounts at random times. I haven’t heard any complaints about apps.facebook.com being broken though, so I would suggest putting a message on your about pages asking users to go to apps.facebook.com instead of apps.new.facebook.com. If you have any absolute links to apps.new especially in notifications, newsfeeds, or notifications, you should also get rid of those immediately since it will cause your users to end up on the new domain, which will rewrite all urls from apps.facebook.com to apps.new.facebook.com, and can lead to further problems.

It’s so annoying that Facebook decided to do this over the weekend, which means we have to work also on the weekends. I was planning to go on a sailing trip today, but when I noticed all the problems had to cancel that to fix all the absolute urls I had. I found I’m losing anywhere from 20-50% of new users simply because of this issue. It also seems that at times only apps.new.facebook is broken, and not www.new.facebook. Hmm, talk about double-standards.

UPDATE 2: Facebook appears to have fixed the problem – when I checked today, apps.new.facebook.com was again correctly redirecting to apps.facebook.com

UPDATE 3: It appears other developers are still seeing the issue, still no word from Facebook: http://staynalive.com/articles/2008/10/06/facebook-dns-blunders-take-down-obama-app/