You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

264 lines
6.7 KiB

import { Client } from 'irc-framework';
import schedule from 'node-schedule';
import { Pushover } from '@hyperlink/pushover';
import Joi from 'joi';
import dotenv from 'dotenv';
dotenv.config();
const { APP_TOKEN, USER_TOKEN, HOST, PORT, NICK, CHANNEL, BAE, NOTICE_MSG } =
process.env;
const envVars = {
APP_TOKEN,
USER_TOKEN,
HOST,
PORT,
NICK,
CHANNEL,
BAE,
NOTICE_MSG,
};
const environmentVariableValidation = (data) => {
const schmea = Joi.object({
APP_TOKEN: Joi.string().required(),
USER_TOKEN: Joi.string().required(),
HOST: Joi.string().required(),
PORT: Joi.number().integer().required(),
NICK: Joi.string().required(),
CHANNEL: Joi.string().required(),
BAE: Joi.string().required(),
NOTICE_MSG: Joi.string().required(),
});
return schmea.validate(data);
};
const validationErrorCheck = (error) => {
try {
if (error) throw error?.details[0]?.message;
} catch (error) {
// logger({ type: 'error', msg: error });
console.error(error);
process.exit(0);
}
};
const { error } = environmentVariableValidation({
...envVars,
});
validationErrorCheck(error);
const CONFIG = {
CLIENT: {
host: HOST,
port: PORT,
nick: NICK,
username: NICK,
},
CHANNEL_NAME: CHANNEL,
BAE: BAE,
NOTICE_MSG: NOTICE_MSG,
};
async function sendMessage(title, msg) {
console.log('sending msg!');
const pushover = new Pushover(APP_TOKEN, USER_TOKEN);
const msgRes = await pushover.sendMessage({
message: msg,
title: title,
});
if (msgRes?.status === 1)
return console.log(`msg req (${msgRes?.request}) sent successfully`);
return console.log('msg req failed');
}
const delay = (sec) =>
new Promise((resolve) => setTimeout(resolve, sec * 1000));
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min);
}
// eg..
// let userList = [
// {
// userNick: 'blenderpls',
// canSpeakTo: true,
// gmbCount: 0,
// msgCount: 0,
// },
// ]
let userList = [];
const bot = new Client();
bot.connect({
...CONFIG.CLIENT,
});
const buffers = [];
bot.on('registered', () => {
const channel = bot.channel(CONFIG.CHANNEL_NAME);
buffers.push(channel);
channel.join();
bot.action(CONFIG.CHANNEL_NAME, CONFIG.NOTICE_MSG);
channel.updateUsers(() => {
// smash all the existing users into the userlist straight away
channel.users.map(
(user) =>
(userList = [
...userList,
{ userNick: user.nick, canSpeakTo: true, gmbCount: 0, msgCount: 0 },
])
);
});
});
const roboCompliments = [
'Are those real or were you upgraded in silicone valley?',
'Are you made of Copper and Tellurium? Because you are Cu-Te',
'Beep Beep Boop Beep Sex',
'Can I have your ip number? I seem to have lost mine.',
`Come with me and I'll insert my floppy into your disk drive.`,
'Commencing explosive containment procedures, why? Because you are the bomb.',
'Do you got a free port for me to plug into?',
'Do you like it when I touch your PCI Slot?',
`Don't worry I just got turing tested.`,
'Hey baby, I am backward compatible, to service all your legacy needs.',
];
// extend array with some sample fnc
Array.prototype.sample = function () {
return this[Math.floor(Math.random() * this.length)];
};
// every minute do smth
// schedule.scheduleJob('*/1 * * * *', () => {});
// at midnight do smth
schedule.scheduleJob('0 0 * * *', () => {
console.log('resetting GMBs!');
userList = userList.map((user) =>
user.gmbCount > 0 ? { ...user, gmbCount: 0 } : user
);
});
// do smth once a week
schedule.scheduleJob('0 0 * * 0', () => {
// basically at the start of the week kick off a randomly scheduled job to give gmbbot a compliment
const roboLove = async () => {
console.log('executing robo love protocols');
// sometime after 4hrs but before 6 days
const randoNumber = getRandomIntInclusive(14400, 518400);
await delay(randoNumber);
bot.channel(CONFIG.CHANNEL_NAME).updateUsers(() => {
const channel = bot.channel(CONFIG.CHANNEL_NAME);
channel.updateUsers(() => {
const baeCheck = channel.users.find((user) => user.nick === CONFIG.BAE);
if (!baeCheck) return console.log(`can't find ${CONFIG.BAE} :(`);
bot.say(
CONFIG.CHANNEL_NAME,
`${CONFIG.BAE}, ${roboCompliments.sample()}`
);
});
});
};
roboLove();
});
schedule.scheduleJob('30 10 * * *', () => {
// check if our bae exist n if not say a sad msg
const checkForbae = async () => {
console.log(`checking for ${CONFIG.BAE}`);
bot.channel(CONFIG.CHANNEL_NAME).updateUsers(() => {
const channel = bot.channel(CONFIG.CHANNEL_NAME);
channel.updateUsers(() => {
const baeCheck = channel.users.find((user) => user.nick === CONFIG.BAE);
if (baeCheck) return console.log(`found ${CONFIG.BAE}, yay!`);
bot.say(CONFIG.CHANNEL_NAME, `😢`);
});
});
};
checkForbae();
});
bot.on('message', (event) => {
// get some msg infos
const msg = event.message.toLowerCase();
const fromNick = event.nick.toLowerCase();
// log the server msgs
if (fromNick === '') console.log(fromNick, msg);
// find user infos
let user;
user = userList?.find(({ userNick }) => userNick === fromNick);
if (!user) {
user = { userNick: fromNick, canSpeakTo: true, gmbCount: 0, msgCount: 0 };
userList = [...userList, user];
}
// msgs that expect the bang at the beginning and don't care what follows
if (msg.indexOf('!robocompliment') === 0)
event.reply(`${roboCompliments.sample()}`);
if (msg.indexOf('!alert') === 0)
sendMessage(`msg from ${fromNick}`, event.message);
if (msg.indexOf('!msgcount') === 0)
event.reply(
`${user.userNick} has sent ${user.msgCount} ${
user.msgCount === 1 ? 'msg' : 'msgs'
}`
);
if (msg.indexOf('!gmbcount') === 0)
event.reply(`${user.userNick} has sent ${user.gmbCount} gmbs today`);
if (msg.indexOf('!resetgmbs') === 0) {
userList = userList.map((user) =>
user.gmbCount > 0 ? { ...user, gmbCount: 0 } : user
);
event.reply('gmbs have been reset');
}
if (msg.indexOf('!cmds') === 0) {
event.reply('!alert, !gmbcount, !msgcount, !resetgmbs');
}
if (msg.includes('gmb')) {
if (user.gmbCount === 0) event.reply(`👋`);
userList = userList.map((obj) =>
obj.userNick === fromNick ? { ...obj, gmbCount: obj.gmbCount + 1 } : obj
);
}
// msgs that only care about matching exactly the string
// msgs that just find a word!
if (msg.includes('blender'))
sendMessage(`msg from ${fromNick}`, event.message);
// bump that msg count
userList = userList.map((obj) =>
obj.userNick === fromNick ? { ...obj, msgCount: obj.msgCount + 1 } : obj
);
});