Discord机器人报错:Discord.MessageAttachment不是构造函数求速解
问题描述
开发Discord机器人时,因MySQL查询返回数据过长,尝试将数据以TXT文件形式发送,但运行代码时抛出TypeError: Discord.MessageAttachment is not a constructor错误。
相关代码
const interactionCreate = require("../events/interactionCreate"); const Parser = require('rss-parser'); const { SlashCommandBuilder } = require("discord.js"); const parser = new Parser() const { Routes } = require('discord-api-types/v9') const { request } = require('undici') const { EmbedBuilder } = require('discord.js'); const fs = require("fs") const jsonToTxt = require("json-to-txt"); const Discord = require("discord.js") module.exports = { name: "adsoyad", description: "ad soyad bilgi ", options:[ { name: "adı", description: "sorgulanacak kişi ismi", type: 3, required: true, }, { name: "soyadı", description : "sorgulanacak kişi soyadı", type: 3, required: true, }, { name: "il", description: "sorgulanacak kişinin oturduğu il / listelemeyi azaltır", type: 3, required: false } ], run: async (client, interaction, str) =>{ const { member, channelId, guildId, applicationId, commandName, deferred, replied, ephemeral, options, id, createdTimestamp, MessageAttachment } = interaction; const { guild } = member; try { var mysql = require('mysql'); var con = mysql.createConnection({ host : 'localhost', user : 'root', password : '', database : '101m' }); var isim = interaction.options.getString("isim") var soyisim = interaction.options.getString("soyisim") var il = interaction.options.getString("il") if (il) { con.query(`SELECT * FROM 101m WHERE ADI="${isim}" AND SOYADI="${soyisim}" AND NUFUSIL="${il}"`, function (err, result) { if (err) throw err; let data = JSON.parse(JSON.stringify(result)) let as31 = data.map((o) => `${o.TC} ${o.ADI} ${o.SOYADI} ${o.DOGUMTARIHI} ${o.NUFUSIL} ${o.NUFUSILCE} ${o.ANNEADI} ${o.ANNETC} ${o.BABAADI} ${o.BABATC} ${o.UYRUK}`).join('\n') const Discord = require('discord.js') // let dosyahazırla = new Discord.MessageAttachment ( const embedmesaj = new EmbedBuilder() .setColor("DarkGrey") .setTitle(`:tada: ${isim} ${soyisim} isminde **${data.length}** kişi bulundu`) .setDescription(`${as31}`) .setFooter({text:`%64 Bot Developed By Mars`}) interaction.reply({ embeds: [embedmesaj] , ephemeral: true }) }) } else { con.query(`SELECT * FROM 101m WHERE ADI="${isim}" AND SOYADI="${soyisim}"`, function (err, result) { if (err) throw err; let data = JSON.parse(JSON.stringify(result)) let as31 = data.map((o) => `${o.TC} ${o.ADI} ${o.SOYADI} ${o.DOGUMTARIHI} ${o.NUFUSIL} ${o.NUFUSILCE} ${o.ANNEADI} ${o.ANNETC} ${o.BABAADI} ${o.BABATC} ${o.UYRUK}`).join('\n') const Discord = require("discord.js") let dosyahazırla = new Discord.MessageAttachment(Buffer.from(as31), 'slm.txt') const embedmesaj = new EmbedBuilder() .setColor("DarkGrey") .setTitle(`:tada: ${isim} ${soyisim} isminde **${data.length}** kişi bulundu`) .setFooter({text:`%64 Bot Developed By Mars`}) interaction.reply({embeds: [embedmesaj], ephemeral: true}) interaction.channel.send({ files: [ dosyahazırla ] }) }); } } catch (e) { console.log(String(e.stack).bgRed) } } }
报错栈
throw err; // Rethrow non-MySQL errors ^ TypeError: Discord.MessageAttachment is not a constructor at Query.<anonymous> (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\commands\adsoyad.js:84:36) at Query.<anonymous> (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\Connection.js:526:10) at Query._callback (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\Connection.js:488:16) at Sequence.end (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24) at Query._handleFinalResultPacket (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\sequences\Query.js:149:8) at Query.EofPacket (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\sequences\Query.js:133:8) at Protocol._parsePacket (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\Protocol.js:291:23) at Parser._parsePacket (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\Parser.js:433:10) at Parser.write (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\Parser.js:43:10) at Protocol.write (C:\Users\trwor\OneDrive\Masaüstü\%64 bot Project\node_modules\mysql\lib\protocol\Protocol.js:38:16) Node.js v18.14.0
解决方法
核心原因
Discord.js v14+ 版本中,MessageAttachment 已被移除,替换为 AttachmentBuilder;同时代码中存在重复导入discord.js的冗余操作,还有参数获取的变量名错误。
修复步骤
- 替换附件构造函数:从
discord.js中导入AttachmentBuilder,替换所有Discord.MessageAttachment的使用。 - 清理冗余导入:删除代码中重复出现的
const Discord = require("discord.js"),仅保留顶部一次导入。 - 修复参数获取:代码中选项定义的是
adı和soyadı,但获取时用了isim和soyisim,修正变量名匹配选项名。 - 调整消息发送逻辑:将附件和嵌入消息合并在同一次
interaction.reply中发送,避免重复发送导致的报错。
修复后的关键代码片段
// 顶部统一导入所需模块 const { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder } = require("discord.js"); // 移除其他位置的Discord重复导入 // 在run函数中修正参数获取 var isim = interaction.options.getString("adı") var soyisim = interaction.options.getString("soyadı") // 创建附件的代码改为 let dosyahazırla = new AttachmentBuilder(Buffer.from(as31), { name: 'slm.txt' }) // 合并消息发送 interaction.reply({ embeds: [embedmesaj], files: [dosyahazırla], ephemeral: true })
额外优化建议
- 改用
mysql2/promise库配合async/await处理数据库查询,替代回调式写法,提升代码可读性和可维护性。 - 修复SQL注入风险,使用参数化查询替换字符串拼接:
// 带il参数的查询 con.query('SELECT * FROM 101m WHERE ADI=? AND SOYADI=? AND NUFUSIL=?', [isim, soyisim, il], function(err, result) { // 处理结果逻辑 })
内容的提问来源于stack exchange,提问作者cdr
相关产品推荐
相关产品推荐

