Search code examples
javascriptdiscord.js

Discord.JS - List all files within a directory as one message


I am having an issue where I cannot seem to find a solution.

I have written a Discord bot from Discord.JS that needs to send a list of file names from a directory as one message. So far I have tried using fs.readddir with path.join and fs.readfilesync(). Below is one example.

        const server = message.guild.id;
        const serverpath = `./sounds/${server}`;
        const fs = require('fs');
        const path = require('path');

        const directoryPath = path.join('/home/pi/Pablo', serverpath);

        fs.readdir(directoryPath, function(err, files) {
            if (err) {
                return console.log('Unable to scan directory: ' + err);
            }
            files.forEach(function(file) {
                message.channel.send(file);
            });
        });

Whilst this does send a message of every file within the directory, it sends each file as a separate message. This causes it to take a while due to Discord API rate limits. I want them to all be within the same message, separated with a line break, with a max of 2000 characters (max limit for Discord messages).

Can someone assist with this?

Thanks in advance.


Solution

  • I recommend using fs.readdirSync(), it will return an array of the file names in the given directory. Use Array#filter() to filter the files down to the ones that are JavaScript files (extentions ending in ".js"). To remove ".js" from the file names use Array#map() to replace each ".js" to "" (effectively removing it entirely) and use Array#join() to join them into a string and send.

    const server = message.guild.id;
    const serverpath = `./sounds/${server}`;
    const { readdirSync } = require('fs');
    const path = require('path');
    
    const directoryPath = path.join('/home/pi/Pablo', serverpath);
    
    const files = readdirSync(directoryPath)
       .filter(fileName => fileName.endsWith('.js'))
       .map(fileName => fileName.replace('.js', ''));
       .join('\n');
    message.channel.send(files);
    

    Regarding handling the sending of a message greater than 2000 characters: You can use the Util.splitMessage() method from Discord.JS and provide a maxLength option of 2000. As long as the number of chunks needed to send is not more than a few you should be fine from API ratelimits

    const { Util } = require('discord.js');
    
    // Defining "files"
    
    const textChunks = Util.splitMessage(files, {
       maxLength: 2000
    });
    
    textChunks.forEach(async chunk => {
       await message.channel.send(chunk);
    });