mirror of
https://github.com/TheShadowEevee/Konpeki-Discord-Bot.git
synced 2025-01-11 06:28:51 -06:00
Updated formatting
This commit is contained in:
parent
ecbd2bdc4e
commit
25346f9ab2
11 changed files with 601 additions and 601 deletions
|
@ -9,24 +9,24 @@ const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
|||
const { clientId, botName, botOwner } = require('../config.json');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('about')
|
||||
.setDescription('Gives basic information about the bot'),
|
||||
async execute(interaction) {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('about')
|
||||
.setDescription('Gives basic information about the bot'),
|
||||
async execute(interaction) {
|
||||
|
||||
const exampleEmbed = new EmbedBuilder()
|
||||
.setColor(interaction.member.displayHexColor)
|
||||
.setTitle(`About ${botName}`)
|
||||
.setURL(`https://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`)
|
||||
.addFields(
|
||||
{ name: 'Admin of this bot', value: `${botOwner}` },
|
||||
{ name: 'Websocket Heartbeat / Ping', value: `${interaction.client.ws.ping}ms` },
|
||||
{ name: 'Invite Link', value: `https://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`, inline: true },
|
||||
{ name: 'Based on the open source Konpeki Discord Bot', value: 'https://github.com/TheShadowEevee/Konpeki-Discord-Bot', inline: true },
|
||||
)
|
||||
.setFooter({ text: `Support for custom changes should go through the admin of this bot, ${botOwner}. Support for the underlying Konpeki Discord Bot is available at https://discord.gg/Zt8zruXexJ.` });
|
||||
const exampleEmbed = new EmbedBuilder()
|
||||
.setColor(interaction.member.displayHexColor)
|
||||
.setTitle(`About ${botName}`)
|
||||
.setURL(`https://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`)
|
||||
.addFields(
|
||||
{ name: 'Admin of this bot', value: `${botOwner}` },
|
||||
{ name: 'Websocket Heartbeat / Ping', value: `${interaction.client.ws.ping}ms` },
|
||||
{ name: 'Invite Link', value: `https://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`, inline: true },
|
||||
{ name: 'Based on the open source Konpeki Discord Bot', value: 'https://github.com/TheShadowEevee/Konpeki-Discord-Bot', inline: true },
|
||||
)
|
||||
.setFooter({ text: `Support for custom changes should go through the admin of this bot, ${botOwner}. Support for the underlying Konpeki Discord Bot is available at https://discord.gg/Zt8zruXexJ.` });
|
||||
|
||||
|
||||
await interaction.reply({ embeds: [exampleEmbed], ephemeral: true });
|
||||
},
|
||||
await interaction.reply({ embeds: [exampleEmbed], ephemeral: true });
|
||||
},
|
||||
};
|
|
@ -6,62 +6,62 @@
|
|||
const { SlashCommandBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('avatar')
|
||||
.setDescription('Shares a users current avatar')
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('avatar')
|
||||
.setDescription('Shares a users current avatar')
|
||||
|
||||
// Optional user selection for avatar target; target selves if none.
|
||||
.addUserOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('Select the user to get an avatar from'))
|
||||
// Optional user selection for avatar target; target selves if none.
|
||||
.addUserOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('Select the user to get an avatar from'))
|
||||
|
||||
// Optional choice for user to choose avatar size; 4096 if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('format')
|
||||
.setDescription('Select what format you want the output to be')
|
||||
.addChoices(
|
||||
{ name: 'WebP', value: 'webp' },
|
||||
{ name: 'PNG', value: 'png' },
|
||||
{ name: 'JPEG', value: 'jpg' },
|
||||
))
|
||||
// Optional choice for user to choose avatar size; 4096 if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('format')
|
||||
.setDescription('Select what format you want the output to be')
|
||||
.addChoices(
|
||||
{ name: 'WebP', value: 'webp' },
|
||||
{ name: 'PNG', value: 'png' },
|
||||
{ name: 'JPEG', value: 'jpg' },
|
||||
))
|
||||
|
||||
|
||||
// Optional choice for user to choose avatar format; webp if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('size')
|
||||
.setDescription('Select what size you want the output to be')
|
||||
.addChoices(
|
||||
{ name: '4096px', value: '4096' },
|
||||
{ name: '2048px', value: '2048' },
|
||||
{ name: '1024px', value: '1024' },
|
||||
{ name: '600px', value: '600' },
|
||||
{ name: '512px', value: '512' },
|
||||
{ name: '300px', value: '300' },
|
||||
{ name: '256px', value: '256' },
|
||||
{ name: '128px', value: '128' },
|
||||
{ name: '96px', value: '96' },
|
||||
{ name: '64px', value: '64' },
|
||||
{ name: '56px', value: '56' },
|
||||
{ name: '32px', value: '32' },
|
||||
{ name: '16px', value: '16' },
|
||||
))
|
||||
// Optional choice for user to choose avatar format; webp if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('size')
|
||||
.setDescription('Select what size you want the output to be')
|
||||
.addChoices(
|
||||
{ name: '4096px', value: '4096' },
|
||||
{ name: '2048px', value: '2048' },
|
||||
{ name: '1024px', value: '1024' },
|
||||
{ name: '600px', value: '600' },
|
||||
{ name: '512px', value: '512' },
|
||||
{ name: '300px', value: '300' },
|
||||
{ name: '256px', value: '256' },
|
||||
{ name: '128px', value: '128' },
|
||||
{ name: '96px', value: '96' },
|
||||
{ name: '64px', value: '64' },
|
||||
{ name: '56px', value: '56' },
|
||||
{ name: '32px', value: '32' },
|
||||
{ name: '16px', value: '16' },
|
||||
))
|
||||
|
||||
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const discordUser = interaction.options.getUser('user') ?? interaction.user;
|
||||
const avatarFormat = interaction.options.getString('format') ?? 'webp';
|
||||
const avatarSize = Number(interaction.options.getString('size')) ?? 4096;
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
async execute(interaction) {
|
||||
const discordUser = interaction.options.getUser('user') ?? interaction.user;
|
||||
const avatarFormat = interaction.options.getString('format') ?? 'webp';
|
||||
const avatarSize = Number(interaction.options.getString('size')) ?? 4096;
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
|
||||
await interaction.reply({ content: `${discordUser.avatarURL({ extension:avatarFormat, size:avatarSize, forceStatic:false })}`, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
await interaction.reply({ content: `${discordUser.avatarURL({ extension:avatarFormat, size:avatarSize, forceStatic:false })}`, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
};
|
436
commands/help.js
436
commands/help.js
|
@ -11,258 +11,258 @@ let helpFile = '';
|
|||
|
||||
// Import help text file
|
||||
if (fs.existsSync('./data/help-text.json')) {
|
||||
helpFile = JSON.parse(fs.readFileSync('./data/help-text.json', 'utf8'));
|
||||
helpFile = JSON.parse(fs.readFileSync('./data/help-text.json', 'utf8'));
|
||||
}
|
||||
|
||||
// List of all commands, by category
|
||||
// Command help, listing options.
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('help')
|
||||
.setDescription('Provides information on avalible commands')
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('help')
|
||||
.setDescription('Provides information on avalible commands')
|
||||
|
||||
// Allow choosing the help page to open
|
||||
.addNumberOption(option =>
|
||||
option.setName('page')
|
||||
.setDescription('Choose help page to skip to'),
|
||||
),
|
||||
// Allow choosing the help page to open
|
||||
.addNumberOption(option =>
|
||||
option.setName('page')
|
||||
.setDescription('Choose help page to skip to'),
|
||||
),
|
||||
|
||||
async execute(interaction) {
|
||||
async execute(interaction) {
|
||||
|
||||
let pageNumber = interaction.options.getNumber('page') ?? 1;
|
||||
const commandsPerPage = 5;
|
||||
let commandsThisPage = 0;
|
||||
let pageNumber = interaction.options.getNumber('page') ?? 1;
|
||||
const commandsPerPage = 5;
|
||||
let commandsThisPage = 0;
|
||||
|
||||
const numberOfCommands = Object.keys(helpFile).length;
|
||||
const pageTotal = String(Math.ceil(numberOfCommands / commandsPerPage));
|
||||
let userRoleColor = Number('0x' + interaction.member.displayHexColor.split('#')[1]);
|
||||
const numberOfCommands = Object.keys(helpFile).length;
|
||||
const pageTotal = String(Math.ceil(numberOfCommands / commandsPerPage));
|
||||
let userRoleColor = Number('0x' + interaction.member.displayHexColor.split('#')[1]);
|
||||
|
||||
// This will also unintentionally catch roles with full black color (#000000), but it should be fine.
|
||||
if (userRoleColor == 0) {
|
||||
userRoleColor = Number(0x55ffff);
|
||||
}
|
||||
// This will also unintentionally catch roles with full black color (#000000), but it should be fine.
|
||||
if (userRoleColor == 0) {
|
||||
userRoleColor = Number(0x55ffff);
|
||||
}
|
||||
|
||||
if (pageNumber > pageTotal) {
|
||||
pageNumber = 1;
|
||||
}
|
||||
if (pageNumber > pageTotal) {
|
||||
pageNumber = 1;
|
||||
}
|
||||
|
||||
let embedPartOne = {
|
||||
color: userRoleColor,
|
||||
title: 'Help Text',
|
||||
description: `Page ${pageNumber} of ${pageTotal}`,
|
||||
};
|
||||
let embedPartOne = {
|
||||
color: userRoleColor,
|
||||
title: 'Help Text',
|
||||
description: `Page ${pageNumber} of ${pageTotal}`,
|
||||
};
|
||||
|
||||
if (pageNumber != pageTotal) {
|
||||
commandsThisPage = commandsPerPage;
|
||||
}
|
||||
else {
|
||||
commandsThisPage = numberOfCommands % commandsPerPage;
|
||||
}
|
||||
if (pageNumber != pageTotal) {
|
||||
commandsThisPage = commandsPerPage;
|
||||
}
|
||||
else {
|
||||
commandsThisPage = numberOfCommands % commandsPerPage;
|
||||
}
|
||||
|
||||
let embedPartTwo = '';
|
||||
let embedPartTwo = '';
|
||||
|
||||
embedPartTwo += '{"fields": [';
|
||||
for (let i = 0; i < commandsThisPage; i++) {
|
||||
embedPartTwo += '{"fields": [';
|
||||
for (let i = 0; i < commandsThisPage; i++) {
|
||||
|
||||
const currentCommandName = Object.keys(helpFile)[i + (commandsPerPage * (pageNumber - 1))];
|
||||
const currentCommandName = Object.keys(helpFile)[i + (commandsPerPage * (pageNumber - 1))];
|
||||
|
||||
embedPartTwo += '{';
|
||||
embedPartTwo += '{';
|
||||
|
||||
embedPartTwo += ' "name": "/' + currentCommandName + '",',
|
||||
embedPartTwo += ' "value": "' + helpFile[currentCommandName].description + '"',
|
||||
embedPartTwo += ' "name": "/' + currentCommandName + '",',
|
||||
embedPartTwo += ' "value": "' + helpFile[currentCommandName].description + '"',
|
||||
|
||||
embedPartTwo += '},';
|
||||
}
|
||||
embedPartTwo = embedPartTwo.substring(0, embedPartTwo.length - 1) + ']}';
|
||||
embedPartTwo += '},';
|
||||
}
|
||||
embedPartTwo = embedPartTwo.substring(0, embedPartTwo.length - 1) + ']}';
|
||||
|
||||
let buttonList = '';
|
||||
let buttonList = '';
|
||||
|
||||
// Change buttons based on page number. Is there an easier/shorter way to do this?
|
||||
if (pageNumber == 1) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
else if (pageNumber == pageTotal) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
);
|
||||
}
|
||||
else {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
// Change buttons based on page number. Is there an easier/shorter way to do this?
|
||||
if (pageNumber == 1) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
else if (pageNumber == pageTotal) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
);
|
||||
}
|
||||
else {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
|
||||
// Button code
|
||||
const collector = interaction.channel.createMessageComponentCollector({ time: 300000 });
|
||||
// Button code
|
||||
const collector = interaction.channel.createMessageComponentCollector({ time: 300000 });
|
||||
|
||||
collector.on('collect', async i => {
|
||||
collector.on('collect', async i => {
|
||||
|
||||
if (i.customId === 'next') {
|
||||
pageNumber += 1;
|
||||
}
|
||||
if (i.customId === 'back') {
|
||||
pageNumber -= 1;
|
||||
}
|
||||
if (i.customId === 'next') {
|
||||
pageNumber += 1;
|
||||
}
|
||||
if (i.customId === 'back') {
|
||||
pageNumber -= 1;
|
||||
}
|
||||
|
||||
// Replicate the above code to remake the help model for the new page. Again, there has to be an easier way to do this.
|
||||
embedPartOne = {
|
||||
color: userRoleColor,
|
||||
title: 'Help Text',
|
||||
description: `Page ${pageNumber} of ${pageTotal}`,
|
||||
};
|
||||
// Replicate the above code to remake the help model for the new page. Again, there has to be an easier way to do this.
|
||||
embedPartOne = {
|
||||
color: userRoleColor,
|
||||
title: 'Help Text',
|
||||
description: `Page ${pageNumber} of ${pageTotal}`,
|
||||
};
|
||||
|
||||
embedPartTwo = '';
|
||||
embedPartTwo = '';
|
||||
|
||||
if (pageNumber != pageTotal) {
|
||||
commandsThisPage = commandsPerPage;
|
||||
}
|
||||
else {
|
||||
commandsThisPage = numberOfCommands % commandsPerPage;
|
||||
}
|
||||
if (pageNumber != pageTotal) {
|
||||
commandsThisPage = commandsPerPage;
|
||||
}
|
||||
else {
|
||||
commandsThisPage = numberOfCommands % commandsPerPage;
|
||||
}
|
||||
|
||||
embedPartTwo += '{"fields": [';
|
||||
for (let j = 0; j < commandsThisPage; j++) {
|
||||
embedPartTwo += '{"fields": [';
|
||||
for (let j = 0; j < commandsThisPage; j++) {
|
||||
|
||||
const currentCommandName = Object.keys(helpFile)[j + (commandsPerPage * (pageNumber - 1))];
|
||||
const currentCommandName = Object.keys(helpFile)[j + (commandsPerPage * (pageNumber - 1))];
|
||||
|
||||
embedPartTwo += '{';
|
||||
embedPartTwo += '{';
|
||||
|
||||
embedPartTwo += ' "name": "/' + currentCommandName + '",',
|
||||
embedPartTwo += ' "value": "' + helpFile[currentCommandName].description + '"',
|
||||
embedPartTwo += ' "name": "/' + currentCommandName + '",',
|
||||
embedPartTwo += ' "value": "' + helpFile[currentCommandName].description + '"',
|
||||
|
||||
embedPartTwo += '},';
|
||||
}
|
||||
embedPartTwo = embedPartTwo.substring(0, embedPartTwo.length - 1) + ']}';
|
||||
embedPartTwo += '},';
|
||||
}
|
||||
embedPartTwo = embedPartTwo.substring(0, embedPartTwo.length - 1) + ']}';
|
||||
|
||||
// Change buttons based on page number. Is there an easier/shorter way to do this?
|
||||
if (pageNumber == 1) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
else if (pageNumber == pageTotal) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
);
|
||||
}
|
||||
else {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
// Change buttons based on page number. Is there an easier/shorter way to do this?
|
||||
if (pageNumber == 1) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
else if (pageNumber == pageTotal) {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
);
|
||||
}
|
||||
else {
|
||||
buttonList = new ActionRowBuilder()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('back')
|
||||
.setLabel('Previous')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('page')
|
||||
.setLabel(`${pageNumber}/${pageTotal}`)
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true),
|
||||
)
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId('next')
|
||||
.setLabel('Next')
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
);
|
||||
}
|
||||
|
||||
await i.update({ embeds: [Object.assign({}, embedPartOne, JSON.parse(embedPartTwo))], components: [ buttonList ], ephemeral: true });
|
||||
});
|
||||
await i.update({ embeds: [Object.assign({}, embedPartOne, JSON.parse(embedPartTwo))], components: [ buttonList ], ephemeral: true });
|
||||
});
|
||||
|
||||
await interaction.reply({ embeds: [Object.assign({}, embedPartOne, JSON.parse(embedPartTwo))], components: [ buttonList ], ephemeral: true });
|
||||
await interaction.reply({ embeds: [Object.assign({}, embedPartOne, JSON.parse(embedPartTwo))], components: [ buttonList ], ephemeral: true });
|
||||
|
||||
},
|
||||
},
|
||||
};
|
|
@ -9,10 +9,10 @@ const { SlashCommandBuilder } = require('discord.js');
|
|||
const { botName, clientId } = require('../config.json');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('invite')
|
||||
.setDescription(`Invite ${botName} to your own server`),
|
||||
async execute(interaction) {
|
||||
await interaction.reply({ content: `Use this link to invite ${botName} (That's me!) to your own server!\nhttps://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`, ephemeral: true });
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('invite')
|
||||
.setDescription(`Invite ${botName} to your own server`),
|
||||
async execute(interaction) {
|
||||
await interaction.reply({ content: `Use this link to invite ${botName} (That's me!) to your own server!\nhttps://discord.com/oauth2/authorize?client_id=${clientId}&permissions=274877908992&scope=bot%20applications.commands`, ephemeral: true });
|
||||
},
|
||||
};
|
|
@ -7,69 +7,69 @@ const { SlashCommandBuilder } = require('discord.js');
|
|||
const { randomInt } = require('node:crypto');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('lottery')
|
||||
.setDescription('Rolls a set of numbers you can use for whatever')
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('lottery')
|
||||
.setDescription('Rolls a set of numbers you can use for whatever')
|
||||
|
||||
// Get number of numbers to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('count')
|
||||
.setDescription('How many numbers to roll'),
|
||||
)
|
||||
// Get number of numbers to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('count')
|
||||
.setDescription('How many numbers to roll'),
|
||||
)
|
||||
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('max')
|
||||
.setDescription('Set the maximum roll'),
|
||||
)
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('max')
|
||||
.setDescription('Set the maximum roll'),
|
||||
)
|
||||
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
const rollCount = interaction.options.getNumber('count') ?? 6;
|
||||
const maxRoll = interaction.options.getNumber('max') ?? 99;
|
||||
async execute(interaction) {
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
const rollCount = interaction.options.getNumber('count') ?? 6;
|
||||
const maxRoll = interaction.options.getNumber('max') ?? 99;
|
||||
|
||||
// Limit max number rollable to prevent spam and API issues
|
||||
if (maxRoll > 999) {
|
||||
await interaction.reply({ content: `Big roller! Unfortunatly ${maxRoll} is too big a number for me. Try somewhere below 1000!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (maxRoll < 1) {
|
||||
await interaction.reply({ content: `The fewer numbers, the higher the odds! Unfortunatly ${maxRoll} is too low a number... Try a positive number under 1000!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
// Limit max number rollable to prevent spam and API issues
|
||||
if (maxRoll > 999) {
|
||||
await interaction.reply({ content: `Big roller! Unfortunatly ${maxRoll} is too big a number for me. Try somewhere below 1000!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (maxRoll < 1) {
|
||||
await interaction.reply({ content: `The fewer numbers, the higher the odds! Unfortunatly ${maxRoll} is too low a number... Try a positive number under 1000!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
|
||||
// Limit numbers rollable to prevent spam and API issues
|
||||
if (rollCount > 9) {
|
||||
await interaction.reply({ content: `You want ${rollCount} numbers?! That's a bit much, even for me...\nTry 9 or less please!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (rollCount < 1) {
|
||||
await interaction.reply({ content: `It's kinda difficult to roll ${rollCount} numbers...\nTry a positive single digit number!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
// Limit numbers rollable to prevent spam and API issues
|
||||
if (rollCount > 9) {
|
||||
await interaction.reply({ content: `You want ${rollCount} numbers?! That's a bit much, even for me...\nTry 9 or less please!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (rollCount < 1) {
|
||||
await interaction.reply({ content: `It's kinda difficult to roll ${rollCount} numbers...\nTry a positive single digit number!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
|
||||
const lotteryNumbers = [];
|
||||
const lotteryNumbers = [];
|
||||
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
lotteryNumbers.push(randomInt(1, maxRoll));
|
||||
}
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
lotteryNumbers.push(randomInt(1, maxRoll));
|
||||
}
|
||||
|
||||
if (rollCount === 1) {
|
||||
await interaction.reply({ content: `Your lucky number is...\n${lotteryNumbers.toString().split(',').join(', ')}.`, ephemeral: (isEphemeral === 'true') });
|
||||
}
|
||||
else {
|
||||
await interaction.reply({ content: `Your lucky numbers are...\n${lotteryNumbers.toString().split(',').join(', ')}.`, ephemeral: (isEphemeral === 'true') });
|
||||
}
|
||||
},
|
||||
if (rollCount === 1) {
|
||||
await interaction.reply({ content: `Your lucky number is...\n${lotteryNumbers.toString().split(',').join(', ')}.`, ephemeral: (isEphemeral === 'true') });
|
||||
}
|
||||
else {
|
||||
await interaction.reply({ content: `Your lucky numbers are...\n${lotteryNumbers.toString().split(',').join(', ')}.`, ephemeral: (isEphemeral === 'true') });
|
||||
}
|
||||
},
|
||||
};
|
|
@ -8,10 +8,10 @@
|
|||
const { SlashCommandBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Checks to see if the bot is online, as well as it\'s ping'),
|
||||
async execute(interaction) {
|
||||
await interaction.reply({ content: `Pong! Current Websocket Heartbeat / ping is ${interaction.client.ws.ping}ms.`, ephemeral: true });
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Checks to see if the bot is online, as well as it\'s ping'),
|
||||
async execute(interaction) {
|
||||
await interaction.reply({ content: `Pong! Current Websocket Heartbeat / ping is ${interaction.client.ws.ping}ms.`, ephemeral: true });
|
||||
},
|
||||
};
|
148
commands/roll.js
148
commands/roll.js
|
@ -7,94 +7,94 @@ const { SlashCommandBuilder } = require('discord.js');
|
|||
const { randomInt } = require('node:crypto');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('roll')
|
||||
.setDescription('Rolls a set of dice')
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('roll')
|
||||
.setDescription('Rolls a set of dice')
|
||||
|
||||
// Get number of numbers to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('die')
|
||||
.setDescription('Type of dice to roll')
|
||||
.addChoices(
|
||||
{ name: 'd4', value: 4 },
|
||||
{ name: 'd6', value: 6 },
|
||||
{ name: 'd8', value: 8 },
|
||||
{ name: 'd10', value: 10 },
|
||||
{ name: 'd20', value: 20 },
|
||||
{ name: 'd100', value: 100 },
|
||||
))
|
||||
// Get number of numbers to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('die')
|
||||
.setDescription('Type of dice to roll')
|
||||
.addChoices(
|
||||
{ name: 'd4', value: 4 },
|
||||
{ name: 'd6', value: 6 },
|
||||
{ name: 'd8', value: 8 },
|
||||
{ name: 'd10', value: 10 },
|
||||
{ name: 'd20', value: 20 },
|
||||
{ name: 'd100', value: 100 },
|
||||
))
|
||||
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('count')
|
||||
.setDescription('Amount of dice to roll'),
|
||||
)
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('count')
|
||||
.setDescription('Amount of dice to roll'),
|
||||
)
|
||||
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('modifier')
|
||||
.setDescription('+/- to a dice roll'),
|
||||
)
|
||||
// Get max number to roll
|
||||
.addNumberOption(option =>
|
||||
option.setName('modifier')
|
||||
.setDescription('+/- to a dice roll'),
|
||||
)
|
||||
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the avatar in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
const rollCount = interaction.options.getNumber('count') ?? 1;
|
||||
const dieType = interaction.options.getNumber('die') ?? 6;
|
||||
const rollMod = interaction.options.getNumber('modifier') ?? 0;
|
||||
async execute(interaction) {
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
const rollCount = interaction.options.getNumber('count') ?? 1;
|
||||
const dieType = interaction.options.getNumber('die') ?? 6;
|
||||
const rollMod = interaction.options.getNumber('modifier') ?? 0;
|
||||
|
||||
let modSign = '';
|
||||
let rollModStr = '';
|
||||
let rollModNota = '';
|
||||
let modSign = '';
|
||||
let rollModStr = '';
|
||||
let rollModNota = '';
|
||||
|
||||
// Limit numbers rollable to prevent spam and API issues
|
||||
if (rollCount > 100) {
|
||||
await interaction.reply({ content: `You want ${rollCount} numbers?! That's a bit much, even for me...\nTry 100 or less please!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (rollCount < 1) {
|
||||
await interaction.reply({ content: `It's kinda difficult to roll ${rollCount} numbers...\nTry a positive number!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
// Limit numbers rollable to prevent spam and API issues
|
||||
if (rollCount > 100) {
|
||||
await interaction.reply({ content: `You want ${rollCount} numbers?! That's a bit much, even for me...\nTry 100 or less please!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
// Prevent 0 or less numbers
|
||||
else if (rollCount < 1) {
|
||||
await interaction.reply({ content: `It's kinda difficult to roll ${rollCount} numbers...\nTry a positive number!`, ephemeral:true });
|
||||
return;
|
||||
}
|
||||
|
||||
const diceRolls = [];
|
||||
let rollSum = 0;
|
||||
const diceRolls = [];
|
||||
let rollSum = 0;
|
||||
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
const randomNum = randomInt(1, dieType);
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
const randomNum = randomInt(1, dieType);
|
||||
|
||||
diceRolls.push(randomNum);
|
||||
rollSum += randomNum;
|
||||
diceRolls.push(randomNum);
|
||||
rollSum += randomNum;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (rollMod < 0) {
|
||||
modSign = '-';
|
||||
}
|
||||
else if (rollMod > 0) {
|
||||
modSign = '+';
|
||||
}
|
||||
if (rollMod < 0) {
|
||||
modSign = '-';
|
||||
}
|
||||
else if (rollMod > 0) {
|
||||
modSign = '+';
|
||||
}
|
||||
|
||||
if (rollMod != 0) {
|
||||
rollModStr = ' ' + modSign + ' ' + Math.abs(rollMod);
|
||||
rollModNota = modSign + Math.abs(rollMod);
|
||||
}
|
||||
if (rollMod != 0) {
|
||||
rollModStr = ' ' + modSign + ' ' + Math.abs(rollMod);
|
||||
rollModNota = modSign + Math.abs(rollMod);
|
||||
}
|
||||
|
||||
const diceRollsString = diceRolls.toString().split(',').join(' + ');
|
||||
const diceRollsString = diceRolls.toString().split(',').join(' + ');
|
||||
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
diceRolls.push(randomInt(1, dieType));
|
||||
}
|
||||
for (let i = 0; i < rollCount; i++) {
|
||||
diceRolls.push(randomInt(1, dieType));
|
||||
}
|
||||
|
||||
await interaction.reply({ content: `\`${rollCount}d${dieType}${rollModNota}\`\n\`Rolls: ( ${diceRollsString} )${rollModStr} = ${rollSum + rollMod}\``, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
await interaction.reply({ content: `\`${rollCount}d${dieType}${rollModNota}\`\n\`Rolls: ( ${diceRollsString} )${rollModStr} = ${rollSum + rollMod}\``, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
};
|
|
@ -6,56 +6,56 @@
|
|||
const { SlashCommandBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('server-icon')
|
||||
.setDescription('Shares this servers current icon')
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('server-icon')
|
||||
.setDescription('Shares this servers current icon')
|
||||
|
||||
// Optional choice for user to choose icon size; 4096 if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('format')
|
||||
.setDescription('Select what format you want the output to be')
|
||||
.addChoices(
|
||||
{ name: 'WebP', value: 'webp' },
|
||||
{ name: 'PNG', value: 'png' },
|
||||
{ name: 'JPEG', value: 'jpg' },
|
||||
))
|
||||
// Optional choice for user to choose icon size; 4096 if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('format')
|
||||
.setDescription('Select what format you want the output to be')
|
||||
.addChoices(
|
||||
{ name: 'WebP', value: 'webp' },
|
||||
{ name: 'PNG', value: 'png' },
|
||||
{ name: 'JPEG', value: 'jpg' },
|
||||
))
|
||||
|
||||
|
||||
// Optional choice for user to choose icon format; webp if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('size')
|
||||
.setDescription('Select what size you want the output to be')
|
||||
.addChoices(
|
||||
{ name: '4096px', value: '4096' },
|
||||
{ name: '2048px', value: '2048' },
|
||||
{ name: '1024px', value: '1024' },
|
||||
{ name: '600px', value: '600' },
|
||||
{ name: '512px', value: '512' },
|
||||
{ name: '300px', value: '300' },
|
||||
{ name: '256px', value: '256' },
|
||||
{ name: '128px', value: '128' },
|
||||
{ name: '96px', value: '96' },
|
||||
{ name: '64px', value: '64' },
|
||||
{ name: '56px', value: '56' },
|
||||
{ name: '32px', value: '32' },
|
||||
{ name: '16px', value: '16' },
|
||||
))
|
||||
// Optional choice for user to choose icon format; webp if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('size')
|
||||
.setDescription('Select what size you want the output to be')
|
||||
.addChoices(
|
||||
{ name: '4096px', value: '4096' },
|
||||
{ name: '2048px', value: '2048' },
|
||||
{ name: '1024px', value: '1024' },
|
||||
{ name: '600px', value: '600' },
|
||||
{ name: '512px', value: '512' },
|
||||
{ name: '300px', value: '300' },
|
||||
{ name: '256px', value: '256' },
|
||||
{ name: '128px', value: '128' },
|
||||
{ name: '96px', value: '96' },
|
||||
{ name: '64px', value: '64' },
|
||||
{ name: '56px', value: '56' },
|
||||
{ name: '32px', value: '32' },
|
||||
{ name: '16px', value: '16' },
|
||||
))
|
||||
|
||||
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the icon in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
// Optional Ephemeral check to allow user to choose command results to be shared publicly or private; send to self only if no selection.
|
||||
.addStringOption(option =>
|
||||
option.setName('ephemeral')
|
||||
.setDescription('Post the icon in the current channel')
|
||||
.addChoices(
|
||||
{ name: 'Send to me only', value: 'true' },
|
||||
{ name: 'Send in channel', value: 'false' },
|
||||
)),
|
||||
|
||||
async execute(interaction) {
|
||||
const iconFormat = interaction.options.getString('format') ?? 'webp';
|
||||
const iconSize = Number(interaction.options.getString('size')) ?? 4096;
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
async execute(interaction) {
|
||||
const iconFormat = interaction.options.getString('format') ?? 'webp';
|
||||
const iconSize = Number(interaction.options.getString('size')) ?? 4096;
|
||||
const isEphemeral = interaction.options.getString('ephemeral') ?? 'true';
|
||||
|
||||
await interaction.reply({ content: `${interaction.guild.iconURL({ extension:iconFormat, size:iconSize, forceStatic:false })}`, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
await interaction.reply({ content: `${interaction.guild.iconURL({ extension:iconFormat, size:iconSize, forceStatic:false })}`, ephemeral: (isEphemeral === 'true') });
|
||||
},
|
||||
};
|
|
@ -14,17 +14,17 @@ const rest = new REST({ version: '10' }).setToken(token);
|
|||
|
||||
// and deploy your commands!
|
||||
(async () => {
|
||||
try {
|
||||
console.log('Started deleting all application (/) commands.');
|
||||
try {
|
||||
console.log('Started deleting all application (/) commands.');
|
||||
|
||||
// The put method is used to fully refresh all commands
|
||||
rest.put(Routes.applicationCommands(clientId), { body: [] })
|
||||
.then(() => console.log('Successfully deleted all application (/) commands.'))
|
||||
.catch(console.error);
|
||||
// The put method is used to fully refresh all commands
|
||||
rest.put(Routes.applicationCommands(clientId), { body: [] })
|
||||
.then(() => console.log('Successfully deleted all application (/) commands.'))
|
||||
.catch(console.error);
|
||||
|
||||
}
|
||||
catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
|
@ -17,9 +17,9 @@ const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('
|
|||
|
||||
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
||||
for (const file of commandFiles) {
|
||||
const command = require(`./commands/${file}`);
|
||||
commands.push(command.data.toJSON());
|
||||
commandsHelp.push(command.data);
|
||||
const command = require(`./commands/${file}`);
|
||||
commands.push(command.data.toJSON());
|
||||
commandsHelp.push(command.data);
|
||||
}
|
||||
|
||||
// Construct and prepare an instance of the REST module
|
||||
|
@ -27,85 +27,85 @@ const rest = new REST({ version: '10' }).setToken(token);
|
|||
|
||||
// Generate help-text.json
|
||||
try {
|
||||
console.log(`Generating ${commands.length} help text entries.`);
|
||||
console.log(`Generating ${commands.length} help text entries.`);
|
||||
|
||||
let helpJSONString = '{\n';
|
||||
let helpJSONString = '{\n';
|
||||
|
||||
for (let i = 0; i < commandsHelp.length; i++) {
|
||||
helpJSONString += ` "${commandsHelp[i].name}": {\n`;
|
||||
helpJSONString += ` "description": "${commandsHelp[i].description}",\n`;
|
||||
helpJSONString += ' "options": {\n';
|
||||
for (let i = 0; i < commandsHelp.length; i++) {
|
||||
helpJSONString += ` "${commandsHelp[i].name}": {\n`;
|
||||
helpJSONString += ` "description": "${commandsHelp[i].description}",\n`;
|
||||
helpJSONString += ' "options": {\n';
|
||||
|
||||
for (let j = 0; j < commandsHelp[i].options.length; j++) {
|
||||
for (let j = 0; j < commandsHelp[i].options.length; j++) {
|
||||
|
||||
helpJSONString += ` "${commandsHelp[i].options[j].name}": {\n`;
|
||||
helpJSONString += ` "description": "${commandsHelp[i].options[j].description}",\n`;
|
||||
helpJSONString += ` "required": "${commandsHelp[i].options[j].required}",\n`;
|
||||
helpJSONString += ' "choices": {\n';
|
||||
helpJSONString += ` "${commandsHelp[i].options[j].name}": {\n`;
|
||||
helpJSONString += ` "description": "${commandsHelp[i].options[j].description}",\n`;
|
||||
helpJSONString += ` "required": "${commandsHelp[i].options[j].required}",\n`;
|
||||
helpJSONString += ' "choices": {\n';
|
||||
|
||||
if (typeof commandsHelp[i].options[j].choices !== 'undefined') {
|
||||
for (let k = 0; k < commandsHelp[i].options[j].choices.length; k++) {
|
||||
if (typeof commandsHelp[i].options[j].choices !== 'undefined') {
|
||||
for (let k = 0; k < commandsHelp[i].options[j].choices.length; k++) {
|
||||
|
||||
helpJSONString += ` "${commandsHelp[i].options[j].choices[k].name}": {\n`;
|
||||
helpJSONString += ` "value": "${commandsHelp[i].options[j].choices[k].value}",\n`;
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ` "${commandsHelp[i].options[j].choices[k].name}": {\n`;
|
||||
helpJSONString += ` "value": "${commandsHelp[i].options[j].choices[k].value}",\n`;
|
||||
helpJSONString += ' },\n';
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ' },\n';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ' },\n';
|
||||
}
|
||||
helpJSONString += ' },\n';
|
||||
helpJSONString += ' },\n';
|
||||
}
|
||||
|
||||
helpJSONString += '}';
|
||||
helpJSONString += '}';
|
||||
|
||||
// Lazy way out of removing trailing commas
|
||||
// See https://stackoverflow.com/a/34347475
|
||||
const helpJSON = JSON.stringify(JSON.parse(helpJSONString.replace(/,(?!\s*?[{["'\w])/g, '')), null, 4);
|
||||
// Lazy way out of removing trailing commas
|
||||
// See https://stackoverflow.com/a/34347475
|
||||
const helpJSON = JSON.stringify(JSON.parse(helpJSONString.replace(/,(?!\s*?[{["'\w])/g, '')), null, 4);
|
||||
|
||||
// Create data folder if it doesn't exist
|
||||
if (!fs.existsSync('data')) {
|
||||
fs.mkdirSync('data');
|
||||
}
|
||||
// Create data folder if it doesn't exist
|
||||
if (!fs.existsSync('data')) {
|
||||
fs.mkdirSync('data');
|
||||
}
|
||||
|
||||
// Write file to disk
|
||||
fs.writeFile('./data/help-text.json', helpJSON, err => {
|
||||
if (err) {
|
||||
console.log(`Unable to write help-text.json: ${err}`);
|
||||
console.log('Stopping...');
|
||||
return;
|
||||
}
|
||||
});
|
||||
// Write file to disk
|
||||
fs.writeFile('./data/help-text.json', helpJSON, err => {
|
||||
if (err) {
|
||||
console.log(`Unable to write help-text.json: ${err}`);
|
||||
console.log('Stopping...');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Successfully generated ${commandsHelp.length} help text entries.`);
|
||||
console.log(`Successfully generated ${commandsHelp.length} help text entries.`);
|
||||
|
||||
console.log();
|
||||
console.log();
|
||||
|
||||
// Update slash commands on Discord's side
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
// Update slash commands on Discord's side
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
// The put method is used to fully refresh all commands
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(clientId),
|
||||
{ body: commands },
|
||||
);
|
||||
// The put method is used to fully refresh all commands
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(clientId),
|
||||
{ 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);
|
||||
}
|
||||
})();
|
||||
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
|
||||
}
|
||||
catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.error(error);
|
||||
// And of course, make sure you catch and log any errors!
|
||||
console.error(error);
|
||||
}
|
110
index.js
110
index.js
|
@ -28,91 +28,91 @@ const commandsPath = path.join(__dirname, 'commands');
|
|||
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const filePath = path.join(commandsPath, file);
|
||||
const command = require(filePath);
|
||||
// Set a new item in the Collection with the key as the command name and the value as the exported module
|
||||
if ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
}
|
||||
else {
|
||||
logger.log(logger.logLevels.WARN, `The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
const filePath = path.join(commandsPath, file);
|
||||
const command = require(filePath);
|
||||
// Set a new item in the Collection with the key as the command name and the value as the exported module
|
||||
if ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
}
|
||||
else {
|
||||
logger.log(logger.logLevels.WARN, `The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
|
||||
// When the client is ready, run this code (only once)
|
||||
// We use 'c' for the event parameter to keep it separate from the already defined 'client'
|
||||
client.once(Events.ClientReady, c => {
|
||||
logger.log(logger.logLevels.INFO, `${logger.colorText('Ready!', logger.textColor.Green)} Logged in as ${logger.colorText(c.user.tag, logger.textColor.Blue)}`);
|
||||
client.user.setPresence({ activities: [{ name: activity }], status: status });
|
||||
logger.log(logger.logLevels.INFO, `${logger.colorText('Ready!', logger.textColor.Green)} Logged in as ${logger.colorText(c.user.tag, logger.textColor.Blue)}`);
|
||||
client.user.setPresence({ activities: [{ name: activity }], status: status });
|
||||
|
||||
// Track websocket heartbeat with PM2 Histogram
|
||||
let latency = 0;
|
||||
setInterval(function() {
|
||||
latency = c.ws.ping;
|
||||
metrics.websocketHeartbeatHist.update(latency);
|
||||
}, 1000);
|
||||
// Track websocket heartbeat with PM2 Histogram
|
||||
let latency = 0;
|
||||
setInterval(function() {
|
||||
latency = c.ws.ping;
|
||||
metrics.websocketHeartbeatHist.update(latency);
|
||||
}, 1000);
|
||||
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(c.guilds.cache.size);
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(c.guilds.cache.size);
|
||||
|
||||
});
|
||||
|
||||
// Client "on" Events
|
||||
// Someone used an interaction
|
||||
client.on(Events.InteractionCreate, async interaction => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
||||
if (!command) {
|
||||
logger.log(logger.logLevels.ERROR, `No command matching ${interaction.commandName} was found.`);
|
||||
await interaction.reply({ content: `This command no longer exists! Please contact ${botOwner} to report that this is happening!`, ephemeral: true });
|
||||
if (!command) {
|
||||
logger.log(logger.logLevels.ERROR, `No command matching ${interaction.commandName} was found.`);
|
||||
await interaction.reply({ content: `This command no longer exists! Please contact ${botOwner} to report that this is happening!`, ephemeral: true });
|
||||
|
||||
// Report error to PM2 dashboard
|
||||
metrics.interactionErrors.inc();
|
||||
metrics.io.notifyError(new Error('Interaction doesn\'t exist'), {
|
||||
custom: {
|
||||
interactionCommand: interaction.commandName,
|
||||
},
|
||||
});
|
||||
// Report error to PM2 dashboard
|
||||
metrics.interactionErrors.inc();
|
||||
metrics.io.notifyError(new Error('Interaction doesn\'t exist'), {
|
||||
custom: {
|
||||
interactionCommand: interaction.commandName,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
}
|
||||
catch (error) {
|
||||
logger.log(logger.logLevels.ERROR, error);
|
||||
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
}
|
||||
catch (error) {
|
||||
logger.log(logger.logLevels.ERROR, error);
|
||||
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
||||
|
||||
// Report error to PM2 dashboard
|
||||
metrics.interactionErrors.inc();
|
||||
metrics.io.notifyError(new Error('Error executing interaction'), {
|
||||
custom: {
|
||||
interactionCommand: interaction.commandName,
|
||||
error: error,
|
||||
},
|
||||
});
|
||||
// Report error to PM2 dashboard
|
||||
metrics.interactionErrors.inc();
|
||||
metrics.io.notifyError(new Error('Error executing interaction'), {
|
||||
custom: {
|
||||
interactionCommand: interaction.commandName,
|
||||
error: error,
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Successful Execution, report as a PM2 metric
|
||||
// If the bot gets a lot of use, consider removing this for performance
|
||||
metrics.interactionSuccess();
|
||||
// Successful Execution, report as a PM2 metric
|
||||
// If the bot gets a lot of use, consider removing this for performance
|
||||
metrics.interactionSuccess();
|
||||
|
||||
});
|
||||
|
||||
// Joined a server
|
||||
client.on(Events.GuildCreate, guild => {
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(guild.client.guilds.cache.size);
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(guild.client.guilds.cache.size);
|
||||
});
|
||||
|
||||
// Removed from a server
|
||||
client.on(Events.GuildDelete, guild => {
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(guild.client.guilds.cache.size);
|
||||
// Report current server count with PM2 (Servers counted anonymously)
|
||||
metrics.serverCount.set(guild.client.guilds.cache.size);
|
||||
});
|
||||
|
||||
// Log in to Discord with your client's token
|
||||
|
|
Loading…
Reference in a new issue