Question

I'm working on a chat app with Meteor and I'm assuming spam will be an issue so I want to incorporate a Captcha that pops up if you comment too quickly (like more than 3 times in 5 seconds). I have the javascript code below but I have no idea how to do this. Is it possible to have a Captcha just pop up somewhere on the screen? If so, does anybody know how to do this? Here is the code for the chat app part:

Javascript:

// render all of our messages in the ui
Template.chatBox.helpers({
  "messages": function() {
    return chatCollection.find();
  }
});

// get the value for handlerbar helper user
Template.chatMessage.helpers({
  "user": function() {
    if(this.userId == 'me') {
      return this.userId;
    } else if(this.userId) {
      getUsername(this.userId);
      return Session.get('user-' + this.userId);
    } else {
      return 'anonymous-' + this.subscriptionId;
    }
  }
});

// when Send Chat clicked at the message to the collection
Template.chatBox.events({
    "click #send": function() {
        if (Meteor.user() == null) {
            alert("You must login to post");
            return;
        }
        $('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
        var message = $('#chat-message').val();
        chatCollection.insert({
            userId: 'me',
            message: message
        });
        $('#chat-message').val('');

        //add the message to the stream
        chatStream.emit('chat', message);
    },

    "keypress #chat-message": function(e) {
        if (Meteor.user() == null) {
            alert("You must login to post");
            return;
        }
        if (e.which == 13) {
            $('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
            console.log("you pressed enter");
            e.preventDefault();
            //repeat function from #send click event here
            var message = $('#chat-message').val();
            chatCollection.insert({
                userId: 'me',
                message: message
            });
            $('#chat-message').val('');

    //add the message to the stream
    chatStream.emit('chat', message);
    }
  }
});

chatStream.on('chat', function(message) {
  chatCollection.insert({
    userId: this.userId,
    subscriptionId: this.subscriptionId,
    message: message
  });
});
Was it helpful?

Solution 2

I have added some code to your code. I never use Meteor so I don't know whether this code is work or not in Meteor. But is test this by creating similes project here

Template.chatBox.events({
    "click #send": function() {
        if (Meteor.user() == null) {
            alert("You must login to post");
            return;
        }

        //Validation
       var bot =Check_bots();

        if(bot==false)
        {
            $('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
            var message = $('#chat-message').val();
            chatCollection.insert({
                userId: 'me',
                message: message
            });
            $('#chat-message').val('');

            //add the message to the stream
            chatStream.emit('chat', message);
        }
        else
        {
            // Do whatever you want when a Bot detected
        }
    },

    "keypress #chat-message": function(e) {
        if (Meteor.user() == null) {
            alert("You must login to post");
            return;
        }
        if (e.which == 13) {
            $('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
            console.log("you pressed enter");
            e.preventDefault();
            //repeat function from #send click event here
            var message = $('#chat-message').val();
            chatCollection.insert({
                userId: 'me',
                message: message
            });
            $('#chat-message').val('');

    //add the message to the stream
    chatStream.emit('chat', message);
    }
  }
});

Here is the Validation Codes

<script type="text/javascript">
var lastintime=0;
var defference=0;
var msg_count=0;

function Check_bots()
{
    var seconds = new Date().getTime() / 1000;
    seconds=parseInt(seconds);

    if(lastintime < seconds)
    {
        defference = seconds -lastintime;
        lastintime=seconds;

        if(defference<=5 && msg_count>=3)
        {
            return true;
        }
        else
        {
             return false;
        }
    }
}

</script>

OTHER TIPS

This sounds like a great idea, but there are some issues with using a 'conditional captcha'. One being that the JavaScript doesn't have any way to persist beyond a page reload besides cookies and localStorage. So a simple reload and clearing of the cookies would defeat it. Not to mention how to handle it on the server, which isn't sure whether it should be expecting a valid captcha input or not.

With that caveat out of the way, you could set a global variable that acts as a 'timer' and just keeps track of the lapse. So replace the last block with:

chatStream.on('chat', function(message) {
  //do we already have a timer?
  if(typeof window.chatTimer == 'undefined'){
      //no, so start one right now
      window.chatTimer = new Date().getTime();
  }else{
      //we already have a timer. Is it 5 seconds old?
      var now = new Date().getTime();
      if( now - window.chatTimer < 5000) {
        alert('Not so fast, tiger.');
        return false;
      }else{
       chatCollection.insert({
       userId: this.userId,
       subscriptionId: this.subscriptionId,
       message: message
      });
  }

This example uses reCaptcha, minus the custom stuff you would pass in.

Perhaps this has changed recently, but Spambots don't run JavaScript. They are kinda like search engine crawlers that follow links and look for form and textbox elements, and then knit their poison into a POST request to the form's action attribute, bypassing any JavaScript that wants to block it.

In fact, one of the alternatives to a captcha is simply to dynamically generate a hidden input with JavaScript that has an obscure ID/name that the server is waiting for. Spambots won't run this JavaScript, so the checkbox never gets made, so the bot gets rejected without knowing why. Here's more on that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top