Ask Awesomely
Build Typeforms awesomely. In Ruby.
Table of Contents
- Installation
- Usage
- Available fields and options
- Passing Context
- Rendering the Typeform
- Todo
- Development
- Contributing
Installation
I wouldn't recommend you do this yet, because it doesn't actually work. Nevertheless, add this line to your application's Gemfile:
gem 'ask_awesomely'
And then execute:
bundle
Or install it yourself as:
gem install ask_awesomely
Usage
Authentication
Firstly, you will need to be able to authenticate:
AskAwesomely.configure do |config|
config.typeform_api_key = ENV["YOUR_TYPEFORM_IO_API_KEY"]
end
Your API Keys are super secret so don't commit them in your code. Use ENV or
something like dotenv so you can keep the credentials out of the repository. This stops bad people from stealing the key and hijacking your Typeform I/O account.
If you're using images
It's possible to create questions that have images (or pictures, as we call them) attached. In fact, one field type relies on this!
Currently Typeform I/O is only able to accept a URL to an image, which means that any images you use have to be uploaded elsewhere first.
If you already handle image uploads in your app (for example, with Dragonfly), you're okay.
If you don't, you will need to give AskAwesomely your AWS credentials so it can do all of the heavy lifting for you.
AskAwesomely.configure do |config|
config.aws_access_key_id = ENV["YOUR_AWS_ACCESS_KEY_ID"]
config.aws_access_key_secret = ENV["YOUR_AWS_ACCESS_KEY_SECRET"]
end
As before, don't commit these keys to your repo unless you want bad things to happen. Check up on the AWS Best Practices if you want to know more.
Basic example
You will want to create a class that represents a specific form to be built:
class MyNewTypeform
include AskAwesomely::DSL
title "My New Typeform"
"awesome", "hehe"
field :statement do
say "Hello, Rubyists!"
end
field :multiple_choice do
ask "What is your favourite language?"
choice "Ruby"
choice "Python"
choice "Javascript"
choice "COBOL"
can_specify_other
end
end
After that, it's simply a matter of calling build on the class:
typeform = MyNewTypeform.build
Check the rest of the (not currently finished) documentation to find out what else you can do.
Check out Typeform I/O for detailed information about the API, and how to get your API key.
Available fields and options
Each field has unique properties. Here are the fields you can use, and the extra things you can do to customise them.
Note that some options might not yet be available on Typeform I/O.
Also note that some field types and customisations that are available on Typeform.com may not be available on Typeform I/O.
Statement
A block of text that isn't a question and requires no answer.
field :statement do
say "what you want to say"
"Okay, next question"
show_quotation_marks
end
Short text
A question where the answer is a short amount of free-form text.
field :short_text do
ask "What do you think of me?"
max_characters 3
end
Long text
A question where the answer is free-form, like short_text, but can be much longer.
field :long_text do
ask "What do you *really* think of me?"
max_characters 700
end
Multiple choice
A question that allows the user to choose from a range answers.
field :multiple_choice do
ask "Why not both?"
choice "Yes"
choice "No"
allow_multiple_selections
randomize
end
Picture choice
Similar to multiple_choice, only you can add a picture to each answer too. This will handle the complications around image uploading for you if you're dealing with local files and pass along your AWS credentials. Otherwise, it will work with whatever system you already have in place – just give it a URL instead of a file path.
field :picture_choice do
ask "Which of these is a spoon?"
# `image` can be a `String`, a `URL`, a `Pathname`, or a `File`
choice "Knife", picture: "http://iseeyouveplayedknifeyspooneybefore.com/spoon.jpg"
choice "Spoon", picture: Rails.root.join("app/assets/images/knife.jpg")
choice "Spork", picture: "/var/www/images/spork.png"
allow_multiple_selections
randomize
end
Dropdown
Similar again to multiple_choice, when you have too many options to show at once.
field :dropdown do
ask "Which is the odd one out?"
(1..100).each do |number|
choice (number != 70 ? number : "seventy")
end
in_alphabetical_order
end
Yes/No
A question that demands the user to commit to their own certainty.
field :yes_no do
ask "Will you marry me?"
required
end
Number
A short_text style question that only accepts numerical input. It can be limited to a range.
field :number do
ask "How many fingers am I holding up?"
min 0
max 4
# alternatively
between 0..4
end
Rating
A question that prompts the user to quantify their opinion of something.
field :rating do
ask "How much did you enjoy Jonny Wiseau's seminal hit, The Room?"
steps 10
shape :thumbs_up
end
Opinion Scale
A refined form of rating more appropriate for "bad / neutral / good" style questions.
field :opinion_scale do
ask "How would you rate our service?"
steps 11
left_side "Terrible"
middle "Average"
right_side "Amazeballs"
starts_from_one
end
A question type painstakingly created to request a valid email address.
field :email do
ask "Can I have your email please?"
description "So you can be my best pen-pal buddy forever."
end
Website
Ask the user to enter a valid URL.
field :website do
ask "Show me a funny GIF"
end
Legal

Like the yes_no field, but primarily intended for accepting terms and conditions. Stuff like that.
field :legal
ask "Do you accept my lofty demands?"
required
end
Common Customisations
Every field type allows you customize the following things:
- the description: a smaller chunk of text to give extra detail to a question
- tags: small strings to help you identify questions
- answer required: prevent form submission until the question is answered
field :legal do
# ...
description "Don't accept, I dare you."
required
"some-kind-of-tag-for-legal", "wtf"
end
Passing Context
note: not yet supported
Building a form full of hard-coded data is all well and good, but it doesn't offer much benefit over using a web interface. What if you want to build personalised forms based on, say, an ActiveRecord model?
Lets create the basic form, with a title and a single question:
class UserTypeform
include AskAwesomely::DSL
title -> (user) { "#{user.name}'s New Typeform" }
field :yes_no do
say -> (user) { "Is this your email address? #{user.email}" }
required
end
end
Notice that we're now using a lambda for the title and question, instead of a hardcoded string. In this case, we're expecting an object that has a name and an email, so we can inject that data into the form.
The next step is to build the form with such an object. For example, in Rails:
rodrigo = User.create(name: "Rodrigo", email: "[email protected]")
typeform = UserTypeform.build(rodrigo)
Or in plain Ruby:
gabriela = OpenStruct.new(name: "Gabriela", email: "[email protected]")
typeform = UserTypeform.build(gabriela)
Rendering the Typeform
Calling build will send your Typeform structure to the API right away, and if everything is hunky-dory you'll get a nice new Typeform object to play with.
Getting the URL
Every Typeform you successfully generate through Typeform I/O will come back with a new public URL. This points to the rendered version of the Typeform and it's what you can send out to your users, or participants, or whomever.
For example, you might email a bunch of personalised Typeforms in a Rails app like this:
User.find_each do |user|
typeform = UserTypeform.build(user)
TypeformMailer.send_to_user(user, typeform.public_url)
end
Embedding
You can also embed a form straight away if you prefer. AskAwesomely generates the correct embed code for you, with the correct URL and Typeform title. The style can be customised with CSS but some aspects of the embed itself are not currently customisable (e.g. changing button text and widget size).
To see what each embedding option looks like, check out the Embedding Modes[http://docs.typeform.io/docs/embedding-introduction) documentation at Typeform I/O. It has pictures and everything.
Assuming you have built a Typeform as in the other examples, rendering the embed code is simple:
Modal
Pops up over the page content and fills most of the screen.
typeform.(:modal)
Widget
Allows you more control over where the form is embedded and how it appears. Just a box on the page.
typeform.(:widget)
Drawer
Makes the form slide in from the side of the page, hamburger menu style, and fills at least half of the screen.
typeform.(:drawer)
Fullscreen
Becomes the entire page.
Note that this outputs a complete HTML document, CSS and all. If you're working with your own views and layouts this will not embed properly unless inserted into an empty layout. Can work well with Sinatra or other small frameworks if you just want to build a form and display it.
typeform.(:fullscreen)
Todo
- implement and test dynamic fields
- test the API interaction behaves well
- deal with errors from the API
- allow webhook URL to be configured
- allow design to be configured
Development
After checking out the repo, run bin/setup to install dependencies. Then, run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release to create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
Contributing
- Fork it (https://github.com/leemachin/ask_awesomely/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request