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
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 |
|
); |
|
});
|
|
|