Created
September 20, 2011 15:09
-
-
Save jnx/1229355 to your computer and use it in GitHub Desktop.
Node.js Campfire bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// main app.js | |
var client = require('ranger').createClient('ROOM', | |
'SECRET'); | |
var timestamp = require('./timestamp').timestamp; | |
var getWeatherWrapper = require('./weather').getWeatherWrapper; | |
var showMap = require('./map').showMap; | |
var getTweets = require('./tweets').getTweets; | |
client.room(ROOMID, function(room) { | |
console.log('Joining ' + room.name + ': ' + timestamp()); | |
room.join(function() { | |
room.listen(function(msg) { | |
if (msg.type === 'TextMessage') { | |
if (msg.body.match(/^!s(hutdown)?/)) { | |
console.log('Leaving ' + room.name + ': ' + timestamp()); | |
room.leave(function() { process.exit(0); }); | |
} | |
// this works | |
if (wanted = msg.body.match(/^!w(?:eather)?\s+(.*)/)) { | |
getWeatherWrapper(wanted[1], function(e, weather) { | |
if (e || !weather) { | |
return console.log(e.message || 'Got no weather!'); | |
} | |
for (var i = 0; i < 3; i++ ) { | |
(function() { | |
var j = i; | |
process.nextTick(function() {room.speak(weather[j]);}) | |
})(); | |
} | |
}); | |
} | |
// works well - but it's only one item | |
if (wanted = msg.body.match(/^!m(?:ap)?\s+(.*)/)) { | |
showMap(wanted[1], function(e, url) { | |
if (e || !url) { | |
return console.log(e.message || 'Got no url from showMap!'); | |
} | |
room.speak(url); | |
}); | |
} | |
// not working - makes me want to pull out my hair... | |
if (wanted = msg.body.match(/^!t(?:weets)?\s+(.*)/)) { | |
// I tried this, but I'm not even using it at the moment - mostly I blew | |
// the stack when getting this wrong | |
var handle_tweets = function(ids, iteration, callback) { | |
if (iteration >= 3) { | |
return callback(null, ids.shift()); | |
} | |
handle_tweets(ids, iteration+1, callback); | |
} | |
getTweets(wanted[1], function(e, tweet_ids) { | |
if (e || !tweet_ids) { | |
console.log(e.message || 'Got no tweet ids'); | |
} | |
// This uses the same process.nextTick as the weather above, but it doesn't | |
// work for whatever reason. | |
console.log('tweet_ids ' + tweet_ids); | |
for (var i = 0; i < 3; i++) { | |
(function() { | |
var j = i; | |
var status = 'http://twitter.com/' + wanted[1] + | |
'/status/' + tweet_ids[j]; | |
process.nextTick(function() {room.tweet(status);}) | |
})(); | |
} | |
}); | |
} | |
} | |
}); | |
}); | |
}); | |
// weather.js - this one works to give three items in order | |
var http = require('http'); | |
var url = require('url'); | |
// Use this later to cache woeids of places we want weather for | |
var query_to_woeid = {}; | |
function getWOEID(wanted, callback) { | |
var path = '/v1/public/yql?q=' | |
var query = 'select woeid from geo.places where text="' + | |
wanted + '" limit 1' + '&format=json'; | |
query = encodeURI(query); | |
var options = { | |
host: 'query.yahooapis.com', | |
port: 80, | |
path: path + query, | |
method: 'GET' | |
}; | |
var req = http.request(options, function(res) { | |
var json = ''; | |
res.on('data', function(chunk) { json += chunk; }); | |
res.on('end', function() { | |
results = JSON.parse(json); | |
woeid = results['query']['results']['place']['woeid']; | |
return callback(null, woeid); | |
}) | |
res.on('error', function(e) { | |
return callback(e); | |
}); | |
}); | |
req.on('error', function(e) { | |
return callback(e); | |
}); | |
req.end(); | |
} | |
function getWeather(woeid, callback) { | |
// Uncomment for debugging | |
//console.log('Start of getWeather: ' + woeid); | |
var path = '/forecastjson?w=' + woeid; | |
var options = { | |
host: 'weather.yahooapis.com', | |
port: 80, | |
path: path, | |
method: 'GET' | |
}; | |
var req = http.request(options, function(res) { | |
var json = ''; | |
res.on('data', function(chunk) { json += chunk; }); | |
res.on('end', function() { | |
results = JSON.parse(json); | |
cur = 'Current - ' + results['condition']['text'] + ': ' + | |
results['condition']['temperature']; | |
today = 'Today - ' + results['forecast'][0]['condition'] + | |
': high - ' + results['forecast'][0]['high_temperature'] + | |
', low - ' + results['forecast'][0]['low_temperature']; | |
tomorrow = 'Tomorrow - ' + results['forecast'][1]['condition'] + | |
': high - ' + results['forecast'][1]['high_temperature'] + | |
', low - ' + results['forecast'][1]['low_temperature']; | |
return callback(null, [ cur, today, tomorrow ]); | |
}); | |
res.on('error', function(e) { | |
return callback(e); | |
}); | |
}); | |
req.on('error', function(e) { | |
return callback(e); | |
}); | |
req.end(); | |
} | |
function getWeatherWrapper(wanted, callback) { | |
var seen = query_to_woeid[wanted]; | |
if (seen) { | |
console.log('Already seen ' + wanted + '. Using the cache...'); | |
getWeather(seen, function(e, weather) { | |
if (e) { | |
return console.log(e.message); | |
} | |
callback(null, weather); | |
}); | |
} | |
else { | |
getWOEID(wanted, function(e, woeid) { | |
if (e) { | |
return console.log(e.message); | |
} | |
query_to_woeid[wanted] = woeid; | |
getWeather(woeid, function(e, weather) { | |
if (e) { | |
return console.log(e.message); | |
} | |
callback(null, weather); | |
}); | |
}); | |
} | |
} | |
exports.getWeatherWrapper = getWeatherWrapper; | |
// twitter.js - still doesn't work never three, often just one - though | |
// I can see in the logs that I'm getting three valid Twitter status ids | |
exports.getTweets = function(wanted, callback) { | |
var http = require('http'); | |
var url = require('url'); | |
var path = '/1/statuses/user_timeline.json?screen_name=' | |
var query = wanted + '&count=3'; | |
query = encodeURI(query); | |
var options = { | |
host: 'api.twitter.com', | |
port: 80, | |
path: path + query, | |
method: 'GET' | |
}; | |
var req = http.request(options, function(res) { | |
var json = ''; | |
res.on('data', function(chunk) { json += chunk; }); | |
res.on('end', function() { | |
tweets = JSON.parse(json); | |
console.log('tweets ' + tweets); | |
ids = []; | |
for (var i = 0; i < 3; i++) { | |
if (tweets[i] && tweets[i]['id_str']) { | |
ids.push(tweets[i]['id_str']); | |
} | |
} | |
console.log('ids ' + ids); | |
return callback(null, ids); | |
}); | |
res.on('error', function(e) { | |
return callback(e); | |
}); | |
}); | |
req.on('error', function(e) { | |
return callback(e); | |
}); | |
req.end(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment