Discord机器人在线但Presence状态无法设置问题求助
Discord机器人Presence状态设置失败问题
我是Discord斜杠命令机器人开发新手,尝试复用旧机器人的代码为新机器人设置Presence状态。启动后控制台提示机器人已上线,但状态并未成功设置。
相关代码
botpresence.cjs
const { Discord, Client, Intents, GatewayIntentBits, ActivityType, } = require("discord.js"); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences, GatewayIntentBits.DirectMessages, ], }); module.exports.namedCjsExport = function namedCjsExport() { client.once("ready", () => { client.user.setPresence("Watching Dev", { type: "WATCHING" }); setInterval(() => { client.user.setPresence("Watching Dev", { type: "WATCHING" }); }, 60000); }); }; console.log("Bot is online!"); client.login( "TOKEN" );
app.js
import defaultCjsExport, { namedCjsExport } from './botpresence.cjs'; namedCjsExport() import "dotenv/config"; import express from "express"; import { InteractionType, InteractionResponseType } from "discord-interactions"; import { VerifyDiscordRequest, getRandomEmoji, DiscordRequest, } from "./utils.js"; const app = express(); const PORT = process.env.PORT || 3000; app.use(express.json({ verify: VerifyDiscordRequest(process.env.PUBLIC_KEY) })); app.post("/interactions", async function (req, res) { const { type, id, data } = req.body; if (type === InteractionType.PING) { return res.send({ type: InteractionResponseType.PONG }); } if (type === InteractionType.APPLICATION_COMMAND) { const { name } = data; if (name === "test") { return res.send({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: "Finally online and responding " + getRandomEmoji(), }, }); } if (name === "test2") { return res.send({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: "Going in for a second command", }, }); } } }); app.listen(PORT, () => { console.log("Listening on port", PORT); });
控制台显示机器人已在线,但状态未显示,请问该如何解决?
问题解决方法
核心问题分析
setPresence参数格式错误:discord.js v14+版本中,该方法不再接受字符串作为第一个参数,必须传入包含activities和status的对象。- 事件监听时机错误:
app.js先执行namedCjsExport()绑定ready事件,但此时botpresence.cjs的client.login()可能已经完成,导致错过ready事件触发。 - 冗余重复设置:用
setInterval重复设置相同状态属于无效操作,只会增加不必要的API请求。
修复步骤
1. 修正setPresence调用格式
修改botpresence.cjs中的ready事件处理逻辑,使用v14要求的参数格式,并利用导入的ActivityType常量:
client.once("ready", () => { console.log(`Logged in as ${client.user.tag}!`); // 新增日志确认事件触发 client.user.setPresence({ activities: [{ name: "Watching Dev", type: ActivityType.Watching }], status: "online" // 可选,默认值为online,可按需设置idle/dnd/invisible }); });
2. 调整事件监听与登录的顺序
将ready事件绑定逻辑从导出函数中移出,直接放在client.login()之前,避免错过事件:
修改后的botpresence.cjs:
const { Client, GatewayIntentBits, ActivityType, } = require("discord.js"); // 移除不需要的Discord、Intents导入 const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences, GatewayIntentBits.DirectMessages, ], }); // 直接绑定ready事件,无需包裹在导出函数中 client.once("ready", () => { console.log(`Logged in as ${client.user.tag}!`); client.user.setPresence({ activities: [{ name: "Watching Dev", type: ActivityType.Watching }], status: "online" }); }); console.log("Bot is starting..."); client.login(process.env.TOKEN); // 改用环境变量存储TOKEN,禁止硬编码 // 导出client供其他模块使用(若需要) module.exports = client;
3. 调整app.js的导入顺序与逻辑
确保环境变量优先加载,再导入其他模块:
修改后的app.js:
import "dotenv/config"; // 优先加载环境变量 import express from "express"; import { InteractionType, InteractionResponseType } from "discord-interactions"; import { VerifyDiscordRequest, getRandomEmoji, DiscordRequest, } from "./utils.js"; import client from './botpresence.cjs'; // 直接导入client,无需调用导出函数 const app = express(); const PORT = process.env.PORT || 3000; app.use(express.json({ verify: VerifyDiscordRequest(process.env.PUBLIC_KEY) })); // 保留原有交互处理逻辑 app.post("/interactions", async function (req, res) { const { type, id, data } = req.body; if (type === InteractionType.PING) { return res.send({ type: InteractionResponseType.PONG }); } if (type === InteractionType.APPLICATION_COMMAND) { const { name } = data; if (name === "test") { return res.send({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: "Finally online and responding " + getRandomEmoji(), }, }); } if (name === "test2") { return res.send({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: "Going in for a second command", }, }); } } }); app.listen(PORT, () => { console.log("Listening on port", PORT); });
额外注意事项
- 确保
.env文件中正确配置TOKEN和PUBLIC_KEY两个环境变量。 GuildPresences意图用于读取其他成员状态,与设置自身Presence无关,若无需该功能可从intents列表中移除。- 启动后检查控制台是否输出
Logged in as [机器人标签]!,确认ready事件已正常触发。
内容的提问来源于stack exchange,提问作者TTG S7
相关产品推荐
相关产品推荐

