Discord.js |机器人重启后按钮不起作用
Discord.js | Buttons doesn't work after bot restarts
按钮在执行命令后工作,但在重新启动机器人并按下按钮后,它显示 interaction failed
这是我的 ticket.js
const { MessageButton } = require('discord-buttons');
module.exports = {
name: 'ticket-setup',
aliases: ['close'],
category: 'Miscellaneous',
description: 'Makes a ticket embed',
async execute(message, args, cmd, client, Discord){
if(!message.member.permissions.has("MANAGE_CHANNELS")) return message.reply("Normies can't do this command")
if (cmd == 'close') {
if (!message.channel.name.includes('ticket-')) return message.channel.send('You cannot use that here!');
message.channel.delete();
}
let title;
let desc;
let ticketMsg;
const filter = msg => msg.author.id == message.author.id;
let options = {
max: 1
};
message.channel.send("What will the ticket title be?\nSay cancel to cancel")
let col = await message.channel.awaitMessages(filter, options)
if(col.first().content == 'cancel') return message.channel.send("Cancelled");
title = col.first().content
message.channel.send('What will the description be?\nSay cancel to cancel')
let col2 = await message.channel.awaitMessages(filter, options)
if(col2.first().content == 'cancel') return message.channel.send("Cancelled");
desc = col2.first().content
message.channel.send('What is the message that the user will see when they make a ticket?\nSay cancel to cancel')
let col3 = await message.channel.awaitMessages(filter, options)
if(col3.first().content == 'cancel') return message.channel.send("Cancelled");
ticketMsg = col3.first().content
const setupEmbed = new Discord.MessageEmbed()
.setTitle(title)
.setDescription(desc)
.setFooter(message.guild.name, message.guild.iconURL({ dynamic: true }))
.setColor('00f8ff')
const hiEmbed = new Discord.MessageEmbed()
.addField(ticketMsg, "\n\nDo a.close or press the button to close the ticket")
.setColor("RANDOM")
.setTimestamp()
const createTicketButton = new MessageButton()
.setID("ticketCreate")
.setStyle("blurple")
.setLabel("");
const closeTicketButton = new MessageButton()
.setID("ticketClose")
.setLabel("Close ticket")
.setStyle("red");
if(cmd == 'ticket-setup'){
message.channel.send({embed: setupEmbed, button: createTicketButton })
}
client.on('clickButton', async (button) => {
await button.clicker.fetch();
await button.reply.defer();
const user = button.clicker.user
if (button.id === 'ticketCreate') {
button.guild.channels.create(`ticket-${user.id}`, {
permissionOverwrites: [
{
id: user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: button.message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async (channel) =>{
channel.send({embed: hiEmbed, button: closeTicketButton })
})
} else if(button.id == 'ticketClose'){
button.message.channel.delete()
}
});
}
}
我用的是包discord-buttons
Docs link
我尝试将 clickButton 事件放入我的事件处理程序中,但它不起作用,因为我遇到了很多错误。如何在重启后让按钮继续工作?
我也有这个问题,但不是交互失败,而是按钮信息不完整。
client.ws.on('INTERACTION_CREATE', interaction => {
//complete interaction
})
按钮是触发这个的交互,你可以用interaction.data.custom_id
检查这是一个斜线命令还是按钮(这可能是错误的,我无法测试它)。如果它不是按钮,它将是未定义的,但如果它是按钮,它将保留按钮的自定义 id。
问题
你的按钮在你的 bot 重启后不起作用的原因是因为你的 client.on("clickButton")
事件处理程序是 inside 你的“ticket-setup”命令的代码。这意味着您的事件仅在机器人重新启动后使用 ticket-setup 命令时才会设置,或者换句话说,一旦机器人启动后对该文件调用 execute()
。
想一想:在调用 ticket-setup
命令的 execute()
函数之前,不会到达您的 client.on("clickButton")
代码。这会给你带来很多问题。首先,如上所述,在机器人启动后至少使用一次 ticket-setup
之前,甚至不会处理 clickButton
事件。其次,这将在每次使用命令时创建 一个额外的事件处理程序 。换句话说,如果您要使用 ticket-setup
命令两次或更多次,您的 clickButton
处理程序中的代码将执行 多次 每次您的按钮单击(在您的特定情况下,每次单击按钮会创建不止一张票)。
解决方案
您面临的问题有一个非常简单的解决方法。您只需将整个 clickButton
事件处理程序移出 execute()
方法。也许将它移动到您的主 server.js
或 bot.js
文件中,连同您的 client.on("ready")
和 client.on("message")
事件处理程序。这将确保 clickButton
事件处理程序仅设置一次,并在机器人启动时立即设置。
但是请注意,您确实需要对 clickButton
事件处理程序进行一些细微的添加,以确保其正常工作。您需要将 hiEmbed
和 closeTicketButton
的代码移动到 client.on("clickButton")
处理程序中。
根据您问题中的代码,在 server.js
中可能会是这样:
client.on('clickButton', async (button) => {
await button.clicker.fetch();
await button.reply.defer();
const user = button.clicker.user;
const hiEmbed = new Discord.MessageEmbed()
.addField(ticketMsg, "\n\nDo a.close or press the button to close the ticket")
.setColor("RANDOM")
.setTimestamp();
const closeTicketButton = new MessageButton()
.setID("ticketClose")
.setLabel("Close ticket")
.setStyle("red");
if (button.id === 'ticketCreate') {
button.guild.channels.create(`ticket-${user.id}`, {
permissionOverwrites: [
{
id: user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: button.message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async (channel) =>{
channel.send({embed: hiEmbed, button: closeTicketButton })
})
} else if(button.id == 'ticketClose'){
button.message.channel.delete()
}
});
您可能已经注意到另一个问题:ticketMsg
变量将不会被定义。您还需要进行更改以解决该问题。我建议将 ticketMsg
的值保存到 JSON 文件或数据库中,并在 client.on("clickButton")
中访问该信息。如果此代码代表一个正确的票务系统,则无论您是否使用此解决方案,您都需要执行此操作,否则您的用户将需要使用 ticket-setup
再次设置票务系统 你的机器人重启的时间.
按钮在执行命令后工作,但在重新启动机器人并按下按钮后,它显示 interaction failed
这是我的 ticket.js
const { MessageButton } = require('discord-buttons');
module.exports = {
name: 'ticket-setup',
aliases: ['close'],
category: 'Miscellaneous',
description: 'Makes a ticket embed',
async execute(message, args, cmd, client, Discord){
if(!message.member.permissions.has("MANAGE_CHANNELS")) return message.reply("Normies can't do this command")
if (cmd == 'close') {
if (!message.channel.name.includes('ticket-')) return message.channel.send('You cannot use that here!');
message.channel.delete();
}
let title;
let desc;
let ticketMsg;
const filter = msg => msg.author.id == message.author.id;
let options = {
max: 1
};
message.channel.send("What will the ticket title be?\nSay cancel to cancel")
let col = await message.channel.awaitMessages(filter, options)
if(col.first().content == 'cancel') return message.channel.send("Cancelled");
title = col.first().content
message.channel.send('What will the description be?\nSay cancel to cancel')
let col2 = await message.channel.awaitMessages(filter, options)
if(col2.first().content == 'cancel') return message.channel.send("Cancelled");
desc = col2.first().content
message.channel.send('What is the message that the user will see when they make a ticket?\nSay cancel to cancel')
let col3 = await message.channel.awaitMessages(filter, options)
if(col3.first().content == 'cancel') return message.channel.send("Cancelled");
ticketMsg = col3.first().content
const setupEmbed = new Discord.MessageEmbed()
.setTitle(title)
.setDescription(desc)
.setFooter(message.guild.name, message.guild.iconURL({ dynamic: true }))
.setColor('00f8ff')
const hiEmbed = new Discord.MessageEmbed()
.addField(ticketMsg, "\n\nDo a.close or press the button to close the ticket")
.setColor("RANDOM")
.setTimestamp()
const createTicketButton = new MessageButton()
.setID("ticketCreate")
.setStyle("blurple")
.setLabel("");
const closeTicketButton = new MessageButton()
.setID("ticketClose")
.setLabel("Close ticket")
.setStyle("red");
if(cmd == 'ticket-setup'){
message.channel.send({embed: setupEmbed, button: createTicketButton })
}
client.on('clickButton', async (button) => {
await button.clicker.fetch();
await button.reply.defer();
const user = button.clicker.user
if (button.id === 'ticketCreate') {
button.guild.channels.create(`ticket-${user.id}`, {
permissionOverwrites: [
{
id: user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: button.message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async (channel) =>{
channel.send({embed: hiEmbed, button: closeTicketButton })
})
} else if(button.id == 'ticketClose'){
button.message.channel.delete()
}
});
}
}
我用的是包discord-buttons
Docs link
我尝试将 clickButton 事件放入我的事件处理程序中,但它不起作用,因为我遇到了很多错误。如何在重启后让按钮继续工作?
我也有这个问题,但不是交互失败,而是按钮信息不完整。
client.ws.on('INTERACTION_CREATE', interaction => {
//complete interaction
})
按钮是触发这个的交互,你可以用interaction.data.custom_id
检查这是一个斜线命令还是按钮(这可能是错误的,我无法测试它)。如果它不是按钮,它将是未定义的,但如果它是按钮,它将保留按钮的自定义 id。
问题
你的按钮在你的 bot 重启后不起作用的原因是因为你的 client.on("clickButton")
事件处理程序是 inside 你的“ticket-setup”命令的代码。这意味着您的事件仅在机器人重新启动后使用 ticket-setup 命令时才会设置,或者换句话说,一旦机器人启动后对该文件调用 execute()
。
想一想:在调用 ticket-setup
命令的 execute()
函数之前,不会到达您的 client.on("clickButton")
代码。这会给你带来很多问题。首先,如上所述,在机器人启动后至少使用一次 ticket-setup
之前,甚至不会处理 clickButton
事件。其次,这将在每次使用命令时创建 一个额外的事件处理程序 。换句话说,如果您要使用 ticket-setup
命令两次或更多次,您的 clickButton
处理程序中的代码将执行 多次 每次您的按钮单击(在您的特定情况下,每次单击按钮会创建不止一张票)。
解决方案
您面临的问题有一个非常简单的解决方法。您只需将整个 clickButton
事件处理程序移出 execute()
方法。也许将它移动到您的主 server.js
或 bot.js
文件中,连同您的 client.on("ready")
和 client.on("message")
事件处理程序。这将确保 clickButton
事件处理程序仅设置一次,并在机器人启动时立即设置。
但是请注意,您确实需要对 clickButton
事件处理程序进行一些细微的添加,以确保其正常工作。您需要将 hiEmbed
和 closeTicketButton
的代码移动到 client.on("clickButton")
处理程序中。
根据您问题中的代码,在 server.js
中可能会是这样:
client.on('clickButton', async (button) => {
await button.clicker.fetch();
await button.reply.defer();
const user = button.clicker.user;
const hiEmbed = new Discord.MessageEmbed()
.addField(ticketMsg, "\n\nDo a.close or press the button to close the ticket")
.setColor("RANDOM")
.setTimestamp();
const closeTicketButton = new MessageButton()
.setID("ticketClose")
.setLabel("Close ticket")
.setStyle("red");
if (button.id === 'ticketCreate') {
button.guild.channels.create(`ticket-${user.id}`, {
permissionOverwrites: [
{
id: user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: button.message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
}).then(async (channel) =>{
channel.send({embed: hiEmbed, button: closeTicketButton })
})
} else if(button.id == 'ticketClose'){
button.message.channel.delete()
}
});
您可能已经注意到另一个问题:ticketMsg
变量将不会被定义。您还需要进行更改以解决该问题。我建议将 ticketMsg
的值保存到 JSON 文件或数据库中,并在 client.on("clickButton")
中访问该信息。如果此代码代表一个正确的票务系统,则无论您是否使用此解决方案,您都需要执行此操作,否则您的用户将需要使用 ticket-setup
再次设置票务系统 你的机器人重启的时间.