如何用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
相关产品推荐
相关产品推荐

