使用AttachmentBuilder的Discord.js机器人无法发送图片,仅发送欢迎文本
问题:Discord欢迎机器人无法发送Canvas生成的图片附件
我基于discord.js框架,使用AttachmentBuilder和Canvas库开发了一款Discord服务器欢迎机器人,但机器人仅能发送欢迎文本消息,无法成功发送生成的Canvas图片附件,实际效果如图:
我的代码如下:
const { Client, GatewayIntentBits, AttachmentBuilder } = require('discord.js'); const { createCanvas, loadImage } = require('canvas'); const { token } = require('./config.json'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, ], }); client.once('ready', () => { console.log('Bot is online!'); }); client.on('guildMemberAdd', async member => { const channel = member.guild.channels.cache.find(channel => channel.name === 'welcome'); if (!channel) return; const canvas = createCanvas(700, 250); const ctx = canvas.getContext('2d'); // Clear canvas with transparency ctx.clearRect(0, 0, canvas.width, canvas.height); // Set text properties ctx.font = '40px sans-serif'; ctx.fillStyle = '#ffffff'; // Draw welcome text ctx.fillText(`Welcome to the server, ${member.displayName}!`, 50, 100); // Load and draw member's avatar const avatar = await loadImage(member.user.displayAvatarURL({ format: 'jpg' })); ctx.drawImage(avatar, 50, 120, 80, 80); // Adjust position and size as needed // Create attachment from canvas buffer const attachment = new AttachmentBuilder(await canvas.toBuffer(), 'welcome-image.png'); // Send welcome message with attachment channel.send(`Welcome to the server, ${member}!`, { files: [attachment] }); });
解决方法
1. 修正AttachmentBuilder的构造参数
discord.js v14版本中,AttachmentBuilder的第二个参数是配置对象,而非直接传入文件名。原代码的写法会导致附件无法正确识别,修改为:
const attachment = new AttachmentBuilder(await canvas.toBuffer(), { name: 'welcome-image.png' });
2. 检查频道权限
确保机器人在目标welcome频道拥有发送附件的权限,否则Discord会拦截图片发送请求。
3. 优化画布绘制逻辑
透明背景可能在部分客户端显示异常,建议添加纯色背景适配Discord风格:
// 绘制深色背景 ctx.fillStyle = '#2c2f33'; ctx.fillRect(0, 0, canvas.width, canvas.height);
4. 添加头像加载错误捕获
避免头像加载失败导致整个欢迎流程中断,添加try-catch块做容错处理:
try { const avatar = await loadImage(member.user.displayAvatarURL({ format: 'jpg', size: 256 })); ctx.drawImage(avatar, 50, 120, 80, 80); } catch (error) { console.error('加载头像失败:', error); // 可选:绘制默认头像作为替代 }
5. 统一消息发送参数格式
channel.send的参数建议统一放在配置对象中,避免参数顺序引发的问题:
channel.send({ content: `Welcome to the server, ${member}!`, files: [attachment] });
修改后的完整代码
const { Client, GatewayIntentBits, AttachmentBuilder } = require('discord.js'); const { createCanvas, loadImage } = require('canvas'); const { token } = require('./config.json'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, ], }); client.once('ready', () => { console.log('Bot is online!'); }); client.on('guildMemberAdd', async member => { const channel = member.guild.channels.cache.find(channel => channel.name === 'welcome'); if (!channel) return; const canvas = createCanvas(700, 250); const ctx = canvas.getContext('2d'); // 绘制深色背景适配Discord ctx.fillStyle = '#2c2f33'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 设置文本属性 ctx.font = '40px sans-serif'; ctx.fillStyle = '#ffffff'; // 绘制欢迎文本 ctx.fillText(`Welcome to the server, ${member.displayName}!`, 50, 100); // 加载并绘制成员头像,添加错误处理 try { const avatar = await loadImage(member.user.displayAvatarURL({ format: 'jpg', size: 256 })); ctx.drawImage(avatar, 50, 120, 80, 80); } catch (error) { console.error('加载头像失败:', error); } // 正确创建图片附件 const attachment = new AttachmentBuilder(await canvas.toBuffer(), { name: 'welcome-image.png' }); // 发送带附件的欢迎消息 channel.send({ content: `Welcome to the server, ${member}!`, files: [attachment] }); }); // 登录机器人 client.login(token);
内容的提问来源于stack exchange,提问作者Claude
相关产品推荐
相关产品推荐

