如何获取user_id对应的合法snowflake值以修复Discord机器人私信报错
问题根因
你在注册/warn斜杠命令时,将目标用户参数的类型设置为了STRING字符串类型,因此Discord返回的参数值是带提及格式标记的字符串<@!用户ID>,而client.users.fetch()方法仅支持传入纯数字的雪花ID作为参数,因此触发格式校验报错。
另外你原有代码中user.send({ embeds: embed })的写法也存在问题,embeds字段要求传入数组格式,直接传单个Embed实例会触发参数错误。
解决方案
方案一(推荐):修改命令参数为USER类型
注册斜杠命令时将目标用户参数的类型设置为USER(discord.js v14+对应ApplicationCommandOptionType.User),可直接拿到解析好的User对象,无需手动处理ID或调用fetch接口:
- 命令注册参数示例:
const { ApplicationCommandOptionType } = require('discord.js'); // 注册/warn命令的配置 { name: 'warn', description: '向指定用户发送警告', options: [ { type: ApplicationCommandOptionType.User, name: 'user', description: '要警告的目标用户', required: true }, { type: ApplicationCommandOptionType.String, name: 'warning', description: '警告内容', required: true } ] }
- 调整后的业务代码:
// 直接获取解析完成的User对象,无需手动fetch const user = interaction.options.getUser("user"); if (!user) return interaction.channel.send("Error: user not found"); const embed = new MessageEmbed() .setColor("#FCE100") .setTitle(`⚠️ Warning!`) .setDescription(interaction.options.getString("warning")); // embeds字段传入数组格式 await user.send({ embeds: [embed] }).catch(() => { interaction.channel.send("Error: 无法向该用户发送私信,可能是用户关闭了陌生人私信权限"); });
方案二:从提及字符串中提取雪花ID
如果你必须保留参数为STRING类型,可以通过正则匹配提取出字符串中的纯数字雪花ID:
const userMention = interaction.options.getString("user"); // 匹配提及格式中的纯数字ID const snowflakeMatch = userMention.match(/<@!?(\d{17,19})>/); if (!snowflakeMatch) return interaction.channel.send("Error: 请@指定要警告的目标用户"); const userId = snowflakeMatch[1]; const user = await client.users.fetch(userId).catch(console.error); if (!user) return interaction.channel.send("Error: user not found"); // 后续Embed构造、发送逻辑同方案一
内容的提问来源于stack exchange,提问作者Koto
相关产品推荐
相关产品推荐

