Skip to content

Instantly share code, notes, and snippets.

@crystalline
Created July 25, 2017 22:54
Show Gist options
  • Save crystalline/cde099d3a4ce6c6bd83f77f0bfeb5ce8 to your computer and use it in GitHub Desktop.
Save crystalline/cde099d3a4ce6c6bd83f77f0bfeb5ce8 to your computer and use it in GitHub Desktop.
A basic irc client/bot in node.js
var pr = console.log;
var net = require('net');
var readline = require('readline');
//Simple IRC client
function IRC(ip, port, nick, room, debug) {
this.ip = ip;
this.port = port;
this.room = room;
this.nick = nick;
this.debug = debug;
this.maxMsgLen = 250;
this.loginCmdWait = 5000;
this.pingInterval = 100000;
this.prefix = ':'+this.nick+'!~'+'irc.js ';
this.handlers = {};
this.socket = net.Socket({readable: true, writable:true});
var that = this;
this.rl = readline.createInterface({
input: that.socket
});
this.socket.setEncoding('utf8');
function delayMsg(f) {
setTimeout(f, that.loginCmdWait);
}
this.socket.on('connect', function () {
that.debug && pr('Connected.');
that.sendMsg('NICK', that.nick, delayMsg(function () {
that.sendMsg('USER', that.nick+' 0 * :Real name', delayMsg(function () {
that.sendMsg('JOIN', ':'+that.room, delayMsg(function () {
that.handlers.connect && that.handlers.connect();
if (that.pingInterval) {
setInterval(() => {
that.sendMsg('PING', Math.floor(Math.random()*1e6));
}, that.pingInterval);
}
}));
}));
}));
});
var pingRE = /^PING \:([^\s]+)/;
var messageRE = new RegExp(':([^\\s]+)\\sPRIVMSG\\s'+this.room+'\\s:(.+)', 'i');
var nickRE = /^([^\s\!]+)/;
this.rl.on('line', function (line) {
that.debug && pr('Received:',line);
var _match;
if (_match = line.match(pingRE)) {
that.debug && pr('PING',_match[1]);
that.sendMsg('PONG',':'+_match[1]);
} else if (_match = line.match(messageRE)) {
//that.debug && pr('Matches:',_match);
var nick = _match[1].match(nickRE)[1];
var msg = _match[2];
that.handlers.message && that.handlers.message(nick, msg);
}
});
this.socket.connect({host: ip, port:port});
}
IRC.prototype.on = function(event, handler) {
this.handlers[event] = handler;
};
IRC.prototype.sendMsg = function(cmdName, data, onDone) {
var that = this;
this.socket.write(this.prefix+cmdName+' '+data+'\n', 'utf8', function () {
that.debug && pr('Sent:',cmdName,data);
onDone && onDone.apply(that, arguments);
});
};
//Splits messages that are longer than this.maxMsgLen (== 445 by default) bytes when utf encoded
//into multiple msgs
IRC.prototype.send = function(str, onDone) {
var blen = Buffer.byteLength(str, 'utf8');
var msgs = [];
//Split long messages into chunks, reverse the chunk array so you can send chunks by .pop()
//until array is empty
if (blen > this.maxMsgLen) {
this.debug && pr('msg length:',blen);
var rightPart = str;
do {
msgs.push(rightPart.substr(0, this.maxMsgLen));
rightPart = rightPart.substr(this.maxMsgLen);
} while (rightPart.length > this.maxMsgLen)
rightPart.length && msgs.push(rightPart);
msgs.reverse();
this.debug && pr(msgs);
} else {
//Short messages are just arrays of one chunk
msgs = [str];
}
var that = this;
function send() {
if (msgs.length) {
var data = msgs.pop();
that.sendMsg('PRIVMSG', that.room+' :'+data, send);
} else {
onDone && onDone.apply(that, arguments);
}
}
send();
};
// How to use
var ip = '80.65.57.18'; //one of irc.rizon.net IPs
var port = 6667; //UTF8
var room = '#r9kprog';
var nick = 'testbot891023';
var client = new IRC(ip, port, nick, room, true);
client.on('message', function(nick, msg) {
pr('Message from',nick+':',msg);
if (msg.match(/^[Nn]ode/)) {
client.send(nick+' told me that "'+msg+'", I remember everything!');
}
});
client.on('connect', function () {
client.send('Node connected.');
});
//module.exports = IRC;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment