-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathindex.js
2262 lines (1760 loc) · 70.2 KB
/
index.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//Discord Client,with all intents and permissions set
const Discord = require("discord.js");
const client = new Discord.Client({
partials: ["CHANNEL", "MESSAGE", "GUILD_MEMBER", "REACTION"],
intents: 32767,
allowedMentions: {
parse: ["users", "roles"],
repliedUser: false,
},
restTimeOffset: 0,
});
/* All Module Imports for the Bot */
require("dotenv").config();
const token = process.env.token;
const mongoPath = process.env.mongoPath;
const mongoose = require("mongoose");
const background = "./assets/background.jpg";
const youtube = process.env.youtube;
const botname = process.env.botname;
const colors = require("colors");
const fetch = require("node-fetch");
const logger = require("./classes/logger");
const { red, green, blue, yellow, cyan } = require('colors');
const ascii = require("ascii-table");
const { Captcha } = require("captcha-canvas");
const captchaSchema = require("./schemas/captcha");
const { table } = require("table");
const buttonrr = require("./schemas/buttonrr");
const antiraid = require("./schemas/antiraid");
const ownerID = process.env.ownerid;
const axios = require("axios");
const queueSchema = require('./schemas/queueSchema')
const counterSchema = require("./schemas/count");
const path = require("path");
const blacklistWords = require('./schemas/FilterDB');
const nsfwschema = require("./schemas/nsfw");
const banner = "./assets/bot_long_banner.png";
require("dotenv").config();
const tf = require('@tensorflow/tfjs-node');
const nsfw = require('nsfwjs')
const starboardSchema = require("./schemas/starboard");
const fs = require("fs");
const afk = new Discord.Collection();
const boostschema = require('./schemas/boostsystem')
const antiscam = require("./schemas/antiscam");
const unsafe = require("./unsafe.json");
const moment = require("moment");
const Levels = require("discord-xp");
const glob = require("glob");
const { GiveawaysManager } = require('discord-giveaways');
const AntiSpam = require("discord-anti-spam");
const antispamschema = require('./schemas/antispam')
const { promisify } = require("util");
const globPromise = promisify(glob);
const welcomeMessage = require('./schemas/welcomeMessage')
const { VoiceClient } = require("djs-voice");
const afkschema = require("./schemas/afk");
const chalkAnimation = require('chalk-animation')
const { DiscordTogether } = require('discord-together');
client.discordTogether = new DiscordTogether(client);
//Chatbot system using Chat-GPT3 API
// const { Configuration, OpenAIApi } = require("openai");
// const config = new Configuration({
// organization:process.env.openai_org,
// apiKey: process.env.openai,
// })
// const openai = new OpenAIApi(config);
//HuggingFace libraries
const {HfInference} = require('@huggingface/inference')
const hf_token = process.env.hf
const inference = new HfInference(hf_token)
const {backOff} = require('exponential-backoff')
client.snipes = new Discord.Collection();
const Canvas = require("canvas");
const Schema = require("./schemas/welcomeChannel");
const guildSchema = require("./schemas/Guild");
const ms = require("ms");
const altschema = require("./schemas/anti-alt");
const rpctoken = process.env.rpc;
const RPC = require("discord-rpc");
const rpc = new RPC.Client({ transport: "ipc" });
const customSchema = require("./schemas/custom-welcome");
const countSchema = require("./schemas/member-count");
const autoroleschema = require("./schemas/autorole");
const pollSchema = require("./schemas/poll")
const jointocreate = require('./schemas/jointocreatevc');
const blacklistserver = require("./schemas/blacklist-server");
const inviteschema = require("./schemas/anti-invite");
const ghostpingschema = require("./schemas/ghostping");
const Pings = new Discord.Collection();
const chatschema = require("./schemas/chatbot-channel");
const muteschema = require("./schemas/mute");
const starboardcollection = new Discord.Collection();
client.slashCommands = new Discord.Collection();
client.filters = new Discord.Collection()
client.filtersLog = new Discord.Collection()
client.voicetemp = new Discord.Collection();
const giveawayModel = require('./schemas/giveaway')
votes = new Discord.Collection();
//VoiceClient for the Voice Channel Leveling System
const voiceClient = new VoiceClient({
allowBots: false, //Bots Will Not Be Counted
client: client, //Discord Client
debug: false,
mongooseConnectionString: mongoPath, //Mongo Database Connection
})
//Giveaway System Settings
const GiveawayManagerWithOwnDatabase = class extends GiveawaysManager {
async getAllGiveaways() {
return await giveawayModel.find().lean().exec();
}
// This function is called when a giveaway needs to be saved in the database.
async saveGiveaway(messageId, giveawayData) {
await giveawayModel.create(giveawayData);
return true;
}
// This function is called when a giveaway needs to be edited in the database.
async editGiveaway(messageId, giveawayData) {
await giveawayModel.updateOne({ messageId }, giveawayData, { omitUndefined: true }).exec();
return true;
}
// This function is called when a giveaway needs to be deleted from the database.
async deleteGiveaway(messageId) {
await giveawayModel.deleteOne({ messageId }).exec();
return true;
}
};
const manager = new GiveawayManagerWithOwnDatabase(client, {
default: {
botsCanWin: false,
embedColor: '#FF0000',
embedColorEnd: '#000000',
reaction: '🎉'
}
});
client.giveawaysManager = manager;
client.vcclient = voiceClient; //Global Voice Leveling System Variable
client.commands = new Discord.Collection(); //Message Commands Collection
client.color = require('./classes/colors.json') //Global Variable for Color JSON for ease of access to multiple colors
Levels.setURL(mongoPath); //Connection to the Mongo Database for Leveling System
module.exports = {afk, starboardcollection}; //Exporting Discord Collections for Usage Outside of Main File
const { Player } = require("@arthestn/discord-music-player"); //Import Music Player Client
const player = new Player(client, {
leaveOnStop:true,
leaveOnEmpty: true,
deafenOnJoin: true,
timeout: 600000,
volume: 100,
});
//Global Variable for Music Bot
client.player = player;
//Events for the Music Bot
player
//Event for When Only Bot is Present in Voice Channel
.on("channelEmpty", async (queue) => {
queue.connection.leave();
queue.data.channel.send("Left Channel as no one was with me");
})
// .on('error', async(error,queue) => {
// try{
// console.log(error)
// queue.data.channel.send('An Error Has Occured, Please Give Us a Few mins to restart and come back')
// }catch(e){
// console.log(e)
// }
// })
//Event for when Music Queue is Manually Shut Down
.on("queueDestroyed", async (queue) => {
queue.connection.leave();
})
//Event for When Music Client is Manually Stopped/Destroyed
.on('clientDisconnect',async (queue) =>{
if(queue.songs.length <= 1){
queue.connection.leave();
}
else{
}
})
//Event for the First Song in the Queue
.on("songFirst", async(queue, song) => {
try{
if(song.isFirst){
//Removes Tags from YouTube Music Videos
const newname = song.name.replace(/ *\([^)]*\) */g, "");
let image = " "
axios({
method: 'get',
url: `https://v1.nocodeapi.com/endofle/spotify/IUKwQtzrULSFKxMf/search?q=${newname}`,
params: {},
}).then(async function (response) {
console.log(response.data.albums.items[0].images[0].url);
image = response.data.albums.items[0].images[0].url
const embed = new Discord.MessageEmbed()
.setColor(client.color.invis)
.setTitle('**Now Playing**')
.addField("Song Name: ", newname)
.addField("Song Duration", song.duration, false)
.setTimestamp()
.setThumbnail(image ? image : song.thumbnail)
return queue.data.channel.send({embeds:[embed]})
}).catch(async function (error) {
const embed = new Discord.MessageEmbed()
.setColor(client.color.invis)
.setTitle('**Now Playing**')
.addField("Song Name: ", newname)
.addField("Song Duration", song.duration, false)
.setTimestamp()
.setThumbnail(song.thumbnail)
await queue.data.channel.send({embeds:[embed]})
console.log(error);
})
}
}catch(err){
console.log(err)
queue.data.channel.send({content:'An Error Has Occurred'})
}
})
//Event for When a YouTube or Spotify Playlist is added to the queue
.on("playlist", async (raw, queue,requestedBy) => {
try{
const embed = new Discord.MessageEmbed()
.setColor(client.color.invis)
.setTitle('**Playlist Added**')
.addField("Playlist Name: ", raw.name)
.addField('Number of Songs', raw.songs)
.addField("Song Duration", raw.duration, false)
.setThumbnail(raw.thumbnail)
.setTimestamp()
await queue.data.channel.send({embeds:[embed]})
} catch(err){
queue.data.channel.send("An Error Has Occured")
}
})
//Events for when a Song is Added to the queue
.on("songAdd", async(queue, song) => {
try{
if(!song.isFirst){
if(song.name.includes(" (Official Video)") || song.name.includes(" (Official Music Video)") || song.name.includes(" (Official Audio)")){
const newname = `${song.name}`.replaceAll(" (Official Video)", "").replaceAll(" (Official Audio)", "").replaceAll(" (Official Music Video)", "")
const embed = new Discord.MessageEmbed()
.setColor(client.color.invis)
.setTitle('**Added Song to Queue**')
.addField("Song Name: ", newname)
.addField("Song Duration", song.duration, false)
.setThumbnail(song.thumbnail)
.setTimestamp()
await queue.data.channel.send({embeds:[embed]})
}
else{
const embed = new Discord.MessageEmbed()
.setColor(client.color.invis)
.addField("Song Name: ", song.name)
.setTitle('**Added Song to Queue**')
.addField("Song Duration", song.duration, false)
.setThumbnail(song.thumbnail)
.setTimestamp()
await queue.data.channel.send({embeds:[embed]})
}
}
}catch(err){
queue.data.channel.send({content:'An Error Has Occured'})
}
})
//End Of Music Bot Stuff
//Embed Generator that makes Embeds easier to use
client.embed = async (message, options) => {
const embed = new Discord.MessageEmbed(options);
message.channel.send({ embeds: [embed] });
};
//Ready Event
client.on("ready", async () => {
/* Just a Bunch of Decorative Stuff for my terminal */
const data = [
["LOGGED IN AS", `${red(client.user.tag)}`, "The bot that I am logged in as."],
["SERVERS", `${yellow(client.guilds.cache.size.toLocaleString())}`, "The amount of servers that I am in."],
["USERS", `${green(client.users.cache.size.toLocaleString())}`, "The amount of users using my commands."],
["COMMANDS", `${cyan(client.commands.size.toLocaleString())}`, "Commands Loaded"]
]
//Table Setup for my Terminal
const config = {
border: {
topBody: `─`,
topJoin: `┬`,
topLeft: `┌`,
topRight: `┐`,
bottomBody: `─`,
bottomJoin: `┴`,
bottomLeft: `└`,
bottomRight: `┘`,
bodyLeft: `│`,
bodyRight: `│`,
bodyJoin: `│`,
joinBody: `─`,
joinLeft: `├`,
joinRight: `┤`,
joinJoin: `┼`
},
header: {
alignment: 'center',
content: "CLIENT DATA"
}
};
console.log(table(data, config))
console.log(botname);
//Random Ascii Art
const loading = String.raw`
__ ______ __ __ __ __ ______ __ __ ______ __ __ ______
/ | / \ / | / |/ \ / | / \ / | / |/ |/ \ / | / \
$$ | /$$$$$$ |$$ | $$ |$$ \ $$ |/$$$$$$ |$$ | $$ |$$$$$$/ $$ \ $$ |/$$$$$$ |
$$ | $$ |__$$ |$$ | $$ |$$$ \$$ |$$ | $$/ $$ |__$$ | $$ | $$$ \$$ |$$ | _$$/
$$ | $$ $$ |$$ | $$ |$$$$ $$ |$$ | $$ $$ | $$ | $$$$ $$ |$$ |/ |
$$ | $$$$$$$$ |$$ | $$ |$$ $$ $$ |$$ | __ $$$$$$$$ | $$ | $$ $$ $$ |$$ |$$$$ |
$$ |_____ $$ | $$ |$$ \__$$ |$$ |$$$$ |$$ \__/ |$$ | $$ | _$$ |_ $$ |$$$$ |$$ \__$$ |
$$ |$$ | $$ |$$ $$/ $$ | $$$ |$$ $$/ $$ | $$ |/ $$ |$$ | $$$ |$$ $$/
$$$$$$$$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/
`;
try {
let slash = [];
let table = new ascii("Slash commands");
console.log("Slash Commands Loaded");
console.log(red(`Starting ${client.user.tag}, hold on ...`))
console.log(red(loading))
const prefix = "!necro";
console.log(``);
console.log(green(` An Ok Bot`));
console.log(``);
console.log(``);
console.log(yellow(' + ================================================================================== +'));
console.log(cyan(` [i] :: ${prefix} help :: Displays commands. `));
console.log(cyan(` [i] :: /help :: Displays slash commands `));
console.log(yellow(' + ================================Commands========================================== +'));
console.log(cyan(` Author [i] :: Programmed by [Arihant Tripathi] :: © 2021 Necro Development `));
console.log(cyan(` Bot info [i] :: Status :: ✅ Online `));
console.log(cyan(` Users [i] :: :: ${client.users.cache.size} Users `));
console.log(cyan(` Guilds [i] :: :: ${client.guilds.cache.size} Guilds `));
console.log(red("Press [CTRL + C] to stop the Terminal ..."))
//Slash Command Registration
fs.readdirSync("./slashcmd/").forEach((dir) => {
//Read From Files in Slash Command Directory
const commands = fs
.readdirSync(`./slashcmd/${dir}/`)
.filter((file) => file.endsWith(".js"));
//Loop through each file and load
for (let file of commands) {
let pull = require(`./slashcmd/${dir}/${file}`);
//Condition to Make Sure Slash Command has a name set to it
if (pull.name) {
//Set SlashCommands to Collection
client.slashCommands.set(pull.name, pull);
slash.push(pull); //Push Files to Slash Command Array
table.addRow(file, "✅"); //Add a Check for Each Slash Command Registered
} else {
table.addRow(file, `❌ -> missing command parameters`); //Add a X for Each Slash Command Missing
continue;
}
}
});
console.log(table.toString()); //Log the Table in Terminal
await client.application.commands.set(slash); //Register the slash commands
} catch (error) {
console.log(error);
}
//Mongo Database Registration
await mongoose
.connect(mongoPath, {
useFindAndModify: false,
useUnifiedTopology: true,
useNewUrlParser: true,
autoIndex: false,
})
.then(console.log("Connected to Mongo")); //Prompt when Connection to Mongo is Successful
if (!mongoPath) return; //If Mongo Path is not set, continue
blacklistWords.find().then((documents)=>{
documents.forEach((doc)=>{
client.filters.set(doc.Guild, doc.Words);
client.filtersLog.set(doc.Guild, doc.Words)
})
})
//Member Count Channel Registration
setInterval(() => {
countSchema.find().then((data) => {
if (!data && !data.length) return;
data.forEach((value) => {
const guild = client.guilds.cache.get(value.Guild); // Retrieve Server From Databse
const memberCount = guild.memberCount; //Retrieve Current Server Member Count
if (value.Member != memberCount) { //If Member Count is not equal to the one in the Database
const channel = guild.channels.cache.get(value.Channel); //Retrieve Channel from Database
channel.setName(`Members: ${memberCount}`); //Update Member Count
value.Member = memberCount; //Update Member Count in Database
value.save();
}
});
});
}, ms("15 Minutes"));
//Bot Activity List
const arrayOfStatus = [
`Multi-Purpose Bot`,
`Watching Over Everyone`,
`run !necro`,
"/help for slash commands",
];
//Changinging Bot Status Randomly Every 5 Seconds
let index = 0;
setInterval(() => {
if (index == arrayOfStatus.length) index = 0;
const status = arrayOfStatus[index];
client.user.setActivity('Helping Out', { type: 'WATCHING' }); //Set to Watching Prescence
client.user.setPresence({ activities: [{ name: status }], status: 'dnd' }); //Set Do Not Disturb Status
index++;
}, 5000);
});
client.once("disconnect", () => {
console.log("Disconnect");
});
//RPC Token for Local Usage
// rpc.on('ready', () => {
// rpc.setActivity({
// details: 'Working',
// state: 'Working on stuff',
// startTimestamp: new Date(),
// largeImageKey: 'large-key',
// largeImageText: 'Grind Season',
// smallImageKey: 'small-key',
// smallImageText: 'Chilling',
// buttons: [{label : 'Github', url : 'https://github.com/Siris2314'},{label : 'Invite My Bot', url : 'https://dsc.gg/necroatomic'}]
// });
// console.log('RPC online');
// });
// rpc.login({
// clientId: rpctoken
// });
//Welcome Image Creation for The Welcome Image System
var welcome = {};
welcome.create = Canvas.createCanvas(1024, 500); //Uses Canvas to Create a 1024x500 Image
welcome.context = welcome.create.getContext("2d"); //Set the Image Context to 2d, so we can create the image
welcome.context.font = "72px sans-serif"; //Setting Font on Image
welcome.context.fillStyle = "#ffffff"; //Setting the Font Color Style
Canvas.loadImage("./assets/background.jpg").then(async (img) => { //Read the Background image from the assets folder
/*
* Drawing on the Background Image itself, making sure there is space to draw the avatar of the user joining and the text on top of the image
* Fills in the color and font set earlier on the image
*/
welcome.context.drawImage(img, 0, 0, 1024, 500);
welcome.context.fillText("Welcome", 360, 360);
welcome.context.beginPath();
welcome.context.arc(512, 166, 128, 0, Math.PI * 2, true);
welcome.context.fill();
});
// // Anti-Crash System that I use from time to time
process.on("unhandledRejection", (reason, p) => {
console.log(" [antiCrash] :: Unhandled Rejection/Catch" + reason);
console.log(reason, p);
});
process.on("uncaughtException", (err, origin) => {
console.log(" [antiCrash] :: Uncaught Exception/Catch" + err.message);
console.log(err, origin);
});
process.on("uncaughtExceptionMonitor", (err, origin) => {
console.log(" [antiCrash] :: Uncaught Exception/Catch (MONITOR)" + err.message);
console.log(err, origin);
});
process.on("multipleResolves", (type, promise, reason) => {
console.log(" [antiCrash] :: Multiple Resolves" + reason);
console.log(type, promise, reason);
});
//Message Event
client.on("messageCreate", async (message) => {
if (!message.guild || message.author.bot) {
return;
}
if(!message.guild.me.permissions.has(Discord.Permissions.FLAGS.ADMINISTRATOR)){
return;
}
//Random Function that Helps With Getting Ids of Emojis a lot of easier
function randomNumber(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//Not Quite Nitro System
if(message.content.startsWith(':') && message.content.endsWith(':')){
let emojis = message.content.match(/(?<=:)([^:\s]+)(?=:)/g)
if (!emojis) return;
emojis.forEach(m => {
let emoji = client.emojis.cache.find(x => x.name === m)
if (!emoji) return;
let temp = emoji.toString()
if (new RegExp(temp, "g").test(message.content)) message.content = message.content.replace(new RegExp(temp, "g"), emoji.toString())
else message.content = message.content.replace(new RegExp(":" + m + ":", "g"), emoji.toString());
})
let webhook = await message.channel.fetchWebhooks();
let number = randomNumber(1, 2);
webhook = webhook.find(x => x.name === "NQN" + number);
if (!webhook) {
webhook = await message.channel.createWebhook(`NQN` + number, {
avatar: client.user.displayAvatarURL({ dynamic: true })
});
}
await webhook.edit({
name: message.member.nickname ? message.member.nickname : message.author.username,
avatar: message.author.displayAvatarURL({ dynamic: true })
})
message.delete().catch(err => { })
webhook.send(message.content).catch(err => { })
await webhook.edit({
name: `NQN` + number,
avatar: client.user.displayAvatarURL({ dynamic: true })
})
}
//User Message Level System
const randomXP = Math.floor(Math.random() * 29) + 1; //Random XP Value between 1 and 29 that will be given on each message sent by a user in the server
await Levels.appendXp(
message.author.id,
message.guild.id,
randomXP
); //Appends and Saves XP to the Database Upon Each User Leveling Up
try{
const messageContent = message.content.toLowerCase().split(" ")
const blacklistchecker = await blacklistWords.findOne({Guild:message.guild.id}) ? await blacklistWords.findOne({Guild:message.guild.id}) : "No System Enabled"
if(!blacklistchecker || blacklistlistchecker.Blacklist === "No System Enabled"){
}
const filter = client.filters.get(message.guild.id) || "No Filter"
if(!filter){
}
const wordsUsed = [];
let shouldDelete = false;
messageContent.forEach((word) => {
if(filter.includes(word)){
wordsUsed.push(word);
shouldDelete = true;
}
else{
}
})
if(shouldDelete){
message.delete().catch(()=> {})
}
if(wordsUsed.length > 0){
const channelID = blacklistchecker.Log ? blacklistchecker.Log : "No Log"
console.log(channelID)
if(!channelID || channelID == "No Log"){
//Do Nothing
}
const channelObject = message.guild.channels.cache.get(channelID) ? message.guild.channels.cache.get(channelID) : "No Channel"
console.log(channelObject)
if(!channelObject || channelObject == "No Channel"){
//Do Nothing
}
else{
const embed = new Discord.MessageEmbed()
.setColor("RED")
.setAuthor({
name: message.author.tag,
iconURL: message.author.displayAvatarURL({ dynamic: true }),
})
.setDescription([
`Used ${wordsUsed.length} blacklisted word(s) in the message: ${message.channel} => `,
`\`${wordsUsed.map((w) => w)}\``,
].join("\n"))
channelObject.send({embeds:[embed]})
}
}
}catch(err){
}
//FxTwitter System for a Personal Server
// if (
// message.content.includes("https://twitter.com/") &&
// message.guild.id === "684462232679219242"
// ) {
// await message.delete();
// let str = message.content.replace("https://twitter.com/", "");
// let newstr = `https://vxtwitter.com/${str}`;
// message.channel.send({ content: newstr });
// }
await antispamschema.findOne({Guild:message.guild.id}, async(err, data) =>{
if(!data){
return;
}
else{
try{
const antiSpam = new AntiSpam({
warnThreshold: data.warnThreshold,
muteThreshold: data.muteThreshold,
kickThreshold: data.kickThreshold,
banThreshold: data.banThreshold,
maxInterval: data.maxInterval,
warnMessage: "{@user}, Please stop spamming.",
kickMessage: "**{user_tag}** has been kicked for spamming.",
muteMessage: "**{user_tag}** has been muted for spamming.",
banMessage: "**{user_tag}** has been banned for spamming.",
maxDuplicatesWarning: data.maxDuplicatesWarning ? data.maxDuplicatesWarning : 6,
maxDuplicatesKick: data.maxDuplicatesKick ? data.maxDuplicatesKick : 10,
maxDuplicatesBan: data.maxDuplicatesBan ? data.maxDuplicatesBan : 12,
maxDuplicatesMute: data.maxDuplicatesMute ? data.maxDuplicatesMute : 8,
ignoredPermissions: ["ADMINISTRATOR"],
ignoreBots: data.ignoreBots ? data.ignoreBots : true,
verbose: true,
ignoredMembers: [],
unMuteTime: data.unMuteTime ? data.unMuteTime : 10,
removeMessages: data.removeMessage ? data.removeMessage : true,
modLogsEnabled: false,
modLogsChannelName: "mod-logs",
modLogsMode: "embed",
});
antiSpam.message(message)
}catch(err){
console.log(err)
}
}
})
//Anti-Scam Link System that uses a Database to Retrieve Punishments Set by Admins for Sending Scam Links
await antiscam.findOne({ Guild: message.guild.id }, async (err, data) => {
if (!data) return; //If Anti-Scam Link was not set, do nothing
const punishment = String(data.Punishment); //Get The Punishment Set by the Admin
//Loop Through the JSON File of UnSafe Links and see if any user has sent them
unsafe.forEach(async (item) => {
if (message.content === item || message.content.startsWith(item)) {
message.delete(); //Remove The Message Immediately if done so
const Member = await message.guild.members.fetch(message.author.id); //Find the Person who sent the message
message.channel.send(`Scam link sent by ${message.author.username}`); //Alert in the channel itself who sent the scam link
//If the punishment is to mute the user
if (punishment === "mute") {
const role = message.guild.roles.cache.find(
(role) => role.name.toLowerCase() === "muted"
); //Find Muted Role in the Server
//If no muted Role, create one
if (!role) {
try {
message.channel.send({
content:
"Muted role is not found, attempting to create muted role.",
});
let muterole = await message.guild.roles.create({
data: {
name: "muted",
permissions: [],
},
});
message.guild.channels.cache
.filter((c) => c.type === "text")
.forEach(async (channel, id) => {
await channel.createOverwrite(muterole, {
SEND_MESSAGES: false,
ADD_REACTIONS: false,
});
}); //Set Muted Perms, to allow the user to not send messages and react to messages in all text channels
message.channel.send({
content: "Muted role has sucessfully been created.",
});
} catch (error) {
console.log(error);
}
}
//Find the Muted Role in the Server
let role2 = message.guild.roles.cache.find(
(r) => r.name.toLowerCase() === "muted"
);
//If the User has already been muted, do nothing, send message that they are already muted
if (Member.roles.cache.has(role2.id))
return message.channel.send({
content: `${Member.displayName} has already been muted.`,
});
//Else Give User Muted role, hence muting them
await Member.roles.add(role2);
}
//If the punshment is to warn the user
else if (punishment === "warn") {
//Set Reason for Warning
const reason = "Sending Scam Links";
//Send the Warning to the User
Member.send({
embeds: [
new MessageEmbed()
.setTitle("You Have Been Warned")
.setDescription(`${reason}`),
],
});
}
//If the punishment is to ban the user
else if (punishment === "ban") {
Member.ban({ reason: "Sending Scam Links" }); //Ban the User, with reasoning of Sending Scam Links
//Send a more detailed explanation to user
Member.send({
embeds: [
new MessageEmbed()
.setTitle(`You Have Been Banned from ${message.guild.name}`)
.setDescription(`Sending Scam Links`),
],
});
}
//If the punishment is to kick the user
else if (punishment === "kick") {
Member.kick({ reason: "Sending Scam Links" }); //Kick the User, with reasoning of Sending Scam Links
//Send a more detailed explanation to user
Member.send({
embeds: [
new MessageEmbed()
.setTitle(`You Have Been Kicked from ${message.guild.name}`)
.setDescription(`Sending Scam Links`),
],
});
}
}
});
});
//Anti-Invite System
await inviteschema.findOne(
{ Server: message.guild.id },
async (err, data) => {
if (!data) return; //If No Invite System is set, do nothing
//Find Server that is Stored in Database
if (data.Server === message.guild.id) {
const InviteLinks = [
"discord.gg/",
"discord.com/invite/",
"discordapp.com/invite/",
]; //Types of Discord Server Invite Links
//Check to see if one of the Invite Links is in the message
if (
InviteLinks.some((link) =>
message.content.toLowerCase().includes(link)
)
) {
//Decode the User code out of the Invite Link
const UserCode = message.content.split(
"discord.gg/" || "discord.com/invite/" || "discordapp.com/invite/"
)[1];
//Fetch Invites Sent in the Server
message.guild.fetchInvites().then((invites) => {
let InviteArray = [];
for (let inviteCode of invites) {
InviteArray.push(inviteCode[0]);
}
//Check to see if the User Code is in the Invite Array, if it is, do nothing, if not its an outside server Invite
if (!InviteArray.includes(UserCode)) {
message.delete(); //Delete The Message Upon Getting An Outside Server Invite
return message.channel.send({
content: "Please do not send links to other servers",
});
}
});
}
}
}
);
//Counting game system, that tracks the current number via a Database
await counterSchema.findOne(
{ Guild: message.guild.id },
async (err, data) => {
//If No Counting Game is Set, Do Nothing
if (data == null) return;
if (message.channel.id !== data.Channel) return;
let number = parseInt(message.content); //Convert the current Message from a String to an Integer
let current = parseInt(data.Count); //Convert the Current Number from a String to an Integer
if(isNaN(number)){
message.delete() //Deletes the Message if it's not a Number.
}
if (!isNaN(number)) {
if (message.author.id == data.UserID) { //If the next Number sent is by the same user
message.delete() //Deletes the message sent by the same user.
} else { //Different User Sent a Number
if (number == current + 1) { //Checks to see if number sent is one greater than the current number
data.Count = data.Count + 1; //Set the new number in the database
data.UserID = message.author.id; //Set the user's ID to the database
await data.save();
message.react("✅"); //React with Success
}
else { //Number Sent is not one greater than the current number
message.delete() //Deletes the message with the wrong number
}
}
}
}
);
//Ghost Ping Detector
await ghostpingschema.findOne(
{ Guild: message.guild.id },
async (err, data) => {
//If System is not enabled, do nothig
if (!data || data.Guild == null) return;
//If no user is ping, do nothing
if (!message.mentions.members.first()) return;
//If the user pings itself, do nothing
if (message.mentions.members.first().id === message.author.id) return;
//Ghost Ping Timer
const time = 50000;
//Set the GhostPing into the Ghost-Ping Collection, with the ID of user who pinged
if (message.guild.id === data.Guild) {