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

Discord工单机器人关闭日志异常及创建者记录错误求助

解决Discord工单机器人关闭时的日志记录问题

看起来你遇到了两个典型的异步状态和变量作用域问题,我来帮你逐个拆解解决:

问题1:关闭工单后日志显示#deleted-channel

原因

message.channel.delete()是异步操作,但更关键的是:当频道被删除后,原频道对象的属性(比如name)会变成#deleted-channel。如果你在删除之后(或者没提前保存数据)尝试引用频道信息,自然会拿到失效的内容。

解决方案

在执行删除前,先把需要的工单信息(比如频道名、申请者标识)保存到变量里,再用这些变量发送日志,最后删除频道。

问题2:tAuthor只记录最近申请者的信息

原因

你用var tAuthor定义的是全局变量,每次有人提交新申请时,这个变量都会被覆盖成当前申请者的tag。关闭工单时读取的是最后一次赋值的内容,自然不是当前工单的创建者。

解决方案

不要用全局变量存储申请者信息,而是从工单频道本身提取:

  • 方案A:利用你已经设置的频道名t-staff-${message.author.tag},从频道名里拆分出申请者tag(推荐这个,因为你已经在用频道名区分工单,无需额外操作)
  • 方案B:创建频道时把申请者ID/Tag写入频道的topic(主题),关闭时读取这个主题

修改后的完整代码

1. 更新-close命令代码

if (!message.channel.name.startsWith(`t-staff-`)) return message.channel.send(`You can't use the close command outside of a ticket channel.`);
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.channel.send(`${message.author} Do not have permission to close this application`);

// 提前保存工单的关键信息:从频道名提取申请者tag
const applicantTag = message.channel.name.replace('t-staff-', '');
const channelName = message.channel.name;

// Confirm delete - with timeout (Not command)
message.channel.send(`Are you sure? Once confirmed, you cannot reverse this action!\nTo confirm, type \`/confirm\`. This will time out in 10 seconds and be cancelled.`)
.then((m) => {
 message.channel.awaitMessages(response => response.content === '/confirm', { max: 1, time: 10000, errors: ['time'], })
 .then((collected) => {
   // 先发送日志,再删除频道(用提前保存的变量,不会受频道删除影响)
   const currentDate = new Date().toLocaleString();
   client.channels.get(`568210811009499136`).send(`:x: Ticket Closed: #${channelName} (Applicant: ${applicantTag}) at **${currentDate}**`);
   // 执行频道删除
   message.channel.delete();
 })
 .catch(() => {
 m.edit('Ticket close timed out, the ticket was not closed.').then(m2 => {
 m2.delete();
 }, 3000);
 });
});

2. 优化-apply命令(消除全局变量隐患)

把原来的全局var tAuthor改成局部变量,同时修正setParent的错误写法(原代码里message.guild.category.exists是无效语法):

const reason = message.content.split(" ").slice(1).join(" ");
// 改用局部变量存储申请者tag,避免全局污染
const applicantTag = message.author.tag;

if (!message.guild.roles.exists("name", "[»] Helpers")) return message.channel.send(`Server does not have role set correctly., This error has been logged. \nPlease contact bot developer <@251557870603075586>`);
if (message.guild.channels.exists("name", "t-staff-" + applicantTag)) return message.reply(`You already have an application open.`);

message.guild.createChannel(`t-staff-${applicantTag}`, "text").then(c => {
 let role = message.guild.roles.find("name", `${config.role}`);
 let role2 = message.guild.roles.find("name", "@everyone");
 c.overwritePermissions(role, { SEND_MESSAGES: true, READ_MESSAGES: true });
 c.overwritePermissions(role2, { SEND_MESSAGES: false, READ_MESSAGES: false });
 c.overwritePermissions(message.author, { SEND_MESSAGES: true, READ_MESSAGES: true });
 
 // 修正setParent:先找到目标分类频道
 const ticketCategory = message.guild.channels.find(ch => ch.name === "t-staff-" && ch.type === "category");
 if (ticketCategory) {
   c.setParent(ticketCategory);
 }
 
 message.reply(`:white_check_mark: Your application has been created, #${c.name}.`);
 const embed = new Discord.RichEmbed()
 .setColor(0xCF40FA)
 .setTitle(`Staff Application`)
 .setDescription(`<@${message.author.id}>`)
 .addField(`Requirements`, `You must meet all the requirements:\n\n1. Professional attitude and grammar\n2. Working Microphone\n3. No severe punishments on the server. (Racial Slurs, DDos Threats, etc..)\n4. You must be over the age of 14`)
 .addBlankField()
 .addField(`Note:`, `Please check in announcements for open staff positions`)
 .addField(`Note:`, `Please paste the format with your answers`)
 .addField(`Note:`, `If your previous application was denied you must wait one week to sumbit a new one`)
 .addBlankField()
 .addField('Format', `\nWhat position are you applying for: \n\nMinecraft username: \n\nPrevious Minecraft usernames: \n\nWhat is your age: \n\nTimezone: \n\nAbility to record Minecraft video: \n\nHow much time do you have to contribute a week? \n\nWhat do you consider to be your biggest weaknesses?\n\nWhat's your dream job? \n\nHow do you deal with pressure or stressful situations? \n\nAny previous staff skills or experience? \n\nHave you ever been banned or punished for your actions on this server? If so, please include details. \n\nTell us about a time you made a mistake within the last year? How did you deal with it? What did you learn? \n\nAre you currently staff on any other servers? \n\nWhere did you hear about nodepvp? \n\nHave you made any previous applications, if so how many and what is the date of your last one? \n\nWhat would be your daily tasks for the rank you are applying for \n\nAnything else we should know? `)
 .addBlankField()
 .setTimestamp();
 c.send({ embed: embed });
 
 const currentDate = new Date().toLocaleString();
 client.channels.get(`568210811009499136`).send(`:white_check_mark: !!!Ticket Created ${message.author} at **${currentDate}**`);
});

额外提示

  • 尽量避免用var定义全局变量,改用const或let定义局部变量,防止变量污染
  • 如果需要更可靠地存储工单关联信息,可以考虑用轻量数据库(比如SQLite)记录工单ID和申请者的对应关系,不过对于小型机器人来说,从频道名提取已经足够实用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:37:29