Outrage
Outrage

Reputation: 57

Cannot read property “send” of undefined

I am trying to make a Karuta trade application bot and it keeps saying Cannot read property “send” of undefined.

Everytime I try to figure out the problem it gets worse and worse.

Can someone please help me to figure out this problem thats breaking my application process?

It fails when it trys to send to a channel called test

Code:

const { Client, Message, MessageEmbed } = require('discord.js');

module.exports = {
    name: `apply`,
    /**
     * @param {Client} client 
     * @param {Message} message 
     * @param {String[]} args 
     */
    async execute(client, message, args) {
        const questions = [
            "Would you like to advertise your Karuta Card Trades?",
            "Cards FS:",
            "Cards FB:"
        ]
        let collectCounter = 0;
        let endCounter = 0;

        const filter = (m) => m.author.id === message.author.id;
        
        const appStart = await message.author.send(questions[collectCounter++]);
        const channel = appStart.channel

        const collector = channel.createMessageCollector(filter);
        
        collector.on("collect", () => {
            if(collectCounter < questions.length) {
                channel.send(questions[collectCounter++])
            } else {
                channel.send('Your application has been submitted!')
                collector.stop("fulfilled");
            }
        });
        const APPS_CHANNEL_ID = '822605997356875777'
        const appsChannel = await client.channels.fetch(APPS_CHANNEL_ID)
        collector.on('end', (collected, reason) => {
            if(reason == 'fulfilled') {
                let index = 1;
                const mappedResponses = collected.map((msg) => {
                    return `${index++}) ${questions[endCounter++]}\n-> ${msg.content}`;
                })
                .join('\n\n')
                appsChannel.send(
                    new MessageEmbed()
                        .setAuthor(message.author.tag, message.author.displayAvatarURL({dynamic: true})
                        )
                        .setTitle('New Application')
                        .setDescription(mappedResponses)
                        .setColor('RED')
                        .setTimestamp()
                )
                throw new Error('TOKEN_MISSING');
            }
        });
    },
    }

Error:

(node:3435) UnhandledPromiseRejectionWarning: DiscordjsError: Request to use token, but token was unavailable to the client.
    at RequestHandler.execute (/Users/mahdiabbas/Documents/Karuta Trade/node_modules/discord.js/src/rest/RequestHandler.js:93:15)
    at RequestHandler.execute (/Users/mahdiabbas/Documents/Karuta Trade/node_modules/discord.js/src/rest/RequestHandler.js:97:19)
    at RequestHandler.push (/Users/mahdiabbas/Documents/Karuta Trade/node_modules/discord.js/src/rest/RequestHandler.js:39:25)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async ChannelManager.fetch (/Users/mahdiabbas/Documents/Karuta Trade/node_modules/discord.js/src/managers/ChannelManager.js:91:18)
    at async Object.execute (/Users/mahdiabbas/Documents/Karuta Trade/commands/tradead.js:35:29)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3435) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:3435) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Index.js:

const Discord = require('discord.js');
const bot = new Discord.Client()
const client = new Discord.Client()
const prefix = '-';

const queue = new Map();
const fs = require('fs');
bot.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));



for (const file of commandFiles) {
  const command = require(`./commands/${file}`);

  bot.commands.set(command.name, command);
}
bot.on('ready', () => {
  console.log(`${bot.user.tag} is online.`)
  bot.user.setStatus(`dnd`)
  bot.user.setActivity({
    type: `WATCHING`,
    name: `Out For Subaru`,
  })
})


bot.on("message", async message => {
  if (!message.content.startsWith(prefix) || message.author.bot) return;

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

  const command = bot.commands.get(commandName) || bot.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
  try {
    command.execute(client, message, args);
  } catch (error) {
    console.log(error)
  }
});```

Upvotes: 2

Views: 721

Answers (1)

Arun Kumar Mohan
Arun Kumar Mohan

Reputation: 11915

Looks like client.channels.cache.get('822605997356875777') returns undefined. This likely means the channel wasn't cached. You can use ChannelManager#fetch to fetch the channel.

You are also creating an additional Client object (which isn't logged in) and passing it to the execute function. You don't need it. Remove const client = new Discord.Client() from index.js.

And update the command.execute call to only send message and args.

command.execute(message, args)

You can get the client object from message in the execute function.

async execute(message, args) {
  const { client } = message
  // ...

  const APPS_CHANNEL_ID = '822605997356875777'
  const appsChannel = await client.channels.fetch(APPS_CHANNEL_ID)
  // ...
}

Note that you'll have to update all commands' execute functions since they'll only receive message and args.

Upvotes: 3

Related Questions