Created
December 11, 2022 15:03
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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