Skip to content

Instantly share code, notes, and snippets.

@funkatron
Created May 19, 2011 14:24
Show Gist options
  • Save funkatron/980852 to your computer and use it in GitHub Desktop.
Save funkatron/980852 to your computer and use it in GitHub Desktop.
This is a proof of concept to demonstrate listening for a callback request from Twitter's oAuth system with a local socket server in AIR
<?xml version="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
<id>com.funkatron.jsOAuthListenerTest</id>
<filename>jsOAuthListenerTest</filename>
<name>jsOAuth AIR Listener Test</name>
<version>0.1</version>
<initialWindow>
<content>index_socket.html</content>
<visible>true</visible>
<width>700</width>
<height>500</height>
<!-- The window's initial x position. Optional. -->
<x>100</x>
<!-- The window's initial y position. Optional. -->
<y>100</y>
</initialWindow>
<supportedProfiles>desktop</supportedProfiles>
</application>
<!DOCTYPE html>
<html>
<head>
<!--
This is a proof of concept to demonstrate listening for a callback request
from Twitter's oAuth system with a local socket server in AIR
-->
<meta charset="utf-8">
<title>jsOauth test</title>
<script src="AIRAliases.js"></script>
<script src="jquery.min.js"></script>
<!-- get jsOAuth at https://github.com/bytespider/jsoauth -->
<script type="text/javascript" src="jsOAuth-1.1.js"></script>
<style type="text/css" media="screen">
</style>
<script>
// fill these in with your own values
var TWITTER_CONSUMER_KEY = '';
var TWITTER_CONSUMER_SECRET = '';
// this is the window we'll open to authorize
var authWin;
/**
* This is basically a port of an actionscript HTTP socket server by Christophe Coenraets
* See <http://coenraets.org/blog/2009/12/air-2-0-web-server-using-the-new-server-socket-api/>
*/
var OAuthCallbackListener = function(opts) {
if (!opts) { opts = {}; }
var SOCKET_PORT = opts.port || 9999;
var onGotTokens = function(data) { air.trace('Got token data:'+data); };
if (opts.gotTokens) { onGotTokens = opts.gotTokens; }
var serverSocket;
var reqs_cache = [];
function listen() {
try {
serverSocket = new air.ServerSocket();
serverSocket.addEventListener(air.Event.CONNECT, socketConnectHandler);
serverSocket.bind(SOCKET_PORT);
serverSocket.listen();
air.trace("Listening on port " + SOCKET_PORT + "...\n");
} catch (error) {
air.trace("Port " + SOCKET_PORT +
" may be in use. Enter another port number and try again.\n(" +
error.message +")");
}
}
function socketConnectHandler(event) {
var socket = event.socket;
socket.addEventListener(air.ProgressEvent.SOCKET_DATA, socketDataHandler);
}
function socketDataHandler(event) {
try {
var socket = event.target;
var bytes = new air.ByteArray();
socket.readBytes(bytes);
var request = "" + bytes; // convert to string
if (reqs_cache.indexOf(request) !== -1) {
air.trace('This req is cached; skipping');
return;
} else {
reqs_cache.push(request);
}
air.trace("New Request:\n");
air.trace(request+"\n\n\n");
var reqURI = request.substring(4, request.indexOf("HTTP/") - 1);
if (reqURI.indexOf('oauth_token') !== -1) {
var queryString = reqURI.replace(/^\/\?/, ''); // strip leading /?
authWin.close();
socket.flush();
close(socket);
onGotTokens(queryString);
} else {
air.trace('Got something that doesn\'t look like a callback');
}
} catch (error) {
air.trace("Error: "+error.message);
}
}
function close(socket) {
socket.removeEventListener(air.ProgressEvent.SOCKET_DATA, socketDataHandler);
socket.close();
socket = null;
}
return {
'port':SOCKET_PORT,
'listen':listen,
'close':close
};
};
// a helper function to split up query strings into key/val pairs
function getQueryVars(str) {
// split the query string as needed
var qvars = {};
var qvars_tmp = str.split('&');
for (var i = 0; i < qvars_tmp.length; i++) {;
var y = qvars_tmp[i].split('=');
qvars[y[0]] = decodeURIComponent(y[1]);
};
return qvars;
}
// retrieves the home timeline
var getHomeTimeline = function() {
oauth.get('https://api.twitter.com/1/statuses/home_timeline.json',
function(data) { // success
entries = JSON.parse(data.text);
var html = [];
for (var i = 0; i < entries.length; i++) {
html.push(JSON.stringify(entries[i]));
};
$('#timeline').html(html.join('<hr>'));
},
function(data) { // failure
alert('lame');
air.trace(JSON.stringify(data));
}
);
}
// init and start listening for callbacks
var listener = new OAuthCallbackListener({
'port':10000,
'gotTokens':function(qstring) {
$('#msg').text('Got auth tokens; exchanging for access token…');
oauth.get('https://twitter.com/oauth/access_token?'+qstring,
function(data) {
air.trace(JSON.stringify(data));
// split the query string as needed
var accessParams = getQueryVars(data.text);
oauth.setAccessToken([accessParams.oauth_token, accessParams.oauth_token_secret]);
$('#msg').text('Got access tokens; getting home timeline for authenticated user…');
getHomeTimeline();
},
function(data) {
alert('poop');
air.trace(JSON.stringify(data));
}
);
}
});
listener.listen();
// setup OAuth object
var options = {
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackUrl: 'http://localhost:'+listener.port+'/'
};
var oauth = OAuth(options);
// when doc is ready, go get a request token
$(document).ready(function() {
oauth.get('https://twitter.com/oauth/request_token',
function(data) { // success
air.trace(JSON.stringify(data));
authWin = window.open('https://twitter.com/oauth/authorize?'+data.text);
},
function(data) { // failure
alert('Error trying to get the request token');
air.trace(JSON.stringify(data));
}
);
});
</script>
</head>
<body>
<h1>jsOauth test</h1>
<p id="msg">I will be listening for the callback with my big socket…</p>
<div id="timeline">
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment