Discord Bot认领命令异常:订单存在却提示不存在
Problem Description
I'm building an order claiming feature for a Discord Bot, where all orders are stored in a JSON file with this format:
{"mUT": {"orderID": "订单ID", "userID": "用户ID", "guildID": "服务器ID", "channelID": "频道ID", "order": "订单内容", "status": "Unclaimed", "ticketChannelMessageID": "工单频道消息ID"}}
When using the claim command, even though the order exists in the JSON file, the bot always replies with "Couldn't find that order." and the command fails to work correctly. Here's the relevant code:
const colors = require("colors"); exports.id = "claim"; exports.onLoad = api => { api.commands.add("claim", (msg) => { let employeeRole = msg.guild.roles.get("745410836901789749"); if(msg.member.roles.has(employeeRole.id)) { if(msg.channel.id == 746423099871985755) { // The ticket ID. let ticketID = msg.content.substring(7); fsn.readJSON("./orders.json").then((orderDB) => { const order = orderDB[ticketID]; // If the order doesn't exist. if(order === undefined) { msg.reply("Couldn't find that order."); return; } if (order.status === "Unclaimed") { // Edits the message in the tickets channel. api.client.channels.get("746423099871985755").fetchMessages({ around: order.ticketChannelMessageID, limit: 1 }).then(messages => { const fetchedMsg = messages.first(); fetchedMsg.edit({embed: { color: 0xFFFFFF, title: api.client.users.get(order.userID).username, fields: [ { name: "Order Description", value: order, }, { name: "Order ID", value: ticketID, }, { name: "Order Status", value: "claimed", } ], timestamp: new Date(), footer: { text: "Taco Bot" } }}).then((m) => { m = m.id; // Update Status delete orderDB[ticketID]; orderDB[ticketID] = { "orderID": order.orderID, "userID": order.userID, "guildID": order.guildID, "channelID": order.channelID, "order": order.order, "status": "Claimed", "ticketChannelMessageID": m, "chef": msg.author.id }; // Writes Data to JSON. fsn.writeJSON("./orders.json", orderDB, { replacer: null, spaces: 4 }).then(() => { // Sends a message to the cook. msg.channel.send(`You've now claimed \`${ticketID}\`.`); // Sends a message to the customer. api.client.users.get(order.userID).send(`Your order has been claimed and will be delivered soon.`); }).catch((err) => { if (err) { msg.reply(`There was an error while writing to the database! Show the following message to a developer: \`\`\`${err}\`\`\``); } }); console.log(colors.green(`${msg.author.username} claimed order ${ticketID}.`)); }); }); }else if(order.status === "Claimed") { if(order.chef !== msg.author.id) { msg.reply(`This order is already claimed by ${api.client.users.get(order.chef).tag}`); }else { msg.reply("You have already claimed this order. Run `.setimage [Order ID]` to set the order's image."); } }else if(order.status === "Waiting") { msg.reply("This order is in the waiting process. Wait a little bit, then run `.deliver [Order ID]` to deliver."); }else if(order.status === "Ready") { msg.reply("This order is already ready to be delivered. Run `.deliver [Order ID]` to deliver."); } }); }else { msg.reply("Please use this command in the orders channel."); console.log(colors.red(`${msg.author.username} used the claim command in the wrong channel.`)); } }else { msg.reply("You do not have access to this command."); console.log(colors.red(`${msg.author.username} did not have access to the claim command.`)); } }); };
Root Causes & Fixes
Let's break down the most likely issues and how to fix them:
1. Unreliable Ticket ID Extraction
Your current code uses msg.content.substring(7) to get the order ID, which relies on a fixed character length. This is fragile because:
- If the command prefix or spacing varies (e.g., multiple spaces between
.claimand the ID), you'll get an incorrect or empty ticket ID. - If the command is typed as
.claimmUT(no space), it will fail entirely.
Fix: Use split() to safely extract the order ID, which handles any number of spaces:
// Replace the ticketID line with this: const args = msg.content.trim().split(/\s+/); if (args.length < 2) { msg.reply("Please provide an order ID to claim. Usage: `.claim [Order ID]`"); return; } let ticketID = args[1];
2. Case Sensitivity Mismatch
JSON object keys are case-sensitive. If the user enters mut instead of mUT (the key in your JSON example), orderDB[ticketID] will return undefined.
Fix: Make the lookup case-insensitive by checking against lowercase versions of the keys:
// Replace `const order = orderDB[ticketID];` with this: const matchingKey = Object.keys(orderDB).find(key => key.toLowerCase() === ticketID.toLowerCase()); const order = matchingKey ? orderDB[matchingKey] : undefined;
3. Incorrect Channel ID Type Comparison
You're using == to compare the channel ID, but Discord IDs are strings. While == does type coercion, it's safer to use strict equality (===) to avoid unexpected behavior:
// Change this line: if(msg.channel.id == 746423099871985755) { // To this: if(msg.channel.id === "746423099871985755") {
4. Verify JSON File Loading
To confirm you're actually reading the correct data, add a log statement right after loading the JSON:
fsn.readJSON("./orders.json").then((orderDB) => { console.log("Loaded orders:", orderDB); // Check if the orders are correctly loaded // ... rest of your code });
This will show you exactly what's in the loaded object, so you can confirm if the ticket ID exists as a key.
Testing the Fixes
After applying these changes, test the command again:
- Try entering
.claim mUT(with correct case, or any case if you added the case-insensitive fix) - Check the console to ensure the orderDB is loaded correctly
- Verify that the bot now finds the order and updates its status properly
内容的提问来源于stack exchange,提问作者tekeke

