Social Coding – Stay N Alive

It’s Time to Free the Twitter Client

infocard_114x80Dave Winer wants a programmable Twitter client. I think it’s a great idea.  It’s something the browser has had for quite awhile now via extensions, frameworks, and plugins.  Up until this point Twitter clients have been closed systems that can’t really be extended in any way.  Loic Lemeur thinks he has the answer with the ability to extend his company’s Seesmic Desktop client – I applaud them for this – it’s something that I think would allow apps like my SocialToo.com to help clean up the stream both in and out of Twitter.  In this way the Twitter client isn’t stuck with exclusive relationships where partners have to pay large sums of money to participate.  Developers and users have full control over the experience they get from the client.  I have a recommendation for Loic, Iain, and other social browser developers though: extend your browsers using open standards if you’re going to do it.

Up to this point we’ve been talking server-based open architectures.  You have OpenID, OAuth, Wave, rssCloud, Pubsub Hubbub, heck, you even have HTTP, SMTP, and even TCP/IP.  But up until now there haven’t been many client-based architectures that extend across any client enabling developers to easily write code for any web client on the client side and have that port from the AIR client to another AIR client, to the browser, and to any other app that touches the web.  Fortunately that technology is here now, and I think the Twitter and Facebook client developers have the opportunity to push this stuff mainstream and put pressure on the generic web browser developers to do the same with their own extension architectures.  That technology is the Selector – Action cards.

Craig Burton said the Cookie is dead, and this is why:  Cookies can’t extend across multiple applications on a single computer.  The Selector has that potential.  Imagine a plugin architecture that read an Information Card to identify you on Twitter or Facebook, etc.  You could add to it an Action card from a site like SocialToo (my site), and based on that Action card and the settings set forth in the Action card by the user the entire Seesmic Desktop experience will be customized based on the settings SocialToo set for that user based on their preferences.  The cool thing about this is it can all be done in simple (and open) Javascript using frameworks like Kynetx’ KRL.

If I were Loic Lemeur I would seriously be studying the open standard of Information cards and especially Action cards right now.  He has the opportunity to follow an open standard in this plugin development architecture that would extend across his app into other apps and even the browser.  This is Seesmic’s opportunity to lead in this effort.  If not other clients will take the ball by embracing these standards – developers will flock to this if it’s done right.

My hope is that Seesmic and any other Twitter or Facebook client can do these plugin architectures the right way.  Information cards and Action cards right now are the most open and extensive way for any desktop (or even mobile) client to put control back in the developers’, and more importantly, the users’ hands.  I hope they do the right thing.

I commented on Loic’s blog post but did not receive a response – hopefully we can hear more about their plans for this new architecture soon, and let’s hope it’s built on open standards.  If you write the first Twitter client to support Information cards or Action cards let me know and you’ll get a big fat blog post here promoting the heck out of it.  As far as I’m concerned, that’s the future of the web and we need to be pushing it as much as possible.  I’m calling all client developers to action.

Be sure to read my article on my vision for no log in buttons here – it will help you understand this stuff, and more of my vision, even further.

[youtube=http://www.youtube.com/watch?v=ISWOrI0WaLs&w=425&h=344]

Want to Learn How to Write Facebook Apps? Now’s Your Chance

facebook platformOn Thursday morning I’m doing a free webcast for Safari Books Online (moderated by OReilly’s Laurel Ackerman) in which I’m going to go into further detail than I have before on how to get started building Facebook apps.  I’ll take you from start to finish, focusing this time on more hands-on coding, and less introduction and together we’ll build a Facebook app from scratch.  I haven’t figured the time yet, but if we have time, I’ll also show you how in just 3 steps you can integrate a simple Facebook login into your own website and apply the same principles we went over with the Facebook on your own website through Facebook Connect.

I’m going to stick to HTML, FBML, and Javascript for this session – if you have a knowledge of just HTML and Javascript you should be able to follow along pretty well, so this should work well for both the new programmer wanting to get their hands wet, and the experienced programmer just getting started in the Facebook platform environment.  These sessions I normally charge businesses and organizations hundreds per student so this is a unique opportunity for you to come learn on a budget (free)!

You can register for the webcast here – it starts at 10am PST this Thursday (tomorrow!).  Each participant will get a free 45 day registration to Safari Books online’s huge library of tech books, and 10 lucky participants will also win a free autographed copy of my book on Facebook development, FBML Essentials.  Also, I’m starting a thread on my Facebook Page that I’d love to hear your questions and suggestions on what you’d like to hear in the session.  You can comment on that here.

I’m looking forward to sharing what I know with all of you – please hurry and register before it’s too late!

Paypal Pays Off With Paypal X Innovate Conference

Paypal X Innovate 2009Paypal has spent awhile now planning a conference for developers which they would be able to announce their new Paypal X developer platform for flexible payments.  I’ve talked to Sudha Jamthe, in charge of many of their social media promotion efforts for awhile now, and I know they’ve really been looking forward to this event.  I must say their planning and preparation for this event have truly “paid off”, as audience reaction has been spectacular, many stating on Twitter that the event was one of the best events they’ve ever attended, others saying it was “one for the record books”.  I must agree.

Internet problems yesterday aside (today seems to be a little better), Paypal has aimed to please.  Starting off with some amazing keynotes and announcements of an incredible flexible payments platform for developers showcasing some amazing companies that have implemented this platform, it just didn’t stop there!  Paypal continued to impress, offering every developer at the event a free Eee PC Netbook.  The internet quickly went down from additional traffic. 🙂

The event was filled to the brim with snacks, food, drinks, and things to feed developers brains as they would think of the next big idea utilizing the Paypal X developer platform.  Freebies were everywhere.  Sessions included all kinds of howtos and tutorials on how to implement the platform.

Then, concluding the event, an amazing party ensued full of speed painters, dancing, music, “Stomp”-like performers, drinks, food, and more.  Audience members and attendees were able to truly build connections with each other.  They were treated like royalty, and their brains and stomachs were fed.

Paypal has done an amazing job at this conference.  It’s something that many, including myself will remember for years to come.  Thank you, Paypal, for allowing me the opportunity to come out and be a part of this amazing experience.  I hope there are many more to come and others will also be able to experience this in the future.  Paypal truly understands that developers are the “X” factor in their product.  I’m stoked to see what I can do with it.

Paypal X Innovate

Paypal X Innovate 2009I’ve been invited by Paypal to come out to San Francisco and participate in the Paypal X Innovate conference on Tuesday and Wednesday.  I’ll be in San Francisco starting tomorrow morning.  I’d love to meet you!  If you’re going to be at the conference, or in the San Francisco area, let me know and we can try to meet up if I have some time.  Maybe we can arrange a Tweetup or Facebook dev garage while I’m out there or something.

What is Paypal X Innovate?  It’s a conference for developers on the new Paypal X development platform.  At the conference, Paypal will be announcing their new platform, showcasing what you can do with it, and supposedly will be announcing a few surprises as well.  At the event you can expect to see speakers such as Tim O’Reilly, John Donahoe, and Om Malik, amongst many other industry luminaries interested in this space.  Paypal’s going all out at this conference!  I even hear there’s a special surprise gift for each conference attendee.

So if you’ll be at the event, come say hi!  If you haven’t signed up, the event is sold out, but there may be a few tickets available for walk-ins if you want to try the day of.  I’ll be covering everything I can while I’m out there both here, and on my Facebook Fan Page at http://facebook.com/stay. I look forward to seeing you!

It’s About Technology That Creates Community

Plug and Socket - building relationships with technologyI’ve been rambling on Twitter, FriendFeed and Facebook tonight about the differences in how Facebook, Twitter, and FriendFeed’s founders participate in each community.  Look at Mark Zuckerberg’s Facebook Fan Page.  Notice how he basically talks at the community?  I’m not sure I’ve ever seen a comment by him with his followers (perhaps part of the reason why it’s so difficult to manage Fan Pages right now).  Now look at Ev Williams and Biz Stone’s Twitter profiles.  You’ll notice a little more participation, but mostly with their inner circles and occasional outreaches to the community.  Now go read Paul Buchheit and Bret Taylor’s FriendFeed profiles.  Notice that they’re very actively involved in the conversation, responding in their own threads to people they barely know, participating in others’ conversations, etc.  I think if you look at the profiles of other employees in each of the three organizations you’ll see a similar trend.  Why is it that the community where the founders and employees participate the most is the smallest community with the lowest growth rate?

I’ve been contemplating this tonight.  FriendFeed, as a whole has one of the tightest communities of all.  For those that participate actively in the site, we quickly come to know each other – it’s the place where everybody knows your name.  That’s why Scoble, and Louis Gray, and myself are so passionate about it.  It is a great place to go meet new people, find more information, and grow with a community that cares and knows you.  I asked the question why Facebook and even Twitter don’t see this as an opportunity to win a new audience, much of which feels a bit betrayed by the sale of FriendFeed to Facebook, and many who have never done much venturing outside the network to new places. It seems like an opportunity to me – after all, when Facebook bought FriendFeed, they bought the technology, not the community.  The community is something that has to be earned, not bought.

Yet, at the same time I wonder if it really matters.  With Facebook and Twitter’s immense growth, do they really need to be paying attention to the small FriendFeed community?  FriendFeed has great technology, and great talent that built that technology, now working for Facebook (one who just left).  Can the community be won in other ways?  I think it can, and it goes back to the first paragraph above – look at the numbers compared to participation.  I argue a community’s growth is not relative to the participation of its founders, but rather the technology’s capability to build community even further.  It’s the technology that trumps community any day because it creates and enables that community.  Technology that empowers individuals to create their own communities wins any day, and trumps founder participation hands down.

Gasp!  You say – you mean I don’t have to participate to build a community?  No, that’s not what I’m saying.  If you’re a user of the tools, you definitely must be participating, nurturing, and sharing for your community to grow.  What I’m saying though is that no matter who the founders are and whether they participate in your personal community or not, you’re going to take your community to the places that enable you to nurter, build, and grow a community the best.  That’s why Facebook grew the fastest.  That’s why people use Twitter.  It’s also why FriendFeed was the smallest, yet had a great acquisition of some very talented individuals who know how to build this type of technology.

Let’s look at the technologies:

Facebook

Facebook not only enables you to share status updates with your friends, but enables you to share photos, videos, notes, links, and more, all in an integrated environment.  You have privacy controls to which you can control how public the information you share with your friends is.  This encourages a native environment where family and close friends can communicate and share with each other, focusing on each individual’s roots to build community out of.  You have lists that you can organize these individuals and filter their updates in your news stream.

At the same time Facebook provides Fan Pages, indexable by Google, for which you can subscribe, or “fan”, similar to the way you would do on the other networks.  This is your public, more anonymous persona, something I think each individual needs as well.  This enables you to share with the rest of the world what you’re doing, and build community and share through that means.

Then you have the API.  Not only as an entrepreneur, developer, or community builder do I have access to create applications that create and nurture community within the Facebook environment, but Facebook has also given me the technology and tools to do that on my own website, all with the community I’m working to build on Facebook itself.  It enables me to do that with my own community, and enable them to bring their communities into my own.

The richness of that experience is what makes Facebook so big, and is the reason for its growth.  That has nothing to do with its founders or their participation.  I’m not sure they need to participate so long as they keep building technology that further enables individual communities on the network.

Twitter

Twitter baffles me at times, but I think I understand it.  Twitter’s openness and focus on such a simple thing, status updates, is what has made it grow so big.  Users can do whatever they want with the network.  They can use it to update their friends with what they’re doing, respond, and grow a community through open communication.

Twitter also encourages the initiation of conversation.  You post something on Twitter, link to somewhere else, and the communication continues elsewhere.  Some times that filters back to Twitter.  Some times the entire communication happens on Twitter.

Twitter’s API is as open as it can be.  It’s fairly limited as compared to Facebook’s, but has enabled many people to bring their communities on Twitter back to their own brand and vice-versa to further grow community.

The problem with Twitter as compared to Facebook is that it is only status updates.  You can respond, reply, and even retweet items you read, but it all centers around those status updates.  There’s not much more depth than that, limiting the type and size of community one can build on the network.  Yet at the same time the openness and lack of rules around users and its developer platform has enabled people to do things they would not normally be able to do with a community on Facebook.  That’s why they’ve continued to grow and are the size (and hype) they are right now.

At the same time because they’re not quite the enablers of community in regards to their technology which Facebook is, I think their Founders and employees need to participate and get involved a little more.  The technology still doesn’t quite sustain the building of community the way Facebook’s does.

FriendFeed

I could probably argue FriendFeed has better technology that encourages and enables community building better than Twitter’s.  The problem with FriendFeed is that almost all the technology found in FriendFeed keeps getting gobbled up by Twitter and Facebook.  There’s not much new to it, and now that they’ve been bought by Facebook, that doesn’t appear to need to fully compete – it would just be an additional complement to the community-building offerings Facebook offers.

Beforehand FriendFeed was doing a good job keeping up, and perhaps could have even caught up to at least Twitter.  Its growth was even starting to show that before they were acquired.  Yet their founders still participated, as did the other employees of the company.  Why is this?  It was possible because the community was smaller – the founders were simply growing with the community, and the community was and is still a tight-knit community of people that knew each other.

I think as FriendFeed continued to build technology that enabled others to build community and relationships, that participation would have slowly evolved to each of the founders’ own close communities.  They would not have needed to participate for the community to grow.

Conclusion

So what do we make of all this?  I think the moral here is that entrepreneurs need to focus more on building technologies that encourage and enable community.  When you’re writing code or having others write it is it enabling people to build relationships?  Is it enabling people to share with others?  How much so?

The Facebook/Twitter or even Google or Microsoft or Apple battle isn’t over yet – in the end it will be the one that best enables their users through technology to build their own communities and communicate better with each other.  The better competitors will master this.  There will be other entrants.  It’s not the participation of a community’s founders that determines its success.  It’s the technology of the company which creates community that does.  In that regard, technology trumps community, hands down.

Web 3.0: The Building Block Web

lego bricksTim O’Reilly is well-known not only for his successful publishing company (which I have written for), but also for his definition of the term, “Web 2.0”, in summary defining the web as a platform, moving from the desktop to the cloud. I’d like to propose we are in the process of taking that one step further, perhaps even moving to our foundations, taking components of that platform, and enabling others to use those components in their own applications. Some talk about the “real-time web” being Web 3.0, or the 2010 Web, but when you look at it “real-time” is just using the web as a platform, making it real-time.  The web still hasn’t really changed in essence to something else beyond the web becoming “the platform”.  The web needs to shift to something else for that to happen. I think that shift is happening in a form I call “the building block web”.

When I think building blocks I think Lego bricks.  Each one has its own unique size and shape, and when you take the basic lego bricks you can add your own, making something unique and powerful.  The web, as a whole, is evolving towards this state.  We see Twitter, with its open platform enabling others to share in ways they were never able to share before in their own applications.  We see Facebook and Facebook Connect enabling businesses to incorporate Facebook activity, relationships, and more right in the bounds of their own brand (Jeremiah Owyang suggested we might call this “farming”).  Recently, we saw Google Wave producing ways for users to collaborate in ways they were never able to before, and embed these in new ways into external environments. We see Facebook implementing Facebook credits amongst various applications and enabling some developers to charge using Facebook credits, Facebook taking a cut along the way.  Each of these “components” is a building block.  They’re each basic foundations, or Lego bricks that have organized the web into components developers can now build new and interesting things with.  The new platform is on top of these foundations, which are built on top of the web, and viewable via a desktop or browser.

Robert Scoble, as he was interviewing me and Louis Gray last week, mentioned he thought Facebook should implement reviews similar to Yelp, and they could then profit from the deals made surrounding those reviews of retail and other physical purchase locations.  It’s a great idea, but I suggested Facebook doesn’t need to do this.  Facebook seems to understand the building block web.  They are providing means for Yelp and others to take what Facebook is good at – building relationships and sharing activities and content with your close friends and family, and incorporate that content and social graph into and out of Yelp’s own environment.  They are even providing for some developers (as mentioned earlier) the ability to integrate their built in credit system.  Facebook provides their own foundations or Lego bricks, provides a means for those people to pay for things, and Facebook takes a cut of every piece of that along the way.  Seems like a much better model than reinventing the wheel if you ask me.  Now imagine if Yelp joined the building block web by providing their own “blocks” giving other apps the power of what Yelp is good at: organizing great reviews around physical purchase locations around the world.

Now look at Google.  Google understands this well.  They are providing Friend Connect, OpenSocial, Android, Wave (on 3 different levels!), and letting Developers decide what to do with them.  Google is adding to this new platform giving developers new building blocks to play with and create cool things with.

This new web is surrounding us as we speak.  Each of the major players is in a race to see who can create the most building blocks for developers and entrepreneurs to incorporate into their own products.  No longer are entrepreneurs focused on building for the web.  They’re focused on building around these building blocks. The building blocks are the platform. This is Web 3.0.  Who will win?

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

Learn More About Facebook With Upcoming WebCasts

FacebookI’ve been invited to do 2 WebCasts in the next 2 weeks that I think you might be interested in.  As always I’ll try to post my slides on SlideShare if it makes sense to do so.  I really like an interactive presentation so most of the time my slides don’t make sense.

The first is for the Marketers in the Audience.  It’s about gaining Business value from Facebook, and I’ll discuss how to give your business legs using the Social Network.  I’ll cover how to create an effective Facebook Page for your business, when and how to use your personal Facebook Profile for networking, do’s and don’ts on the network, advertising, the tools you need, and more.  That Webinar is hosted by Marketing Coalition, and is $149 per individual, and $129 per individuals in groups of at least 3.  You can register here.  The Webinar takes place on Thursday at 1:30PM EST.

The second WebCast is free, and hosted by Safari Books Online.  It will target developers new to Facebook development, and in it I’ll cover the basics of what you need to get started in Facebook Development.  We did this last year and I think everyone really enjoyed it that attended.  The first people that register get a free Autographed copy of my book, FBML Essentials, and everyone else gets a free 45-day account on Safari Books Online to read FBML Essentials.  Did I mention how much I love O’Reilly?  You can register here.  My slides from the last one of these I did are up on SlideShare.

There will be a Q&A after each session, so come with your questions and I’ll do my best to answer!

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.

What Would You Like To Learn About Social Web Development?

Help is on the wayOne of my strongest expertise is developing web apps that utilize Social APIs and technologies.  My website, SocialToo is built all around these.  I’ve written a book on the subject, and reviewed others.  I’ve blogged about it, and written many apps myself, and consulted for many others.  I wrote one of the first howtos on Facebook Connect development, and wrote the very first Facebook Connect WordPress plugin.

However, I’ve realized that I’m not sharing that much.  I have presentations I’ve shared via Slideshare, but those just don’t do it justice.  I’d like to share more here on this blog, do a few geeky howtos for the developers and coders out there, and hopefully help a few of you out.  I’m not quite sure where to start though.

So my question for you is, what would you like me to talk about?  What would you like to learn?  It can be any Social Network API, really.  If I don’t know it yet I’ll go learn it and share it with you.  I’d like to help you learn what you don’t already know though.  I figure I’m pretty good at this stuff, so I may as well share it.  So, what would you like me to talk about?  Trust me, it will be much more interesting if you tell me, than if I just guess myself.  How can I help you?

Image courtesy Cory Doctorow