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

Slack Bot接收app_mention事件后连续重复响应问题

Slack 机器人 Chochon app_mention 事件重复响应修复

问题描述

  • 运行环境:Slack 平台 Socket Mode 模式开发的机器人「Chochon」
  • 异常现象:机器人接收到app_mention(用户@机器人)事件时,会连续多次发送重复响应消息,没有按预期仅发送1条后等待下一次@触发
  • 异常效果参考:
    Slack频道内重复响应截图

问题根因

  1. 未按Slack Socket Mode规范确认事件:所有事件推送到客户端后,若3秒内未收到客户端的ack确认响应,Slack会判定推送失败,按重试策略重复投递同一条事件,导致回调被多次触发
  2. 缺少自消息过滤逻辑:未判断事件是否为机器人自身发出,极端场景下会出现自触发循环
  3. 异步方法未加await:chat.postMessage为异步方法,未加await时可能出现时序异常

修复方案

核心修改点

  • 事件回调增加ack参数,收到事件第一时间调用await ack()确认接收,阻断Slack重试逻辑
  • 增加bot消息判断,跳过所有机器人账号发出的消息触发的事件
  • 给所有异步API调用增加await,保证执行时序

修正后的事件监听代码

socketModeClient.on('app_mention', async ({ event, ack }) => {
    try {
        // 立刻确认事件接收,阻止Slack重复推送
        await ack();
        // 过滤机器人自身发送的消息,避免自触发循环
        if (event.bot_id) return;

        console.log(event);
        let userBox = await Chochon.users.info({ user: event.user });
        let userProfile = userBox.user.profile;
        console.log(cli.green(`Event received : [ ${event.type} ] from [ ${userProfile.display_name} ]`));

        // 发送响应消息
        await Chochon.chat.postMessage({
            channel: event.channel,
            text: `Hello <@${event.user}>, I'm Chochon!, I'm a bot that can help you to manage your team.`
        });

    } catch (error) {
        console.error(error);
    }
});

修正后完整项目代码

// Dependencies :
const dotenv = require('dotenv').config();
const path = require('path');
const cli = require('cli-color');

// Web client [CLI]
const { WebClient } = require('@slack/web-api');
const Chochon = new WebClient(process.env.SLACK_BOT_TOKEN.trim());  

// Socket IO
const { SocketModeClient } = require('@slack/socket-mode');
const appToken = process.env.SLACK_APP_TOKEN;
const socketModeClient = new SocketModeClient({ appToken });
socketModeClient.start();

// Internal functions
//const eventManager = require(path.resolve(__dirname, './utils/events/manager'));

socketModeClient.on('app_mention', async ({ event, ack }) => {
    try {
        await ack();
        if (event.bot_id) return;
        
        console.log(event);
        let userBox = await Chochon.users.info({ user: event.user });
        let userProfile = userBox.user.profile;
        console.log(cli.green(`Event received : [ ${event.type} ] from [ ${userProfile.display_name} ]`));

        // Respond to the event
        await Chochon.chat.postMessage({
            channel: event.channel,
            text: `Hello <@${event.user}>, I'm Chochon!, I'm a bot that can help you to manage your team.`
        });

    } catch (error) {
        console.error(error);
    }
});

socketModeClient.on('slash_commands', async ({ body, ack }) => {
    if (body.command === "/ping") {
        console.log(cli.green(`Event received : [ ${body.command} ]`));
        await ack({"text": "I got it, pong!"});
    }
});

补充说明

原有代码里的slash_commands回调已经正确实现了ack()调用,所以斜杠命令不会出现重复响应问题,两类事件的处理逻辑要求是一致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:01:11