Skip to content

Instantly share code, notes, and snippets.

@daniel-j
Last active December 30, 2015 20:49
Show Gist options
  • Save daniel-j/7882925 to your computer and use it in GitHub Desktop.
Save daniel-j/7882925 to your computer and use it in GitHub Desktop.
My IRC bot template..
#!/usr/bin/env node
'use strict';
// IRC bot by djazz
// Modules
//var http = require('http');
var irc = require('irc');
var colors = require('colors');
var util = require('util');
var readline = require('readline');
// Config
var SERVER = 'irc.canternet.org'; // The server we want to connect to
var PORT = 6667; // The connection port which is usually 6667
var NICK = 'djazzbot'; // The bot's nickname
var IDENT = null; // Password of the bot. Set to null to not use password login.
var REALNAME = 'djazz\'s bot'; // Real name of the bot
var CHANNEL = '#BronyTalk'; // The default channel for the bot
var airDate = Date.UTC(2013, 11-1, 23, 15, 30, 0); // Year, month-1, day, hour, minute, second (UTC)
var week = 7*24*60*60*1000;
function handleMessage(nick, message, simplified, isMentioned, isPM) {
var target = isPM ? nick : CHANNEL;
if (simplified[0] === "!test") {
sendPM(target, irc.colors.wrap("orange", "Test success!"));
} else if (simplified[0] === '!nextep') {
var counter = 0;
var now = Date.now();
do {
var timeLeft = Math.max(((airDate+week*(counter++)) - now)/1000, 0);
} while (timeLeft === 0 && counter < 26);
if (timeLeft === 0) {
sendPM(target, "Season 4 is over :(");
} else {
sendPM(target, "Next S4 episode airs in %s", readableTime(timeLeft, true));
}
} else if (isMentioned) {
sendPM(target, ":3");
}
// use sendChat to send to channel, or sendPM(target, msg) to send to channel or private chat.
}
var bot = new irc.Client(SERVER, NICK, {
channels: [CHANNEL],
password: IDENT,
realName: REALNAME,
port: PORT,
stripColors: true
});
var lasttopic = "";
var lasttopicnick = "";
bot.on('error', function (message) {
info('ERROR: %s: %s', message.command, message.args.join(' '));
});
bot.on('topic', function (channel, topic, nick) {
lasttopic = topic;
lasttopicnick = nick;
logTopic(channel, topic, nick);
});
bot.on('message'+CHANNEL, function (from, message) {
var simplified = message.replace(/\:/g, ' ').replace(/\,/g, ' ').replace(/\./g, ' ').replace(/\?/g, ' ').trim().split(' ');
var isMentioned = simplified.indexOf(NICK) !== -1;
logChat(from, message, isMentioned);
handleMessage(from, message, simplified, isMentioned, false);
});
bot.on('join'+CHANNEL, function (nick) {
if (nick === NICK) {
info("You joined channel "+CHANNEL.bold);
rl.setPrompt(util.format("> ".bold.magenta), 2);
rl.prompt(true);
} else {
mylog((" --> ".green.bold)+'%s has joined %s', nick.bold, CHANNEL.bold);
}
});
bot.on('part'+CHANNEL, function (nick) {
if (nick !== NICK) {
mylog((" <-- ".red.bold)+'%s has left %s', nick.bold, CHANNEL.bold);
}
});
bot.on('pm', function (nick, message) {
logPM(nick, message);
var simplified = message.replace(/\:/g, ' ').replace(/\,/g, ' ').replace(/\./g, ' ').replace(/\?/g, ' ').trim().split(' ');
var isMentioned = simplified.indexOf(NICK) !== -1;
handleMessage(nick, message, simplified, isMentioned, true);
});
bot.on('notice', function (nick, to, text) {
//mylog(nick, to, text);
});
bot.on('raw', function (message) {
if (message.command === 'PRIVMSG' && message.args[0] === CHANNEL && message.args[1].indexOf("\u0001ACTION ") === 0) {
var action = message.args[1].substr(8);
action = action.substring(0, action.length-1);
mylog("* %s".bold+" %s", message.nick, action);
}
});
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.setPrompt("");
rl.on('line', function (line) {
if (line === '') {
return;
}
if (line.indexOf('/quit') === 0) {
info("Quitting...");
rl.setPrompt("");
bot.disconnect("Quitting..", function () {
process.exit(0);
});
return;
} else if (line.indexOf('/msg ') === 0) {
var split = line.split(" ");
var nick = split[1];
var msg = split.slice(2).join(" ");
sendPM(nick, msg);
} else if (line.indexOf('/me ') === 0) {
var msg = line.substr(4);
bot.action(CHANNEL, msg);
} else if (line === '/topic') {
logTopic(CHANNEL, lasttopic, lasttopicnick);
} else if (line.indexOf("/") === 0) {
info(("Unknown command "+line.substr(1).bold).red);
} else {
sendChat(line);
}
rl.prompt(true);
});
info('Connecting...');
function mylog() {
// rl.pause();
rl.output.write('\x1b[2K\r');
console.log.apply(console, Array.prototype.slice.call(arguments));
// rl.resume();
rl._refreshLine();
}
function info() {
arguments[0] = " -- ".magenta+arguments[0];
mylog(util.format.apply(null, arguments));
}
function sendChat() {
var message = util.format.apply(null, arguments);
logChat(NICK, message);
bot.say(CHANNEL, message);
}
function sendPM(target) {
if (target === CHANNEL) {
sendChat.apply(null, Array.prototype.slice.call(arguments, 1));
return;
}
var message = util.format.apply(null, Array.prototype.slice.call(arguments, 1));
logPM(NICK+" -> "+target, message);
bot.say(target, message);
}
function logChat(nick, message, isMentioned) {
if (isMentioned) {
nick = nick.yellow;
}
mylog('%s: %s', nick.bold, message);
}
function logPM(target, message) {
mylog('%s: %s', target.bold.blue, message);
}
function logTopic(channel, topic, nick) {
info('Topic for %s is "%s" set by %s', channel.bold, topic.yellow, nick.bold.cyan);
}
function zf(v) {
if (v > 9) {
return ""+v;
} else {
return "0"+v;
}
}
function readableTime(timems, ignoreMs) {
var time = timems|0;
var ms = ignoreMs?'':"."+zf((timems*100)%100|0);
if (time < 60) return zf(time)+ms+"s";
else if (time < 3600) return zf(time / 60|0)+"m "+zf(time % 60)+ms+"s";
else if (time < 86400) return zf(time / 3600|0)+"h "+zf((time % 3600)/60|0)+"m "+zf((time % 3600)%60)+ms+"s";
else return (time / 86400|0)+"d "+zf((time % 86400)/3600|0)+"h "+zf((time % 3600)/60|0)+"m "+zf((time % 3600)%60)+"s";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment