How to Give Super Powers to Your Forms With Chatbots

Case Study Mar 29, 2021

We can safely say that forms represent a big part of the internet. Pretty early, as the internet was growing, webmasters and website creators realized that displaying simple forms just didn't cut it, they had to be well presented, good-looking, simple, and quick to fill. Companies like SurveyMonkey or Typeform have built entire products around forms.

A few years ago, chatbots started to become more and more popular and today is time for chatbots to make better forms, much like websites did a few years ago.

Let's go through the good practices to make great forms, surveys, and polls. But before starting, let's take the time to state the obvious and remind ourselves why we use forms: we want to get a set of accurate information from the user as quick as possible.

For example, we'll work on an event subscription form.

⚡️ Ask short questions that go straight to the point

The main goal of a great form is to avoid user frustration and therefore, we don't want to talk to the user for minutes before asking a question. Questions should go straight to the point asking clear information to a user and giving options to select from, when possible.

// DO NOT write long questions that are boring to the user
say "Sometimes it is useful for us to know how big it the company you work for, if it's over 1000 employees, we'll get somebody from our sales team to reach out to you so he can work out what's offer fits you best. Would it be ok to tell us how big is your company?"

// DO write clear short questions with options
say QuickReply("How many employees does your comany count",
	Button("Less than 10"),
	Button("10 to 100"),
	Button("100 to 1000"),
	Button("Over 1000")])
Full code can be found down at the bottom

⏭ Pre-fill fields

As stated before, we want to get the user to fill in the form as fast as possible in order to get all the information. To achieve this goal, we shouldn't ask questions to which we already have the answer.

For instance, the user may have subscribed to an event a while ago, so chatbot already has a bunch of information, the perfect opportunity to skip a few questions!

In CSML, we can check if a value exists with a simple condition like the one below:

if (company) {
    say "I already got your company name, let's move forward!"
    goto next_step
Full code can be found down at the bottom

🙌 Don't start over

When filling a long survey, a user may need to leave the chatbot at some point. It is not unusual that users happen to come back to talk to the chatbot later. In this case, we want to skip the questions that the user has already answered and go straight back to the question the user left at.

Since CSML works with steps, it is very easy and convenient to know whether or not a step was completed, or in other words, the user answered the question.

if (currentQuestion) goto $currentQuestion
Full code can be found down at the bottom

📣 Set reminders

We've just said that a user may leave right in the middle of a questionnaire, this is quite unfortunate and we should plan an action to get the user back.

A great way to get the user back and get him/her to answer the rest of the questions is simply to send him/her a message within a few hours to remind him/her to finish the survey.

CSML offers an App that does just that: the Scheduler app! It allows the chatbot to reach out to a user at a specific point in time. It is unbelievably useful to increase questionnaire completion rate!

do App("utils/scheduler", action="broadcast", delay="5 hrs", flow_id="questionnaire")
Full code can be found down at the bottom

👩‍💻 Use third-party services

There is a bunch of API out there. From NLU with Dialogflow down to address completion with Google, you can bring intelligence to your chatbot in a matter of minutes using all these API.

To find a city name based on a postcode, we could use this API (for the UK only).

do pcInfos = HTTP("{{event}}").get().send()
if (pcInfos.result.admin_district) {
    remember city = pcInfos.result.admin_district
Full code can be found down at the bottom

🔥 Final result

Here is the final code for, a chatbot that asks precise questions, uses third-party services, remembers information, and where the user left to get him/her back to the right place!

  // We check if the user has already starting completing the form
  if (currentQuestion) goto $currentQuestion
  // We schedule a reminder right from the begining, we'll desable it if the user finishes the form
  remember scheduleId = App("utils/scheduler", action="broadcast", delay="5 hrs", flow_id="Default")

  say Typing(3000)
  say "In order to subscribe you to this super cool event, I just need to ask you a few questions."
  goto getFirstname

  if (firstname) goto getCompany
  // We set currentQuestion in memory so the chatbot can remember
  // where the user left if necessary
  remember currentQuestion = "getFirstname"
  say "What's your firstname?"
  remember firstname = event
  say Typing(2000)
  say "Alright {{firstname}}"
  goto getCompany

  if (company) goto getCompanySize
  remember currentQuestion = "getCompany"
  say "What company do you work for?"
  remember company = event
  goto getCompanySize

  if (companySize) goto getPostcode
  remember currentQuestion = "getPostcode"
  say QuickReply("How many employees does your comany count",
      Button("Less than 10"),
      Button("10 to 100"),
      Button("100 to 1000"),
      Button("Over 1000")])
  remember companySize = event
  goto getPostcode

  remember currentQuestion = "getPostcode"
  if (!postcode) {
    say "What's your postcode?"
    remember postcode = event
  // We check if the post code is know, if it is we skip the city
  // For UK, you can try with postcode "OX1 1AB"
  do pcInfos = HTTP("{{postcode}}").get().send()
  if (pcInfos.result.admin_district) {
    remember city = pcInfos.result.admin_district
    goto save
  goto getCity

  if (company) goto save
  remember currentQuestion = "getCity"
  say "What city do you live in?"
  remember city = event
  goto save

  // We save the result using NACAPI APi
  do HTTP("")
      "firstname": firstname,
      "company": company,
      "companySize": companySize,
      "postcode": postcode,
      "city": city
    say Typing(3000)
    say "All done, thanks {{firstname}}!"
    // We remove the scheduler
    do App("utils/scheduler", action="cancel", schedule_id=scheduleId)
    // We set the current question back to null
    remember currentQuestion = null
    goto end