Initial commit
This commit is contained in:
5
example.env
Normal file
5
example.env
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
DISCORD_TOKEN=MTI4MDQ0NDY1MjUyODQ2Nz...
|
||||||
|
DISCORD_APPLICATION_ID=12804446...
|
||||||
|
GIPHY_API_KEY=mg7MHuxn42R4TE33...
|
||||||
|
PLANTNET_API_KEY=2b10p4Zb7K...
|
||||||
|
OMDB_API_KEY=96e...
|
||||||
46
lib/utilities/commandModules.js
Normal file
46
lib/utilities/commandModules.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { glob } from 'glob';
|
||||||
|
import { ApplicationCommand } from 'discord.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all command modules from the commands directory.
|
||||||
|
* @returns {Promise<string[]>} The file paths of all command modules.
|
||||||
|
*/
|
||||||
|
async function getCommandModulePaths() {
|
||||||
|
return await glob(path.join(process.cwd(), 'src/commands/**/*.js'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a single command module.
|
||||||
|
* @param {string} modulePath The path to the command module.
|
||||||
|
* @returns {Promise<ApplicationCommand>} The loaded command module.
|
||||||
|
*/
|
||||||
|
async function loadCommandModule(modulePath) {
|
||||||
|
try {
|
||||||
|
const module = await import(path.resolve(modulePath));
|
||||||
|
const commandModule = module.default;
|
||||||
|
|
||||||
|
if (!commandModule.data || !commandModule.execute) {
|
||||||
|
console.warn(`Invalid command module at ${modulePath}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(`Loaded command module: ${commandModule.data.name}`);
|
||||||
|
return commandModule;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error loading module at ${modulePath}.`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all command modules.
|
||||||
|
* @returns {Promise<ApplicationCommand[]>} The loaded command modules.
|
||||||
|
*/
|
||||||
|
export async function loadCommandModules() {
|
||||||
|
const commandModulePaths = await getCommandModulePaths();
|
||||||
|
const commandModules = await Promise.all(
|
||||||
|
commandModulePaths.map(loadCommandModule)
|
||||||
|
);
|
||||||
|
|
||||||
|
return commandModules.filter((module) => module);
|
||||||
|
}
|
||||||
1925
package-lock.json
generated
Normal file
1925
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
package.json
Normal file
28
package.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "butlerbotng",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node --env-file .env src/index.js",
|
||||||
|
"register-slash-commands": "node --env-file .env src/register-slash-commands.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.3t.network/terriblecodeclub/butlerbotng.git"
|
||||||
|
},
|
||||||
|
"author": "Butlersaurus",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.7.7",
|
||||||
|
"date-fns": "^3.6.0",
|
||||||
|
"discord.js": "^14.16.1",
|
||||||
|
"glob": "^11.0.0",
|
||||||
|
"prettier": "^3.3.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^9.9.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/commands/lookup/domain.js
Normal file
56
src/commands/lookup/domain.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const GODADDY_API_URL = 'https://api.godaddy.com/v1/domains/available';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('domain')
|
||||||
|
.setDescription('Check the availability and price of a domain name.')
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('domain')
|
||||||
|
.setDescription('The domain to check')
|
||||||
|
.setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const domain = interaction.options.getString('domain');
|
||||||
|
let embed = new EmbedBuilder().setTitle('Domain checker');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(GODADDY_API_URL, {
|
||||||
|
params: { domain: domain },
|
||||||
|
headers: { Authorization: `sso-key ${process.env.GODADDY_API_KEY}` },
|
||||||
|
timeout: 5000,
|
||||||
|
});
|
||||||
|
console.log(`Got response for domain: ${domain}.`, response.data);
|
||||||
|
|
||||||
|
const result = response.data;
|
||||||
|
let isDomainAvailable = 'No.';
|
||||||
|
let color = 0xff0000;
|
||||||
|
let price = null;
|
||||||
|
|
||||||
|
if (response.status === 200 && result.available) {
|
||||||
|
isDomainAvailable = 'Yes!';
|
||||||
|
color = 0x00ff00;
|
||||||
|
price = (result.price / 1000000).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
embed.setColor(color).addFields({
|
||||||
|
name: 'Is the domain available?',
|
||||||
|
value: isDomainAvailable,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (price) {
|
||||||
|
embed.addFields({ name: 'Price', value: `$${price}` });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error looking up domain: ${domain}.`, error);
|
||||||
|
await interaction.reply('An error occurred when querying the GoDaddy API.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
71
src/commands/lookup/imdb.js
Normal file
71
src/commands/lookup/imdb.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const OMDB_API_URL = 'http://www.omdbapi.com/?apikey={apiKey}';
|
||||||
|
const FIELDS = [
|
||||||
|
'Title',
|
||||||
|
'Year',
|
||||||
|
'Rated',
|
||||||
|
'Released',
|
||||||
|
'Genre',
|
||||||
|
'Director',
|
||||||
|
'Actors',
|
||||||
|
'Plot',
|
||||||
|
'imdbRating',
|
||||||
|
'BoxOffice',
|
||||||
|
];
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('imdb')
|
||||||
|
.setDescription('Return IMDB listing for the specified film.')
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('film_name')
|
||||||
|
.setDescription('The name of the film')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
.addIntegerOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('film_year')
|
||||||
|
.setDescription('The year the specified film was released')
|
||||||
|
.setMinValue(1800)
|
||||||
|
.setMaxValue(2100)
|
||||||
|
);
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const filmName = interaction.options.getString('film_name');
|
||||||
|
const filmYear = interaction.options.getInteger('film_year');
|
||||||
|
let embed = new EmbedBuilder().setTitle('IMDB').setColor(0xf5de50);
|
||||||
|
|
||||||
|
let omdbQueryUrl = OMDB_API_URL.replace('{apiKey}', process.env.OMDB_API_KEY);
|
||||||
|
omdbQueryUrl += `&t=${encodeURIComponent(filmName.toLowerCase())}`;
|
||||||
|
|
||||||
|
if (filmYear) {
|
||||||
|
omdbQueryUrl += `&y=${filmYear}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(omdbQueryUrl, { timeout: 5000 });
|
||||||
|
const result = response.data;
|
||||||
|
|
||||||
|
FIELDS.forEach((field) => {
|
||||||
|
const fieldValue = result[field];
|
||||||
|
if (fieldValue) {
|
||||||
|
embed.addFields({ name: field, value: fieldValue });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const poster = result.Poster;
|
||||||
|
if (poster) {
|
||||||
|
embed.setImage(poster);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error looking up film: ${filmName}.`, error);
|
||||||
|
await interaction.reply('An error occurred when querying the OMDB API.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
75
src/commands/lookup/plant.js
Normal file
75
src/commands/lookup/plant.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const API_URL = 'https://my-api.plantnet.org/v2/identify/all?api-key={apiKey}';
|
||||||
|
const LEAF_THUMBNAIL =
|
||||||
|
'https://cdn.discordapp.com/attachments/870024275556446328/1006249009201033287/monstera.png';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('plant')
|
||||||
|
.setDescription('Identify a plant by uploading an image.')
|
||||||
|
.addAttachmentOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('image')
|
||||||
|
.setDescription('The image of the plant to identify')
|
||||||
|
.setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const image = interaction.options.getAttachment('image');
|
||||||
|
let embed = new EmbedBuilder()
|
||||||
|
.setTitle('Plant Detector™️')
|
||||||
|
.setThumbnail(LEAF_THUMBNAIL)
|
||||||
|
.setColor(0xff0000);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
API_URL.replace('{apiKey}', process.env.PLANTNET_API_KEY),
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
images: image.url,
|
||||||
|
organs: 'leaf',
|
||||||
|
},
|
||||||
|
timeout: 5000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const bestMatch = response.data.results[0];
|
||||||
|
const commonName =
|
||||||
|
bestMatch.species.commonNames[0] || 'No common name found';
|
||||||
|
const scientificName = bestMatch.species.scientificNameWithoutAuthor;
|
||||||
|
const confidence = parseFloat(bestMatch.score);
|
||||||
|
|
||||||
|
let detail = '';
|
||||||
|
|
||||||
|
if (0.0 <= confidence && confidence < 0.25) {
|
||||||
|
detail = `I'm really not sure, but I think that looks like a **${commonName}**?`;
|
||||||
|
} else if (0.25 <= confidence && confidence < 0.5) {
|
||||||
|
detail = `I think that looks like a **${commonName}**!`;
|
||||||
|
} else if (0.5 <= confidence && confidence < 0.75) {
|
||||||
|
detail = `That looks like a **${commonName}**!`;
|
||||||
|
} else if (confidence >= 0.75) {
|
||||||
|
detail = `That is a really cool **${commonName}**!`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUrl = `https://www.google.com/search?q=${encodeURIComponent(commonName || scientificName)}&tbm=isch`;
|
||||||
|
|
||||||
|
detail += `\n\n**Scientific Name**: ${scientificName}`;
|
||||||
|
detail += `\n\n**Images**: [More images](${imageUrl})`;
|
||||||
|
detail += `\n\n**Confidence**: ${(confidence * 100).toFixed(3)}%`;
|
||||||
|
|
||||||
|
embed
|
||||||
|
.setColor(0x00ff00)
|
||||||
|
.addFields({ name: 'Plant Details', value: detail });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error looking up plant: ${image.url}`, error);
|
||||||
|
await interaction.reply(
|
||||||
|
'An error occurred when querying the PlantNet API.'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
14
src/commands/memes/2020.js
Normal file
14
src/commands/memes/2020.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const TWENTY_TWENTY_IMAGE =
|
||||||
|
'https://cdn.discordapp.com/attachments/506852356898422797/765256712063025172/unknown.png';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('2020')
|
||||||
|
.setDescription('Returns a tweet from Boris, posted on 2 January 2020.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
await interaction.reply(TWENTY_TWENTY_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
45
src/commands/memes/8ball.js
Normal file
45
src/commands/memes/8ball.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('8ball')
|
||||||
|
.setDescription('Returns a Magic 8 ball response.')
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName('question')
|
||||||
|
.setDescription('The question to ask the Magic 8 ball')
|
||||||
|
.setRequired(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
const MAGIC_EIGHT_BALL_RESPONSES = [
|
||||||
|
'As I see it, yes.',
|
||||||
|
'Ask again later.',
|
||||||
|
'Better not tell you now.',
|
||||||
|
'Cannot predict now.',
|
||||||
|
'Concentrate and ask again.',
|
||||||
|
"Don't count on it.",
|
||||||
|
'It is certain.',
|
||||||
|
'It is decidedly so.',
|
||||||
|
'Most likely.',
|
||||||
|
'My reply is no.',
|
||||||
|
'My sources say no.',
|
||||||
|
'Outlook not so good.',
|
||||||
|
'Outlook good.',
|
||||||
|
'Reply hazy, try again.',
|
||||||
|
'Signs point to yes.',
|
||||||
|
'Very doubtful.',
|
||||||
|
'Without a doubt.',
|
||||||
|
'Yes.',
|
||||||
|
'Yes - definitely.',
|
||||||
|
'You may rely on it.',
|
||||||
|
];
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const randomIndex = Math.floor(
|
||||||
|
Math.random() * MAGIC_EIGHT_BALL_RESPONSES.length
|
||||||
|
);
|
||||||
|
const response = MAGIC_EIGHT_BALL_RESPONSES[randomIndex];
|
||||||
|
|
||||||
|
await interaction.reply(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
60
src/commands/memes/birthday.js
Normal file
60
src/commands/memes/birthday.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
import {
|
||||||
|
format,
|
||||||
|
differenceInYears,
|
||||||
|
differenceInMonths,
|
||||||
|
differenceInDays,
|
||||||
|
addYears,
|
||||||
|
isToday,
|
||||||
|
} from 'date-fns';
|
||||||
|
|
||||||
|
const BIRTHDAY_TIMESTAMP = 1582576229;
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('birthday')
|
||||||
|
.setDescription("Returns ButlerBot's Birthday information.");
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const today = new Date();
|
||||||
|
const birthday = new Date(BIRTHDAY_TIMESTAMP * 1000);
|
||||||
|
|
||||||
|
const ageYears = differenceInYears(today, birthday);
|
||||||
|
const ageMonths = differenceInMonths(today, birthday) % 12;
|
||||||
|
const ageDays = differenceInDays(today, addYears(birthday, ageYears)) % 30;
|
||||||
|
|
||||||
|
let ageMessage = `I am ${ageYears} year`;
|
||||||
|
ageMessage += ageYears !== 1 ? 's, ' : ', ';
|
||||||
|
ageMessage += `${ageMonths} month`;
|
||||||
|
ageMessage += ageMonths !== 1 ? 's ' : ' ';
|
||||||
|
ageMessage += `and ${ageDays} day`;
|
||||||
|
ageMessage += ageDays !== 1 ? 's ' : ' ';
|
||||||
|
ageMessage += 'old!';
|
||||||
|
|
||||||
|
let birthdayMessage = `I was created on ${format(birthday, 'dd MMMM yyyy')}.`;
|
||||||
|
|
||||||
|
const nextBirthdayYear =
|
||||||
|
today.getMonth() > birthday.getMonth() ||
|
||||||
|
(today.getMonth() === birthday.getMonth() &&
|
||||||
|
today.getDate() >= birthday.getDate())
|
||||||
|
? today.getFullYear() + 1
|
||||||
|
: today.getFullYear();
|
||||||
|
const nextBirthday = new Date(
|
||||||
|
nextBirthdayYear,
|
||||||
|
birthday.getMonth(),
|
||||||
|
birthday.getDate()
|
||||||
|
);
|
||||||
|
const countdown = differenceInDays(nextBirthday, today);
|
||||||
|
|
||||||
|
if (isToday(nextBirthday)) {
|
||||||
|
birthdayMessage += " It's my Birthday today!";
|
||||||
|
} else if (countdown === 1) {
|
||||||
|
birthdayMessage += " It's my Birthday tomorrow!";
|
||||||
|
} else {
|
||||||
|
birthdayMessage += ` It's my Birthday in ${countdown} days!`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullMessage = `${ageMessage} ${birthdayMessage}`;
|
||||||
|
await interaction.reply(fullMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
16
src/commands/memes/corrupt.js
Normal file
16
src/commands/memes/corrupt.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const CORRUPT_IMAGE =
|
||||||
|
'https://media.discordapp.net/attachments/506852356898422797/717395817626861638/isntthatcorrupt2.PNG';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('corrupt')
|
||||||
|
.setDescription(
|
||||||
|
"Returns a powerful quote from Neil Breen's infamous indie film, Pass Thru (2016)."
|
||||||
|
);
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
await interaction.reply(CORRUPT_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
40
src/commands/memes/eyecandy.js
Normal file
40
src/commands/memes/eyecandy.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const GIPHY_API_URL = 'http://api.giphy.com/v1/gifs/search';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('eyecandy')
|
||||||
|
.setDescription('Returns a random gif of Gerard Butler.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const giphyApiKey = process.env.GIPHY_API_KEY;
|
||||||
|
|
||||||
|
if (!giphyApiKey) {
|
||||||
|
await interaction.reply(
|
||||||
|
'The bot has not been configured with a Giphy API key.'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomOffset = Math.floor(Math.random() * 100);
|
||||||
|
const giphyQueryUrl = `${GIPHY_API_URL}?api_key=${giphyApiKey}&q=gerard+butler&limit=1&offset=${randomOffset}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(giphyQueryUrl, { timeout: 5000 });
|
||||||
|
const result = response.data;
|
||||||
|
|
||||||
|
if (result.data.length === 0) {
|
||||||
|
await interaction.reply('No gifs found.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUrl = result.data[0].images.original.url;
|
||||||
|
await interaction.reply(imageUrl);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error querying the Giphy API:', error);
|
||||||
|
await interaction.reply('An error occurred when querying the Giphy API.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
139
src/commands/memes/kanye.js
Normal file
139
src/commands/memes/kanye.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const KANYE_QUOTES = [
|
||||||
|
'2024.',
|
||||||
|
'All you have to be is yourself.',
|
||||||
|
'Believe in your flyness... conquer your shyness.',
|
||||||
|
'Burn that Excel spreadsheet.',
|
||||||
|
'Decentralize.',
|
||||||
|
'Distraction is the enemy of vision.',
|
||||||
|
'Everything you do in life stems from either fear or love.',
|
||||||
|
'For me giving up is way harder than trying.',
|
||||||
|
'For me, money is not my definition of success. Inspiring people is a definition of success.',
|
||||||
|
'Fur pillows are hard to actually sleep on.',
|
||||||
|
"George Bush doesn't care about black people.",
|
||||||
|
'Have you ever thought you were in love with someone but then realized you were just staring in a mirror for 20 minutes?',
|
||||||
|
'I care. I care about everything. Sometimes not giving a f#%k is caring the most.',
|
||||||
|
'I feel calm but energized.',
|
||||||
|
"I feel like I'm too busy writing history to read it.",
|
||||||
|
'I feel like me and Taylor might still have sex.',
|
||||||
|
'I give up drinking every week.',
|
||||||
|
'I leave my emojis Bart Simpson color.',
|
||||||
|
"I love sleep; it's my favorite.",
|
||||||
|
'I make awesome decisions in bike stores!!!',
|
||||||
|
"I really love my Tesla. I'm in the future. Thank you Elon.",
|
||||||
|
'I still think I am the greatest.',
|
||||||
|
"I think I do myself a disservice by comparing myself to Steve Jobs and Walt Disney and human beings that we've seen before. It should be more like Willy Wonka...and welcome to my chocolate factory.",
|
||||||
|
'I want the world to be better! All I want is positive! All I want is dopeness!',
|
||||||
|
'I wish I had a friend like me.',
|
||||||
|
"I'd like to meet with Tim Cook. I got some ideas.",
|
||||||
|
"I'll say things that are serious and put them in a joke form so people can enjoy them. We laugh to keep from crying.",
|
||||||
|
"I'm a creative genius.",
|
||||||
|
"I'm nice at ping pong.",
|
||||||
|
"I'm the best.",
|
||||||
|
"If I don't scream, if I don't say something then no one's going to say anything.",
|
||||||
|
'If I got any cooler I would freeze to death.',
|
||||||
|
"If you have the opportunity to play this game of life you need to appreciate every moment. a lot of people don't appreciate the moment until it's passed.",
|
||||||
|
'Just stop lying about shit. Just stop lying.',
|
||||||
|
'Keep squares out yo circle.',
|
||||||
|
'Keep your nose out the sky, keep your heart to god, and keep your face to the rising sun.',
|
||||||
|
"Let's be like water.",
|
||||||
|
'Man... whatever happened to my antique fish tank?',
|
||||||
|
'My dad got me a drone for Christmas.',
|
||||||
|
"My greatest award is what I'm about to do.",
|
||||||
|
'My greatest pain in life is that I will never be able to see myself perform live.',
|
||||||
|
"One day I'm gon' marry a porn star.",
|
||||||
|
"One of my favorite of many things about what the Trump hat represents to me is that people can't tell me what to do because I'm black.",
|
||||||
|
'Only free thinkers.',
|
||||||
|
"People always say that you can't please everybody. I think that's a cop-out. Why not attempt it? Cause think of all the people that you will please if you try.",
|
||||||
|
"People always tell you 'Be humble. Be humble.' When was the last time someone told you to be amazing? Be great! Be awesome! Be awesome!",
|
||||||
|
'People only get jealous when they care.',
|
||||||
|
'Perhaps I should have been more like water today.',
|
||||||
|
'Pulling up in the may bike.',
|
||||||
|
'Shut the fuck up I will fucking laser you with alien fucking eyes and explode your fucking head.',
|
||||||
|
'Sometimes I push the door close button on people running towards the elevator. I just need my own elevator sometimes. My sanctuary.',
|
||||||
|
'Sometimes you have to get rid of everything.',
|
||||||
|
'Style is genderless.',
|
||||||
|
'The thought police want to suppress freedom of thought.',
|
||||||
|
'The world is our family.',
|
||||||
|
'The world is our office.',
|
||||||
|
"Today is the best day ever and tomorrow's going to be even better.",
|
||||||
|
"Truth is my goal. Controversy is my gym. I'll do a hundred reps of controversy for a 6 pack of truth.",
|
||||||
|
'Tweeting is legal and also therapeutic.',
|
||||||
|
"We all self-conscious. I'm just the first to admit it.",
|
||||||
|
"We came into a broken world. And we're the cleanup crew.",
|
||||||
|
"You can't look at a glass half full or empty if it's overflowing.",
|
||||||
|
"I hate when I'm on a flight and I wake up with a water bottle next to me like oh great now I gotta be responsible for this water bottle.",
|
||||||
|
'All the musicians will be free.',
|
||||||
|
'Artists are founders.',
|
||||||
|
'Buy property.',
|
||||||
|
'Culture is the most powerful force in humanity under God.',
|
||||||
|
'Empathy is the glue.',
|
||||||
|
'I am one of the most famous people on the planet.',
|
||||||
|
'I am running for President of the United States.',
|
||||||
|
'I am the head of Adidas. I will bring Adidas and Puma back together and bring me and jay back together.',
|
||||||
|
'I am Warhol. I am the No. 1 most impactful artist of our generation. I am Shakespeare in the flesh.',
|
||||||
|
"I channel Will Ferrell when I'm at the daddy daughter dances.",
|
||||||
|
"I don't wanna see no woke tweets or hear no woke raps ... it's show time ... it's a whole different energy right now.",
|
||||||
|
'I hear people say this person is cool and this person is not cool. People are cool. Man has never invented anything as awesome as a an actual person but sometimes we value the objects we create over life itself.',
|
||||||
|
'I honestly need all my Royeres to be museum quality... if I see a fake Royere Ima have to Rick James your couch.',
|
||||||
|
'I love UZI. I be saying the same thing about Steve Jobs. I be feeling just like UZI.',
|
||||||
|
'I need an army of angels to cover me while I pull this sword out of the stone.',
|
||||||
|
'I spoke to Dave Chapelle for two hours this morning. He is our modern day Socrates.',
|
||||||
|
'I was just speaking with someone that told me their life story and they used to be homeless.',
|
||||||
|
'I watch Bladerunner on repeat.',
|
||||||
|
"I'm giving all Good music artists back the 50% share I have of their masters.",
|
||||||
|
"I'm going to personally see to it that Taylor Swift gets her masters back. Scooter is a close family friend.",
|
||||||
|
"I'm the new Moses.",
|
||||||
|
'Life is the ultimate gift.',
|
||||||
|
'Ma$e is one of my favorite rappers and I based a lot of my flows off of him.',
|
||||||
|
'Manga all day.',
|
||||||
|
"My first pillar when I'm on the board of adidas will be an adidas Nike collaboration to support community growth.",
|
||||||
|
"My mama was a' English teacher. I know how to use correct English but sometimes I just don't feel like it aaaand I ain't got to.",
|
||||||
|
'My memories are from the future.',
|
||||||
|
'My mother in law Kris Jenner ... makes the best music playlist.',
|
||||||
|
"People say it's enough and I got my point across ... the point isn't across until we cross the point.",
|
||||||
|
'People tried to talk me out of running for President. Never let weak controlling people kill your spirit.',
|
||||||
|
'So many of us need so much less than we have especially when so many of us are in need.',
|
||||||
|
"Speak God's truth to power.",
|
||||||
|
'The media tries to kill our heroes one at a time.',
|
||||||
|
'The world needs more Joy... this idea is super fresh.',
|
||||||
|
'There are 5 main pillars in a professional musicians business - Recording, Publishing, Touring, Merchandise & Name and likeness.',
|
||||||
|
'There are people sleeping in parking lots.',
|
||||||
|
"There's a crying need for civility across the board. We need to and will come together in the name of Jesus.",
|
||||||
|
"There's so many lonely emojis man.",
|
||||||
|
"Trust me ... I won't stop.",
|
||||||
|
'Two years ago we had 50 million people subscribed to music streaming services around the world. Today we have 400 million.',
|
||||||
|
'We are here to complete the revolution. We are building the future.',
|
||||||
|
'We as a people will heal. We will insure the well being of each other.',
|
||||||
|
'We have to evolve.',
|
||||||
|
'We must and will cure homelessness and hunger. We have the capability as a species.',
|
||||||
|
'We must form a union. We must unify.',
|
||||||
|
'We used to diss Michael Jackson the media made us call him crazy ... then they killed him.',
|
||||||
|
'We will be recognized.',
|
||||||
|
'We will change the paradigm.',
|
||||||
|
'We will cure hunger.',
|
||||||
|
'We will heal. We will cure.',
|
||||||
|
"We're going to move the entire music industry into the 21st Century.",
|
||||||
|
"We've gotten comfortable with not having what we deserve.",
|
||||||
|
'Who made up the term major label in the first place???',
|
||||||
|
'Winning is the only option.',
|
||||||
|
"For me to say I wasn't a genius I'd just be lying to you and to myself.",
|
||||||
|
"I've known my mom since I was zero years old. She is quite dope.",
|
||||||
|
"I don't expect to be understood at all.",
|
||||||
|
"I'm on the pursuit of awesomeness, excellence is the bare minimum.",
|
||||||
|
'You basically can say anything to someone on an email or text as long as you put LOL at the end.',
|
||||||
|
];
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('kanye')
|
||||||
|
.setDescription('Returns a random Kanye West quote.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * KANYE_QUOTES.length);
|
||||||
|
const quote = KANYE_QUOTES[randomIndex];
|
||||||
|
|
||||||
|
await interaction.reply(quote);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
14
src/commands/memes/reminder.js
Normal file
14
src/commands/memes/reminder.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const REMINDER_IMAGE =
|
||||||
|
'https://media.discordapp.net/attachments/506852356898422797/715690132883111996/Capture.PNG';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('reminder')
|
||||||
|
.setDescription('Returns an image which must always be remembered.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
await interaction.reply(REMINDER_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
184
src/commands/memes/taylor.js
Normal file
184
src/commands/memes/taylor.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const TAYLOR_QUOTES = [
|
||||||
|
"I don't know what I want, so don't ask me, 'cause I'm still trying to figure it out.",
|
||||||
|
'When you think Tim McGraw, I hope you think of me.',
|
||||||
|
'So watch me strike a match on all my wasted time.',
|
||||||
|
"I'll be strong, I'll be wrong, oh but life goes on…",
|
||||||
|
'And when you take, you take the very best of me.',
|
||||||
|
"But no one notices until it's too late to do anything.",
|
||||||
|
"Our song is the slamming screen door, sneakin' out late, tapping on your window.",
|
||||||
|
"And I don't know why, but with you I'd dance in a storm in my best dress, fearless.",
|
||||||
|
"But in your life, you'll do things greater than dating the boy on the football team…But I didn't know it at fifteen.",
|
||||||
|
"I've found time can heal most anything and you just might find who you're supposed to be.",
|
||||||
|
"Romeo, save me. They're trying to tell me how to feel. This love is difficult but it's real.",
|
||||||
|
'Why are people always leaving? I think you and I should stay the same.',
|
||||||
|
"My mistake, I didn't know to be in love you had to fight to have the upper hand.",
|
||||||
|
'This is a big world, that was a small town there in my rear view mirror disappearing now.',
|
||||||
|
"You've got a smile that could light up this whole town.",
|
||||||
|
"And we know it's never simple, never easy. Never a clean break, no one here to save me.",
|
||||||
|
'You took a swing, I took it hard. And down here from the ground I see who you are.',
|
||||||
|
"All this time I was wasting, hoping you would come around… I've been giving out chances every time and all you do is let me down.",
|
||||||
|
"And then you feel so low you can't feel nothing at all.",
|
||||||
|
"It rains when you're here and it rains when you're gone.",
|
||||||
|
'These walls that they put up to hold us back will fall down…',
|
||||||
|
"My mind forgets to remind me you're a bad idea.",
|
||||||
|
"It turns out freedom ain't nothing but missing you.",
|
||||||
|
"She floats down the aisle like a pageant queen, but I know you wish it was me… don't you?",
|
||||||
|
'I lived in your chess game, but you changed the rules every day.',
|
||||||
|
"I'm shining like fireworks over your sad, empty town.",
|
||||||
|
"Someday I'll be living in a big, old city and all you're ever gonna be is mean.",
|
||||||
|
"I'd tell you I miss you, but I don't know how, I've never heard silence quite this loud.",
|
||||||
|
'This is looking like a contest of who can act like they care less. But I liked it better when you were on my side.',
|
||||||
|
"And don't lose the way that you dance around in your pj's getting ready for school.",
|
||||||
|
"This night is sparkling, don't you let it go. I'm wonderstruck, blushing all the way home.",
|
||||||
|
'2AM, who do you love?',
|
||||||
|
"Your string of lights is still bright to me… Who you are is not where you've been.",
|
||||||
|
'Today is never too late to be brand new.',
|
||||||
|
"You and I walk a fragile line; I have known it all this time. But I never thought I'd live to see it break.",
|
||||||
|
"I don't know how to be something you miss.",
|
||||||
|
'Bring on all the pretenders. One day, we will be remembered.',
|
||||||
|
"So don't you worry your pretty, little mind, people throw rocks at things that shine.",
|
||||||
|
"We are alone with our changing minds. We fall in love 'til it hurts or bleeds or fades in time.",
|
||||||
|
'Love is a ruthless game unless you play it good and right.',
|
||||||
|
"He's long gone when he's next to me and I realize the blame is on me.",
|
||||||
|
"No apologies. He'll never see you cry. Pretends he doesn't know that he's the reason why.",
|
||||||
|
'The saddest fear comes creeping in - that you never loved me or her, or anyone, or anything...',
|
||||||
|
"…That magic's not here no more. And I might be OK, but I'm not fine at all.",
|
||||||
|
"And your mother's telling stories about you on a tee ball team. You taught me 'bout your past, thinking your future was me.",
|
||||||
|
'I forget about you long enough to forget why I needed to...',
|
||||||
|
"Maybe we got lost in translation, maybe I asked for too much. But maybe this thing was a masterpiece 'til you tore it all up. Running scared, I was there, I remember it all too well.",
|
||||||
|
'You call me up again just to break me like a promise, so casually cruel in the name of being honest.',
|
||||||
|
"Time won't fly, it's like I'm paralyzed by it. I'd like to be my old self again, but I'm still trying to find it.",
|
||||||
|
"Cause there we are again, when I loved you so, back before you lost the one, real thing you've ever known.",
|
||||||
|
"Now you mail back my things and I walk home alone, but you keep my old scarf from that very first week, 'cause it reminds you of innocence and it smells like me.",
|
||||||
|
"Stay, and I'll be loving you for quite some time. No one else is gonna love me when I get mad.",
|
||||||
|
"We're happy, free, confused, and lonely at the same time. It's miserable and magical.",
|
||||||
|
"I wish I could run to you. And I hope you know that every time I don't I almost do.",
|
||||||
|
'You wear your best apology, but I was there to watch you leave.',
|
||||||
|
'But sometimes I wonder how you think about it now.',
|
||||||
|
"But I don't wanna dance if I'm not dancing with you.",
|
||||||
|
"Words, how little they mean when you're a little too late.",
|
||||||
|
"And they tell you that you're lucky, but you're so confused, 'cause you don't feel pretty, you just feel used.",
|
||||||
|
"I've been spending the last eight months thinking all love ever does is break and burn and end...",
|
||||||
|
"And what do you do when the one who means the most to you is the one who didn't show?",
|
||||||
|
"Your close friends always seem to know when there's something really wrong",
|
||||||
|
'You called me later and said, "I\'m sorry I didn\'t make it". And I said, "I\'m sorry, too".',
|
||||||
|
'Loving him is like driving a new Maserati down a dead-end street - faster than the wind, passionate as sin, ending so suddenly.',
|
||||||
|
'The lights are so bright, but they never blind me.',
|
||||||
|
"Love's a game, wanna play?",
|
||||||
|
"So it's gonna be forever or it's gonna go down in flames.",
|
||||||
|
"But you'll come back each time you leave 'cause darling, I'm a nightmare dressed like a daydream.",
|
||||||
|
"When we go crashing down, we come back every time 'cause we never go out of style.",
|
||||||
|
'I got that red lip, classic thing that you like.',
|
||||||
|
'The rest of the world was black and white, but we were in screaming color.',
|
||||||
|
'The more I think about it now, the less I know, all I know is that you drove us off the road.',
|
||||||
|
'People like you always want back the love they pushed aside, but people like me are gone forever when you say goodbye.',
|
||||||
|
"Why'd you have to go and lock me out when I let you in?",
|
||||||
|
"While you've been getting down and out about the liars and the dirty, dirty cheats of the world… You could've been getting down to this sick beat.",
|
||||||
|
"We're a crooked love in a straight line down.",
|
||||||
|
'And I wish you knew that I miss you too much to be mad anymore.',
|
||||||
|
'You give me everything and nothing.',
|
||||||
|
'Makes you wanna run and hide, but it made us turn right back around.',
|
||||||
|
"Band-aids don't fix bullet holes. You say sorry just for show.",
|
||||||
|
'Someday when you leave me, I bet these memories follow you around.',
|
||||||
|
"When you're young, you just run, but you come back to what you need.",
|
||||||
|
'This love left a permanent mark.',
|
||||||
|
'Your kiss, my cheek; I watch you leave. Your smile, my ghost; I fall to my knees.',
|
||||||
|
"It was months and months of back and forth, you're still all over me like a wine-stained dress I can't wear anymore.",
|
||||||
|
"When I was drowning that's when I could finally breathe.",
|
||||||
|
"Just because you're clean, don't mean you don't miss it.",
|
||||||
|
"Didn't it all seem new and exciting? …It's all fun and games 'til somebody loses their mind.",
|
||||||
|
'You search the world for something else to make you feel like what we had. And in the end in wonderland, we both went mad.',
|
||||||
|
'Heartbreak is the national anthem, we sing it proudly.',
|
||||||
|
"They'll take their shots, but we are bulletproof.",
|
||||||
|
'So I punched a hole in the roof; let the flood carry away all my pictures of you.',
|
||||||
|
'When all you wanted was to be wanted; wish you could go back and tell yourself what you know now.',
|
||||||
|
"32 and still growing up now. Who you are is not what you did. You're still an innocent.",
|
||||||
|
"We play dumb but we know exactly what we're doing.",
|
||||||
|
"Please don't ever become a stranger whose laugh I could recognize anywhere.",
|
||||||
|
'Can we always be this close forever and ever?',
|
||||||
|
"I'm only seventeen. I don't know anything but I know I miss you.",
|
||||||
|
'I was walking home on broken cobblestones just thinking of you, when she pulled up like a figment of my worst intentions.',
|
||||||
|
'You play stupid games, you win stupid prizes.',
|
||||||
|
'I had a marvelous time ruining everything.',
|
||||||
|
"Untouchable, burning brighter than the sun, and when you're close I feel like coming undone.",
|
||||||
|
'I could build a castle out of all the bricks they threw at me.',
|
||||||
|
'Cold was the steel of my axe to grind for the boys who broke my heart. Now I send their babies presents.',
|
||||||
|
'Back when you fit in my poems like a perfect rhyme.',
|
||||||
|
"I once believed love would be burning red... but it's golden.",
|
||||||
|
'The monsters turned out to be just trees, when the sun came up you were looking at me.',
|
||||||
|
"I can't decide if it's a choice: getting swept away?",
|
||||||
|
'They told me all of my cages were mental, so I got wasted like all my potential.',
|
||||||
|
"I don't like that falling feels like flying till the bone crush.",
|
||||||
|
'I persist and resist the temptation to ask you: "If one thing had been different, would everything be different today?"',
|
||||||
|
'When you are young they assume you know nothing.',
|
||||||
|
"You drew stars around my scars, but now I'm bleeding.",
|
||||||
|
'You wear the same jewels that I gave you, as you bury me.',
|
||||||
|
"We gather stones, never knowing what they'll mean - some to throw, some to make a diamond ring.",
|
||||||
|
'Bold was the waitress on our three-year trip... Getting lunch down by the Lakes, she said I looked like an American singer.',
|
||||||
|
'One single thread of gold tied me to you.',
|
||||||
|
"I swear I don't love the drama, it loves me.",
|
||||||
|
"I bury hatchets, but I keep maps of where I put 'em.",
|
||||||
|
"Love made me crazy, if it doesn't, you ain't doin' it right.",
|
||||||
|
"My name is whatever you decide, and I'm just gonna call you mine.",
|
||||||
|
"Handsome, you're a mansion with a view.",
|
||||||
|
'Sometimes I wonder when you sleep, are you ever dreaming of me?',
|
||||||
|
'The world goes on another day, another drama. But not for me, all I think about is karma.',
|
||||||
|
'You asked me for a place to sleep, locked me out and threw a feast.',
|
||||||
|
"You know I'm not a bad girl, but I do bad things with you.",
|
||||||
|
"You did a number on me but, honestly, baby, who's counting?",
|
||||||
|
'Ocean blue eyes looking in mine. I feel like I might sink and drown and die.',
|
||||||
|
"Your love is a secret I'm hoping, dreaming, dying to keep.",
|
||||||
|
'Is this the end of all the endings? My broken bones are mending.',
|
||||||
|
'I loved you in spite of deep fears that the world would divide us.',
|
||||||
|
"Say that we got it! I'm a mess, but I'm the mess that you wanted!",
|
||||||
|
'I brought a knife to a gunfight.',
|
||||||
|
'He built a fire just to keep me warm.',
|
||||||
|
'I want to wear his initial on a chain round my neck, not because he owns me, but cause he really knows me, which is more than they can say.',
|
||||||
|
'Holding my breath, slowly, I said "You don\'t need to save me, but would you run away with me?"',
|
||||||
|
"Would've been right there, front row even if nobody came to your show.",
|
||||||
|
"I'm always waiting for you to be waiting below.",
|
||||||
|
"I don't wanna keep secrets just to keep you.",
|
||||||
|
"I'm drunk in the back of the car and I cried like a baby coming home from the bar. Said, \"I'm fine,\" but it wasn't true.",
|
||||||
|
"For whatever it's worth, I love you, ain't that the worst thing you ever heard?",
|
||||||
|
"I've got a hundred thrown-out speeches I almost said to you.",
|
||||||
|
"I am an architect, I'm drawing up the plans.",
|
||||||
|
"I'll never let you go 'cause I know this is a fight that someday we're gonna win.",
|
||||||
|
"I'm with you even if it makes me blue.",
|
||||||
|
"Without all the exes, fights, and flaws, we wouldn't be standing here so tall.",
|
||||||
|
'We were a fresh page on the desk, filling in the blanks as we go.',
|
||||||
|
'We were in the backseat drunk on something stronger than the drinks in the bar.',
|
||||||
|
'If the story is over, why am I still writing pages?',
|
||||||
|
"I ask the traffic lights if it will be alright, they say I don't know.",
|
||||||
|
"They say home is where the heart is, but that's not where mine lives.",
|
||||||
|
'I pinned your hands behind your back. Thought I had reason to attack, but no.',
|
||||||
|
"Fighting with a true love is boxing with no gloves... Chemistry 'til it blows up, 'til there's no us.",
|
||||||
|
"And I can't talk to you when you're like this, staring out the window like I'm not your favorite town.",
|
||||||
|
'They say the road gets hard and you get lost.',
|
||||||
|
"Remember how I said I'd die for you?",
|
||||||
|
"I come back stronger than a '90s trend.",
|
||||||
|
'"This dorm was once a madhouse." I made a joke: "Well, it\'s made for me."',
|
||||||
|
"Sometimes you just don't know the answer 'til someone's on their knees and asks you.",
|
||||||
|
"I can't dare to dream about you anymore.",
|
||||||
|
'I parked my car right between the Methodist and the school that used to be ours.',
|
||||||
|
"I'll go back to L.A. and the so-called friends who'll write books about me if I ever make it and wonder about the only soul who can tell which smiles I'm fakin'.",
|
||||||
|
'What would you do if I break free and leave us in ruins, took this dagger in me and removed it, gain the weight of you then loose it?',
|
||||||
|
'Your nemesis will defeat themselves before you get the chance to swing.',
|
||||||
|
'My waves meet your shore ever and evermore.',
|
||||||
|
'I replay my footsteps on each stepping stone, trying to find the one where I went wrong.',
|
||||||
|
"He can't see the smile I'm faking and my heart's not breaking 'cause I'm not feeling anything at all.",
|
||||||
|
];
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('taylor')
|
||||||
|
.setDescription('Returns a random Taylor Swift quote.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * TAYLOR_QUOTES.length);
|
||||||
|
const quote = TAYLOR_QUOTES[randomIndex];
|
||||||
|
|
||||||
|
await interaction.reply(quote);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
24
src/commands/utilities/countdown.js
Normal file
24
src/commands/utilities/countdown.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('countdown')
|
||||||
|
.setDescription('Start a five second countdown.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
// Initial response to acknowledge the command
|
||||||
|
await interaction.reply({ content: 'Starting countdown...' });
|
||||||
|
|
||||||
|
// Initial delay before starting the countdown
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 2000)); // 2-second delay
|
||||||
|
|
||||||
|
// Edit the response with the countdown
|
||||||
|
for (let i = 5; i > 0; i--) {
|
||||||
|
await interaction.editReply({ content: String(i) });
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000)); // 1-second delay between numbers
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final message
|
||||||
|
await interaction.editReply({ content: '🎉 GO! 🎉' });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
14
src/commands/utilities/servertime.js
Normal file
14
src/commands/utilities/servertime.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('servertime')
|
||||||
|
.setDescription("Returns the server's current time.");
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const now = new Date();
|
||||||
|
const formattedTime = format(now, 'dd/MM/yyyy HH:mm:ss');
|
||||||
|
await interaction.reply(`The server's current time is: ${formattedTime}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
111
src/commands/work/payday.js
Normal file
111
src/commands/work/payday.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
||||||
|
import {
|
||||||
|
format,
|
||||||
|
addDays,
|
||||||
|
subDays,
|
||||||
|
getDay,
|
||||||
|
differenceInDays,
|
||||||
|
startOfToday,
|
||||||
|
set,
|
||||||
|
} from 'date-fns';
|
||||||
|
|
||||||
|
const ARM_EMPLOYEES = [141339536453140480];
|
||||||
|
const ARM_THUMBNAIL =
|
||||||
|
'https://cdn.discordapp.com/attachments/724000975626698894/928379448301088868/unknown.png';
|
||||||
|
const BAE_THUMBNAIL =
|
||||||
|
'https://cdn.discordapp.com/attachments/724000975626698894/928380073965408306/Untitled-1.png';
|
||||||
|
|
||||||
|
// Adjust payday for weekends
|
||||||
|
function adjustPayday(payday) {
|
||||||
|
const dayOfWeek = getDay(payday);
|
||||||
|
|
||||||
|
if (dayOfWeek === 6) {
|
||||||
|
// Saturday
|
||||||
|
return subDays(payday, 1);
|
||||||
|
} else if (dayOfWeek === 0) {
|
||||||
|
// Sunday
|
||||||
|
return subDays(payday, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return payday;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate next payday based on the current date
|
||||||
|
function calculateNextPayday(
|
||||||
|
payday = 22,
|
||||||
|
currentDate = new Date(),
|
||||||
|
adjust = 0
|
||||||
|
) {
|
||||||
|
let theoreticalPayday = set(currentDate, { date: payday });
|
||||||
|
let adjustedPayday = adjustPayday(theoreticalPayday);
|
||||||
|
|
||||||
|
if (adjustedPayday < currentDate) {
|
||||||
|
theoreticalPayday = set(addDays(currentDate, adjust * 30), {
|
||||||
|
date: payday,
|
||||||
|
});
|
||||||
|
adjustedPayday = adjustPayday(theoreticalPayday);
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjustedPayday;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName('payday')
|
||||||
|
.setDescription('Calculate the number of days until the next payday.');
|
||||||
|
|
||||||
|
async function execute(interaction) {
|
||||||
|
const authorId = interaction.user.id;
|
||||||
|
const embed = new EmbedBuilder().setTitle('Payday');
|
||||||
|
|
||||||
|
let payday = 22;
|
||||||
|
let thumbnailUrl = BAE_THUMBNAIL;
|
||||||
|
let color = 0xf26521;
|
||||||
|
|
||||||
|
if (ARM_EMPLOYEES.includes(authorId)) {
|
||||||
|
payday = 26;
|
||||||
|
thumbnailUrl = ARM_THUMBNAIL;
|
||||||
|
color = 0x0091bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextPayday = calculateNextPayday(payday);
|
||||||
|
const daysToNextPayday = differenceInDays(nextPayday, startOfToday());
|
||||||
|
|
||||||
|
let monzoDaysToNextPayday = differenceInDays(
|
||||||
|
subDays(nextPayday, 1),
|
||||||
|
startOfToday()
|
||||||
|
);
|
||||||
|
if (monzoDaysToNextPayday < 0) {
|
||||||
|
monzoDaysToNextPayday = differenceInDays(
|
||||||
|
subDays(calculateNextPayday(payday, new Date(), 1), 1),
|
||||||
|
startOfToday()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
embed
|
||||||
|
.setColor(color)
|
||||||
|
.setThumbnail(thumbnailUrl)
|
||||||
|
.addFields(
|
||||||
|
{
|
||||||
|
name: '💳 Days to go',
|
||||||
|
value: `${daysToNextPayday} day${daysToNextPayday !== 1 ? 's' : ''}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '<:monzo:764978030653210705> Days to go',
|
||||||
|
value: `${monzoDaysToNextPayday} day${monzoDaysToNextPayday !== 1 ? 's' : ''}`,
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!ARM_EMPLOYEES.includes(authorId)) {
|
||||||
|
embed.addFields({
|
||||||
|
name: '💸 Inconvenience',
|
||||||
|
value: nextPayday.getMonth() % 3 === 0 ? '💰💰💰' : '🗑️🗑️🗑️',
|
||||||
|
inline: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { data, execute };
|
||||||
45
src/index.js
Normal file
45
src/index.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { Client, Collection, Events, GatewayIntentBits } from 'discord.js';
|
||||||
|
import { loadCommandModules } from '../lib/utilities/commandModules.js';
|
||||||
|
|
||||||
|
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||||
|
|
||||||
|
// Load all command modules and set them in the client.
|
||||||
|
client.commands = new Collection();
|
||||||
|
const commandModules = await loadCommandModules();
|
||||||
|
commandModules.forEach((module) => {
|
||||||
|
client.commands.set(module.data.name, module);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register the event listener for command interactions.
|
||||||
|
client.on(Events.InteractionCreate, async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand()) return;
|
||||||
|
|
||||||
|
const command = client.commands.get(interaction.commandName);
|
||||||
|
if (!command) {
|
||||||
|
console.warn(`Command ${interaction.commandName} not found.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await command.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
if (interaction.replied || interaction.deferred) {
|
||||||
|
await interaction.followUp({
|
||||||
|
content: 'There was an error while executing this command!',
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await interaction.reply({
|
||||||
|
content: 'There was an error while executing this command!',
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.once(Events.ClientReady, (readyClient) => {
|
||||||
|
console.log(`Ready! Logged in as ${readyClient.user.tag}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(process.env.DISCORD_TOKEN);
|
||||||
25
src/register-slash-commands.js
Normal file
25
src/register-slash-commands.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { REST, Routes } from 'discord.js';
|
||||||
|
import { loadCommandModules } from '../lib/utilities/commandModules.js';
|
||||||
|
|
||||||
|
// Register all slash commands, globally across all Guilds.
|
||||||
|
const commandModules = await loadCommandModules();
|
||||||
|
const commands = commandModules.map((commandModule) =>
|
||||||
|
commandModule.data.toJSON()
|
||||||
|
);
|
||||||
|
|
||||||
|
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Started refreshing application (/) commands.');
|
||||||
|
|
||||||
|
// Refresh all slash commands globally.
|
||||||
|
const data = await rest.put(
|
||||||
|
Routes.applicationCommands(process.env.DISCORD_APPLICATION_ID),
|
||||||
|
{ body: commands }
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||||
|
} catch (error) {
|
||||||
|
// And of course, make sure you catch and log any errors!
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user