Contact: (801) 853-8339 or jesse@staynalive.com
Twitter, FriendFeed, LinkedIn, or Facebook
Like StayNAlive.com on Facebook!:
TwitterCounter for @Jesse

Facebook-hosted “Pages” are No Longer Necessary – Here’s Why

Social Media Examiner shared some advice I gave on their Facebook Page recently regarding the warning about Facebook “boxes” being removed from Facebook Pages in the next week.  The reminder was met with a lot of concern from subscribers, who had grown attached to the ability to customize the look and feel of their Facebook Pages through the Static FBML app on Facebook and the ability to add custom “boxes” to the Wall of their Page.  The other concern is that Facebook will also be switching to the smaller, 520px Tab format, reducing the amount of surface area for a custom tab to add personalization to a Facebook Page.  I argue all this concern is moot however – there is something better Page owners can be doing that they aren’t, and that is moving their Pages over to their own websites and managing the interface there instead of on Facebook.com, and I think that’s the direction Facebook wants Page owners to go.

At Facebook’s sold out F8 developer conference this year this focus seemed evident.  Facebook launched a series of new “Social Plugins”, and a protocol (called Open Graph Protocol) enabling any website to essentially become a “Facebook Page”.  Right off, website owners could simply put a “like button” Social Plugin on their website by copying and pasting an iframe tag from Facebook’s developer site, and immediately, with some added meta tags added to the <head> section of their HTML, they could have all the functionality of a Facebook Page right on their own website.

Facebook had a great demo at the conference, which Jolie O’Dell (from Mashable) pointed me to (see her article about it here), where they basically took all the content from Lady Gaga’s Page and converted it to its own, customized website with its own look and feel that you could easily change themes.  Facebook-me.com, which appears to still be there, enabled customized themes to be applied to profiles, perhaps similar to MySpace in a way, but in a way that website owners themselves could host those themes on their own servers.  All this could be done through simple Graph API calls and some customization on your own server.  See their demo they gave me here:

For instance, if you query http://graph.facebook.com/stay/feed in your browser, immediately you’ll be presented with a parseable feed taken straight from my Facebook Page of all the posts put there.  Re-format that in any way you like and you have your own customized Facebook Page.  No login necessary.

It can be even better though.  Rather than letting Facebook host the data, you can handle most of it on your own through Social Plugins.  For instance, let’s look at what happens if I want to make StayNAlive.com its own Facebook Page (in fact I’ll do it right here so you can try it out when I’m finished).  I simply go to http://developers.facebook.com and click on the big green “Add Facebook to my Site” button, then click on the Social Plugins link.  Select the “Like Button” social plugin, and enter http://staynalive.com in the URL box.  Click the “Get Code” button, and you’ll be given code that looks like this:

<iframe src=”http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fstaynalive.com&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80″ scrolling=”no” frameborder=”0″ style=”border:none; overflow:hidden; width:450px; height:80px;” allowTransparency=”true”></iframe>

Now, if I put that at the top of the website, a like button appears, and my website is now a Facebook Page.  Go ahead and click “like” and you’ll see what I mean.  Now you’re subscribed to my “Page”, you’ll get all the posts I send to your news feed, and best of all, any links to the “Page” go back to my actual website, and not Facebook.com.

Becoming an Admin

To get all the benefits of turning your website into a Page and having the full flexibility of customization, you’ll need to make a couple updates to the <head> section of your site’s HTML.  These meta tags follow a standard called “Open Graph Protocol”, and by following it, Facebook will know how to represent your site inside Facebook.  There are different tags that can specify the title of your site, a main image for your site, and more, but the most important tag you need to add to your site’s <head> section is a meta tag that looks like this:

<meta property=”fb:admins” content=”683545112″ />

This specific meta tag identifies the user, 683545112 (which happens to be my Facebook ID), as the admin for your website on Facebook.  To get your Facebook ID, the best way I use is to go to your profile, click on your profile image, and look at the number after “id=” in the URL.  That’s your Facebook ID.  You can also specify multiple Facebook IDs in the content attribute of the meta tag by separating them by commas.

Once you specify this, next to your like button that you just installed you’ll see a “Admin Page” link next to the like button that, by clicking on the link, will take you to what looks like a regular Facebook Page on Facebook.  It’s from there you can post updates to your fans and have them see it in their news feed.  Also, once you’re identified as an admin, any link to the Facebook Page in your own Feed will link back to that admin interface on Facebook.com. (not to the website itself, which is what all other users will see)

For other meta tag identifiers you can use, view the source of this website and look in the <head> section – look for the “og:” meta tags.  You can also read more about it in the developer documentation here.

The Feed

By using this method, you get all the benefits of any normal Facebook Page on Facebook.com.  You just have to install the proper Facebook Social Plugins to get what you want.  For instance, if you want your visitors to see a feed of all items you’ve posted to the feed, install the “Like Box” social plugin, and enter the ID of the Facebook Page you just set up. (to get the ID, go to the “Admin Page” link next to your like button, and it’s the long number in the URL)  Look over on the right of this website to see an example of the Like Box feed.

As mentioned above, you can also post items to your feed.  Click “Edit Page” on your admin Page, and you can set up an RSS feed to import notes into your feed.  I can also post videos, pictures, or anything else, just as I would a normal Facebook Page hosted on Facebook.com.

Importing Your Blog Posts

You’ll notice the “Like Box” on the right that has all the posts from this blog on it.  That’s because I’m importing the RSS for this blog and now ever time a new post goes out all the people that have “Liked” StayNAlive.com via the link above will get all the posts I submit via this blog.  This can be a great alternative to allowing users to subscribe via RSS.

So there you have it – any need to customize a Facebook.com-hosted Page is now moot.  We don’t need them any more.  I see no reason for hosting on Facebook itself if you need full customization.  In fact, all links your visitors see in Facebook will now point back to your own website and not Facebook.com.  When the user likes your website it will now appear in their interests and link back to your website.  That can be good for SEO.  Search results will link back to your website, and hints will show up for all your visitors’ friends, pointing them back to your website.

This, IMO is the ideal way to set up a Facebook Page now.  The Facebook Page hosted on Facebook.com is not the future.  Your website is the future, and Facebook has made it completely possible for you to own this experience.

Are there any reasons you can think of not to use this method?  What other tips do you have?  I’d like to hear them in the comments and I’ll update this post as it makes sense.

How to Downgrade From iOS 4.0 to iOS 3.1.3 Firmware on the iPhone

Recently, after the excitement of upgrading to iOS 4.0 this last week, I had need to downgrade again so I could sell it in preparation for my new iPhone 4.  There are many others who say iOS 4 is slow on their iPhones and also want a way to downgrade.  Previously, there were ways to downgrade if you had the iOS 4.0 beta installed, but since the final release, Apple seems to be verifying new restores, and doesn’t seem to want people to downgrade to the 3.1.3 firmware.  You can tell from the long list of support requests in the Apple Support Forums.

I finally found a way to make this work, thanks to combined help from GadgetsDNA and MacLife.  It seems that Apple is checking a server at gs.apple.com, and if you previously saved your ECID SHSH certificate to Saurik’s authentication server you can trick iTunes into thinking his server is their own and go through with the install.  If you haven’t saved your certificate (you may have done this if you jailbroke your iPhone before), feel free to try this and let me know if it works, but I hear unfortunately there isn’t yet a way to make it work.  I hope to be proven wrong.

So here’s what you need to do:

  • First, you need to trick iTunes into thinking Saurik’s server is Apple’s.  To do so, you need to find your hosts file (On a Mac, this is on /etc/hosts.  On a PC, this is in c:\windows\system32\drivers\etc\).  Once you’ve found it, edit it, and add the line, “74.208.10.249 gs.apple.com” to the end.  This points gs.apple.com to 74.208.10.249.
  • Next, you need to put your phone in restore mode in preparation for the restore.  To do this, just disconnect your iPhone and turn it off (do this by holding down the power button until you see the “power off” slider).  Then hold your home button while you reconnect the phone to your computer.  Keep the home button pressed until iTunes opens and gives you a message saying you need to restore.
  • Now, you’re going to need a 3.1.3 firmware file.  Here is one for the 3GS.  Here is one for the 3G.  To load the file, hold down the alt button on a PC, or on a Mac, hold down the alt/option key and click “Restore” in iTunes.
  • Wait for the restore, and if it works when you’re done, it should reboot into 3.1.3 and you’re done!
  • For me, I got a 1015 error, so I then went and followed the instructions MacLife to complete the restore process.  To start, you need to download iRecovery (I only have the Mac version) and libusb.
  • With iRecovery downloaded, go to the directory you downloaded it to and type:

./iRecovery -s

setenv auto-boot true

saveenv

fsboot

exit

  • Now, you just need to reboot the phone and you’ll be back to iOS 3.1.3!  To reboot the phone, just hold down the power and home buttons until you see the Apple logo.

Let me know how this works for you.  Oh, and do so at your own risk!  While I don’t anticipate these steps hurting your phone, I offer no guarantee and there is always a chance doing steps Apple didn’t intend will break your phone.

Make Your Facebook Page Fly With the FBFoundations Facebook Chicklet

facebook-wordpress-twitterMost guys (and girls) who love Facebook like I do probably have a Facebook Page where those wanting to get a scoop of the latest in our professional lives can come learn, chat, and converse with each other.  I consider a Facebook Page (some call them “Fan Pages”) the equivalent on Facebook to a Twitter Profile, as it enables a public, anonymous way to express yourself without limit to the number of people that “follow” you.  Pages are powerful, and can build strong engagement for you and your brand in ways Twitter or even a regular Facebook Profile can’t.  I was surprised that with all the little “chicklets” out there displaying anywhere from the number of readers on your blog to the number of followers you have on Twitter that there wasn’t anything for blog owners to display the number of Fans they have on Facebook. That’s why I created the FBFoundations Facebook Chicklet for WordPress blogs.

The premise of the chicklet is simple.  It uses Facebook Connect (something I argue is even more powerful than a Facebook Page, but requires someone with at least HTML and Javascript knowledge to implement) to go out and get the number of fans for a Facebook Page you specify, and share the number of those fans right on your blog.  In addition, it hyperlinks the chicklet back to your Facebook Page.  Displaying this chicklet on your blog can be a great way to encourage readers to click through and become fans on Facebook as well, where more conversations can take place and your blog can spread even further.  You can see the Facebook Chicklet for this blog up above this article next to the subscribers and twitter followers chicklets.  Go ahead and click on it and become a fan and I’ll send you more updates!

Implementation

To implement the chicklet, you’ll first need to download the FBFoundations plugin (download here) that I wrote and can be downloaded here.  This just makes it so that it can access Facebook to get the number of Fans for your Page.  It will also add an additional meta tag or two to make sharing your blog a little prettier when it’s shared on Facebook.

Once you’ve downloaded and activated FBFoundations on your blog, just download the FBFoundations Facebook Chicklet plugin, extract it into your WordPress plugins directory, and activate it.  You’ll then want to configure it to point to your Facebook Page in your blog’s admin (if not, it will point to mine!).  Now, go to either the sidebar widgets section in your administration if your blog is widgets-enabled, or go into your Blog’s theme files, and place the following code anywhere you want the chicklet to show up:

<?php if (function_exists(‘fbchicklet_button’)) echo fbchicklet_button(); ?>

Once that’s in and the plugin is activated, the chicklet should start showing with the number of Fans on your Facebook Page.  It’s that simple.

Again, be sure to enable the FBFoundations plugin on your blog for this to work.  Also, if you want to also enable sharing for each blog post on your blog to Facebook, along with the number of people that have shared the post, be sure to also check out my FBShare plugin for WordPress!

I guess this is kind of my Christmas present to you all.  Happy Holidays, Merry Christmas, and Happy Chanukah this season!

You can download the plugin straight from WordPress right here.  Here is the WordPress plugin page: http://wordpress.org/extend/plugins/fbfoundations-facebook-chicklet/

Image Courtesy Robb Sutton from http://robbsutton.com/micro-blogging-are-facebook-and-twitter-replacing-personal-blogs/

Netflix’ Little Known Information for Parents Feature

This post is guest-authored by Luke Stay – you can find him on his blog, AfroWhitey.com, on Twitter, or on his Facebook Page. Luke is Jesse’s younger brother.

netflixI was doing a little exploring on Netflix a while ago when I came across a feature that I had never seen before. It’s called “Information for Parents,” and I don’t know why Netflix doesn’t promote it more. It takes a little digging (as far as I can tell) to even get to it, but it should be one of the most-used features on the site.

To get to the feature, you must first click on the link for a movie (not all movies have the feature, so stick with popular releases). For this post, I will use the new Star Trek. Under the “Details” section, you’ll see the rating of the movie with the MPAA reasons for the rating, and below that you’ll see Netflix’ rating, along with a link for more. Click on that link and you’ll be taken to the Parental Information feature.

Rating link

The section that comes up is full of valuable information. I am a firm believer in active viewership, meaning that when watching a movie, especially with children, attention should be paid to the messages and themes underlying the plot and all the spectacle. In this feature, Netflix provides sample discussion points for parents to address with children after viewing, thus promoting the active viewership so often missing in many households. It also brings up some possible underlying messages you may have missed.

Possible discussion topics

Next, the feature spells out specifically what elements gave the movie the rating Netflix awarded and why it is or is not appropriate for a certain age group. The categories covered are: Sexual Content, Violence, Language, Social Behavior, Consumerism, and Drug/Tobacco/Alcohol. Your bases are fully covered here, as it provides information for things I wouldn’t have even thought to include. Even the most protective parent can be satisfied.

Detailed descriptions of rating reasons

So there you go, kudos to Netflix for providing this feature that every parent should be using. There is no reason to go into a theater or to rent uneducated. Now, if Netflix would only promote this valuable feature more.

This post is guest-authored by Luke Stay – you can find him on his blog, AfroWhitey.com, on Twitter, or on his Facebook Page. Luke is Jesse’s younger brother.

How to Customize Your Facebook Page

Static FBMLI get asked a lot how to customize your Facebook Page (that’s with a capital “P”, not to be confused with your personal profile).  I wrote an article over on Tamar Weinberg’s (author of “The New Community Rules”) blog showing you what you need to do to get the most from your Page, including how to build your own custom tabs using the Static FBML app.  This can be a great use for my book, FBML Essentials.  If you have a cool design and aren’t sure what to do to customize this stuff this is a service I offer when I consult for my clients.  I would be happy to help you with these efforts.

Check out the article here: http://www.techipedia.com/2009/create-facebook-page/

Oh, and please be sure to share the custom Pages you create with the Static FBML App – I’m doing a book giveaway to the best implementation of what you learned!

Introducing the FB Share Button WordPress Plugin for Facebook Share

FacebookToday Facebook launched a nifty little tool enabling website owners and bloggers to allow their users to better share and track their content on Facebook.  The new tool provides a piece of HTML and javascript that renders a little “Share” button.  When clicked, the post is tracked by Facebook, the number of shares is shown, and via an API comments, likes, shares, and more can be tracked across all of Facebook for items shared via that button.  Today I’m going to add to that by providing a WordPress plugin.

The FB Share Button WordPress plugin renders the Facebook share button of your choice on your blog.  Via admin settings in WordPress you can choose which Share button you would like to display, where you want to display it, and even provide the language for the link.  The plugin is based on the same Easy Retweet plugin by Sudar which you see on this blog.

To install, just download this link, untar and ungzip into your WordPress plugins directory.  Activate the plugin, adjust your settings to display where you like (or you can manually add it to your template or posts – see the readme), and it will display for every post you write on your blog.  You can even turn it on or off per blog post.

I’m also working to make this FBFoundations compatible so it will load as an optional XFBML tag if you like – expect that in a future revision.  Now WordPress bloggers everywhere have the capability to enable and track Facebook sharing on their blog.  You can download it here:

http://downloads.wordpress.org/plugin/facebook-fb-share-wordpress-plugin.zip

Stay tuned though – in the next revision I’m hoping to add Facebook API support so you can track and read the number of shares, comments, likes across all of Facebook from your WordPress admin.  That will all fit in with the FB Foundations plugin I wrote earlier.

FBFoundations Facebook Connect Plugin for WordPress

lego bricksOne of my biggest frustrations in adapting Facebook Connect into WordPress blogging has been the fact that most plugins out there either have too much, or too little incorporated into them.  When you add more than one, you end up calling the Facebook Javascript Client libraries more than once, and often reinvent the wheel for what other people have done.  I mentioned this in a wish-list I posted earlier.  I want building blocks – I should be able to add a foundation, and add basic building blocks on top of that foundation to get what I want out of Facebook Connect on my blog.

Today I’m giving you that foundation.  I’ve written a WordPress plugin called FBFoundations which sets up the bare-bones necessities of any Facebook Connect install.  Once you have installed this plugin, the user can log in, and you have access to their login credentials from then forward to do whatever you want with. It’s a foundation – something to build a house on top of, and my hope is that many more FBFoundations-compatible plugins can emerge from this.

For instance, my next step will be to create a simple plugin for WordPress that uses the stream.publish API to post your blog to Facebook, and enable others to do so (tracking the number of comments and likes along the way if possible).  There will be no need to add a user log in to that process, nor do I have to load the XFBML init scripts to render XFBML.  It will all have already been loaded for me.

The script works a lot like Richard Miller’s “What Would Seth Godin Do” plugin from a UI perspective.  At a default (you can configure this in your preferences) the first 3 times a user visits your blog they will be presented with a popup dialog box encouraging them to connect with Facebook.  After those 3 times the popup no longer appears.  There will also always be a “Connect with Facebook” login button above your comments (assuming they’re wrapped in a #commentform div) that will appear until the user clicks on it and logs in.

Using this plugin encourages each reader to log in through Facebook (remember – there are over 300 million Facebook users.  Chances are most of your readers are on Facebook), and enables you to do cool stuff with each of those readers.  Hopefully this will inspire others to make other FBFoundations-compatible plugins so we’re not re-inventing the wheel any more.  Stay tuned for more plugins from me – what will you build with this as your foundation?

You can download the plugin here.  Just download it and unzip it into your plugins directory in WordPress, activate it, and then add the API key for your website.  (You’ll need to go to http://developers.facebook.com to add the developer app and add an app for your website if you haven’t done so already)

Or click here to download:

http://downloads.wordpress.org/plugin/fbfoundations-facebook-connect-plugin.zip

Please let me know in the comments if you see any issues.  This is 100% GPL so please make your own adjustments and let me know if I can fix mine!

UPDATE – v0.4 – 10/26/2009: The popup is no longer default and can be turned on/off. Also added meta tag support and better compatibility with 3rd-party comment systems.  See this blog post for more info on 0.4.

Here are some screenshots:

Screen shot 2009-10-10 at 6.21.49 PM

Screen shot 2009-10-10 at 6.19.47 PM

Screen shot 2009-10-10 at 6.19.13 PM

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'},
&nbsp;'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'},
&nbsp;'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.

Automatic Data Compression With DBIx::Class::CompressColumns

UPDATE: You can now get the DBIx::Class::CompressColumns module on CPAN here or via CPAN command-line shell.

Too Many PeopleI’m going to get geeky on you for a minute, but you should find this interesting.  One of the challenges I’ve had with SocialToo recently has been the massive Social Graph data we’ve had to story and process and track. We cache a lot of the data so we don’t have to hit Twitter’s servers as often, and also to enable us to track new follows and unfollows regularly on behalf of our users.

If you are a SocialToo user you may have noticed that your data hasn’t been as accurate lately as it should.  The reason for that is we have had a) 20,000+ users all wanting to auto-follow or have their follower base tracked, and b) all 20,000+ of those users have anywhere from 100 to near 1 million followers that we have to store and process.  It’s not an easy task!  And our database, set up in a relational manner of followers to users, just wasn’t cutting it in regards to being able to retrieve and process so many followers at a time.

So I took a cue from Bret Taylor and FriendFeed, who talks about how they denormalized their database, and now reference “bags” of data that they can then process in their code.  I went for a hybrid model, and with each user entry I now have a single column on that table we reference, in BLOB format, which contains all the social graph data for that user.  In Perl, I simply create a hash structure of the data, freeze it, and then store it in the database in our social graph column.  To retrieve it, we pull it from the database, thaw it, and we have an entire social graph we can play around with and do with as we please.

The issue I was running into however is that plain text, stored in a single column, for a user with 1 million followers, gets to be quite a large amount of data we need to pull through the pipes.  I needed an easy way to compress the data before inserting into the database, storing it in binary format, and decompress.  I also wanted it to be automatic, so no coder would ever have to worry about this extra step – it would just happen magically.

So today I’m releasing DBIx::Class::CompressColumns for all you Perl coders out there.  What this module does is it sits on top of Perl’s DBIx::Class database abstraction libraries and allows you to monitor a single column.  Any inserts or updates into that column get compressed in Zlib format, and any selects/get_column calls to that data (you must use get_column) get de-compressed, meaning you don’t have to worry at all about that extra step, the data is a significantly smaller footprint, and your throughput is much less, causing much less load on the database.  For one-million followers, I measured just 4 Megabytes in space taken that has to go in and out of MySQL.

Approaching Graph optimization in this manner has significantly sped up our processes, and I’m already seeing huge benefits from it.  There is much less load on the database, it’s much faster to retrieve and process the data, and we’re getting through our users’ followers much faster now.

The module namespace is currently being applied for on CPAN at the moment, and I’ll post a link there as soon as it is approved, but for now you can download the Makefile-compatible gzipped library here.  I hope some of you find this useful, and please feel free to modify or send me any updates or bugs you think I missed!

The link for the download is http://socialtoo.com/DBIx-Class-CompressColumns-0.01000.tar.gz

Oh, and TMTOWTDI so please if you have better ways of approaching this I’d love to hear your ideas!

Photo courtesy rp72

Check Out My New Twitter Avatar!

If you check out my Twitter Profile, you’ll notice a new, winter-themed, festive Avatar. Yes, it’s animated, and everyone is going to hate me now for revealing how to do this. Check out my post on LouisGray.com to learn how it’s done. Consider it my second gift to you this Christmas!