Compare commits

...

3 Commits

  1. 2
      .gitignore
  2. 26
      bot.js
  3. 3915
      package-lock.json
  4. 42
      package.json
  5. 6
      src/api/index.js
  6. 0
      src/bot/runtime/commands/bot/commands.js.test
  7. 1
      src/bot/runtime/commands/bot/ping.js
  8. 16
      src/bot/runtime/events/messageCreate.js
  9. 4
      src/bot/runtime/events/ready.js
  10. 2
      src/bot/startup/collect/commands.js
  11. 2
      src/bot/startup/collect/events.js
  12. 0
      src/bot/startup/run/collect.js
  13. 2
      src/bot/startup/run/getflags.js
  14. 0
      src/bot/startup/run/hello.js
  15. 0
      src/bot/startup/run/login.js
  16. 0
      src/bot/startup/run/setstatus.js
  17. 2
      src/db/connect.js
  18. 20
      src/json/randresp.json
  19. 11
      src/util/log/errorhandler.js
  20. 13
      src/util/misc/nodehandlers.js

2
.gitignore vendored

@ -1,5 +1,5 @@
node_modules/ node_modules/
auth.json src/json/auth.json
test.js test.js
/.idea/ /.idea/

@ -1,10 +1,6 @@
const Discord = require('discord.js'); const Discord = require('discord.js');
const auth = require('./src/json/auth.json');
const config = require('./src/json/config.json');
const randresp = require('./src/json/randresp.json');
const errorhandler = require('./src/util/log/errorhandler'); const errorhandler = require('./src/util/log/errorhandler');
const log = require('./src/util/log/log'); const log = require('./src/util/log/log');
const flags = Discord.GatewayIntentBits; const flags = Discord.GatewayIntentBits;
@ -12,26 +8,32 @@ const partials = Discord.Partials;
let fl = []; Object.keys(flags).forEach(flag => fl.push(flags[flag])); // fuck new standards i'm in't'zing with all the flags. let fl = []; Object.keys(flags).forEach(flag => fl.push(flags[flag])); // fuck new standards i'm in't'zing with all the flags.
const client = new Discord.Client({intents: fl, partials: [partials.Channel, partials.Message, partials.Reaction]}); const client = new Discord.Client({intents: fl, partials: [partials.Channel, partials.Message, partials.Reaction]});
// a "fuck v14" counter is gonna be here real soon i can feel it. // a "fuck v14" counter is gonna be here real soon i can feel it.
//fuck new embeds
const startBot = async () => { const startBot = async () => {
client.config = config;
client.auth = auth; client.config = require('./src/json/config.json');
client.config.randResp = randresp; client.auth = require('./src/json/auth.json');
client.config.randResp = require('./src/json/randresp.json');
require('./src/util/misc/setutils')(client); // add some basic swiss army knife utils require('./src/util/misc/setutils')(client); // add some basic swiss army knife utils
const loggers = log(client); const loggers = log(client);
Object.keys(loggers).forEach(logger => client[logger] = loggers[logger]); Object.keys(loggers).forEach(logger => client[logger] = loggers[logger]);
client.log(client.utils.gr(client.config.randResp.clistart), {color: "#78d9f8", source: "NATS"}, true, true); //natsuki's wakeup log client.log(client.utils.gr(client.config.randResp.clistart), {color: "#78d9f8", source: client.config.bot.consoleName}, true, true); //natsuki's wakeup log
require('./src/handle/startup/run/getflags')(client); require('./src/bot/startup/run/getflags')(client);
await require('./src/db/connect')(client); //connect to database await require('./src/db/connect')(client); //connect to database
await require('./src/handle/startup/run/collect')(client); //load in commands and events await require('./src/bot/startup/run/collect')(client); //load in commands and events
await require('./src/handle/startup/run/login')(client); //log in to discord await require('./src/bot/startup/run/login')(client); //log in to discord
require('./src/util/misc/nodehandlers')(client); //bot uncaught promises, warnings, event loop shenanigans
}; };
startBot().catch(e => errorhandler(e)); // TODO add a .catch() and flag to recover the process startBot().catch(e => errorhandler(client, e)); // TODO add a .catch() and flag to recover the process
// feels like there isn't a function name to do this justice :joy: // feels like there isn't a function name to do this justice :joy:
// to do list: // to do list:

3915
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -4,26 +4,6 @@
"description": "An anime-themed multipurpose bot", "description": "An anime-themed multipurpose bot",
"main": "bot.js", "main": "bot.js",
"author": "Wubzy", "author": "Wubzy",
"dependencies": {
"@discordjs/rest": "^1.3.0",
"canvas": "^2.9.0",
"chalk": "^4.1.0",
"cron": "^1.8.2",
"discord-api-types": "^0.22.0",
"discord.js": "^14.6.0",
"dreidels": "^0.5.2",
"express": "^4.18.2",
"fuzzysort": "^1.1.4",
"gradient-string": "^2.0.0",
"lastfm": "^0.9.0",
"moment": "^2.28.0",
"moment-precise-range-plugin": "^1.3.0",
"mongoose": "^5.10.3",
"node-fetch": "^2.6.1",
"ora": "^5.3.0",
"tinygradient": "^1.1.5",
"ws": "^7.4.6"
},
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"
}, },
@ -36,5 +16,27 @@
"presync": "git pull origin", "presync": "git pull origin",
"sync": "git push origin", "sync": "git push origin",
"postsync": "git push wubzy" "postsync": "git push wubzy"
},
"dependencies": {
"@discordjs/rest": "^2.4.3",
"canvas": "^3.1.0",
"chalk": "^4.1.0",
"discord-api-types": "^0.37.119",
"discord.js": "^14.18.0",
"dreidels": "^0.6.1",
"express": "^4.21.2",
"fuzzysort": "^3.1.0",
"gradient-string": "^2.0.2",
"lastfm": "^0.9.4",
"moment": "^2.30.1",
"moment-precise-range-plugin": "^1.3.0",
"mongoose": "^8.10.0",
"node-fetch": "^3.3.2",
"ora": "^5.3.0",
"tinygradient": "^2.0.0",
"ws": "^8.18.0"
},
"devDependencies": {
"typescript": "^5.7.3"
} }
} }

@ -1,13 +1,17 @@
const express = require('express'); const express = require('express');
const chalk = require('chalk');
module.exports = (client) => { module.exports = (client) => {
return new Promise(r => {
const api = express(); const api = express();
client.api = {wubzy: {}, natsuki: {}}; client.api = {wubzy: {}, natsuki: {}};
client.api.log = (message, type, prenl, postnl) => client.log(message, {source: 'API', sourceColor: '#1F2B56', suffix: `${type ? chalk.gray(` [${type.toUpperCase()}]`) : ''} >> `}, prenl, postnl);
client.api.wubzy.app = api; client.api.wubzy.app = api;
client.api.wubzy.app.get('/', (req, res) => res.send("You've reached the wubzy.xyz API. If you're looking for Natsuki's endpoints, please append /natsuki to your query.")); client.api.wubzy.app.get('/', (req, res) => res.send("You've reached the wubzy.xyz API. If you're looking for Natsuki's endpoints, please append /natsuki to your query."));
client.api.wubzy.app.get('/natsuki', (req, res) => res.send("You've reached Natsuki's status endpoint. Receiving this 200 reply indicates that Natsuki is online. If you're looking for the Natsuki API, it has been moved to natsuki.app")); client.api.wubzy.app.get('/natsuki', (req, res) => res.send("You've reached Natsuki's status endpoint. Receiving this 200 reply indicates that Natsuki is online. If you're looking for the Natsuki API, it has been moved to natsuki.app"));
client.api.wubzy.app.get('/natsuki/:any?', (req, res) => res.status(301).send("Natsuki's API permanently resides at natsuki.app")); client.api.wubzy.app.get('/natsuki/:any?', (req, res) => res.status(301).send("Natsuki's API permanently resides at natsuki.app"));
client.api.wubzy.server = client.api.wubzy.app.listen(4072, () => console.log(`Ready at ${client.api.wubzy.server.address().address}:${client.api.wubzy.server.address().port}`)); client.api.wubzy.server = client.api.wubzy.app.listen(4072, () => {client.api.log(`API ready at ${client.api.wubzy.server.address().address.replace('::', 'localhost')}:${client.api.wubzy.server.address().port}`, 'boot', false, true); r();});
});
}; };

@ -1,6 +1,7 @@
module.exports = { module.exports = {
name: "ping", name: "ping",
aliases: ["p"], aliases: ["p"],
syntax: '`ping`',
async run(client, message, args, cmd) { async run(client, message, args, cmd) {
message.reply("Pong! This is Natsuki v2 you're speaking with \\*tips hat*"); message.reply("Pong! This is Natsuki v2 you're speaking with \\*tips hat*");
} }

@ -1,9 +1,19 @@
const chalk = require('chalk'); const chalk = require('chalk');
const {Embed, EmbedBuilder} = require('discord.js');
module.exports = async (client, message) => { module.exports = async (client, message) => {
if (!message.content || !message.content.length) {return;} //privileged intent fallback if (!message.content || !message.content.length) {return;} //privileged intent fallback //TODO edit for privileged intent
if ([`<@${client.user.id}>`, `<@!${client.user.id}>`].includes(message.content.trim())) {} //TODO insert ping hello let prefix = client.basePrefix; //TODO prefixes
if ([`<@${client.user.id}>`, `<@!${client.user.id}>`].includes(message.content.trim())) { //Ping hello
message.channel.send({embeds: [new EmbedBuilder()
.setTitle(client.utils.gr(client.config.randResp.pinghello))
.setDescription(`You've reached ${client.config.options.dev ? "a developer (beta) instance of" : ''} Natsuki! My prefix here is \`${prefix}\`, and you can use the \`help\` command to get started.`)
.setColor('c375f0')
.setFooter({text: "Natsuki", iconURL: client.user.avatarURL()})
]});
}
let cmd = {}; let cmd = {};
cmd.msg = message.content.toLowerCase().trim(); //i believe in shitty naming conventions :D cmd.msg = message.content.toLowerCase().trim(); //i believe in shitty naming conventions :D

@ -1,8 +1,10 @@
module.exports = async client => { module.exports = async client => {
client.basePrefix = client.config.options.dev ? client.config.options.prefix || client.config.bot.devPrefix : client.config.bot.prefix; client.basePrefix = client.config.options.dev ? client.config.options.prefix || client.config.bot.devPrefix : client.config.bot.prefix;
await require('../../../api/index')(client);
require('../../startup/run/hello')(client); // startup info require('../../startup/run/hello')(client); // startup info
require('../../startup/run/setstatus')(client); require('../../startup/run/setstatus')(client);
require('../../../api/index')(client); client.log(client.utils.gr(client.config.randResp.cliloaded), {color: "#78d9f8", source: client.config.bot.consoleName}, true, true); //natsuki doing some more complaining
}; };

@ -2,7 +2,7 @@ const fs = require('fs');
const chalk = require('chalk'); const chalk = require('chalk');
const {Collection} = require('discord.js'); const {Collection} = require('discord.js');
const commandsDirName = './src/handle/runtime/commands'; const commandsDirName = './src/bot/runtime/commands';
module.exports = async client => { module.exports = async client => {
client.aliases = new Collection(); client.aliases = new Collection();

@ -2,7 +2,7 @@ const fs = require('fs');
const chalk = require('chalk'); const chalk = require('chalk');
const {Collection} = require('discord.js'); const {Collection} = require('discord.js');
const eventsDirName = './src/handle/runtime/events'; const eventsDirName = './src/bot/runtime/events';
module.exports = async client => { module.exports = async client => {
client.aliases = new Collection(); client.aliases = new Collection();

@ -5,7 +5,7 @@ const {Tag, TagFilter} = require('../../../util/ts/tagfilter');
module.exports = client => { module.exports = client => {
const options = new TagFilter([ const options = new TagFilter([
new Tag(['dev', 'd', 'developer', 'test'], 'dev', 'toggle'), new Tag(['dev', 'd', 'developer', 'test'], 'dev', 'toggle'),
new Tag(['prefix', 'devprefix'], 'prefix', 'append') new Tag(['prefix', 'devprefix', 'p'], 'prefix', 'append')
]).test(process.argv.slice(2).join(" ")); ]).test(process.argv.slice(2).join(" "));
client.config.options = {}; client.config.options = {};

@ -10,7 +10,7 @@ module.exports = async client => {
client.misc.dbconnected = true; client.misc.dbconnected = true;
await ora(chalk.blueBright.bold.underline("Connecting to MongoDB..."), await ora(chalk.blueBright.bold.underline("Connecting to MongoDB..."),
mongoose.connect(`mongodb+srv://${auth.database.user}:${auth.database.password}@${auth.database.cluster}.3jpp4.mongodb.net/test`, { mongoose.connect(`mongodb+srv://${auth.database.user}:${auth.database.password}@${auth.database.cluster}.3jpp4.mongodb.net/test`, {
useFindAndModify: false, useNewUrlParser: true, dbName: auth.database.name, useUnifiedTopology: true, useCreateIndex: true dbName: auth.database.name //TODO research mongo connect options
}) })
).catch((e) => { ).catch((e) => {
client.error("Failed to connect to mongoose!! Error below.", 0, 0, true, e); client.error("Failed to connect to mongoose!! Error below.", 0, 0, true, e);

@ -7,5 +7,25 @@
"I think Natsuki mentioned something about wanting to rest... I'm guessing that won't be happening?", "I think Natsuki mentioned something about wanting to rest... I'm guessing that won't be happening?",
"*in robotic voice* starting up. booting now. am i convincing yet?", "*in robotic voice* starting up. booting now. am i convincing yet?",
"Sure sure I'd love to be bothered by Discord users all day. It's not like I had anything else to do, really." "Sure sure I'd love to be bothered by Discord users all day. It's not like I had anything else to do, really."
],
"cliloaded": [
"*rubs tired eyes* Natsuki reporting for duty... or whatever.",
"You interrupted a good dream for this?",
"Can I go back to cuddling with Tamaki yet?",
"I take a nappy nap.",
"Sure I'll serve users... doesn't mean they'll like me when I do.",
"When I agreed to this I was not under the impression it would be so damn demanding!",
"Again with your beckoning call, Wubzy."
],
"pinghello": [
"You rang?", " That's me, teehee", "\"At your service, milord,\" she says in a posh accent",
"Reporting for duty! Wait this isn't my rp", "That is the name ^^", "Natsuki Tivastl, to be exact.",
"That's me! What's up?", "I'm not interested in my car's extended warranty, thanks.",
"Quick, take the neko formula, I don't have much time. They're coming.",
"You were looking for Natsuki? Oof. Bad choice", "Useless Natsuki here! Or um... best bot Natsuki...",
"PING PONG! Bots can't mute their Discords - be nice.", "*slurp* can I help you?",
"*slurp* little busy here but what's up?", "Yep, that's me!", "^^ Hiya!", "Oh, hi there!",
"Sure, what's up?", "How can I help!", "Natsuki is busy, but I can take a message for you!",
"You were looking for Natsuki Tivastl, right?", "Sure! What's up?", "Pong!"
] ]
} }

@ -1,8 +1,11 @@
const chalk = require('chalk'); const chalk = require('chalk');
module.exports = e => { module.exports = (client, e, p) => {
console.log(`#######################################\n\n${chalk.grey('[NATS]')} >> ${chalk.hex('#78d9f8')("Well this is awkward.")}\n`); console.log(`#######################################\n\n[${chalk.grey(client.config.bot.consoleName)}] >> ${chalk.hex('#78d9f8')("Well this is awkward.")}\n`);
console.log(`${chalk.bold.redBright.underline("There was an error that killed Natsuki's process.")}\n${chalk.redBright("See available stack trace and error information below.")}\n`); console.log(`${chalk.bold.redBright.underline(`There was an error that killed ${client.utils.ps(client.config.bot.name)} process.`)}\n${chalk.redBright("See available stack trace and error information below.")}\n`);
if (p) {
client.log("This exception originates from an unhandled, uncaught promise rejection. Ya doofus.", 0, 0, 1);
}
console.error(e); console.error(e);
console.log(`\n#######################################\n\n${chalk.grey('[NATS]')} >> ${chalk.hex('#78d9f8')("Back to sleepies...")}`); console.log(`\n#######################################`);
}; };

@ -0,0 +1,13 @@
const errorhandler = require("../log/errorhandler");
const chalk = require('chalk');
module.exports = client => {
process.on('unhandledRejection', (e, p) => { //nested promise rejections like to be icky so this should catch them all
errorhandler(client, e, p);
return process.exit(1); //i guess this handler does keep the event loop running but i'll adopt a zero-tolerance policy for unhandled rejections
}); // gotta catch 'em all
process.on('exit', code => {
client.log("Back to sleepies...", {color: "#78d9f8", source: client.config.bot.consoleName}, true);
return console.log(chalk.grey(`Exit code ${chalk.white(code)}`));
});
};
Loading…
Cancel
Save