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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:11:15