You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:19:07