2023-01-18 00:35:24 +00:00
/* eslint-disable no-case-declarations */
/* eslint-disable indent */
// dotenv for handling environment variables
const dotenv = require ( 'dotenv' ) ;
dotenv . config ( ) ;
const token = process . env . TOKEN ;
2023-02-20 01:42:14 +00:00
const statusChannelId = process . env . STATUSCHANNELID ;
2023-08-11 02:13:08 +00:00
const heartbeatUrl = process . env . HEARTBEAT _URL ;
const sendHeartbeat = typeof heartbeatUrl === 'string' ;
2023-01-18 00:35:24 +00:00
// Discord.JS
2023-01-24 01:50:14 +00:00
const { Client , GatewayIntentBits , Partials , ActivityType } = require ( 'discord.js' ) ;
2023-01-18 00:35:24 +00:00
const client = new Client ( {
intents : [
GatewayIntentBits . Guilds ,
GatewayIntentBits . GuildMessages ,
GatewayIntentBits . GuildMessageReactions ,
2023-01-18 01:27:04 +00:00
GatewayIntentBits . MessageContent
2023-01-18 00:35:24 +00:00
] ,
partials : [
Partials . Channel ,
2023-01-18 01:27:04 +00:00
Partials . Message
2023-01-18 00:35:24 +00:00
] ,
} ) ;
// Various imports
2023-01-19 17:44:49 +00:00
const fn = require ( './modules/functions.js' ) ;
const strings = require ( './data/strings.json' ) ;
2023-02-01 03:51:10 +00:00
const dbfn = require ( './modules/dbfn.js' ) ;
2023-06-17 00:01:29 +00:00
const { GuildInfo } = require ( './modules/CustomClasses.js' ) ;
2023-08-28 00:27:11 +00:00
const isDev = process . env . DEBUG === "true" ;
2023-06-08 21:51:41 +00:00
let statusChannel ;
2023-01-18 00:35:24 +00:00
2023-02-20 01:42:14 +00:00
client . once ( 'ready' , async ( ) => {
2023-02-20 19:07:38 +00:00
fn . collectionBuilders . slashCommands ( client ) ;
2023-05-16 17:24:42 +00:00
fn . collectionBuilders . dotCommands ( client ) ;
fn . collectionBuilders . setvalidCommands ( client ) ;
2023-02-20 01:42:14 +00:00
await fn . collectionBuilders . guildInfos ( client ) ;
2023-02-20 19:07:38 +00:00
await fn . collectionBuilders . messageCollectors ( client ) ;
2023-06-03 20:14:00 +00:00
const serverCount = client . guilds . cache . size ;
2023-02-26 17:09:04 +00:00
// checkRateLimits();
2023-01-18 00:35:24 +00:00
console . log ( 'Ready!' ) ;
2023-06-03 20:14:00 +00:00
client . user . setActivity ( { name : ` ${ serverCount } trees grow. ` , type : ActivityType . Watching } ) ;
2023-06-08 21:51:41 +00:00
statusChannel = await client . channels . fetch ( statusChannelId ) ;
2023-02-01 03:51:10 +00:00
if ( isDev == 'false' ) {
2023-06-08 21:51:41 +00:00
statusChannel . send ( ` ${ new Date ( ) . toISOString ( ) } -- \n Startup Sequence Complete <@481933290912350209> ` ) ;
2023-02-01 03:51:10 +00:00
}
2023-08-11 02:13:08 +00:00
// Heartbeat Timer
if ( sendHeartbeat ) {
setInterval ( ( ) => {
fn . sendHeartbeat ( heartbeatUrl ) ;
} , 30000 ) ;
if ( isDev ) console . log ( "Heartbeat interval set." ) ;
2023-08-27 23:34:15 +00:00
} else {
if ( isDev ) console . log ( "No heartbeat URL set, will not send heartbeats for uptime monitoring." ) ;
2023-08-11 02:13:08 +00:00
}
2023-01-18 00:35:24 +00:00
} ) ;
// slash-commands
client . on ( 'interactionCreate' , async interaction => {
2023-07-06 23:04:13 +00:00
try {
if ( interaction . isCommand ( ) ) {
if ( isDev ) {
// console.log(interaction);
}
const { commandName } = interaction ;
if ( client . slashCommands . has ( commandName ) ) {
client . slashCommands . get ( commandName ) . execute ( interaction ) ;
} else {
2023-09-02 23:33:32 +00:00
interaction . reply ( 'Sorry, I don\'t have access to that command.' ) . catch ( e => console . err ( e ) ) ;
2023-07-06 23:04:13 +00:00
console . error ( 'Slash command attempted to run but not found: ' + commandName ) ;
}
2023-02-20 01:42:14 +00:00
}
2023-07-06 23:04:13 +00:00
if ( interaction . isButton ( ) ) {
switch ( interaction . component . customId ) {
case 'refresh' :
// console.log(JSON.stringify(interaction));
await fn . refresh ( interaction ) . catch ( err => {
2023-09-02 23:33:32 +00:00
interaction . channel . send ( fn . builders . errorEmbed ( "Oops! Something went wrong!" ) ) . catch ( e => console . err ( e ) ) ;
2023-02-20 01:42:14 +00:00
} ) ;
2023-07-06 23:04:13 +00:00
break ;
case 'deleteping' :
if ( interaction . message . deletable ) {
await interaction . message . delete ( ) . catch ( err => {
// console.error(err);
} ) ;
}
break ;
case 'waterpingrole' :
const waterPingStatus = await fn . buttonHandlers . waterPing ( interaction ) ;
await interaction . reply ( waterPingStatus ) . catch ( e => console . error ( e ) ) ;
break ;
case 'fruitpingrole' :
const fruitPingStatus = await fn . buttonHandlers . fruitPing ( interaction ) ;
await interaction . reply ( fruitPingStatus ) . catch ( e => console . error ( e ) ) ;
break ;
default :
break ;
}
}
} catch ( err ) {
if ( err === "Guild doesn't exist in database!" ) {
2023-09-02 23:33:32 +00:00
interaction . channel . send ( fn . builders . errorEmbed ( strings . error . noGuild ) ) . catch ( e => console . err ( e ) ) ;
2023-07-06 23:04:13 +00:00
console . error ( err ) ;
} else {
2023-09-02 23:33:32 +00:00
interaction . channel . send ( "Oops! An error occurred... Sorry about that, please contact my owner @vfsh if this keeps happening." ) . catch ( e => console . err ( e ) ) ;
2023-07-06 23:04:13 +00:00
console . error ( err ) ;
2023-02-01 03:51:10 +00:00
}
2023-01-18 00:35:24 +00:00
}
2023-07-06 23:04:13 +00:00
2023-01-18 00:35:24 +00:00
} ) ;
2023-03-11 20:12:34 +00:00
client . on ( 'messageUpdate' , async ( oldMessage , message ) => {
2023-06-03 18:42:44 +00:00
await fn . messages . updateHandler ( message ) . catch ( async e => {
switch ( e ) {
case strings . error . noCompareMessage :
2023-09-02 23:33:32 +00:00
await message . channel . send ( strings . error . noCompareMessage ) . catch ( e => console . err ( e ) ) ;
2023-06-03 18:42:44 +00:00
break ;
default :
break ;
}
} ) ;
2023-03-11 20:12:34 +00:00
} ) ;
client . on ( 'messageCreate' , async message => {
await fn . messages . updateHandler ( message ) . catch ( e => console . error ( e ) ) ;
2023-05-16 17:24:42 +00:00
// Dot Command Handling
// Some basic checking to prevent running unnecessary code
if ( message . author . bot ) return ;
// Break the message down into its components and analyze it
const commandData = fn . dotCommands . getCommandData ( message ) ;
2023-06-03 18:58:42 +00:00
// if (isDev) console.log(commandData);
2023-05-16 17:24:42 +00:00
2023-06-03 19:40:12 +00:00
if ( commandData . isValid && commandData . isCommand ) {
2023-05-16 17:24:42 +00:00
try {
client . dotCommands . get ( commandData . command ) . execute ( message , commandData ) ;
}
catch ( error ) {
console . error ( error ) ;
message . reply ( 'There was an error trying to execute that command.' ) ;
}
}
return ;
2023-03-11 02:16:32 +00:00
} ) ;
2023-06-08 21:51:41 +00:00
client . on ( 'guildCreate' , async guild => {
2023-06-10 19:09:45 +00:00
const serverCount = client . guilds . cache . size ;
client . user . setActivity ( { name : ` ${ serverCount } trees grow. ` , type : ActivityType . Watching } ) ;
2023-06-08 21:51:41 +00:00
await statusChannel . send ( ` I've been added to a new guild: ${ guild . name } ( ${ guild . id } ) ` ) ;
2023-06-17 00:01:29 +00:00
const guildInfo = new GuildInfo ( )
. setIds ( guild . id , guild . ownerId ) ;
const setBasicQuery = guildInfo . queryBuilder ( "setBasic" ) ;
await dbfn . setGuildInfo ( setBasicQuery ) . catch ( e => console . error ( e ) ) ;
2023-06-08 21:51:41 +00:00
} ) ;
2023-06-10 19:09:45 +00:00
client . on ( 'guildDelete' , async guild => {
const serverCount = client . guilds . cache . size ;
client . user . setActivity ( { name : ` ${ serverCount } trees grow. ` , type : ActivityType . Watching } ) ;
await statusChannel . send ( ` I've been removed from a guild: ${ guild . name } ( ${ guild . id } ) ` ) ;
2023-06-17 00:01:29 +00:00
if ( client . guildInfos . has ( guild . id ) ) {
let guildInfo = client . guildInfos . get ( guild . id ) ;
guildInfo . setReminders ( undefined , undefined , undefined , undefined , false ) ;
const setRemindersQuery = guildInfo . queryBuilder ( "setReminders" ) ;
await dbfn . setGuildInfo ( setRemindersQuery ) ;
}
2023-06-10 19:09:45 +00:00
} ) ;
2023-02-21 23:41:47 +00:00
async function checkRateLimits ( hi ) {
const axios = require ( 'axios' ) ;
// Make a GET request to the Discord API
await axios . get ( 'https://discord.com/api/v10/users/@me' , {
headers : {
'Authorization' : ` Bot ${ token } `
}
} ) . then ( response => {
// Get the rate limit headers
const remaining = response . headers [ 'x-ratelimit-remaining' ] ;
const reset = response . headers [ 'x-ratelimit-reset' ] ;
// Log the rate limit headers
console . log ( ` Remaining requests: ${ remaining } ` ) ;
console . log ( ` Reset time (Unix epoch seconds): ${ reset } ` ) ;
} ) . catch ( error => {
console . error ( error ) ;
} ) ;
await fn . sleep ( 500 ) . then ( async ( ) => {
await checkRateLimits ( ) ;
} )
}
2023-02-20 19:07:38 +00:00
2023-01-25 08:07:41 +00:00
process . on ( 'unhandledRejection' , error => {
2023-06-03 19:47:49 +00:00
console . error ( 'Unhandled promise rejection (pls dont break up with me):' , error ) ;
2023-01-25 08:07:41 +00:00
} ) ;
2023-01-18 00:35:24 +00:00
client . login ( token ) ;