Compare commits
9 commits
76f186f68e
...
f620993606
Author | SHA1 | Date | |
---|---|---|---|
f620993606 | |||
ca0b405b2c | |||
e0483fd89e | |||
d994f9ff26 | |||
e1a29c688d | |||
e176dc113f | |||
ab079fa0b2 | |||
75eaa21e93 | |||
d8c5ffa1d9 |
12 changed files with 1479 additions and 24 deletions
|
@ -1,6 +1,8 @@
|
||||||
token=YourToken
|
token=YourToken
|
||||||
clientId=BotClientId
|
clientId=BotClientId
|
||||||
guildId=DevGuildId
|
guildId=DevGuildId
|
||||||
|
ownerId=OwnerUserId
|
||||||
|
statusChannel=
|
||||||
uptimeURL=UptimeKumaOrWhateverStatusThingYouUseOrJustLeaveEmpty
|
uptimeURL=UptimeKumaOrWhateverStatusThingYouUseOrJustLeaveEmpty
|
||||||
uptimeInterval=60
|
uptimeInterval=60
|
||||||
twiConsumer=TwitterConsumerToken
|
twiConsumer=TwitterConsumerToken
|
||||||
|
|
|
@ -4,9 +4,16 @@
|
||||||
"node": true,
|
"node": true,
|
||||||
"es6": true
|
"es6": true
|
||||||
},
|
},
|
||||||
|
"parser": "@babel/eslint-parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2022,
|
"ecmaVersion": 2022,
|
||||||
"sourceType": "module"
|
"sourceType": "module",
|
||||||
|
"requireConfigFile": false,
|
||||||
|
"babelOptions": {
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-syntax-import-assertions"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"arrow-spacing": ["warn", { "before": true, "after": true }],
|
"arrow-spacing": ["warn", { "before": true, "after": true }],
|
||||||
|
|
|
@ -6,7 +6,7 @@ import os from 'node:os';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
|
||||||
import db from '../../models/index.js';
|
import db from '../../models/index.js';
|
||||||
import wordToCensor from '../../json/censor.json' assert {type: 'json'};;
|
import wordToCensor from '../../json/censor.json' assert {type: 'json'};
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
const { twiConsumer, twiConsumerSecret, twiToken, twiTokenSecret, twiChannel, twiLogChannel } = process.env;
|
const { twiConsumer, twiConsumerSecret, twiToken, twiTokenSecret, twiChannel, twiLogChannel } = process.env;
|
||||||
|
@ -28,21 +28,20 @@ export default {
|
||||||
ratelimit: 3,
|
ratelimit: 3,
|
||||||
cooldown: 3600,
|
cooldown: 3600,
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
await interaction.deferReply({ ephemeral: false });
|
await interaction.deferReply({ ephemeral: false });
|
||||||
const client = interaction.client;
|
|
||||||
let tweet = interaction.options.getString('content');
|
let tweet = interaction.options.getString('content');
|
||||||
const attachment = interaction.options.getAttachment('image');
|
const attachment = interaction.options.getAttachment('image');
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
// If account is less than 6 months old don't accept the tweet ( alt prevention )
|
// If account is less than 6 months old don't accept the tweet ( alt prevention )
|
||||||
if (interaction.user.createdAt > date.setMonth(date.getMonth() - 6)) {
|
if (interaction.user.createdAt > date.setMonth(date.getMonth() - 6)) {
|
||||||
await interaction.editReply({ content: 'Your account is too new to be able to use this command!' });
|
await interaction.editReply({ content: 'Your account is too new to be able to use this command!' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If account is less than 1 year old don't accept attachment
|
// If account is less than 1 year old don't accept attachment
|
||||||
if (attachment && interaction.user.createdAt > date.setFullYear(date.getFullYear() - 1)) {
|
if (attachment && interaction.user.createdAt > date.setFullYear(date.getFullYear() - 1)) {
|
||||||
await interaction.editReply({ content: 'Your account need to be 1 year or older to be able to send attachment!' });
|
await interaction.editReply({ content: 'Your account need to be 1 year or older to be able to send attachment!' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove zero width space
|
// remove zero width space
|
||||||
|
@ -57,20 +56,20 @@ export default {
|
||||||
Blacklists.create(body);
|
Blacklists.create(body);
|
||||||
|
|
||||||
await interaction.editReply({ content: 'Sike, you just posted cringe! Enjoy the blacklist :)' });
|
await interaction.editReply({ content: 'Sike, you just posted cringe! Enjoy the blacklist :)' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very simple link detection
|
// Very simple link detection
|
||||||
if (new RegExp('([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?').test(tweet) && !tweet.includes('twitter.com')) {
|
if (new RegExp('([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?').test(tweet) && !tweet.includes('twitter.com')) {
|
||||||
await interaction.editReply({ content: 'You may not tweet links outside of twitter.com' });
|
await interaction.editReply({ content: 'You may not tweet links outside of twitter.com' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do not allow discord invites
|
// Do not allow discord invites
|
||||||
if (tweet.includes('discord.gg') || tweet.includes('discord.com/invite/')) {
|
if (tweet.includes('discord.gg') || tweet.includes('discord.com/invite/')) {
|
||||||
await interaction.editReply({ content: 'No discord invite allowed.' });
|
await interaction.editReply({ content: 'No discord invite allowed.' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T = new Twit({
|
const T = new Twit({
|
||||||
consumer_key: twiConsumer,
|
consumer_key: twiConsumer,
|
||||||
|
@ -114,7 +113,7 @@ export default {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await interaction.editReply({ content: 'File type not supported, you can only send jpg/png/gif' });
|
await interaction.editReply({ content: 'File type not supported, you can only send jpg/png/gif' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -124,7 +123,7 @@ export default {
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
await interaction.editReply({ content: 'Oh no, an error has occurred :(' });
|
await interaction.editReply({ content: 'Oh no, an error has occurred :(' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Tweet(data) {
|
function Tweet(data) {
|
||||||
|
@ -167,10 +166,10 @@ export default {
|
||||||
let channel = interaction.client.channels.resolve(twiChannel);
|
let channel = interaction.client.channels.resolve(twiChannel);
|
||||||
channel.send(TweetLink);
|
channel.send(TweetLink);
|
||||||
|
|
||||||
const Embed = new MessageEmbed()
|
const Embed = new MessageEmbed()
|
||||||
.setAuthor({ name: interaction.user.username, iconURL: interaction.user.displayAvatarURL() })
|
.setAuthor({ name: interaction.user.username, iconURL: interaction.user.displayAvatarURL() })
|
||||||
.setDescription(tweet)
|
.setDescription(tweet)
|
||||||
.addField('Link', TweetLink, true)
|
.addField('Link', TweetLink, true)
|
||||||
.addField('Tweet ID', tweetid, true)
|
.addField('Tweet ID', tweetid, true)
|
||||||
.addField('Channel ID', interaction.channel.id, true)
|
.addField('Channel ID', interaction.channel.id, true)
|
||||||
.addField('Messsage ID', interaction.id, true)
|
.addField('Messsage ID', interaction.id, true)
|
||||||
|
@ -187,8 +186,8 @@ export default {
|
||||||
|
|
||||||
if (attachment) Embed.setImage(attachment.url);
|
if (attachment) Embed.setImage(attachment.url);
|
||||||
|
|
||||||
channel = interaction.client.channels.resolve(twiLogChannel);
|
channel = interaction.client.channels.resolve(twiLogChannel);
|
||||||
channel.send({ embeds: [Embed] });
|
channel.send({ embeds: [Embed] });
|
||||||
return interaction.editReply({ content: `Go see ur epic tweet ${TweetLink}` });
|
return interaction.editReply({ content: `Go see ur epic tweet ${TweetLink}` });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
48
events/client/guildCreate.js
Normal file
48
events/client/guildCreate.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import db from '../../models/index.js';
|
||||||
|
const guildBlacklist = db.guildBlacklist;
|
||||||
|
import { MessageEmbed } from 'discord.js';
|
||||||
|
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
const { statusChannel } = process.env;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'guildCreate',
|
||||||
|
once: true,
|
||||||
|
async execute(guild, client) {
|
||||||
|
const guildOwner = await client.users.fetch(guild.ownerId);
|
||||||
|
|
||||||
|
console.log(`${guild.name}\n${guild.memberCount} users\nOwner: ${guildOwner.username}\nOwner ID: ${guild.ownerId}`);
|
||||||
|
|
||||||
|
const blacklist = await guildBlacklist.findOne({ where: { guildID:guild.id } });
|
||||||
|
|
||||||
|
if (blacklist) {
|
||||||
|
guild.leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If stats channel settings exist, send bot stats to it
|
||||||
|
if (statusChannel) {
|
||||||
|
const channel = client.channels.resolve(statusChannel);
|
||||||
|
const botCount = guild.members.cache.filter(member => member.user.bot).size;
|
||||||
|
console.log(guild.memberCount);
|
||||||
|
const addEmbed = new MessageEmbed()
|
||||||
|
.setColor('#52e80d')
|
||||||
|
.setTitle('New boiz in town')
|
||||||
|
.setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4')
|
||||||
|
.setThumbnail(guild.iconURL())
|
||||||
|
.addField('Guild', `${guild.name} (${guild.id})`)
|
||||||
|
.addField('Total number of members', guild.memberCount.toString(), true)
|
||||||
|
.addField('Number of users', (guild.memberCount - botCount).toString(), true)
|
||||||
|
.addField('Number of bots', botCount.toString(), true)
|
||||||
|
.addField('Owner', `${guildOwner.username} (${guild.ownerId})`, true)
|
||||||
|
.setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` })
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (blacklist) {
|
||||||
|
return channel.send(`${guildOwner.username} (${guild.ownerId}) tried to add me to their guild while being blacklisted!\n${guild.name} (${guild.id})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.send({ embeds: [addEmbed] });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
44
events/client/guildDelete.js
Normal file
44
events/client/guildDelete.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import db from '../../models/index.js';
|
||||||
|
const guildBlacklist = db.guildBlacklist;
|
||||||
|
import { MessageEmbed } from 'discord.js';
|
||||||
|
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
const { statusChannel } = process.env;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'guildDelete',
|
||||||
|
once: true,
|
||||||
|
async execute(guild, client) {
|
||||||
|
const guildOwner = await client.users.fetch(guild.ownerId);
|
||||||
|
|
||||||
|
console.log(`***BOT KICKED***\n${guild.name}\n${guild.memberCount} users\nOwner: ${guildOwner.username}\nOwner ID: ${guild.ownerId}\n***BOT KICKED***`);
|
||||||
|
|
||||||
|
const blacklist = await guildBlacklist.findOne({ where: { guildID:guild.id } });
|
||||||
|
|
||||||
|
// If stats channel settings exist, send bot stats to it
|
||||||
|
if (statusChannel) {
|
||||||
|
const channel = client.channels.resolve(statusChannel);
|
||||||
|
const botCount = guild.members.cache.filter(member => member.user.bot).size;
|
||||||
|
console.log(guild.memberCount);
|
||||||
|
const kickEmbed = new MessageEmbed()
|
||||||
|
.setColor('#FF0000')
|
||||||
|
.setTitle('Some mofo just removed me from there guild :(')
|
||||||
|
.setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4')
|
||||||
|
.setThumbnail(guild.iconURL())
|
||||||
|
.addField('Guild', `${guild.name} (${guild.id})`)
|
||||||
|
.addField('Total number of members', guild.memberCount.toString(), true)
|
||||||
|
.addField('Number of users', (guild.memberCount - botCount).toString(), true)
|
||||||
|
.addField('Number of bots', botCount.toString(), true)
|
||||||
|
.addField('Owner', `${guildOwner.username} (${guild.ownerId})`, true)
|
||||||
|
.setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` })
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (blacklist) {
|
||||||
|
kickEmbed.setFooter({ text: kickEmbed.footer.text + ' | Left this guild because owner is blacklisted!' });
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.send({ embeds: [kickEmbed] });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
import { exec } from 'node:child_process';
|
import { exec } from 'node:child_process';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
const { statusChannel } = process.env;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ready',
|
name: 'ready',
|
||||||
|
@ -31,5 +32,11 @@ export default {
|
||||||
console.log(`There is \x1b[33m${commandSize}\x1b[0m command loaded.`);
|
console.log(`There is \x1b[33m${commandSize}\x1b[0m command loaded.`);
|
||||||
console.log(`Running yt-dlp \x1b[33m${ytdlpVersion.replace('\n', '')}\x1b[0m`);
|
console.log(`Running yt-dlp \x1b[33m${ytdlpVersion.replace('\n', '')}\x1b[0m`);
|
||||||
console.log('===========[ READY ]===========');
|
console.log('===========[ READY ]===========');
|
||||||
|
|
||||||
|
// If stats channel settings exist, send bot stats to it
|
||||||
|
if (statusChannel) {
|
||||||
|
const channel = client.channels.resolve(statusChannel);
|
||||||
|
channel.send(`Ready to serve in ${channelSize} channels on ${guildSize} servers.\nThere is ${commandSize} command loaded.\nRunning yt-dlp ${ytdlpVersion.replace('\n', '')}\n${client.readyAt}`);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
35
events/client/status.js
Normal file
35
events/client/status.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import game from '../../json/playing.json' assert {type: 'json'};
|
||||||
|
import watch from '../../json/watching.json' assert {type: 'json'};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ready',
|
||||||
|
once: true,
|
||||||
|
async execute(client) {
|
||||||
|
// Bot status
|
||||||
|
setStatus();
|
||||||
|
// Change status every 30 minutes
|
||||||
|
setInterval(async () => {
|
||||||
|
setStatus();
|
||||||
|
}, 1800000);
|
||||||
|
|
||||||
|
async function setStatus() {
|
||||||
|
const random = Math.floor((Math.random() * 2));
|
||||||
|
// Random "Watching" status taken from json
|
||||||
|
if (random === 0) {
|
||||||
|
console.log('Status type: \x1b[32mWatching\x1b[0m');
|
||||||
|
|
||||||
|
const status = watch[Math.floor((Math.random() * watch.length))];
|
||||||
|
console.log(`Setting status to: ${status}`);
|
||||||
|
client.user.setActivity(status, { type: 'WATCHING' });
|
||||||
|
}
|
||||||
|
// Random "Playing" status taken from json
|
||||||
|
else if (random === 1) {
|
||||||
|
console.log('Status type: \x1b[32mPlaying\x1b[0m');
|
||||||
|
|
||||||
|
const status = game[Math.floor((Math.random() * game.length))];
|
||||||
|
console.log(`Setting status to: ${status}`);
|
||||||
|
client.user.setActivity(status, { type: 'PLAYING' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
5
index.js
5
index.js
|
@ -15,6 +15,7 @@ const client = new Client({ intents: [Intents.FLAGS.GUILDS], shards: 'auto' });
|
||||||
client.commands = new Collection();
|
client.commands = new Collection();
|
||||||
await loadCommandFromDir('fun');
|
await loadCommandFromDir('fun');
|
||||||
await loadCommandFromDir('utility');
|
await loadCommandFromDir('utility');
|
||||||
|
await loadCommandFromDir('admin');
|
||||||
await loadCommandFromDir('owner');
|
await loadCommandFromDir('owner');
|
||||||
|
|
||||||
// Load events
|
// Load events
|
||||||
|
@ -45,10 +46,10 @@ async function loadEventFromDir(dir, listener) {
|
||||||
let event = await import(filePath);
|
let event = await import(filePath);
|
||||||
event = event.default;
|
event = event.default;
|
||||||
if (event.once) {
|
if (event.once) {
|
||||||
listener.once(event.name, (...args) => event.execute(...args));
|
listener.once(event.name, (...args) => event.execute(...args, client));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
listener.on(event.name, (...args) => event.execute(...args));
|
listener.on(event.name, (...args) => event.execute(...args, client));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
3
json/playing.json
Normal file
3
json/playing.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
"/feedback <feedback> to tell me what you think of the bot!", "Did you know? This bot used to run on a Raspberry Pi & a hacked Playstation 4!", "with you", "waluigi taco stand", "Minecraft", "super smash bros", "mario kart wii", "Cult of the lamb", "SOMEONE SEND HELP PLEASE, IM STUCK IN THIS BOT", "alone", "You can support me with the donate command!"
|
||||||
|
]
|
3
json/watching.json
Normal file
3
json/watching.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
"you", "everything you type", "Le funny meme", "my wee wee grow", "the world burn"
|
||||||
|
]
|
1304
package-lock.json
generated
1304
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -29,6 +29,8 @@
|
||||||
"twit": "^2.2.11"
|
"twit": "^2.2.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/eslint-parser": "^7.18.9",
|
||||||
|
"@babel/plugin-syntax-import-assertions": "^7.18.6",
|
||||||
"@types/node": "^18.7.3",
|
"@types/node": "^18.7.3",
|
||||||
"eslint": "^8.16.0",
|
"eslint": "^8.16.0",
|
||||||
"sequelize-cli": "^6.4.1"
|
"sequelize-cli": "^6.4.1"
|
||||||
|
|
Loading…
Reference in a new issue