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

如何用JavaScript基于node-telegram-bot-api实现Telegram bot反垃圾系统

实现方案

核心思路

  • 用Map在内存中记录每个用户的请求历史和冻结状态,重启bot数据会清空,需要持久化可自行替换为Redis等存储
  • 可自定义限流阈值:时间窗口、最大请求数、冻结时长
  • 同时覆盖普通消息触发和按钮回调触发两种场景

完整修改后代码

import {
    bot
} from '../token.js';

import {
    keyboardMain
} from '../keyboards/keyboardsMain.js';

// 反刷屏配置,可根据需求调整
const RATE_LIMIT = {
  TIME_WINDOW: 10 * 1000, // 统计时间窗口:10秒
  MAX_COUNT: 5, // 窗口内最多允许触发5次
  BAN_TIME: 60 * 1000 // 触发限流后冻结时长:60秒
}

// 存储用户行为数据 key=用户ID value={requests: 时间戳数组, banEndTime: 冻结到期时间戳}
const userActionRecord = new Map()

// 通用限流检查函数
function checkLimit(userId) {
  const now = Date.now()
  const userData = userActionRecord.get(userId) || { requests: [], banEndTime: 0 }

  // 检查是否在冻结期
  if (userData.banEndTime > now) {
    return userData.banEndTime - now
  }

  // 清理窗口外的旧请求记录
  userData.requests = userData.requests.filter(t => now - t < RATE_LIMIT.TIME_WINDOW)
  userData.requests.push(now)

  // 触发限流
  if (userData.requests.length > RATE_LIMIT.MAX_COUNT) {
    userData.banEndTime = now + RATE_LIMIT.BAN_TIME
    userActionRecord.set(userId, userData)
    return RATE_LIMIT.BAN_TIME
  }

  userActionRecord.set(userId, userData)
  return false
}

export function commands() {
    // 普通消息事件处理
    bot.on('message', msg => {
        const chatId = msg.chat.id;
        const userId = msg.from.id;
        const text = msg.text;

        // 先做限流检查
        const banRemain = checkLimit(userId)
        if (banRemain) {
          const remainSec = Math.ceil(banRemain / 1000)
          return bot.sendMessage(chatId, `操作过于频繁,请${remainSec}秒后再尝试`)
        }

        if (text === '/start') {
           return bot.sendMessage(chatId, 'hello', keyboardMain);
        }

        return bot.sendMessage(chatId, 'error');
    });

    // 按钮回调事件处理(按钮交互场景需要加这个)
    bot.on('callback_query', callback => {
      const chatId = callback.message.chat.id
      const userId = callback.from.id

      // 同样做限流检查
      const banRemain = checkLimit(userId)
      if (banRemain) {
        const remainSec = Math.ceil(banRemain / 1000)
        // 给回调回个提示,也可以用sendMessage发消息
        return bot.answerCallbackQuery(callback.id, {
          text: `操作过于频繁,请${remainSec}秒后再尝试`,
          show_alert: true
        })
      }

      // 这里写你自己的按钮交互逻辑
    })
}

注意事项

  • 当前是内存存储方案,bot重启后所有限流记录会清空,生产环境建议替换为Redis存储用户行为数据
  • RATE_LIMIT里的三个参数可以根据自己的运营需求调整数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:06:01