Skip to main content

Collecting Input

To get a typed answer from the user, use an ask.* step. It sends a prompt, waits for the user's reply, and gives you the answer back.

The basic ask​

flow name on command "/name" {
answer = ask.text("What's your name?")
send.text(`Hello, ${answer}!`)
}

ask.text(...) binds the user's reply to a local named answer (you can name it anything). The flow pauses until they respond.

Ask types​

StepReturns
ask.text(prompt)a String
ask.number(prompt)a Number
ask.location(prompt)a location object
ask.contact(prompt)a contact object
ask.document(prompt)an uploaded document
ask.photo(prompt)a photo
age = ask.number("How old are you?")
loc = ask.location("Share your location 📍")

Always handle timeout and cancel​

A user might not answer, or might cancel. Production bots must handle this. Pass a timeout and route the outcomes with a branch:

flow survey on command "/survey" {
branch ask.text("What's your favorite color?", timeout: "120s") {
"timeout" {
send.text("No answer received — say /survey to try again.")
stop
}
"error" {
send.text("Something went wrong. Try again.")
stop
}
default {
// The user's answer is available as `answer` here.
send.text(`Great choice: ${answer}`)
}
}
}
  • The "timeout" arm runs if the user doesn't reply in time.
  • The "error" arm runs if something goes wrong.
  • The default arm runs with the answer bound to answer.
warning

Any ask.* that blocks the flow should handle "timeout". A bot that silently hangs waiting forever is a bad experience.

Validating answers​

After collecting input, validate it before using it. For example, require a non-empty name:

branch ask.text("Enter a project name:", timeout: "120s") {
"timeout" { send.text("Timed out.") stop }
default {
set { flow.trimmed = str.trim(answer) }
when str.isEmpty(flow.trimmed) {
send.text("Name can't be empty. Run the command again.")
stop
} else {
set { user.project = flow.trimmed }
send.text(`Created project "${flow.trimmed}".`)
}
}
}

For repeated retry-until-valid prompts, see the flow.validateInput recipe.

Confirmations​

For a quick yes/no, use confirm:

confirm(title: "Delete everything?")

See Statement Reference → Input for the full input reference.

Next​