Using OAuth to Access Twitter from KRL


Kynetx Logo

The latest build (Build 391) of the Kynetx Rule Language (KRL) includes support for accessing Twitter data intrinsically within the language. Integrating interesting data with KRL is an important part of what makes the language so useful for building cross-site applications that mash-up data and user interactions. But what's really interesting about this release is that we're using OAuth to access the Twitter API and have built primitives into the language for dealing with the Twitter OAuth interaction to save developers from doing it.

Not only are we making it easy for developers to write apps that use Twitter, but this is also the first time that end users will see significantly different behavior from an app than their friend might. An app that uses the Twitter library will use my Twitter data for me and your Twitter data for you. Using OAuth, Kynetx apps can now be personalized.

Using Twitter data inside a KRL app generally involves two KRL patterns: authorize then use and initialize then populate

In the authorize then use pattern, a rule is put in place to check if the app is authorized to take a certain action and, if not, do what is necessary to complete the authorization. What makes this work is using the rule postlude to ensure that the rest of the rules (which presumably rely on the authorization) don't run. Here's an example from an app I wrote to demonstrate using the the new Twitter library:

rule auth is active {
  select using ".*" setting ()
  if(not twitter:authorized()) then
      twitter:authorize()
        with opacity=1.0 and
             sticky = true

  fired {
     last
  }
}

Notice that this rule only fires if the predicate twitter:authorized() is false. The action, twitter:authorize(), is what initiates the OAuth ceremony. The action will pop up a notification in the user's browser that looks like this:

OAuth ceremony initiated by a KRL application

The postlude of the rule (fired {...}) runs the last statement if the rule fires to ensure that nothing else happens. Of course, if the app is authorized, the rule doesn't fire, the OAuth ceremony is not initiated, the last is never executed, and the remaining rules in the ruleset are evaluated.

The initialize then populate pattern is important any time you're working with complex data. With complex data, you will frequently need to do something for each component of an array. That's what the foreach statement does as part of the rule selector: executes a rule once for each member of an array.

The problem is that if we use a foreach to loop over the tweets we get back and use notify to place them on the page, we'll end up with one notification box for each tweet. Not very pretty.

A better solution is to use a rule to place the notification box (the initializer) and another rule to loop over the tweets and place them in the notification box (the populater).

Here's the initialization rule:

rule init_tweetdom is active {
  select using ".*" setting ()

  pre {
    init_div = <<
<div id="tweet_list">
</div>
>>
  }

  notify("Friends Tweets", init_div)
    with sticky=true and
         opacity = 1.0

This is a pretty simple rule that places an empty notification box on the page.

The real work is done by the populating rule:

rule populate_tweetdom is active {
  select using ".*" setting ()
    foreach tweets setting (tweet)
      pre {
        text = tweet.pick("$..text");
        div = "<div style='background-color:#666;margin:2px'>" +
              text + 
              "</div>";
      }
      append("#tweet_list", div)
}

This rule loops over the tweets, grabs data out of them using pick, and appends the result to the div in the notification box.

The tweets variable was set in the global block:

tweets = 
  twitter:authorized() => twitter:friends_timeline({"count": 8})
                        | [];

After you've gone through the OAuth ceremony at Twitter, wherever you run this app, you will see a box like this that contains the last eight tweets from your friends timeline on Twitter. Here's the results for me:

The last eight tweets from my friends timeline on twitter.

Of course, if you run this app, either by card or bookmarket, you'll see the results from your friends timeline.

Craig Burton has created a nice tutorial about how all this works. There's some important data in the tutorial about how to get the keys from Twitter for your application. The library is also well documented and the source code for the ruleset is available.

The ability to personalize apps by appealing to personal data elsewhere on the Web is a huge step forward for KRL. Look for other APIs to be embedded in KRL in the near term and, eventually, more general support for OAuth so that developers can use any OAuth protected data source.