【问题标题】:client.on is not a functionclient.on 不是函数
【发布时间】:2021-10-18 01:08:15
【问题描述】:

我正在使用 Discord.JS 编写一个 Discord 机器人。

我最近遇到了一个似乎突然出现的错误,说 client.on 不是函数。

我已经重新排序和重写了我认为可能导致问题的部分代码,但到目前为止还没有成功。

// Importing Packages
const Discord = require("discord.js")

const client = new Discord.Client({
  intents: [Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES, Discord.Intents.FLAGS.GUILD_PRESENCES],
});
const SQLite = require("better-sqlite3")
const sql = new SQLite('./mainDB.sqlite')
const {
  join
} = require("path")
const fs = require("fs");
const {
  readdirSync
} = require("fs");
const {
  REST
} = require('@discordjs/rest');
const {
  Routes
} = require('discord-api-types/v9');
const {
  token
} = require('./config.json');

client.commands = new Discord.Collection();
const cooldowns = new Discord.Collection();
const talkedRecently = new Map();

// Token, Prefix, and Owner ID
const config = require("./config.json");


    client.on("ready", () => {
      const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));

      for (const file of commandFiles) {
        const command = require(`./commands/${file}`);
        client.commands.set(command.name, command);
      }
    
    
    
    
      
      const rest = new REST({
        version: '9'
      }).setToken(token);
    
      (async () => {
        try {
          console.log('Started refreshing application (/) commands.');
    
          await rest.put(
            Routes.applicationGuildCommands(client.user.id, "874809270259052585"), {
              body: client.commands.map(({
                execute,
                ...data
              }) => data)
            },
          );
    
          console.log('Successfully reloaded application (/) commands.');
        } catch (error) {
          console.error(error);
        }
        });
    
  // Check if the table "points" exists.
  const levelTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'levels';").get();
  if (!levelTable['count(*)']) {
    sql.prepare("CREATE TABLE levels (id TEXT PRIMARY KEY, user TEXT, guild TEXT, xp INTEGER, level INTEGER, totalXP INTEGER);").run();
  }

  client.getLevel = sql.prepare("SELECT * FROM levels WHERE user = ? AND guild = ?");
  client.setLevel = sql.prepare("INSERT OR REPLACE INTO levels (id, user, guild, xp, level, totalXP) VALUES (?, ?, ?, ?, ?, ?);");

  // Check if the table "backgrounds" exists.
  const bgTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'background';").get();
  if (!bgTable['count(*)']) {
    sql.prepare("CREATE TABLE background (user TEXT, guild TEXT, bg TEXT)").run();
  }

  client.getBg = sql.prepare("SELECT bg FROM background WHERE user = ? AND guild = ?;");
  client.setBg = sql.prepare("INSERT OR REPLACE INTO background (user, guild, bg) VALUES (@user, @guild, @bg);");

  // Role table for levels
  const roleTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'roles';").get();
  if (!roleTable['count(*)']) {
    sql.prepare("CREATE TABLE roles (guildID TEXT, roleID TEXT, level INTEGER);").run();
  }

  // Prefix table
  const prefixTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'prefix';").get();
  if (!prefixTable['count(*)']) {
    sql.prepare("CREATE TABLE prefix (serverprefix TEXT, guild TEXT PRIMARY KEY);").run();
  }

  // Blacklist table
  const blacklistTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'blacklistTable';").get();
  if (!blacklistTable['count(*)']) {
    sql.prepare("CREATE TABLE blacklistTable (guild TEXT, typeId TEXT, type TEXT, id TEXT PRIMARY KEY);").run();
  }

    // 2X XP table
    const doubleXPTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'doubleXP';").get();
    if (!doubleXPTable['count(*)']) {
      sql.prepare("CREATE TABLE doubleXP (guild TEXT, role TEXT);").run();
    }

  // Settings table
  const settingsTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'settings';").get();
  if (!settingsTable['count(*)']) {
    sql.prepare("CREATE TABLE settings (guild TEXT PRIMARY KEY, levelUpMessage TEXT, customXP INTEGER, customCooldown INTEGER);").run();
  }

  const channelTable = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'channel';").get();
  if (!channelTable['count(*)']) {
    sql.prepare("CREATE TABLE channel (guild TEXT PRIMARY KEY, channel TEXT);").run();
  }

  console.log(`Logged in as ${client.user.username}`)
})();

client.on('interactionCreate', async interaction => {
  if (!interaction.isCommand()) return;

  if (!client.commands.has(interaction.commandName)) return;

  try {
    await client.commands.get(interaction.commandName).execute(interaction);
  } catch (error) {
    console.error(error);
    return interaction.reply({
      content: 'There was an error while executing this command!',
      ephemeral: true
    });
  }
});

// XP Messages 
client.on("messageCreate", message => {
  if (message.author.bot) return;
  if (!message.guild) return;

      // 2X XP table
      const doubleXPTable = sql.prepare("SELECT role FROM 'doubleXP' WHERE guild = " + message.guild.id).get()["role"];      ;
      if (doubleXPTable['role'] && message.member.roles.has(doubleXPTable['role'])) {
        var xpMulti = 2;
      }  else {
        var xpMulti = 1;
      }

  let blacklist = sql.prepare(`SELECT id FROM blacklistTable WHERE id = ?`);
  if (blacklist.get(`${message.guild.id}-${message.author.id}`) || blacklist.get(`${message.guild.id}-${message.channel.id}`)) return;

  // get level and set level
  const level = client.getLevel.get(message.author.id, message.guild.id)
  if (!level) {
    let insertLevel = sql.prepare("INSERT OR REPLACE INTO levels (id, user, guild, xp, level, totalXP) VALUES (?,?,?,?,?,?);");
    insertLevel.run(`${message.author.id}-${message.guild.id}`, message.author.id, message.guild.id, 0, 0, 0)
    return;
  }

  let customSettings = sql.prepare("SELECT * FROM settings WHERE guild = ?").get(message.guild.id);
  let channelLevel = sql.prepare("SELECT * FROM channel WHERE guild = ?").get(message.guild.id);

  const lvl = level.level;

  let getXpfromDB;
  let getCooldownfromDB;

  if (!customSettings) {
    getXpfromDB = 16; // Default
    getCooldownfromDB = 1000;
  } else {
    getXpfromDB = customSettings.customXP;
    getCooldownfromDB = customSettings.customCooldown;
  }

  // xp system
  const generatedXp = Math.floor(Math.random() * getXpfromDB);
  const nextXP = level.level * 2 * 250 + 250 * xpMulti;
  // message content or characters length has to be more than 4 characters also cooldown
  if (talkedRecently.get(message.author.id) || message.content.length < 3 || message.content.startsWith(config.prefix)) {
    return;
  } else { // cooldown is 10 seconds
    level.xp += generatedXp;
    level.totalXP += generatedXp;


    // level up!
    if (level.xp >= nextXP) {
      level.xp = 0;
      level.level += 1;

      let levelUpMsg;

      if (!customSettings) {

        levelUpMsg = `**Congratulations** ${message.author}! You have now leveled up to **level ${level.level}**`;
      } else {
        function antonymsLevelUp(string) {
          return string
            .replace(/{member}/i, `${message.member}`)
            .replace(/{xp}/i, `${level.xp}`)
            .replace(/{level}/i, `${level.level}`)
        }

        levelUpMsg = antonymsLevelUp(customSettings.levelUpMessage.toString());
      }
      // using try catch if bot have perms to send EMBED_LINKS      
      try {
        if (!channelLevel || channelLevel.channel == "Default") {
          message.channel.send(levelUpMg);
        } else {
          let channel = message.guild.channels.cache.get(channelLevel.channel)
          const permissionFlags = channel.permissionsFor(message.guild.me);
          if (!permissionFlags.has("SEND_MESSAGES") || !permissionFlags.has("VIEW_CHANNEL")) return;
          channel.send(levelUpMsg);
        }
      } catch (err) {
        if (!channelLevel || channelLevel.channel == "Default") {
          message.channel.send(levelUpMsg);
        } else {
          let channel = message.guild.channels.cache.get(channelLevel.channel)
          const permissionFlags = channel.permissionsFor(message.guild.me);
          if (!permissionFlags.has("SEND_MESSAGES") || !permissionFlags.has("VIEW_CHANNEL")) return;
          channel.send(levelUpMsg);
        }
      }
    };
    client.setLevel.run(`${message.author.id}-${message.guild.id}`, message.author.id, message.guild.id, level.xp, level.level, level.totalXP);
    // add cooldown to user
    talkedRecently.set(message.author.id, Date.now() + getCooldownfromDB);
    setTimeout(() => talkedRecently.delete(message.author.id, Date.now() + getCooldownfromDB))
  }
  // level up, time to add level roles
  const member = message.member;
  let Roles = sql.prepare("SELECT * FROM roles WHERE guildID = ? AND level = ?")

  let roles = Roles.get(message.guild.id, lvl)
  if (!roles) return;
  if (lvl >= roles.level) {
    if (roles) {
      if (member.roles.cache.get(roles.roleID)) {
        return;
      }
      if (!message.guild.me.permissions.has("MANAGE_ROLES")) {
        return
      }
      member.roles.add(roles.roleID);
    }
  }
});

client.login(config.token);

注意事项:

  1. 我正在使用 Discord.JS v13.0.00
  2. 我不在乎这段代码绝对是一团糟。我稍后会解决这个问题;这不是当前的问题。
  3. 我已经多次重新安装 Discord.JS。
  4. client 不是未定义的。
  5. 它发生在ready 事件上,但如果它有机会到达那里,它可能会发生在其他事件上。

【问题讨论】:

  • 你能告诉我们错误发生在哪里吗?也可以缩短您的代码示例,以便您的问题中只有关键行
  • 它发生在 ready 事件上,但我不明白如果它有机会到达那里,为什么它会在任何其他事件上起作用。
  • 当你console.log(client) 在控制台中说什么?
  • 我记录了一次,它不是 null 或 undefined,但我不记得它到底是什么了。它很长,所以我无法将其发布在 cmets 中,但我可以尝试再次记录它,然后您告诉我要查找的内容,以便我可以查看您想要的内容是否存在?
  • 如果错误出现在前20行,为什么要发布这么多代码?请阅读minimal reproducible exampleHow to debug small programs

标签: javascript node.js discord discord.js


【解决方案1】:

client.on 确实不是一个函数。它是一个听众。

无论如何,您的问题似乎在第 123 行:

})();

将其更改为:

});

当您使用侦听器时(在您的情况下为client.on..),您不一定必须使用() 调用它。

【讨论】:

  • 谢谢!!!我是机器人编码的新手哈哈,很抱歉我搞砸了。
  • 没问题,我们都是初学者,祝你有美好的一天:D
  • client.on() 是一个方法(与对象关联的函数),它注册了一个事件监听器。问题是 function call 的表达式本身并不是一个函数。函数的结果/返回值可能是函数,您必须将函数调用包装到括号中才能像以前那样调用它。
  • 技术上是这样的,但我不想听起来令人困惑
猜你喜欢
  • 2018-06-15
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 2019-01-06
  • 2021-07-27
  • 2022-07-28
  • 2021-12-03
相关资源
最近更新 更多