Code Generator | JavaScript

Discord Bot Rank Update Command for Roblox

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.


Empty image or helper icon

Prompt

const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const path = require('path');
const fs = require('fs');
const axios = require('axios');
const crypto = require('crypto');

const dataFilePath = path.join(__dirname, '../commands/data.json');
const rankFile = path.join(__dirname, '../commands/rutbe.json');

// API ile retry mekanizması
async function fetchWithRetry(url, options, retries = 3, backoff = 1000) {
    try {
        console.log(`Fetching URL: ${url} with options: ${JSON.stringify(options)}`);
        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;
        }
    }
}

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 });
        }

        try {
            await interaction.deferReply({ ephemeral: true });

            let ranks;
            try {
                ranks = JSON.parse(fs.readFileSync(rankFile, 'utf8')).main;
                console.log('Ranks loaded successfully.');
            } catch (error) {
                console.error('Error reading rank file:', error);
                await interaction.editReply('Rütbe dosyası okunurken bir hata oluştu.');
                return;
            }

            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');

            if (altRutbe && ustRutbe) {
                console.warn('Both rank options selected; user must select only one.');
                await interaction.editReply('Bir rütbe seçeneği seçebilirsiniz. Lütfen sadece birini seçin.');
                return;
            }

            if (!altRutbe && !ustRutbe) {
                console.warn('No rank option selected.');
                await interaction.editReply('Bir rütbe seçmelisiniz.');
                return;
            }

            const yeniRutbeKey = altRutbe || ustRutbe;
            const yeniRutbeIndex = parseInt(yeniRutbeKey, 10);
            console.log(`Selected rank: ${yeniRutbeIndex}`);

            if (!kullaniciRobloxUsername) {
                console.warn('Roblox username not found for the target user.');
                await interaction.editReply('Roblox kullanıcı adı bulunamadı.');
                return;
            }

            const executorUserId = interaction.user.id;
            const executorRobloxUsername = data[executorUserId]?.robloxUsername;

            if (!executorRobloxUsername) {
                console.warn('Executor Roblox username not found.');
                await interaction.editReply('Komutu kullananın Roblox kullanıcı adı bulunamadı.');
                return;
            }

            // Get executor's Roblox ID
            const executorUsernamesResponse = await fetchWithRetry('https://users.roblox.com/v1/usernames/users', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                data: {
                    usernames: [executorRobloxUsername],
                    excludeBannedUsers: true
                }
            });

            const executorUser = executorUsernamesResponse.data.find(user => user.name === executorRobloxUsername);

            if (!executorUser) {
                console.warn('Executor user not found in Roblox.');
                await interaction.editReply('Komutu kullanan kullanıcı bulunamadı.');
                return;
            }

            const executorId = executorUser.id;

            const executorRankResponse = await fetchWithRetry(`https://apis.roblox.com/datastores/v1/universes/${process.env.UNIVERSE_ID}/standard-datastores/datastore/entries/entry?datastoreName=main&entryKey=${executorId}`, {
                method: 'GET',
                headers: {
                    'x-api-key': process.env.ROBLOX_API_KEY,
                }
            });

            const executorRankIndex = parseInt(executorRankResponse?.value || executorRankResponse, 10);
            console.log(`Executor's current rank: ${executorRankIndex}`);

            // **Rütbe kontrolü**: Eğer kullanıcı mevcut bir rütbeye sahipse ve bu rütbe yeterliyse
            if (executorRankIndex <= yeniRutbeIndex) { // Örneğin, 50 ve üzeri bir rütbe gerekiyor olabilir
                console.warn('Executor does not have a high enough rank to update this user.');
                await interaction.editReply('Bu komutu kullanmak için yeterli rütbeye sahip değilsiniz.');
                return;
            }

            const kullaniciUsernamesResponse = await fetchWithRetry('https://users.roblox.com/v1/usernames/users', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                data: {
                    usernames: [kullaniciRobloxUsername],
                    excludeBannedUsers: true
                }
            });

            const kullaniciUser = kullaniciUsernamesResponse.data.find(user => user.name === kullaniciRobloxUsername);

            if (!kullaniciUser) {
                console.warn('Target user not found in Roblox.');
                await interaction.editReply('Rütbe verilecek kullanıcı bulunamadı.');
                return;
            }

            const kullaniciId = kullaniciUser.id;

            
            const JSONValue = JSON.stringify(yeniRutbeIndex);
            const ConvertAdd = crypto.createHash("md5").update(JSONValue).digest("base64");

            // Rütbe güncelleme
            const updateResponse = await fetchWithRetry(`https://apis.roblox.com/datastores/v1/universes/${6363491423}/standard-datastores/datastore/entries/entry`, {
                method: 'POST',
                headers: {
                    'x-api-key': process.env.ROBLOX_API_KEY,
                    'content-md5': ConvertAdd,
                    'content-type': 'application/json',
                },
                params: {
                    datastoreName: 'main',
                    entryKey: kullaniciId
                },
                data: JSONValue
            });

                if (updateResponse.status === 200) {
                    const embed = new EmbedBuilder()
                        .setTitle('Rütbe Güncellendi')
                        .setDescription(`Rütbe başarıyla güncellendi: ${kullaniciRobloxUsername} şu anda rütbe numarası "${yeniRutbeIndex}".`)
                        .setColor('GREEN');
                    await interaction.editReply({ embeds: [embed] });
                } else {
                    throw new Error('Rütbe güncelleme işlemi başarısız oldu.');
                }
            } catch (error) {
                console.error('Error during rank update process:', error.message);
                if (error.response) {
                    console.error('Error response data:', error.response.data);
                    console.error('Error response status:', error.response.status);
                    console.error('Error response headers:', error.response.headers);
                } else if (error.request) {
                    console.error('No response received:', error.request);
                } else {
                    console.error('Request setup error:', error.message);
                }
                    console.log('Rank update response:', updateResponse);
                
            
                await interaction.editReply('Rütbe güncellenirken bir hata oluştu.');
            }
    },
};

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.

Create your Thread using our flexible tools, share it with friends and colleagues.

Your current query will become the main foundation for the thread, which you can expand with other tools presented on our platform. We will help you choose tools so that your thread is structured and logically built.

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.