2022-07-09 20:30:31 +03:00
//#region imports
2022-06-10 16:19:47 +03:00
const { Client , Intents , MessageActionRow , MessageButton , MessageSelectMenu } = require ( 'discord.js' ) ;
2022-02-17 21:42:57 -05:00
const Discord = require ( 'discord.js' ) ;
2022-05-12 17:38:08 +03:00
const { MongoClient , ServerApiVersion } = require ( 'mongodb' ) ;
const fs = require ( 'fs' ) ;
2022-07-03 18:26:50 +03:00
// const OpenAI = require('openai-api')
const { Configuration , OpenAIApi } = require ( "openai" ) ;
2022-07-08 14:21:09 +03:00
const Stripe = require ( 'stripe' ) ;
2022-07-03 18:26:50 +03:00
2022-05-28 16:55:56 +03:00
const turnManager = require ( './commands/turnManager.js' ) ;
2022-06-10 16:19:47 +03:00
const { welcome } = require ( './commands/admin/welcome.js' ) ;
2022-07-01 15:00:52 +03:00
const { handle _interaction } = require ( './commands/interactionhandler.js' ) ;
2022-07-03 18:26:50 +03:00
const { handle _dm } = require ( './commands/dm_handler' ) ;
2022-07-08 17:09:36 +03:00
const { devCheck } = require ( './commands/dev only/devcheck.js' ) ;
2022-07-09 20:30:31 +03:00
const { moderation _handler } = require ( './commands/admin/moderation.js' ) ;
2022-05-12 17:38:08 +03:00
const { exit } = require ( 'process' ) ;
2022-07-09 20:30:31 +03:00
//#endregion
2022-05-12 17:38:08 +03:00
const BASE _LVL _XP = 20 ;
2022-05-20 12:19:27 +03:00
2022-07-08 14:21:09 +03:00
//#region Token area
2022-05-20 12:19:27 +03:00
//Adding integration for development mode
let token ;
2022-05-25 22:33:42 +03:00
let IDM = false ;
2022-06-11 17:53:44 +03:00
let home _server ;
2022-07-19 15:41:49 +03:00
let debug _channel ;
2022-07-03 18:26:50 +03:00
let MLAIKEY ;
2022-07-08 14:21:09 +03:00
let StripeAPIKey ;
2022-07-03 18:26:50 +03:00
2022-05-20 12:19:27 +03:00
if ( process . env . token != undefined ) {
//Use "setx NAME VALUE" in the local powershell terminal to set
token = process . env . token ;
2022-06-11 17:53:44 +03:00
home _server = process . env . home _server ;
2022-07-19 15:41:49 +03:00
debug _channel = process . env . debug _channel ;
2022-07-03 18:26:50 +03:00
MLAIKEY = process . env . MLAIKEY ;
2022-07-08 14:21:09 +03:00
StripeAPIKey = process . env . StripeAPIKey ;
2022-05-20 12:19:27 +03:00
} else {
token = require ( './config.json' ) . token ;
2022-06-11 17:53:44 +03:00
home _server = require ( './config.json' ) . home _server ;
2022-07-19 15:41:49 +03:00
debug _channel = require ( './config.json' ) . debug _channel ;
2022-07-08 14:21:09 +03:00
MLAIKEY = require ( './config.json' ) . MLAIKEY ;
StripeAPIKey = require ( './config.json' ) . StripeAPIKey ;
2022-08-18 14:25:25 -07:00
2022-07-19 15:41:49 +03:00
// { token, home_server, debug_channel, MLAIKEY, StripeAPIKey } = require('./config.json'); // Doesn't work
IDM = true ;
2022-05-20 12:19:27 +03:00
}
2022-07-08 14:21:09 +03:00
//#endregion
2022-04-17 08:51:30 -04:00
2022-04-30 15:51:55 -04:00
const bot = new Client ( {
2022-02-17 21:42:57 -05:00
intents : [
Intents . FLAGS . GUILDS ,
Intents . FLAGS . GUILD _MESSAGES ,
2022-04-30 15:51:55 -04:00
Intents . FLAGS . GUILD _MESSAGE _REACTIONS ,
2022-05-13 12:14:24 +03:00
Intents . FLAGS . GUILD _VOICE _STATES ,
2022-06-10 16:19:47 +03:00
Intents . FLAGS . GUILD _EMOJIS _AND _STICKERS ,
Intents . FLAGS . GUILD _PRESENCES ,
2022-07-03 18:26:50 +03:00
Intents . FLAGS . GUILD _MEMBERS ,
Intents . FLAGS . DIRECT _MESSAGES ,
Intents . FLAGS . DIRECT _MESSAGE _REACTIONS ,
Intents . FLAGS . DIRECT _MESSAGE _TYPING ,
2022-02-17 21:42:57 -05:00
] ,
2022-07-03 18:26:50 +03:00
partials : [ 'CHANNEL' ]
2022-02-17 21:42:57 -05:00
} ) ;
2022-05-18 21:34:58 +03:00
const prefix = '!' ;
bot . prefix = new String ;
bot . prefix = prefix ;
2022-05-25 22:33:42 +03:00
bot . inDebugMode = IDM ;
2022-06-11 17:53:44 +03:00
bot . home _server = home _server ;
2022-07-19 15:41:49 +03:00
bot . debug _channel = debug _channel ;
2022-09-06 15:29:48 -04:00
bot . inviteLink = 'https://discord.com/oauth2/authorize?client_id=944046902415093760&scope=applications.commands+bot&permissions=549755289087' ;
2022-02-17 21:42:57 -05:00
2022-07-03 18:26:50 +03:00
const configuration = new Configuration ( {
apiKey : MLAIKEY ,
} ) ;
bot . openai = new OpenAIApi ( configuration ) ;
bot . temptext = '' ;
2022-07-08 14:21:09 +03:00
bot . stripe = Stripe ( StripeAPIKey ) ;
2022-07-03 18:26:50 +03:00
2022-07-12 20:10:35 +03:00
//The first thing will be an audioPlayer(), the second a queue
bot . audioData = new Map ( ) ;
2022-02-17 21:42:57 -05:00
2022-07-08 14:21:09 +03:00
//#region MongoDB integration
2022-05-20 12:19:27 +03:00
//Development support
let mongouritemp ;
if ( process . env . MONGODB _URI ) {
mongouritemp = process . env . MONGODB _URI ;
} else {
2022-07-16 19:26:06 +03:00
mongouritemp = require ( './config.json' ) . mongooseURI ;
2022-05-20 12:19:27 +03:00
}
const mongouri = mongouritemp ;
2022-07-03 18:26:50 +03:00
bot . mongouri = mongouri ;
2022-07-31 10:11:55 +03:00
const client = new MongoClient ( mongouri , { useNewUrlParser : true , useUnifiedTopology : true , serverApi : ServerApiVersion . v1 } ) ;
bot . mongoconnection = client . connect ( ) ;
2022-05-12 17:38:08 +03:00
const { connect } = require ( 'mongoose' ) ;
2022-07-08 14:21:09 +03:00
//#endregion MongoDB Integration end
2022-06-10 16:19:47 +03:00
2022-05-12 17:38:08 +03:00
2022-07-08 14:21:09 +03:00
//#region set up bot commands
2022-06-10 16:19:47 +03:00
2022-07-08 14:21:09 +03:00
// const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js')); // Obsolete?
2022-05-09 12:11:18 +03:00
2022-04-30 15:51:55 -04:00
bot . commands = new Discord . Collection ( ) ;
2022-07-16 19:26:06 +03:00
const forbiddenFolders = [ 'db' , 'dev only' ] ; //premium,
2022-02-17 21:42:57 -05:00
2022-05-13 22:29:54 +03:00
fs . readdirSync ( './commands' )
. forEach ( dir => {
2022-07-08 14:21:09 +03:00
if ( ! forbiddenFolders . includes ( dir ) && ! dir . endsWith ( '.js' ) ) {
2022-05-24 08:55:57 +03:00
fs . readdirSync ( ` ./commands/ ${ dir } ` )
. filter ( file => file . endsWith ( '.js' ) )
. forEach ( file => {
const command = require ( ` ./commands/ ${ dir } / ${ file } ` ) ;
2022-07-12 20:10:35 +03:00
if ( command . name && command . description ) {
2022-07-16 19:26:06 +03:00
bot . commands . set ( command . name . toLowerCase ( ) , command ) ;
2022-07-12 20:10:35 +03:00
}
2022-05-24 08:55:57 +03:00
} ) ;
2022-07-08 15:43:41 +03:00
}
2022-05-13 22:29:54 +03:00
} ) ;
2022-05-13 22:03:05 +03:00
2022-05-24 08:55:57 +03:00
2022-07-08 14:21:09 +03:00
//Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file)
2022-06-10 16:19:47 +03:00
let temp _command = require ( "./commands/db/econ.js" ) ;
2022-05-28 16:55:56 +03:00
const { STATE } = require ( './commands/db/econ.js' ) ;
2022-06-10 16:19:47 +03:00
bot . commands . set ( 'econ' , temp _command ) ;
2022-07-01 15:00:52 +03:00
temp _command = require ( './commands/games/game.js' ) ;
2022-06-10 16:19:47 +03:00
bot . commands . set ( 'game' , temp _command ) ;
2022-05-24 08:55:57 +03:00
2022-07-08 14:21:09 +03:00
//Everything in the API should be handled by specific handler functions
2022-07-16 19:26:06 +03:00
// const chat = require('./commands/premium/chat.js');
// bot.commands.set('chat', chat);
// const stripeCommands = require('./commands/premium/stripe.js');
// bot.commands.set('premium', stripeCommands);
// const
// bot.commands.set('RSS', )
2022-07-08 14:21:09 +03:00
//#endregion
//#region bot.[anything] section
2022-02-17 21:42:57 -05:00
2022-05-12 17:38:08 +03:00
//XP Table section
let xp _collection = new Map ( ) ;
let items ;
2022-02-17 21:42:57 -05:00
2022-04-30 15:51:55 -04:00
bot . on ( 'ready' , async ( ) => {
2022-05-12 17:38:08 +03:00
//Make then copy the shop
2022-07-31 10:11:55 +03:00
bot . mongoconnection . then ( client => {
2022-05-12 17:38:08 +03:00
const shop = client . db ( "main" ) . collection ( "shop" ) ;
shop . find ( ) . toArray ( function ( err , itemstemp ) {
if ( err ) throw err ;
items = [ ... itemstemp ] ;
} ) ;
2022-05-24 08:55:57 +03:00
//Srt status and Activity (idle and listening to !help)
bot . user . setActivity ( ` ${ bot . prefix } help ` , { type : "LISTENING" } ) ;
// bot.user.setStatus('idle');
2022-05-12 17:38:08 +03:00
} ) ;
//Note the xp numbers are a little wonky on levels 6, 8 and 13 (why though?)
//See https://stackoverflow.com/questions/72212928/why-are-the-differences-between-my-numbers-inconsistent-sort-of-compund-interes
for ( let i = 1 ; i < 101 ; i ++ ) {
// xp_collection.set(i, BASE_LVL_XP * .1);
let amount = BASE _LVL _XP * ( Math . ceil ( Math . pow ( ( 1.1 ) , ( 2 * i ) ) ) + i ) ;
xp _collection . set ( i + 1 , amount ) ;
}
2022-04-17 08:51:30 -04:00
2022-05-13 12:14:24 +03:00
//Reaction map area
2022-05-25 22:33:42 +03:00
if ( ! bot . inDebugMode ) {
2022-05-20 12:19:27 +03:00
console . log ( 'SLEEMER BOT ONLINE!!!!! OH MY GOD OH MY GOD!!!' ) ;
} else {
console . log ( "Testing testing 1 2 5..." ) ;
}
2022-06-17 16:41:02 +03:00
//Add the money symbol
let srv = bot . guilds . cache . get ( bot . home _server ) . emojis . cache ;
emj = srv . find ( ( g ) => { return g . name == 'selmer_coin' } ) ;
bot . currencysymbolmmain = ` ${ emj } ` ;
2022-02-17 21:42:57 -05:00
} ) ;
2022-05-27 14:58:30 +03:00
//Button Section
2022-05-28 16:55:56 +03:00
bot . on ( 'interactionCreate' , async interaction => {
2022-07-01 15:00:52 +03:00
handle _interaction ( interaction , mongouri , turnManager , bot , STATE , items , xp _collection ) ;
2022-06-10 16:19:47 +03:00
} ) ;
2022-07-08 14:21:09 +03:00
//Add the bot to a server setup
bot . on ( "guildCreate" , guild => {
2022-07-09 20:30:31 +03:00
if ( guild . roles . cache . find ( ( role ) => { return ( role . name == 'Selmer Bot Commands' ) ; } ) == undefined ) {
guild . roles . create ( { name : 'Selmer Bot Commands' } ) ;
}
2022-08-17 20:21:19 -07:00
if ( guild . roles . cache . find ( ( role ) => { return ( role . name == 'Selmer Bot Calendar' ) ; } ) == undefined ) {
guild . roles . create ( { name : 'Selmer Bot Calendar' } ) ;
}
2022-07-08 14:21:09 +03:00
//const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here');
const server = bot . guilds . cache . get ( guild . id ) ;
const owner = server . members . fetch ( guild . ownerId ) . then ( function ( owner ) {
2022-08-17 20:21:19 -07:00
owner . send ( 'Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Commands_" role and people you want to access set the calendar the "Selmer Bot Calendar" role' ) ;
2022-07-08 14:21:09 +03:00
owner . send ( 'To help set up Selmer Bot to work better with your server, use _!setup help_ in a channel Selmer Bot is in!' ) ;
} ) ;
//Set up the server
2022-07-31 10:11:55 +03:00
bot . mongoconnection . then ( client => {
2022-07-08 14:21:09 +03:00
const dbo = client . db ( guild . id ) . collection ( 'SETUP' ) ;
2022-08-17 12:09:40 -07:00
dbo . insertMany ( [ { _id : 'WELCOME' , 'welcomechannel' : null , 'welcomemessage' : null , 'welcomebanner' : null } , { _id : 'LOG' , 'keepLogs' : false , 'logchannel' : null , 'severity' : 0 } , { _id : 'announcement' , channel : null , role : null } ] ) ;
2022-07-08 14:21:09 +03:00
} ) ;
} ) ;
2022-08-17 20:21:19 -07:00
bot . on ( "guildDelete" , guild => {
bot . mongoconnection . then ( ( client ) => {
//Insufficient Permission????
// db.dropDatabase();
try {
const db = client . db ( guild . id ) ;
db . listCollections ( ) . forEach ( function ( x ) { db . collection ( x . name ) . drop ( ) ; } ) ;
var times ;
const dbo = client . db ( 'main' ) . collection ( 'reminderKeys' ) ;
//ReminderKeys are all stored as userId, the reminders themselves are not
dbo . findOne ( { userId : guild . id } ) . then ( ( doc ) => {
2022-09-03 20:27:09 -04:00
if ( ! doc || ! doc . times ) { return ; }
2022-08-17 20:21:19 -07:00
times = doc . times ;
const tbo = client . db ( 'main' ) . collection ( 'reminders' ) ;
tbo . find ( { time : { $in : times } } ) . toArray ( ( err , docs ) => {
2022-09-03 20:27:09 -04:00
try {
for ( let i = 0 ; i < docs . length ; i ++ ) {
for ( let j in docs [ i ] ) {
if ( ! isNaN ( j ) && ( docs [ i ] [ j ] . guildId == guild . id ) ) {
delete docs [ i ] [ j ] ;
docs [ i ] . amt -- ;
}
2022-08-17 20:21:19 -07:00
}
2022-09-03 20:27:09 -04:00
if ( docs . amt > 0 ) {
tbo . replaceOne ( { time : docs [ i ] . time } , docs [ i ] ) ;
} else {
tbo . deleteOne ( { time : docs [ i ] . time } ) ;
}
2022-08-17 20:21:19 -07:00
}
2022-09-03 20:27:09 -04:00
} catch ( err ) {
console . error ( err ) ;
2022-08-17 20:21:19 -07:00
}
} ) ;
} ) ;
dbo . deleteOne ( { userId : guild . id } ) ;
} catch ( err ) {
2022-09-03 20:27:09 -04:00
console . error ( err ) ;
2022-08-17 20:21:19 -07:00
}
} )
} ) ;
2022-07-08 14:21:09 +03:00
2022-06-10 16:19:47 +03:00
//Welcome new members
bot . on ( 'guildMemberAdd' , async ( member ) => {
2022-07-09 20:30:31 +03:00
2022-06-10 16:19:47 +03:00
//Check for impartial data
if ( member . partial ) await member . fetch ( ) ;
2022-05-28 16:55:56 +03:00
2022-06-10 16:19:47 +03:00
const guild = bot . guilds . cache . get ( member . guild . id ) ;
2022-07-31 10:11:55 +03:00
bot . mongoconnection . then ( client => {
2022-06-10 16:19:47 +03:00
const dbo = client . db ( member . guild . id ) . collection ( 'SETUP' ) ;
dbo . find ( { _id : 'WELCOME' } ) . toArray ( async ( err , docs ) => {
var welcomechannel ;
if ( docs [ 0 ] . welcomechannel == null ) {
welcomechannel = guild . channels . cache . find ( channel => channel . name . toLowerCase ( ) === 'welcome' ) ;
} else {
welcomechannel = guild . channels . cache . get ( docs [ 0 ] . welcomechannel )
}
if ( welcomechannel == null ) {
return console . log ( 'No welcome channel detected' ) ;
}
2022-06-10 20:48:43 +03:00
await welcome ( member , welcomechannel , docs [ 0 ] . welcomemessage ) ;
2022-06-10 16:19:47 +03:00
} )
2022-06-17 16:41:02 +03:00
} )
2022-05-27 14:58:30 +03:00
} ) ;
2022-04-30 15:51:55 -04:00
bot . on ( 'messageCreate' , ( message ) => {
2022-07-03 18:26:50 +03:00
//DM SECTION
if ( message . channel . type === "DM" ) {
return handle _dm ( message , bot ) ;
2022-07-08 17:09:36 +03:00
} else if ( message . content . indexOf ( '!spam_collection' ) != - 1 ) {
//Handle spam collection/Dev commands
return devCheck ( message , bot ) ;
2022-07-19 15:41:49 +03:00
} else if ( message . type === "CHANNEL_PINNED_MESSAGE" ) {
//Debug log stuff
if ( message . guild . id == bot . home _server && message . channel . id == bot . debug _channel ) {
message . delete ( ) ;
}
2022-07-08 17:09:36 +03:00
}
2022-07-03 18:26:50 +03:00
2022-07-19 15:41:49 +03:00
//Special case, testing server (still need the emojis and error logging)
2022-06-11 18:47:49 +03:00
if ( ! bot . inDebugMode && message . guild . id == bot . home _server ) { return ; }
2022-06-11 17:53:44 +03:00
2022-02-17 21:42:57 -05:00
//COMMAND AREA
//Check if the prefix exists
if ( ! message . content . startsWith ( prefix ) || message . author . bot ) return ;
2022-05-27 14:58:30 +03:00
2022-02-17 21:42:57 -05:00
const args = message . content . slice ( prefix . length ) . split ( ' ' ) ;
const command = args . shift ( ) . toLowerCase ( ) ;
2022-07-09 20:30:31 +03:00
//Log logable commands then execute them
const logable = [ 'kick' , 'ban' , 'unban' , 'mute' , 'unmute' , 'timeout' ] ;
if ( logable . includes ( command ) ) {
moderation _handler ( bot , message , args , command ) ;
}
2022-06-10 16:19:47 +03:00
2022-02-17 21:42:57 -05:00
//Performes the command
2022-05-14 20:40:58 +03:00
//Admin section
2022-07-09 20:30:31 +03:00
else if ( command == 'reactionrole' ) { bot . commands . get ( command ) . execute ( message , args , Discord , bot ) ; }
2022-05-13 22:29:54 +03:00
2022-05-24 08:55:57 +03:00
else if ( bot . commands . has ( command ) && command != 'ECON' ) {
//Database access is required, change the inputs
2022-06-10 16:19:47 +03:00
if ( command == 'game' || command == 'accept' || command == 'setup' ) {
2022-05-28 16:55:56 +03:00
bot . commands . get ( command ) . execute ( bot , message , args , command , Discord , mongouri , items , xp _collection ) ;
2022-05-24 08:55:57 +03:00
} else {
bot . commands . get ( command ) . execute ( message , args , Discord , Client , bot ) ;
}
}
2022-05-13 22:29:54 +03:00
2022-06-10 16:19:47 +03:00
//Econ and also the catch statement
2022-05-24 08:55:57 +03:00
else { bot . commands . get ( 'econ' ) . execute ( bot , message , args , command , Discord , mongouri , items , xp _collection ) ; }
2022-02-17 21:42:57 -05:00
} )
2022-07-08 14:21:09 +03:00
//#endregion
2022-02-17 21:42:57 -05:00
2022-05-12 17:38:08 +03:00
//Last Line(s)
2022-05-20 12:19:27 +03:00
bot . login ( token ) ;