You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord票务机器人/add命令功能异常求助:Mongoose字段类型冲突导致报错

Fixing the /add Command Crash in Your Discord Ticket Bot

Let's break down why your /add command is crashing and walk through the fixes step by step.

Root Cause of the Issues

Your problems stem from a mismatch between the MembersID field type in your Mongoose Schema and the data already stored in your database:

  1. When MembersID was a String: You tried calling .push() on a string value, which isn't a valid method for strings—hence the is not a function error.
  2. When you switched to an Array: Existing documents in your DB still had MembersID stored as a string, so MongoDB threw a type mismatch error when trying to process those old entries.

Step 1: Fix the Mongoose Schema

First, update your Ticket.js Schema to enforce MembersID as an array of strings, and set a default empty array to ensure new tickets start with valid data:

module.exports = model("Tickets", new Schema({
  GuildID: String,
  MembersID: {
    type: [String],
    default: [] // Critical: ensures new tickets have an empty array instead of undefined/string
  },
  TicketID: String,
  ChannelID: String,
  Closed: Boolean,
  Locked: Boolean,
  Type: String,
  Claimed: Boolean,
  ClaimedBy: String
}));

Step 2: Migrate Existing Ticket Data

You need to convert all old MembersID string values in your database to arrays. Add this migration script to run when your bot starts up:

const Ticket = require('./Structures/Schemas/Tickets');

async function migrateOldTickets() {
  try {
    // Find all tickets where MembersID is still a string
    const oldTickets = await Ticket.find({ MembersID: { $type: "string" } });
    
    for (const ticket of oldTickets) {
      let membersArray;
      // Handle cases where the string might have comma-separated IDs
      if (ticket.MembersID.includes(',')) {
        membersArray = ticket.MembersID.split(',').map(id => id.trim());
      } else {
        // Convert single ID string to a single-element array
        membersArray = ticket.MembersID ? [ticket.MembersID] : [];
      }
      
      ticket.MembersID = membersArray;
      await ticket.save();
    }
    console.log('✅ Old ticket data migrated successfully');
  } catch (err) {
    console.error('❌ Error migrating ticket data:', err);
  }
}

// Run migration after bot is ready
client.once('ready', async () => {
  await migrateOldTickets();
  console.log('🚀 Bot is online and ready');
});

Step 3: Update the /add and /remove Command Logic

Rewrite your command logic to use async/await (instead of callbacks) for better error handling, and ensure proper array operations:

const { MessageEmbed, CommandInteraction} = require("discord.js");
const DB = require("../../Structures/Schemas/Tickets");

module.exports = {
  name: "actions",
  description: "Ticket Actions.",
  permission: "ADMINISTRATOR",
  options: [
    {
      name: "action",
      type: "STRING",
      description: "Add or Remove a member from this ticket.",
      required: true,
      choices: [
        { name: "Add", value: "add" },
        { name: "Remove", value: "remove" },
      ],
    },
    {
      name: "member",
      description: "Select the Member(s)",
      type: "USER",
      required: true,
    },
  ],
  /**
   * @param {CommandInteraction} interaction
   */
  async execute(interaction) {
    const { guildId, options, channel } = interaction;
    const Action = options.getString("action");
    const Member = options.getMember("member");
    const Embed = new MessageEmbed();

    try {
      switch(Action) {
        case "add":
          const addTicket = await DB.findOne({ GuildID: guildId, ChannelID: channel.id });
          if (!addTicket) {
            return interaction.reply({
              embeds: [Embed.setColor("#5104DB").setDescription("⛔ | This channel is not tied with a ticket.")],
              ephemeral: true,
            });
          }

          if (addTicket.MembersID.includes(Member.id)) {
            return interaction.reply({
              embeds: [Embed.setColor("#5104DB").setDescription("⛔ | This member has already been added to this ticket.")],
              ephemeral: true,
            });
          }

          // Add member to the array
          addTicket.MembersID.push(Member.id);
          // Update channel permissions
          await channel.permissionOverwrites.edit(Member.id, {
            SEND_MESSAGES: true,
            VIEW_CHANNEL: true,
            READ_MESSAGE_HISTORY: true,
          });

          await addTicket.save();
          await interaction.reply({
            embeds: [Embed.setColor("#5104DB").setDescription(`✅ | ${Member} has been added to this ticket.`)],
          });
          break;

        case "remove":
          const removeTicket = await DB.findOne({ GuildID: guildId, ChannelID: channel.id });
          if (!removeTicket) {
            return interaction.reply({
              embeds: [Embed.setColor("#5104DB").setDescription("⛔ | This channel is not tied with a ticket.")],
              ephemeral: true,
            });
          }

          if (!removeTicket.MembersID.includes(Member.id)) {
            return interaction.reply({
              embeds: [Embed.setColor("#5104DB").setDescription("⛔ | This member is not associated with this ticket.")],
              ephemeral: true,
            });
          }

          // Remove member from the array (filter is cleaner than .remove())
          removeTicket.MembersID = removeTicket.MembersID.filter(id => id !== Member.id);
          // Update channel permissions
          await channel.permissionOverwrites.edit(Member.id, {
            VIEW_CHANNEL: false,
          });

          await removeTicket.save();
          await interaction.reply({
            embeds: [Embed.setColor("#5104DB").setDescription(`✅ | ${Member} has been removed from this ticket.`)],
          });
          break;
      }
    } catch (err) {
      console.error(`Error handling ${Action} action:`, err);
      await interaction.reply({
        embeds: [Embed.setColor("#FF0000").setDescription("❌ | An error occurred while processing this action.")],
        ephemeral: true,
      });
    }
  },
};

Key Improvements in This Fix

  • Error Handling: Wrapped all logic in a try/catch block to prevent bot crashes and provide user-friendly error messages.
  • Async/Await: Replaced callback functions with async/await for cleaner, more readable code.
  • Array Operations: Used valid array methods (push, filter) instead of invalid string methods.
  • Data Consistency: Ensured all existing and new tickets use the correct array type for MembersID.

内容的提问来源于stack exchange,提问作者senpai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:42:33