Skip to content

Builtin functions

Expressions are used in places where you want to create dynamic content or perform calculations. They can occur as part of any Bubblescript statement. For instance, the argument to the say statement can contain an expression, to make it dynamic.

Consider this example:

name = "Pete"
say "Hello " + name + ", " + random(["how are you?", "what's up?", "how you doing?"])

This uses a variable (name), the string concatenation operator (+), and the random() function to generate a dynamic answer.

The following builtin functions are available to use in expressions:

List (array) functions

filter(list, query)

Filter list of maps according to a MatchEngine query.


Return the first item in a list

item(ets, index)

Return tne n-th item from the given list (the first element is at index 0)

join(list, joiner)

Join the given list using a string.

join(list, joiner, last_joiner)

Join the given list using a string.

The last_joiner string will be used to join the last two items in the list. This helps with joining strings in a "human readable" way:

candidates = ["John", "Mary", "Elsa"]
say "The candidates are: " + join(candidates, ", ", " and ")

Will result in: The candidates are: John, Mary and Elsa


Return the keys of a map or keyword list.

When a plain list is given, returns a list with the list indexes ([0, 1, 2, ...]).

Raises an error on non list/map values.


Return the last item from a list

pluck(list, key)

Given a list of maps, return for each map the item with the given key.

score(list, query)

Score a list of maps according to a MatchEngine query.


Shuffle the given list

sort(enum, opts \\ [])

Sort a list.

Options: - direction: either :asc or :desc - field: when sorting a list of maps, specify which field in the maps to sort on.


map = [[num: 1], [num: 2], [num: 3], [num: 4], [num: 5]]
map = sort(map, field: "num", direction: :desc)

split(string, pattern, opts \\ [])

Split the given string on the pattern, returning a list.

Options (doc):

  • :parts (positive integer or :infinity) - the string is split into at most as many parts as this options specifies. If :infinity, the string will be split into all possible parts. Defaults to :infinity.

  • :trim (boolean) - if true, empty strings are removed from the resulting list.


Return a list with unique elements (no duplicates)


Return the values of a map or a keyword list.

When a plain list is given, returns the list itself.

Raises an error on non list/map values.

Date functions

As there is no native datetime datatype in the DSL, all date functions expect a valid ISO date string as input, and also return an ISO date string. Internally, the Timex library is used for all date operations.

date_diff(a, b, granularity)

Get the difference between two dates.

You need to specify a diff granularity, any of the following:

  • :years
  • :months
  • :calendar_weeks (weeks of the calendar as opposed to actual weeks in terms of days)
  • :weeks
  • :days
  • :hours
  • :minutes
  • :seconds
  • :milliseconds
  • :microseconds
  • :duration

and the result will be an integer value of those units or a Duration struct. The diff value will be negative if a comes before b, and positive if a comes after b. This behaviour mirrors compare/3.

See the Timex manual.

date_format(date, format_string, formatter \\ nil)

Formats an UTC ISO8601 time string.

Expects an ISO date string, a format string and optionally a formatter module.

For the format of the date format string, see the documentation of the Timex date formatter.

The formatter argument can be set to :strftime to

date_now(timezone \\ nil)

Returns the current time as extended ISO8601 string.

When a timezone is passed in, the current date is returned in that timezone.

date_parse(string, opts \\ [])

Parse a given date into a UTC ISO8601 time string.

The input date needs to be a string. The Duckling date parser is used (unless the format option is specified), so a "human input" string ("tomorrow", "in 2 hours") can be used as input.

Options can contain the following: - format - when format is given, parsing is done using Timex.parse, otherwise, parsing is done using Duckling. - locale - the locale used for parsing (in case of Ducking parser), defaults to en_US - timezone - the timezone used for parsing (in case of Ducking parser), defaults to Europe/Amsterdam

When using format:, date_parse fails with a runtime error when failing to parse the date. When using the duckling option, it returns nil when the parsing fails.

date_part(date, part)

Get a component of the given datetime.

The component name is one of the following:

  • :year
  • :month
  • :day
  • :hour
  • :minute
  • :second

Returns nil when an invalid part was given.

date_set(date, opts)

Return a new date/time value with the specified fields replaced by new values.

Values are automatically validated and clamped to good values by default.

See the Timex manual.

date_shift(date, opts)

Shifts the given datetime by the given duration.

A single function for adjusting the date using various units: duration, microseconds, seconds, minutes, hours, days, weeks, months, years.

The result of applying the shift will be the same type as that of the input, with the exception of shifting DateTimes, which may result in an AmbiguousDateTime if the shift moves to an ambiguous time period for the zone of that DateTime.

Valid units are:

  • years
  • months
  • weeks
  • days
  • hours
  • minutes
  • seconds
  • milliseconds
  • microseconds

See the Timex manual.

Miscelaneous helper functions

contains(string, substring)

Return whether a given value is part of the given list, or whether a given value is a substring of the given string.

This is a polymorphic function. When one of the arguments is nil, it will return false. In other cases, when invalid values are passed in, it will raise a runtime error.

distance(a, b)

Return the geographical distance (in meters) between two geographical locations.

The parameters need be valid geographical locations, e.g. maps with a lon and lat attribute.


Construct a new entity


Construct an event for use in expecting:

extract_entity(input, entity)

Given an input sentence and an entity, extract the entity, returning its value.

When there is no entity found, it returns nil.


Construct a new intent


Return the length of a string or the length of a list.

This is a polymorphic function: When passed in a string, it returns the number of characters in the string. When passed a list or a map, it returns the number of elements. For all other values, it returns 0.


Return a random item.

This is a polymorphic function: When a number is given, returns a random number between 0 and that number. When a list is given, returns a random element from the list.


Reverse the given list or string.

When a different value is passed in, it will raise a runtime error.

slice(string, startpos, endpos \\ nil)

Slice a substring out of the given string, or a sublist out of the given list.

When a different value is passed in, it will raise a runtime error.

Numeric functions


Return the abs of the given number.


Return the ceil of the given number.


Return the floor of the given number.

max(a, b)

Return the max of the given numbers.

min(a, b)

Return the min of the given numbers.

modulo(a, b)

Return the modulo of the given numbers.


Converts most values to their numeric counterpart. Returns nil when conversion fails.


Return the round of the given number.

Show functions


Creates and validates a data structure for presenting an audio fragment.

The result is meant to be passed in to the show statement, e.g: show audio "…"

buttons(text, buttons)

Creates and validates a data structure for showing a buttons template

For more info on the exact data format see


Creates a card template. A card template is a gallery template with only one item. This is not supported on Facebook Messenger, only on web and google assistant.


Creates and validates a data structure for offering a file for download.

The result is meant to be passed in to the show statement, e.g: show file "…"

Creates and validates a data structure for showing a horizontal gallery template.

Options: pass in modal: false to prevent the elements showing in a modal gallery popup, but as large elements in the chat stream instead.

For more info on the exact data format see


Creates and validates a data structure for showing an image.

The result is meant to be passed in to the show statement, e.g: show image "…"

input_method(type, config \\ nil)

Creates and validates a data structure for the given input method, to be used in an expecting: clause.

See for more details on different input methods.

list_template(elements, button \\ nil, top_element_style \\ "compact")

Creates and validates a data structure for showing a list template.

For more info on the exact data format see

location(value, opts \\ [])

Convert the given value to a valid location structure


Creates and validates a data structure for showing a video clip.

The result is meant to be passed in to the show statement, e.g: show video "…"


Creates and validates a data structure for showing a website in an iframe.

The result is meant to be passed in to the show statement, e.g: show web "…"

String functions


Capitalizes each word in the string


Converts a string to lowercase


Decode HTML entities in a string.


Encode HTML entities in a string.


Given a singular word, returns the plural version of it (according to English grammar)

regex_replace(string, regex, replacement, options \\ [])

Replace string in the given string with a replacement.

replace(string, pattern, replacement, options \\ [])

Replace string in the given string with a replacement.


Given a plural word, returns the singular version of it (according to English grammar)


Trim whitespace characters from both ends of a string.

trim(string, what)

Trim given characters from both ends of a string.


Trim leading whitespace characters from a string.

trim_leading(string, what)

Trim given leading characters from a string


Trim trailing whitespace characters from a string

trim_trailing(string, what)

Trim given trailing characters from a string

truncate(value, length, append \\ "…")

Truncates a string down to the number of characters passed as the first parameter.

An appendinx, defailting to the ellipsis character(…), is appended to the truncated string. The final string length is at max length characters, including the appendix.

truncate_words(value, numwords, append \\ "…")

Truncates a string down to the number of words passed as the first parameter. An ellipsis (…) is appended to the truncated string.


Converts a string to uppercase


Decode escaped URL characters


Converts any URL-unsafe characters in a string into percent-encoded characters. Note that url_encode will turn a space into a + sign instead of a percent-encoded character.


Escapes any URL-unsafe characters in a string into percent-encoded characters, but leaves reserved characters alone (/, &, :, ?)


Convert the given list of key/value pairs into a string which can be used in a URL query string.

XML functions

XML is represented in Bubblescript as a nested array.

XML is an inherently more difficult datatype to work with than JSON, as XML an XML element has different notions of data: the XML's attribute name, its attributes, and a list of its children.

An XML element like this:

<element attr="val">content</element>

Will be represented as an array with three elements:

["element", %{"attr" => "val"}, "content"]

The first element of this array is always the element's name; the second are its attributes, and the third is its contents. When the XML element contains children, the elemen's contents will be an array of new XML elements (again represented of 3-element arrays).


Build an XML string out of a data structure.

iex> xml_build(["element", %{"attr" => "val"}, "content"])
"<element attr="val">content</element>"


Parse an XML string into a data structure.

iex> xml_parse("<element attr="val">content</element>")
["element", %{"attr" => "val"}, "content"]

xml_xpath_all(data, query)

Select a list of values or XML elements

Selects a list of values or XML elements from the given XML using an XPath expression. Always returns a list. In the case that no elements were selected, an empty list is returned.

xml_xpath_one(data, query)

Select a single value or XML element

Selects a single value or XML from the given XML data structure using an XPath expression. If the result of the expression is not exactly one single element, nil will be returned.

Additional builtin functions

These are additional functions which can be used inside the bot processes. They cover more specific tasks that are related to the Botsquad platform, like token management, process management and communication.


Mark a given string as translatable.

For example:

say _("Hello world")

For more information, see the translation guide.


Will cancel the given scheduled emit. The identifier can be obtained from the emit statement; a scheduled emit (with in: or at: option) sets the variable with the name schedule_id in the bot script. You can use this variable to cancel it:

emit "status_update", [], in: 10

When you give the scheduled event a name, it can also be cancelled using that name:

emit "status_update", [], in: 10, name: "update"

chat_link(frontend, params \\ nil)

Generates a link to this bot for sharing purposes.

say "Reach me on the web on this link:"
say chat_link("web_pwa")

If you want a link to the same channel that the current user is chatting through, you can pass in the user.frontend variable:

say chat_link(user.frontend)

The second argument, params is used to add extra parameters to the chat link, for instance the g parameter to join a group.

say chat_link("web_pwa", g: group)

To create a link which leads into a users's session, use the user_id parameter:

say chat_link("web_pwa", user_id: some_user_id)

Account linking

To create a link which leads into a user's session and then aliases your current user ID to the new user ID, use user_id combined with alias_user_id (which is the "old" user id):

say chat_link("web_pwa", user_id: some_user_id, alias_user_id: user.user_id)


Delete a given token ID

See API integrations


Detect the language of the given text, using the Google Natural Language processing API.

Only works when your account has DialogFlow support enabled.


Stop the interaction.

Note: deprecated: use stop instead

escalate(reason \\ "Assistance required", opts \\ [])

Send an escalation message to the operators of this bot.

The operators which are on call are notified, either in the studio, by web push notification, or with email. The return value is true when an operator could be reached, or false if there were no operators on call.

The reason that can be passed in is supposed to be a human-readable message, describing why the bot needed to hand over the conversation. It is sent as the subject of the email and push notification.

Options can include:

  • to: - the audience of the escalation. This is either a role tag (to: "tag:finance"), which will send the escalation to all roles with the finance tag; an array of tags: to: ["tag:finance", "tag:frontdesk"]; or a user id of a user in the studio: to: "studio:68eafe876f8a6e87a6e"


Return the plain access token for the given token identifer. This access token is used in HTTP calls to perform requests to the integrated service.

See API integrations


Get all operators which are on call. Returns a list of user id, name and profile picture.


Return the locale in which the bot is currently talking to the user.


Retrieves the full token information structure, mainly for inspection purposes.

See API integrations


Return some basic information about the user that is connected to the specific token:

log get_token_info(

See API integrations


Retrieve user details for all users that are registered with the given email address. Used for account linking.


Generates a deterministic group name for a list of identifiers based on a hash.

The identifiers can appear in any order, they are sorted before they are hashed. No ~ is prepended to the group name - you need to do this yourself.

Returns a link to this conversation in the inbox of the Botsquad Studio.


Convert a given value to a string encoded as JSON.


Convert the given JSON-encoded string to a data structure. Returns nil when decoding fails.


Logs a debugging statement in the chat session's stream.

mail(to, subject, message, opts \\ [])

Sends a notification e-mail to the given user.

mail("", "Subject", "Hi there! This is your bot talking to you.")

This will send a pre-formatted HTML email, with the bot's name, profile picture and the message details.

HTML can not be used inside e-mail. The mail function is meant for basic notification and reminder messages.

The fourth argument can be given as options:

  • link_url: can be used to render a button below the text, which will link to the given URL.
  • link_caption: The optional caption of the button, defaults to "Open link"
  • image_url: The URL of an image to show below the text (and below the button). When link_url is also set, the image links to the link URL as well.
  • unsubscribe_url: The URL where the recipient can go to unsubscribe theirselves from messages like this. When set, an 'unsubscribe' option will be added to the mail message's footer.
  • locale: The locale to localize the unsubscribe link in. Defaults to en.
mail("", "Subject", "Body", link_url: "", image_url: "")

See e-mail handling for more information on the mail capabilities of the platform.

mustache(template, context)

Render a mustache template with the given variables.


This function generates a link for the requested integration which starts the OAuth authorization flow.

The one required argument is the name of the provider or alias of which integration to start:

say oauth_link("google")

See API integrations

query(recipient, name, payload \\ [])

Sends an event to the given user, and waits for the reply.

reply = query :master, "ping"
say reply

In the other script, define a task or dialog that catches the ping event, and use the reply construct to send a payload back:

task event: "ping" do
reply "pong"

Make sure that the handling task / dialog in the other process finishes quickly. If there is no reply received within 1 second, the value :timeout is returned in the calling process.

See Communication and coordination


Read a script file by name, returning its text.

resolve_dialogflow_intent(text, lang \\ nil)

Check if the given text resolves to a dialogflow intent

If an intent matches it returns the intent structure, otherwise nil.

Like the global intent matcher, this function looks first in a locally defined Dialogflow agent (if the dialogflow Google Service account JSON file was found); otherwise it uses the globally-available Botsquad-Defaults Dialogflow agent.


Create a shortened URL, for use in SMS messages and such.

The shortened URLs are scoped to the current bot and, as such, are removed when the bot is removed. Shortening the same URL again returns the same short URL.

Only HTTP and HTTPS URLs can be shortened. Giving invalid input to the function returns nil instead of a short URL.

sms_notify(phone, message)

Send a notification SMS message to the given phone number.

The phone number must be specified in full international format, e.g. +31641345678. The sender of the SMS is the fixed Botsquad notification number.

In order for this function to work, you need to have setup a Twilio connection to your existing SMS service. Read more about SMS handling

spawn_group(group \\ nil, context \\ %{})

Spawn a group process.


Retrieve the value of a prefixed tag, or true / false for a normal tag, for the tags that are set on the current conversation.

tag "workflow::assigned"
say tag?("workflow")

Will say assigned.

tag "hello"
if tag?("hello"), do: say "Hello is set"


Transliterate a string with accented characters to a plain ASCII version without any accents or special symbols.


Convert a given value to a string encoded as YAML.


Convert the given JSON-encoded string to a data structure. Returns nil when decoding fails.