Discord.js v12.5.3 机器人实现图片保存功能时触发[ERR_INVALID_ARG_TYPE]错误求助
嘿,我来帮你解决这个问题!你遇到的TypeError是因为在Discord.js v12.5.3里,Attachment对象根本没有file这个属性——你直接调用image.file拿到的是undefined,而fs.writeFileSync要求传入字符串、Buffer这类有效数据,自然就报错了。
在v12版本中,Discord.js的附件对象只提供了文件的元信息(比如URL、文件名),不会直接给你文件的原始数据。想要保存图片,你需要从附件的URL中获取文件内容,这里有两种简单的方法:
方法1:用Discord.js自带的fetch()方法(无需额外依赖)
这个方法最省心,因为是Discord.js内置的,直接调用附件的fetch()就能拿到文件Buffer:
const Discord = require("discord.js"); const fs = require("fs"); const client = new Discord.Client(); const prefix = "."; // 确保保存图片的文件夹存在,不存在则创建 const saveDir = "./saved-images"; if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir); } client.on("ready", () => { client.user.setStatus('online'); console.log("Bot is up and running!"); }); client.on("message", async (message) => { // 先判断消息有没有附件,避免空指针错误 if (message.attachments.size === 0) return; const attachment = message.attachments.first(); // 可选:只处理图片类型的附件 if (!attachment.contentType?.startsWith("image/")) { message.reply("这不是图片哦~"); return; } try { // 调用fetch()获取文件Buffer const fileBuffer = await attachment.fetch(); // 拼接保存路径 const savePath = `${saveDir}/${attachment.name}`; // 写入文件 fs.writeFileSync(savePath, fileBuffer); console.log(`成功保存图片:${attachment.name}`); message.reply("图片已经保存啦!"); } catch (err) { console.error("保存图片出错:", err); message.reply("保存图片失败了,再试一次吧?"); } }); client.login(process.env.token);
方法2:用node-fetch下载(需要额外安装依赖)
如果你更习惯用HTTP请求库,可以安装node-fetch(注意v12环境要装v2版本,因为v3是ESM模块):
npm install node-fetch@2
然后修改代码:
const Discord = require("discord.js"); const fs = require("fs"); const fetch = require("node-fetch"); const client = new Discord.Client(); const prefix = "."; const saveDir = "./saved-images"; if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir); } client.on("ready", () => { client.user.setStatus('online'); console.log("Bot is online."); }); client.on("message", async (message) => { if (message.attachments.size === 0) return; const attachment = message.attachments.first(); if (!attachment.contentType?.startsWith("image/")) { message.reply("请发送图片哦!"); return; } try { // 从附件URL获取响应 const res = await fetch(attachment.url); // 转换为Buffer const fileBuffer = await res.buffer(); // 写入文件 fs.writeFileSync(`${saveDir}/${attachment.name}`, fileBuffer); console.log(`图片保存成功:${attachment.name}`); message.reply("图片已保存!"); } catch (err) { console.error("保存失败:", err); message.reply("保存图片时出问题了T_T"); } }); client.login(process.env.token);
额外注意点:
- 一定要确保保存文件的文件夹已经存在,否则会抛出路径不存在的错误,上面的代码已经加了文件夹判断和创建的逻辑。
- 因为用到了
async/await,所以message事件的回调函数必须加上async关键字,不然会报错。 - 可以加个类型判断,只处理图片类型的附件,避免保存其他格式的文件。
内容的提问来源于stack exchange,提问作者m_hm0ud
相关产品推荐
相关产品推荐

