Skip to content

Instantly share code, notes, and snippets.

@timwienk
Last active January 27, 2017 17:50
Show Gist options
  • Save timwienk/4345306 to your computer and use it in GitHub Desktop.
Save timwienk/4345306 to your computer and use it in GitHub Desktop.
Simple IRC notify script, sic (http://tools.suckless.org/sic) inspired.
#!/usr/bin/env node
"use strict"
var connection = null,
buffer = '',
listeners = {};
var options = {
host: 'chat.freenode.net',
port: 6667,
nick: process.env.USER + '-notify',
channel: null,
input: null,
debug: false
};
function print(message, stream){
if (!stream) stream = 'stdout';
options.debug && process[stream].write(message + '\n');
}
function send(message){
print('-> ' + message);
connection && connection.write(message + '\r\n');
}
function exit(code){
if (!code) code = 0;
print('Exiting (' + code + ')');
process.exit(code);
}
var irc = {
send: function(line){
if (line[0] != ':'){
if (options.channel){
send('PRIVMSG ' + options.channel + ' :' + line);
} else {
print('No channel to send to.', 'stderr');
}
} else if (line.length == 2 || line[2] == ' '){
var command = line[1],
args = line.substr(3);
var firstSpace = args.indexOf(' '),
firstArg = args.slice(0, firstSpace),
nextArgs = args.slice(firstSpace + 1);
switch (command){
case 'm':
send('PRIVMSG ' + firstArg + ' :' + nextArgs);
break;
case 'n':
send('NOTICE ' + firstArg + ' :' + nextArgs);
break;
case 'l':
send('PART ' + firstArg + ' :' + nextArgs);
break;
case 'j':
send('JOIN ' + firstArg);
options.channel = firstArg;
break;
case 's':
options.channel = firstArg;
break;
case 'q':
send('QUIT');
exit(0);
break;
default:
send(command + ' ' + args);
}
} else {
send(line.substr(1));
}
},
receive: function(data){
buffer += data;
var lines = buffer.split('\r\n');
buffer = lines.pop();
lines.forEach(function(line){
if (line[0] == ':'){
line = line.substr(1);
var space = line.indexOf(' '),
source = line.slice(0, space).replace(/!.*/, ''),
message = line.slice(space + 1);
} else {
var source = '',
message = line;
}
var command = message.replace(/ .*/, '');
print(source + '> ' + message);
irc.publish(command, message, source);
});
},
publish: function(command, message, source){
if (listeners[command]){
listeners[command].forEach(function(listener){
try {
listener.call(listener, message, source);
} catch (error) {
print(error.name + ': ' + error.message, 'stderr');
}
});
}
},
subscribe: function(command, listener){
if (listeners[command]){
listeners[command].push(listener);
} else {
listeners[command] = [listener];
}
},
unsubscribe: function(command, listener){
if (listeners[command]){
var index = listeners[command].indexOf(listener);
if (index >= 0){
listeners[command].splice(index, 1);
}
}
}
};
var args = process.argv.splice(2),
arg;
parseArguments: while (args.length){
arg = args.shift();
switch (arg){
case '-h':
options.host = args.shift();
break;
case '-p':
options.port = args.shift();
break;
case '-n':
options.nick = args.shift();
break;
case '-c':
options.channel = args.shift();
break;
case '-d':
options.debug = true;
break;
default:
options.input = arg + ' ' + args.join(' ');
break parseArguments;
}
}
if (!options.input) exit(0);
irc.subscribe('PING', function(message){
send(message.replace(/^PING /, 'PONG '));
});
irc.subscribe('QUIT', function(){
exit(0);
});
irc.subscribe('PRIVMSG', function(message, source){
if (message.match(/^PRIVMSG\s+\S+\s+:\u0001VERSION\u0001$/)){
send('NOTICE ' + source + ' :\u0001VERSION irc-notify.js\u0001')
};
});
irc.subscribe('001', function(){
if (options.channel){
send('JOIN ' + options.channel);
}
options.input.split(';').forEach(function(message){
irc.send(message.trim());
});
send('QUIT');
});
connection = require('net').createConnection(options.port, options.host, function(){
send('NICK ' + options.nick);
send('USER ' + options.nick + ' localhost ' + options.host + ' :' + options.nick);
});
connection.addListener('data', irc.receive);
@larryxiao
Copy link

Hi timwienk!
This script is well written.
Can you elaborate a bit?
Thank you!

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