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

Discord.js V14按钮15分钟后停止更新,如何绕过超时限制?

解决Discord.js V14按钮超时后无法更新时间的问题

核心逻辑

Discord的SlashCommand交互令牌15分钟后就会过期,没法再用它编辑最初的回复。要实现永久更新,得换个不受这个限制的方式——用webhook或者直接用bot身份发送的普通消息来管理内容,这俩都没有15分钟的编辑限制。

具体实现方法

方法一:用Webhook管理消息(推荐)

Webhook不受15分钟编辑限制,只要bot有频道的Manage Webhooks权限,就能一直更新消息。

步骤如下:

  1. 触发命令时,先在目标频道创建一个临时webhook(也可以提前手动建好在频道里,直接用它的ID和token)。
  2. 通过这个webhook发送带时区按钮的消息,同时把webhook的ID、token和消息ID存起来(PM2重启会丢内存数据,最好存在数据库里,比如SQLite或者MongoDB)。
  3. 用setInterval定时通过webhook编辑消息,更新按钮标签。

示例代码:

const { ButtonBuilder, ActionRowBuilder, WebhookClient, SlashCommandBuilder } = require('discord.js');
const { DateTime } = require('luxon');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('timezones')
    .setDescription('显示各时区实时时间'),
  async execute(interaction) {
    // 创建临时webhook
    const webhook = await interaction.channel.createWebhook({
      name: '时区更新bot',
      avatar: interaction.user.displayAvatarURL(),
    });

    // 封装生成按钮的函数
    const getTimeButtons = () => {
      return new ActionRowBuilder()
        .addComponents(
          new ButtonBuilder()
            .setCustomId('utc')
            .setLabel(`UTC: ${DateTime.utc().toFormat('HH:mm:ss')}`)
            .setStyle('Primary'),
          new ButtonBuilder()
            .setCustomId('beijing')
            .setLabel(`北京: ${DateTime.now().setZone('Asia/Shanghai').toFormat('HH:mm:ss')}`)
            .setStyle('Success'),
          new ButtonBuilder()
            .setCustomId('newyork')
            .setLabel(`纽约: ${DateTime.now().setZone('America/New_York').toFormat('HH:mm:ss')}`)
            .setStyle('Danger')
        );
    };

    // 通过webhook发送消息
    const sentMsg = await webhook.send({
      content: '实时时区时间:',
      components: [getTimeButtons()],
    });

    // 存webhook和消息信息到数据库(示例用全局变量,生产环境换数据库)
    global.timezoneTasks = global.timezoneTasks || [];
    global.timezoneTasks.push({
      webhookId: webhook.id,
      webhookToken: webhook.token,
      msgId: sentMsg.id,
    });

    // 给用户发个悄悄通知
    await interaction.reply({ content: '实时时区面板已创建!', ephemeral: true });

    // 启动30秒更新定时器
    setInterval(async () => {
      const webhookClient = new WebhookClient({ id: webhook.id, token: webhook.token });
      try {
        await webhookClient.editMessage(sentMsg.id, {
          components: [getTimeButtons()],
        });
      } catch (err) {
        console.error('更新按钮失败:', err);
        // 可以在这里加个逻辑:如果webhook失效,就清理这个定时器
      }
    }, 30000);
  },
};

方法二:直接发送普通频道消息

如果不想搞webhook,也可以直接用bot的身份在频道发普通消息(不是通过交互回复),然后用bot的token去编辑这条消息——bot自己发的消息,只要有Manage Messages权限,就能永久编辑。

示例代码片段:

// 在命令执行里发送普通消息
const sentMsg = await interaction.channel.send({
  content: '实时时区时间:',
  components: [getTimeButtons()],
});

// 定时更新消息里的按钮
setInterval(async () => {
  await sentMsg.edit({
    components: [getTimeButtons()],
  });
}, 30000);

// 给用户反馈
await interaction.reply({ content: '实时时区面板已创建!', ephemeral: true });

这个方法更简单,但要注意:如果bot被踢出服务器,或者消息被删除,更新就会停止。

内容的提问来源于stack exchange,提问作者Jon LeForge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:50:06