Smart Captcha Automation
Latest commit ce250df Aug 25, 2011 @seejohnrun Skip validation tests
Failed to load latest commit information.
gotchas Fix for ruby < 1.9 Apr 13, 2011
spec Skip validation tests Aug 25, 2011
.gitignore Updated gitignore Mar 8, 2011
Gemfile Basic gotcha in place Mar 8, 2011
Rakefile Update the Rakefile Mar 8, 2011


Adding captchas to some action should be really easy. It shouldn't require a migration, like Brain Buster or API calls like reCAPTCHA. Gotcha is an easy way to ask (custom) questions of your users in order for them to perform some action (like submitting a form).


To install Gotcha, just run:

$ gem install gotcha

Or put it in your Gemfile

gem 'gotcha'

Built-in Gotchas

There are a few captchas implemented and installed by default:

  • SumGotcha - Two random numbers, ask the user for the sum of them
  • BackwardGotcha - Ask the user to retype a random string backwards (case-insensitive)

A random Gotcha type will be generated on each call to gotcha

Using Gotcha

In your forms (HAML used for brevity):

= form_for @thing do |f|
  = gotcha_error
  = gotcha
  = f.submit

In your controller

def new
  @thing =

def create
  @thing =[:thing])
  if gotcha_valid? &&
    redirect_to @thing
    render :new

Multiple Gotchas in a page?

= form_for @thing do |f|
  = gotcha_error
  - 10.times do
    .gotcha= gotcha
  = f.submit

and in your controller


Writing your own Gotchas

To write your own Gotcha, all you have to do is extend Gotcha::Base and provide a question and an answer:

class MyGotcha < Gotcha::Base
  def initialize
    @question = 'Who made this?'
    @answer = 'john'

When writing your own gotchas, you may want the answers to be able to flex a bit, like allowing users to enter things in different cases. In that case, your Gotcha can just override self.down_transform with whatever logic you want. It takes a single argument, text which is the text of the answer. You are expected to put it in a form that it would match regardless of the cases you want. By default, self.down_transform is implemented as:

def self.down_transform(text)
  text = text.is_a?(String) ? text.dup : text.to_s
  text.gsub!(/\s+/, ' ')

Meaning by default, space types don't matter - and case is insensitive.

Installing your gotchas

In an initializer:

Gotcha.unregister_all_types # Remove pre-defined
Gotcha.register_type SumGotcha

Determine if the gotcha was valid

You have a few ways to determine whether or not a Gotcha was valid. You can use gotcha_valid? in views and controllers, or use validate_gotcha! (which throws a Gotcha::ValidationException if the Gotcha was not valid) in your controllers.


In testing, it's sometimes useful to make validation always return true. For this, you can use: Gotcha.skip_validation = true


MIT License. See attached