斜杠命令(Slash Commands)已成为现代聊天机器人(Discord、Slack、飞书等)的标准交互方式。相比传统的 !help 前缀命令,它能提供自动补全、参数提示和更清晰的界面。
9.4.1 基础注册流程
以 Discord.js v14 为例,创建斜杠命令只需三步:
1. 定义命令结构
const { SlashCommandBuilder } = require('discord.js');
const command = new SlashCommandBuilder()
.setName('查天气') // 命令名称(小写,无空格)
.setDescription('查询指定城市天气')
.addStringOption(option =>
option.setName('城市')
.setDescription('城市名称,如:北京')
.setRequired(true) // 必填参数
);
2. 向 Discord 注册
命令需要注册到 Discord 服务器才能显示在输入框里:
// 全局注册(最多1小时生效,适合生产环境)
await client.application.commands.create(command);
// 或仅测试服务器注册(立即生效,适合开发)
await guild.commands.create(command);
3. 监听并响应
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === '查天气') {
const city = interaction.options.getString('城市');
// 模拟API调用
await interaction.deferReply(); // 延迟回复(处理耗时操作必加)
const weather = await fetchWeather(city);
await interaction.editReply(`${city}今天晴,25°C`);
}
});
9.4.2 实用技巧
参数类型选择
addStringOption: 文本输入(适合名称、查询内容)addIntegerOption: 整数(适合数量、页码)addUserOption: @用户(自动显示成员列表)addChannelOption: #频道(自动显示频道列表)addChoice: 限定选项(如addChoice('开启', 'on'))
错误处理必加
try {
await interaction.reply('处理中...');
} catch (error) {
// 如果回复已发送,使用 followUp;否则用 reply
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: '出错了,请重试', ephemeral: true });
} else {
await interaction.reply({ content: '出错了', ephemeral: true });
}
}
注:ephemeral: true 表示仅命令执行者可见,适合错误提示。
9.4.3 本地调试与部署
开发环境快速刷新
每次修改命令定义后,必须重新注册才能看到变化。建议单独写一个 deploy-commands.js 脚本:
// 只在 Node 环境变量为 development 时执行
if (process.env.NODE_ENV === 'development') {
const rest = new REST({ version: '10' }).setToken(token);
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands }
);
console.log('测试服务器命令已更新');
}
生产环境注意事项
- 全局命令有每日注册次数限制(约200次),不要在代码里每次启动都注册
- 修改命令描述或选项属于结构性变更,必须重新注册
- 仅修改回复逻辑无需重新注册
9.4.4 完整示例:工单系统
// commands/ticket.js
module.exports = {
data: new SlashCommandBuilder()
.setName('工单')
.setDescription('创建技术支持工单')
.addStringOption(opt =>
opt.setName('类型')
.setDescription('问题类型')
.setRequired(true)
.addChoices(
{ name: '账号问题', value: 'account' },
{ name: '支付故障', value: 'payment' },
{ name: '功能咨询', value: 'feature' }
))
.addStringOption(opt =>
opt.setName('描述')
.setDescription('详细描述您的问题')
.setRequired(true)),
async execute(interaction) {
const type = interaction.options.getString('类型');
const desc = interaction.options.getString('描述');
await interaction.reply({
content: `✅ 工单已创建\n类型:${type}\n描述:${desc}`,
ephemeral: true // 仅自己可见,避免刷屏
});
// 转发到管理员频道(实际项目中使用)
// await adminChannel.send(`新工单来自 ${interaction.user.tag}...`);
}
};
关键要点总结:
- 命令名称必须小写,支持中文但建议英文(避免编码问题)
- 耗时操作务必先
deferReply(),否则3秒内无响应会报错 - 选项超过25个时用
Autocomplete动态加载,而非静态addChoices - 权限控制通过
setDefaultMemberPermissions(PermissionFlagsBits.Administrator)实现
完成上述代码后,在 Discord 输入 / 即可看到你的自定义命令及参数提示。