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

如何在Discord.js中用Bull、Throng、Redis运行Worker并返回任务结果

解决Discord Bot + Heroku + Bull队列的核心问题

一、如何运行Worker文件执行繁重任务

本地测试运行

打开两个终端窗口分别启动进程:

  • 启动Discord Bot主进程:node index.js
  • 启动Worker队列处理进程:node worker.js

Heroku部署后运行

  1. 创建Procfile:在项目根目录新建名为Procfile(首字母大写,无文件后缀)的文件,写入内容:
web: node index.js
worker: node worker.js
  • web进程负责监听Discord命令、向队列添加任务
  • worker进程负责执行爬取等繁重任务
  1. 启动Worker Dyno:
    • 命令行方式:执行heroku ps:scale worker=1(数字1代表启动1个worker进程,可按需调整数量)
    • 后台操作方式:登录Heroku应用后台→进入Resources页面,找到worker进程,开启开关并设置进程数

二、获取任务返回值并发送给Discord用户

当前global:completed事件仅能拿到任务ID和结果,无法关联触发任务的用户。解决核心是添加任务时存入用户/交互的关键信息,任务完成后通过这些信息定位用户并发送结果。

修改主进程代码(index.js)

client.on('interactionCreate', async interaction => {
    if (!interaction.isChatInputCommand()) return
    const {commandName} = interaction
    if (commandName === 'views') {
        // 存入用户ID、频道ID、交互token等关键信息
        const jobData = {
            userId: interaction.user.id,
            channelId: interaction.channelId,
            interactionToken: interaction.token, // 用于编辑之前的回复
            text: 'Running...'
        }
        await workQueue.add('process', jobData)
        await interaction.reply(`processing... 结果完成后会通知你`)
    }
})

// 监听任务完成事件
workQueue.on('global:completed', async (jobId, result) => {
    // 根据任务ID获取完整任务数据
    const job = await workQueue.getJob(jobId)
    if (!job) return

    const {userId, channelId, interactionToken} = job.data
    const channel = client.channels.cache.get(channelId)
    if (!channel) return

    // 方式1:直接在频道@用户发送结果
    await channel.send(`<@${userId}> 你的爬取任务完成!结果:${JSON.stringify(result)}`)

    // 方式2:编辑之前的回复(替代单独发送消息)
    // await client.rest.interactions.editReply(interactionToken, `任务完成!结果:${JSON.stringify(result)}`)
})

完善Worker进程的爬取逻辑(worker.js)

将测试代码替换为实际爬取逻辑:

workQueue.process(maxJobsPerWorker, async job => {
    console.log(`开始处理任务 ${job.id}`)
    // 替换为你的实际爬取函数
    const scrapeResult = await yourScrapingFunction(job.data.text)
    // 返回爬取结果,供主进程的global:completed事件捕获
    return {
        jobId: job.id,
        scrapeData: scrapeResult
    }
})

额外注意事项

  • Redis配置:Heroku环境需安装Heroku Redis插件,本地测试使用本地Redis服务
  • 错误处理:可添加global:failed事件监听任务失败,及时通知用户
  • 进程调整:根据任务量通过heroku ps:scale worker=N调整worker进程数
  • 任务持久化:Bull将任务存储在Redis中,即使Heroku Dyno重启,未完成任务也不会丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:20:34