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.
