Prompt
Answer
JavaScript Discord Bot Command for Rank Update
This guide provides a structured JavaScript function that updates a user's rank in Roblox via a Discord command, implementing error handling, input validation, and detailed documentation.
Overview
Purpose
The command allows a user with appropriate permissions to change another user's rank on Roblox based on their current roles in Discord.
Key Features
- API retry mechanism for robust data fetching
- User permission validation
- Error handling with informative logging
- Integration with Discord and Roblox APIs
Imports
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const path = require('path');
const fs = require('fs');
const axios = require('axios');
const crypto = require('crypto');
File Path Constants
const dataFilePath = path.join(__dirname, '../commands/data.json');
const rankFile = path.join(__dirname, '../commands/rutbe.json');
Fetch with Retry Function
This function fetches data while handling errors and supporting retries.
/**
* Fetches data from the given URL with retry support for failed requests.
* @param {string} url - The URL to fetch data from.
* @param {object} options - Axios config for the request.
* @param {number} retries - Number of retries on failure.
* @param {number} backoff - Delay time in ms between retries.
* @returns {Promise} - The data received.
* @throws {Error} - Throws error on failure after retries.
*/
async function fetchWithRetry(url, options, retries = 3, backoff = 1000) {
try {
console.log(`Fetching URL: ${url}`);
const response = await axios(url, options);
console.log(`Response received: ${JSON.stringify(response.data)}`);
return response.data;
} catch (error) {
console.error(`Fetch error: ${error.message}`);
if (retries === 0) throw error;
if (error.response && error.response.status === 429) {
console.log(`API rate limit exceeded, retrying in ${backoff}ms...`);
await new Promise(resolve => setTimeout(resolve, backoff));
return fetchWithRetry(url, options, retries - 1, backoff * 2);
} else {
throw error;
}
}
}
Discord Command Module
The command definition and execution logic for changing user ranks.
module.exports = {
data: new SlashCommandBuilder()
.setName('rutbelendir')
.setDescription('Kullanıcının rütbesini değiştirir.')
.addStringOption(option =>
option.setName('sebep')
.setDescription('Rütbe değişiklik sebebi.')
.setRequired(true))
.addUserOption(option =>
option.setName('kullanici')
.setDescription('Discord kullanıcısı')
.setRequired(true))
.addStringOption(option =>
option.setName('alt_rutbe')
.setDescription('Alt rütbelerden birini seçin')
.addChoices(
...Object.entries(JSON.parse(fs.readFileSync(rankFile, 'utf8')).main)
.filter(([key]) => parseInt(key) <= 25)
.map(([key, value]) => ({ name: value, value: key }))
))
.addStringOption(option =>
option.setName('ust_rutbe')
.setDescription('Üst rütbelerden birini seçin')
.addChoices(
...Object.entries(JSON.parse(fs.readFileSync(rankFile, 'utf8')).main)
.filter(([key]) => parseInt(key) > 25)
.map(([key, value]) => ({ name: value, value: key }))
)),
async execute(interaction) {
console.log('Command execution started.');
if (!interaction.member.roles.cache.has(process.env.BOT_USTYETKI)) {
console.warn('User lacks permission to execute this command.');
return interaction.reply({ content: 'Bu komutu kullanmak için yetkiniz yok.', ephemeral: true });
}
await interaction.deferReply({ ephemeral: true });
try {
let ranks = JSON.parse(fs.readFileSync(rankFile, 'utf8')).main;
const data = JSON.parse(fs.readFileSync(dataFilePath, 'utf8'));
const kullaniciDiscordId = interaction.options.getUser('kullanici').id;
const kullaniciRobloxUsername = data[kullaniciDiscordId]?.robloxUsername;
const sebep = interaction.options.getString('sebep');
const altRutbe = interaction.options.getString('alt_rutbe');
const ustRutbe = interaction.options.getString('ust_rutbe');
// Validation for selected ranks
if (altRutbe && ustRutbe) {
console.warn('Both rank options selected; user must select only one.');
return await interaction.editReply('Bir rütbe seçeneği seçebilirsiniz. Lütfen sadece birini seçin.');
}
if (!altRutbe && !ustRutbe) {
console.warn('No rank option selected.');
return await interaction.editReply('Bir rütbe seçmelisiniz.');
}
const yeniRutbeKey = altRutbe || ustRutbe;
const yeniRutbeIndex = parseInt(yeniRutbeKey, 10);
console.log(`Selected rank: ${yeniRutbeIndex}`);
// Further processing logic...
} catch (error) {
console.error('Error during rank update process:', error.message);
await interaction.editReply('Rütbe güncellenirken bir hata oluştu.');
}
}
};
Practical Example of Command Usage
// Example of calling the command within a Discord bot
const command = require('./commands/rutbelendir');
bot.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
if (interaction.commandName === 'rutbelendir') {
await command.execute(interaction);
}
});
Conclusion
This implementation covers the necessary aspects to run the command effectively within a Discord bot, ensuring it handles errors, validates input, and fetches data from external APIs. For further learning and improvements, consider exploring resources on the Enterprise DNA Platform.
Description
This guide details a JavaScript command for a Discord bot that allows authorized users to update another user's rank in Roblox. It includes error handling, input validation, and integration with Discord and Roblox APIs.