Skip to content

Instantly share code, notes, and snippets.

@joshcarr
Forked from powdahound/hipchat_bot.js
Created September 24, 2011 22:31
Show Gist options
  • Save joshcarr/1239952 to your computer and use it in GitHub Desktop.
Save joshcarr/1239952 to your computer and use it in GitHub Desktop.
Basic XMPP bot example for HipChat using node.js
// Basic XMPP bot example for HipChat using node.js
// To use:
// 1. Set config variables
// 2. Run `node hipchat_bot.js`
// 3. Send a message like "!weather 94085" in the room with the bot
var request = require('request'); // github.com/mikeal/request
var sys = require('sys');
var util = require('util');
var xmpp = require('node-xmpp');
// Config (get details from https://www.hipchat.com/account/xmpp)
var jid = "[email protected]"
var password = ""
var room_jid = "[email protected]"
var room_nick = "Xxx Xxx"
var cl = new xmpp.Client({
jid: jid + '/bot',
password: password
});
// Log all data received
//cl.on('data', function(d) {
// util.log("[data in] " + d);
//});
// Once connected, set available presence and join room
cl.on('online', function() {
util.log("We're online!");
// set ourselves as online
cl.send(new xmpp.Element('presence', { type: 'available' }).
c('show').t('chat')
);
// join room (and request no chat history)
cl.send(new xmpp.Element('presence', { to: room_jid+'/'+room_nick }).
c('x', { xmlns: 'http://jabber.org/protocol/muc' }).
c('history', { maxchars: '0'})
);
// send keepalive data or server will disconnect us after 150s of inactivity
setInterval(function() {
cl.send(' ');
}, 30000);
});
cl.on('stanza', function(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}
// ignore everything that isn't a room message
if (!stanza.is('message') || !stanza.attrs.type == 'groupchat') {
return;
}
// ignore messages we sent
if (stanza.attrs.from == room_jid+'/'+room_nick) {
return;
}
var body = stanza.getChild('body');
// message without body is probably a topic change
if (!body) {
return;
}
var message = body.getText();
// Look for messages like "!weather 94085"
if (message.indexOf('!weather') === 0) {
var search = message.substring(9);
util.log('Fetching weather for: "' + search + '"');
// hit Yahoo API
var query = 'select item from weather.forecast where location = "'+search+'"';
var uri = 'http://query.yahooapis.com/v1/public/yql?format=json&q='+encodeURIComponent(query);
request({'uri': uri}, function(error, response, body) {
body = JSON.parse(body);
var item = body.query.results.channel.item;
if (!item.condition) {
response = item.title;
} else {
response = item.title+': '+item.condition.temp+' degrees and '+item.condition.text;
}
// send response
cl.send(new xmpp.Element('message', { to: room_jid, type: 'groupchat' }).
c('body').t(response)
);
});
}
});
// when exiting, send proper exit info to server
// and also a nice message
// then exit on next processTick
process.on('SIGINT', function() {
util.log("shutting down this bot!");
// send response
cl.send(new xmpp.Element('message', { to: room_jid, type: 'groupchat' }).
c('body').t('Heading out, everybody. Ciao.')
);
cl.send(new xmpp.Element('presence', { type: 'unavailable', to: room_jid+'/'+room_nick })
);
process.nextTick(function() {
process.exit(0);
});
});
@joshcarr
Copy link
Author

A couple of changes from original author's:

When joining room, adding the following so that previous chathistory is not sent to the bot:
c('history', { maxchars: '0'})

When sending the msg, don't send privately, send to the whole room (by removing the /room_nick)

Adding a proper exit routine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment