Reference Source

rx-irc/bot-fun/lib/module.js

// NPM Dependencies
const { filter } = require('rxjs/operators');
const { spawn } = require('child_process');

// Local Depdendencies
const logger = require('./logger');
const { version } = require('../package.json');

let defaults = {};

module.exports = class FunModule {
	/**
	 * @param {ClientWrapper} client
	 * @param {object} options
	 */
	constructor(client, options) {
		/** @type {object} */
		this.settings = { ...defaults, ...options };
		/** @type {string} */
		this.version = version;

		//  ____  _
		// / ___|| |_ _ __ ___  __ _ _ __ ___  ___
		// \___ \| __| '__/ _ \/ _` | '_ ` _ \/ __|
		//  ___) | |_| | |  __/ (_| | | | | | \__ \
		// |____/ \__|_|  \___|\__,_|_| |_| |_|___/
		//

		let privmsg$ = client.raw$.pipe(
			filter(message => message.command === 'PRIVMSG')
		);

		let figlet$ = privmsg$.pipe(
			filter(message => message.args[1].startsWith('!figlet'))
		);

		let cowsay$ = privmsg$.pipe(
			filter(message => message.args[1].startsWith('!cowsay'))
		);

		let fortune$ = privmsg$.pipe(
			filter(message => message.args[1] === '!fortune')
		);

		let fortunesay$ = privmsg$.pipe(
			filter(message => message.args[1] === '!fortunesay')
		);

		let roll$ = privmsg$.pipe(
			filter(message => message.args[1].startsWith('!roll'))
		);

		//  ____        _                   _       _   _
		// / ___| _   _| |__  ___  ___ _ __(_)_ __ | |_(_) ___  _ __  ___
		// \___ \| | | | '_ \/ __|/ __| '__| | '_ \| __| |/ _ \| '_ \/ __|
		//  ___) | |_| | |_) \__ \ (__| |  | | |_) | |_| | (_) | | | \__ \
		// |____/ \__,_|_.__/|___/\___|_|  |_| .__/ \__|_|\___/|_| |_|___/
		//                                   |_|
		//

		figlet$.subscribe(message => {
			let nick = message.args[0];
			let text = message.args[1].substring(8).trim();

			if (text.length === 0) {
				client.tell(nick, 'No text provided.');
			} else {
				let params = [];

				if (/\[[\w\d-]+\] .+/i.test(text)) {
					let [, file, text_trimmed] = text.match(/\[([\w\d-]+)\] (.+)/i);

					params.push(`-f${file}`);
					params.push(text_trimmed);
				} else {
					params.push(text);
				}

				logger.info('FIGLET ' + params.join(' '));

				let figlet = spawn('figlet', params);

				figlet.stderr.on('data', data => client.tell(nick, data, ' '));
				figlet.stdout.on('data', data => client.tell(nick, data, ' '));
			}
		});

		cowsay$.subscribe(message => {
			let nick = message.args[0];
			let text = message.args[1].substring(8).trim();

			if (text.length === 0) {
				client.tell(nick, 'No text provided.');
			} else {
				let params = [];

				if (/\[[a-z_-]+\] .+/i.test(text)) {
					let [, file, text_trimmed] = text.match(/\[([a-z_-]+)\] (.+)/i);

					params.push(`-f${file}`);
					params.push(text_trimmed);
				} else {
					params.push(text);
				}

				logger.info('COWSAY ' + params.join(' '));

				let cowsay = spawn('cowsay', params);

				cowsay.stderr.on('data', data => client.tell(nick, data, ' '));
				cowsay.stdout.on('data', data => client.tell(nick, data, ' '));
			}
		});

		fortune$.subscribe(message => {
			logger.info('FORTUNE');

			let nick = message.args[0];

			let fortune = spawn('fortune');

			fortune.stderr.on('data', data => client.tell(nick, data, ' '));
			fortune.stdout.on('data', data => client.tell(nick, data, ' '));
		});

		fortunesay$.subscribe(message => {
			logger.info('FORTUNESAY');

			let nick = message.args[0];

			let fortune = spawn('fortune');
			let cowsay = spawn('cowsay');

			fortune.stdout.on('data', data => {
				cowsay.stdin.write(data);
			});

			fortune.stderr.on('data', data => client.tell(nick, data, ' '));

			fortune.on('close', (code) => {
				if (code !== 0) {
					logger.error(`FORTUNESAY fortune exited with code ${code}`);
				}
				cowsay.stdin.end();
			});

			cowsay.stdout.on('data', data => client.tell(nick, data, ' '));
			cowsay.stderr.on('data', data => client.tell(nick, data, ' '));

			cowsay.on('close', (code) => {
				if (code !== 0) {
					logger.error(`FORTUNESAY cowsay exited with code ${code}`);
				}
			});
		});

		roll$.subscribe(message => {
			let nick = message.args[0];
			let dices = Number(message.args[1].substring(6).trim()) || 2;

			let rolls = Array.from({ length: dices })
				.map(() => Math.ceil(Math.random() * 6))
				.map(number => `[${number}]`)
				.join(' ');

			logger.info(`ROLL ${rolls}`);

			client.tell(nick, rolls);
		});
	}
};