1

I want to ask for a .txt file, read file and send the file content to the channel using a discord bot.

Description of intended behavior:

  • User writes the command: !readfile
  • Bot responds with message asking the user to drop/send the file in the chat
  • Bot awaits for the file
  • Bot reads the file content
  • Sends the content back to the channel in a message

This is my most recent attempt at creating this command:

if (message.content === '!readfile') {

message.channel.send("Send your file please...");

 message.channel.awaitMessages(filter, {max: 1}).then(msg => {
   const filter = m => m.author.id === message.author.id;
   let file = msg.attachments.first().file;
   fs.readFile(file, (err, data) => {
     msg.channel.send("Read the file! Fetching data...");
     msg.channel.send(data);
   });
 });
}
4
  • 1
    What problems/errors are you having? It’s hard to help if you don’t give us how exactly it doesn’t work. Commented Jul 6, 2021 at 3:11
  • @MrMythical it isn't an error, he/she wants to fetch the ".txt" or any file sent in a message. Commented Jul 6, 2021 at 4:00
  • also @noobami I don't feel there's any way to fetch the file from message except links and text or text format Commented Jul 6, 2021 at 4:01
  • Be 100% sure, that no user is going to abuse that. Sending files to a bot, and reading those, is one of the most dangerous things you can do with a discord bot. Your bot could crash, or in the worst case, your bot could get hacked. Maybe limit the function to only users with a certain role as a safety precaution. Commented Jul 6, 2021 at 7:36

1 Answer 1

1

As I've mentioned in a previous post, you can't use the fs module to read the content of the attached files as it only deals with local files.

When you upload a file through Discord, it gets uploaded to a CDN. You can't grab the file itself (and there is no file property on the MessageAttachment either), all you can do is to grab the URL of the uploaded file using the url property.

As you want to get a file from the web, you will need to fetch it by a URL. You can use the built-in https module, or you can install one from npm, like axios, node-fetch, etc.

I used node-fetch in my example and make sure you install it first by running npm i node-fetch in your root folder.

Check out the working code below, it works fine with text files:

// on the top
const fetch = require('node-fetch');

client.on('message', async (message) => {
  if (message.author.bot) return;

  const args = message.content.slice(prefix.length).split(/ +/);
  const command = args.shift().toLowerCase();

  if (command === 'readfile') {
    message.channel.send('Send your file please...');

    const filter = (m) => m.author.id === message.author.id;

    try {
      const collected = await message.channel.awaitMessages(filter, { max: 1 });

      // get the file's URL
      const file = collected.first().attachments.first()?.url;
      if (!file) return console.log('No attached file found');

      // await the message, so we can later delete it
      const sent = await message.channel.send(
        'Reading the file! Fetching data...',
      );

      // fetch the file from the external URL
      const response = await fetch(file);

      // if there was an error send a message with the status
      if (!response.ok) {
        sent.delete();
        return message.channel.send(
          'There was an error fetching your file:',
          response.statusText,
        );
      }

      // take the response stream and read it to completion
      const text = await response.text();

      if (text) {
        sent.delete();
        return message.channel.send(`\`\`\`${text}\`\`\``);
      }
    } catch (err) {
      console.log(err);
      return message.channel
        .send(`Oops, that's lame. There was an error...`)
        .then((sent) => setTimeout(() => sent.delete(), 2000));
    }
  }
});

Also, don't forget that awaitMessages() returns a collection of messages, even if the max option is set to 1, so you will need to grab the first() one.

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.