如何在我的IRC机器人上实现反垃圾邮件技术?

我在数百个用户的公共频道上运行我的机器人。 昨天有一个人进来,只是滥用了它。

我想让任何人使用这个机器人,但是如果他们连续发送垃圾命令,并且如果他们不是像我这样的机器人“所有者”,那么我想将它们添加到一个小时左右到期的忽略列表中。

我想的一种方法是保存所有用户的所有命令,如下所示:

({ 'meder@freenode': [{command:'.weather 20851', timestamp: 209323023 }], 'jack@efnet': [{command:'.seen john' }] }) 

我会设置一个cron作业来每24小时刷新一次,但是我会基本上确定一个人是否在15秒的时间内做出了X个命令,并将它们添加到忽略列表中。

其实,当我正在写这个答案的时候,我想到了一个更好的主意。也许不是存储每个用户的命令,只是将bot的命令存储在一个列表中,并继续推动,直到它达到极限15。

 lastCommands = [], limit = 5; function handleCommand( timeObj, action ) { if ( lastCommands.length < limit ) { action(); } else { // enumerate through lastCommands and compare the timestamps of all 5 commands // if the user is the same for all 5 commands, and... // if the timestamps are all within the vicinity of 20 seconds // add the user to the ignoreList } } watch_for('command', function() { handleCommand({timestamp: 2093293032, user: user}, function(){ message.say('hello there!') }) }); 

对于这个问题,我会很感激的。

这里有一个简单的algorithm:

  • 每当用户向机器人发送一个命令,增加一个与该用户绑定的数字。 如果这是新用户,请为其创build号码并将其设置为1。
  • 当用户的号码增加到某个值(比如说15)时,将其设置为100。
  • 每<period>秒,遍历列表并将所有数字递减1.零表示用户的数字可以被释放。

在执行一个命令之前,在增加用户的计数器之后,检查它是否超过了你的魔术最大值(15以上)。 如果是,请在执行命令之前退出。

这可以让你在一段时间内限制行为和宽恕过度。 将用户期望的禁止长度除以递减周期,以查找用户超出阈值(100以上)时设置的号码。 如果特定用户在被禁止后继续发送命令,也可以添加到号码中。

那么Nathon已经提供了一个解决scheme,但是可以减less所需的代码。

 var user = {}; user.lastCommandTime = new Date().getTime(); // time the user send his last command user.commandCount = 0; // command limit counter user.maxCommandsPerSecond = 1; // commands allowed per second function handleCommand(obj, action) { var user = obj.user, now = new Date().getTime(); var timeDifference = now - user.lastCommandTime; user.commandCount = Math.max(user.commandCount - (timeDifference / 1000 * user.maxCommandsPerSecond), 0) + 1; user.lastCommandTime = now; if (user.commandCount <= user.maxCommandsPerSecond) { console.log('command!'); } else { console.log('flooding'); } } var obj = {user: user}; var e = 0; function foo() { handleCommand(obj, 'foo'); e += 250; setTimeout(foo, 400 + e); } foo(); 

在这个实现中,每隔X秒就不需要一个列表或者一些全局的callbackcommandCount ,而是每当有一个新的消息的时候,根据与最后一个命令的时间差别来减lesscommandCount ,也可以允许不同的命令速率用户。

我们需要的是用户对象上的3个新属性:)

Redis的

我将使用疯狂快速的高级键值存储redis写这样的事情,因为:

  • 它非常快速。
  • 不需要cronjob,因为你可以在键上设置过期 。
  • 它有primefaces操作来递增密钥
  • 你可以使用redis-cli进行原型devise。

我自己真的很喜欢node_redis作为redis客户端。 这是一个非常快速的redis客户端,可以使用npm轻松安装。

Algorithme

我认为我的algorithm看起来像这样:

  1. 为每个用户创build一个唯一的键,对连续执行的命令进行计数。 还设置过期时间,当你不再标记用户垃圾邮件发送者了。 假设垃圾邮件发送者的昵称为xexpire 15

    在redis-cli里面
    incr x
    到期x 15

    当你15秒后get x一个get x ,那么这个键就不存在了。

  2. 如果密钥的值大于阈值,则将用户标记为垃圾邮件发送者。

    得到x

这些答案似乎是对这个错误的方式。

IRC服务器将断开你的客户端,不pipe你是否正在“debugging”,或者如果客户端或机器人泛滥了一个通道或服务器。

做一个一揽子的防洪,使用方法@nmichaels已经详细,但在bot的networking连接到服务器本身。