如何在discord.js中实现发送自定义URL对应网页截图的命令
问题排查与修复方案
原代码核心问题
- 命令逻辑拆分错误:同时存在
execute和run两个处理函数,常规discord.js命令框架仅会调用其中一个,导致url变量定义在execute的局部作用域,run函数无法访问 - 未做URL合法性校验:用户输入为空/非HTTP链接时会直接触发puppeteer报错
- 缺少puppeteer兼容参数:无桌面环境的服务器运行时会启动失败
- 文件发送语法不兼容:discord.js v13及以上版本的消息发送API参数格式已调整
修复后完整代码
const Discord = require("discord.js"); const puppeteer = require('puppeteer'); module.exports = { name: 'screenshot', description: '输入!screenshot + 网页链接即可获取对应网页截图', usage: '!screenshot <URL>', cooldown: 5, async execute(message, args) { // 提取并校验URL const url = args.join(' ').trim(); if (!url) return message.reply('请输入需要截图的网页链接'); if (!/^https?:\/\//.test(url)) return message.reply('请输入带http/https前缀的合法链接'); let browser; try { // 启动puppeteer,添加无桌面环境兼容参数 browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] }); const page = await browser.newPage(); // 设置页面视口大小,可自定义调整 await page.setViewport({ width: 1920, height: 1080 }); // 加载页面,添加超时限制避免无限等待 await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }); // 直接生成Buffer无需保存到本地磁盘 const screenshot = await page.screenshot({ fullPage: false }); // 需要整页截图可把fullPage改成true // 兼容discord.js各版本的文件发送语法 await message.channel.send({ content: `✅ ${url} 的截图已生成:`, files: [{ attachment: screenshot, name: 'screenshot.png' }] }); } catch (err) { console.error('截图生成失败:', err); message.reply('截图生成失败,请检查链接是否可正常访问后重试'); } finally { // 无论是否生成成功都关闭浏览器进程,避免内存泄漏 if (browser) await browser.close(); } } }
部署注意事项
- 如果你使用的命令框架默认调用
run函数,把代码里的async execute改成async run(client, message, args)即可 - 部署到Linux服务器时需要提前安装puppeteer系统依赖:
sudo apt install libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 - 首次使用前安装所有依赖包:
npm i discord.js puppeteer
内容的提问来源于stack exchange,提问作者bogdan
相关产品推荐
相关产品推荐

