Skip to content

Instantly share code, notes, and snippets.

@ItsOnlyBinary
Created December 11, 2022 15:03
Show Gist options
  • Save ItsOnlyBinary/0e677815b89bf73c3f753925f7aca028 to your computer and use it in GitHub Desktop.
Save ItsOnlyBinary/0e677815b89bf73c3f753925f7aca028 to your computer and use it in GitHub Desktop.
Example of using irc-fw middleware to intercept and modify outgoing who messages
const IRC = require('irc-framework');
const debugRaw = true;
const debugEvents = false;
// Catch uncaught exceptions so the bot does not crash
process.on('uncaughtException', function (err) {
console.error(err.stack);
});
// Create irc-framework instance
const bot = new IRC.Client({
host: 'testnet.inspircd.org',
port: 6697,
tls: true,
nick: 'ircbot',
});
// Overload bot.raw to intercept outgoing messages
const originalRaw = bot.raw;
bot.raw = function raw(...args) {
let message = null;
if (args[0] instanceof IRC.Message) {
message = args[0];
} else {
const rawString = bot.rawString(...args);
message = IRC.ircLineParser(rawString);
}
if (message.command === 'WHO' && message.params.length === 2) {
// Intercept the outgoing WHO command so the fields can be modified
const parts = message.params[1].split(',');
// Set the new whox fields
// If changing the number of whox fields make sure to update params.length
// within the middleware's token validator
// default %tcuhsnfdaor
parts[0] = '%tcuhsnfdaor';
message.params[1] = parts.join(',');
}
const line = message.to1459();
if (debugRaw && line.indexOf('PING') === -1) {
console.log('[<-]', line);
}
originalRaw.apply(bot, [message]);
};
// Use middleware
bot.use(ircMiddleware());
// Handle registered event
bot.on('registered', (event) => {
console.info('Connected!');
bot.join('#testers');
});
// Handle join event
bot.on('join', (event) => {
// See above bot.raw for intercepting this outgoing command
bot.who(event.channel);
});
// Handle wholist event
bot.on('wholist', (event) => {
console.log('wholist', event);
});
// Connect to network
bot.connect();
function ircMiddleware() {
return function (client, rawEvents, parsedEvents) {
rawEvents.use(rawMiddleware);
parsedEvents.use(parsedMiddleware);
};
function rawMiddleware(command, event, rawLine, client, next) {
if (debugRaw) {
if (rawLine.indexOf('PONG') > -1) {
next();
return;
}
console.info('[->]', rawLine.trim());
}
if (command === '354') {
// RPL_WHOSPCRPL
// Custom handler for whox requests
const handler = client.command_handler;
const cache = handler.cache('who');
if (!cache.members) {
cache.members = [];
cache.type = 'whox';
}
const params = event.params;
if (cache.token === 0) {
// Token validation has already been attempted but failed,
// ignore this event as it will not be emitted
return;
}
if (!cache.token) {
const token = parseInt(params[1], 10) || 0;
// If changing the number of whox fields make sure to update params.length
if (token && params.length === 12 && client.whox_token.validate(token)) {
// Token is valid, store it in the cache
cache.token = token;
} else {
// This event does not have a valid token so did not come from irc-fw,
// ignore it as the response order may differ
cache.token = 0;
return;
}
}
const { parsedFlags, unparsedFlags } = IRC.Helpers.parseWhoFlags(params[7], handler.network.options);
// Some ircd's use n/a for no level, use undefined to represent no level
const op_level = /^[0-9]+$/.test(params[10]) ? parseInt(params[10], 10) : undefined;
// If changing the number of whox fields make sure to update params.length in the token validator above
cache.members.push({
nick: params[6],
ident: params[3],
hostname: params[4],
server: params[5],
op_level: op_level,
real_name: params[11],
account: params[9] === '0' ? '' : params[9],
num_hops_away: parseInt(params[8], 10),
channel: params[2],
tags: command.tags,
unparsed_flags: unparsedFlags,
...parsedFlags,
});
// Raw event is handled, return so not to trigger next()
return;
}
next();
}
function parsedMiddleware(command, event, client, next) {
if (debugEvents) {
console.info('[--]', command, event);
}
next();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment