discord.js-commando实现无标签无提及私信指定用户问题
解决手动构建用户对象发私信失败的问题
嘿,我来帮你搞定这个问题!你遇到的核心问题是:你手动创建的普通JavaScript对象并不是Discord.js的User类实例,Discord.js里的send()这类交互方法,都是绑定在它自己封装的类实例上的——这些实例内置了和Discord API通信的逻辑,普通对象根本没有这些能力,所以调用user.send()肯定会失败。
下面给你两种解决方案,其中第一种是官方推荐的稳妥方式,第二种能满足你“必须手动构建”的需求:
方案1:通过客户端获取合法的User实例(优先推荐)
如果你知道目标用户的ID,直接用Commando的client对象去获取真实的User实例就好,这样就能正常调用send(),而且完全符合你的“不带发送者标签、不提及用户”的需求:
/*jshint esversion: 6*/ const commando = require('discord.js-commando'); class Msgowner extends commando.Command { constructor(client) { super(client, { name: 'msgowner', group: 'info', memberName: 'msgowner', description: 'Gives rules on mock or legit duels.', examples: ['ladderrules type'], }); } async run(message) { try { // 通过用户ID获取官方的User实例 const user = await this.client.users.fetch('12345'); // 直接发送私信,默认就不会带发送者标签、也不会提及用户 await user.send('Test'); message.reply('私信已经发出去啦!'); } catch (error) { console.error('发送私信出错:', error); message.reply('没法发送私信哦,可能是用户关闭了陌生人私信,或者机器人和用户不在同一个服务器里。'); } } } module.exports = Msgowner;
方案2:手动创建Discord.js的User实例(满足你“必须手动构建”的需求)
如果你确实需要手动构建用户对象,那得用Discord.js提供的User构造函数来创建实例,而不是自己写一个普通对象。不过要注意:这种方式依赖Discord.js的内部实现,版本更新可能会失效,所以尽量用方案1:
/*jshint esversion: 6*/ const commando = require('discord.js-commando'); // 引入Discord.js的User类 const { User } = require('discord.js'); class Msgowner extends commando.Command { constructor(client) { super(client, { name: 'msgowner', group: 'info', memberName: 'msgowner', description: 'Gives rules on mock or legit duels.', examples: ['ladderrules type'], }); } async run(message) { try { // 用官方构造函数创建User实例,必须传入client和完整的用户数据 const user = new User(this.client, { id: '12345', username: 'Bloodmorphed', discriminator: '12345', avatar: 'd510ca3d384a25b55d5ce7f4c259b2d0', bot: false, }); // 现在就能正常调用send()发私信了 await user.send('Test'); message.reply('私信发送成功!'); } catch (error) { console.error('发送失败:', error); message.reply('没法发送私信,请检查用户数据是否完整正确。'); } } } module.exports = Msgowner;
额外注意点
- 不管用哪种方案,发送的私信默认都不会带发送者标签(除非你自己在消息内容里加),也不会自动提及用户,完全符合你的需求。
- 要确保用户允许接收来自服务器成员的私信,或者机器人和用户在同一个服务器里,不然会发送失败哦。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

