-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbot.js
142 lines (111 loc) · 4.81 KB
/
bot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const config = require( './loadConfig.js' );
const ScheduledTasks = require( './scheduled-tasks.js' );
// Require FS
const fs = require( 'fs' );
// require the discord.js module
const Discord = require( 'discord.js' );
// create a new Discord client
const client = new Discord.Client( { partials: ['MESSAGE', 'CHANNEL', 'REACTION'] } );
client.commands = new Discord.Collection();
/**
* Used to send a message to a channel given a channel ID and the message to send
*/
client.sendMessage = function ( channelID, message ) {
// If there is no message, don't even try
if ( ! message.toString().length ) return;
client.channels.fetch( channelID )
.then( channel => {
// TODO: Make sure there's a message to send
channel.send( message );
} )
.catch( error => {
console.error( 'There was an error using sendMessage:\n', error );
});
}
const commandFiles = fs.readdirSync( './commands' ).filter( file => file.endsWith( '.js' ) );
for ( const file of commandFiles ) {
const command = require( `./commands/${file}` );
client.commands.set( command.name, command );
}
// Cooldowns
const cooldowns = new Discord.Collection();
// when the client is ready, run this code
// this event will only trigger one time after logging in
client.once('ready', () => {
console.log( 'Ready!' );
client.commands.filter( cmd => 'function' === typeof cmd.onReady )
.each( cmd => {
cmd.onReady( client );
} );
ScheduledTasks.startAll();
});
// Run on every message
client.on( 'message', message => {
// Ignore messages not meant for us
if ( ! message.content.startsWith( config.prefix ) ) { return; }
// Used to also ignore messages from bots, but stopped so cron messages can trigger commands
// || message.author.bot
// Fill args with all content of the message, removing prefix and exploding on spaces
const args = message.content.slice( config.prefix.length ).split( / +/ );
// The command is the first argument
const commandName = args.shift().toLowerCase();
const rawArgs = message.content.slice( config.prefix.length + commandName.length ).trim();
const command = client.commands.get(commandName)
|| client.commands.find( cmd => cmd.aliases && cmd.aliases.includes( commandName ) );
if ( ! command ) { return; }
// For commands that are only available in a regular server channel
if ( command.guildOnly && 'text' !== message.channel.type ) {
return message.reply( 'I can\'t execute that command inside DMs!' );
}
// When limited to certain channels
if ( command.allowedInChannels || ( config.commandsAllowedInChannels && config.commandsAllowedInChannels[command.name] ) ) {
let allowedChannels = [].concat( command.allowedInChannels, config.commandsAllowedInChannels[command.name] ).filter( c => c !== undefined );
if ( ! allowedChannels.includes( message.channel.id ) ) {
return message.reply( `that command is only for use in <#${allowedChannels.join( '>, <#' )}>` );
}
}
// When Args are required
if ( ( command.args && ! args.length ) || ( Number.isInteger( command.args ) && args.length < command.args ) ) {
let reply = `You didn't provide the needed arguments, ${message.author}!`;
// If a usage is specified, offer that to the user
if ( command.usage ) {
let usage = '\nThe proper usage would be: ';
if ( 'function' === typeof command.usage ) {
usage += command.usage();
} else if ( 'string' === typeof command.usage ) {
usage += command.usage;
}
reply += usage.replace( /{prefix}/g, config.prefix ).replace( /{commandName}/g, command.name );
}
return message.channel.send( reply );
}
// Each command needs it's own cooldown collection
if ( !cooldowns.has( command.name ) ) {
cooldowns.set( command.name, new Discord.Collection() );
}
const now = Date.now();
const timestamps = cooldowns.get( command.name );
// Cooldown in ms - 3 second default
const cooldownAmount = ( command.cooldown || 3 ) * 1000;
// If three's
if ( timestamps.has( message.author.id ) ) {
const expirationTime = timestamps.get( message.author.id ) + cooldownAmount;
if ( now < expirationTime ) {
const timeLeft = ( expirationTime - now ) / 1000;
return message.reply( `please wait ${timeLeft.toFixed( 1 )} more second(s) before reusing the \`${config.prefix}${command.name}\` command.` );
}
}
// Add the last-used timestamp for the author for this command
timestamps.set( message.author.id, now );
// Set a timeout to remove that last used timestamp
setTimeout( () => timestamps.delete( message.author.id ), cooldownAmount );
try {
command.execute( { message: message, args: args, rawArgs: rawArgs, commandName: commandName } );
} catch ( error ) {
console.error( error );
message.reply( 'there was an error trying to execute that command!' );
}
});
process.on( 'unhandledRejection', error => console.error( 'Uncaught Promise Rejection', error ) );
// login to Discord
client.login( config.token );