Skip to content

Additional

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

_(msgid)

Mark a given string as translatable.

For example:

say _("Hello world")

For more information, see the translation guide.

__testing_name_lookup(identifier)

Look up a bot by testing name

__testing_phone_number_lookup(identifier)

Look up a bot by testing phone number

assign_conversation(user)

Assign the current conversation to the given user.

The user can either be an exact UUID, or a user as returned by the get_assignable_users or get_operator_by_uuid functions.

Returns true when the operation succeeded, or false when the user was not found or does not have access to the inbox. It crashes when trying to assign from a process conversation (master or group), or when an invalid user UUID is passed in.

Examples:

_result = assign_conversation("cb190dcb-a428-4420-9dfc-c4b1ce15c6fb")

get_assignable_users()
|> first()
|> assign_conversation()

bml_escape(string)

Escape a BML string as a normal string.

iex> bml_escape(1) "\"1\""

iex> bml_escape("aa") "\"aa\""

iex> bml_escape("a\"a") "\"a\\"a\""

iex> bml_escape("a\na") "\"a\na\""

iex> bml_escape("#{bla}") "\"#{bla}\""

iex> bml_escape("[time] | do not want | private") "\"[time] | do not want | private\""

iex> bml_escape("is a [0] [0] /^reg/[=val]") "\"is a [0] [0] /^reg/[=val]\""

cancel_emit(schedule_id)

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
cancel_emit schedule_id

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

emit "status_update", [], in: 10, name: "update"
cancel_emit "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)

create_chargeable_event(event_type, opts \\ [])

Add a charge for a billable event.

create_todo(opts)

Create a new todo item.

Options:

  • :title: String with the title of the todo.
  • :description: The main body describing the work that needs to be done.
  • :tags: A list of tags to assign to the todo.
  • :start_at: When the todo should start.
  • :due_at: Deadline for when the todo needs to be a done.

delete_token(token_id)

Delete a given token ID

See API integrations

detect_language(text)

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

Only works when your account has Dialogflow support enabled.

end_session()

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"

  • :tag - the tag of the audience of the escalation. tag: "foo" is a shorthand notation for to: "tag:foo".

flow_condition?(expression, opts \\ [])

Check a given flow expression against the list of tags.

The expression argument is the internal data structure that is the output of the ui:widget: flow_condition CMS input control, consisting of a list of clauses which are evaluated in an OR'ed fashion.

Options:

  • :tags - the tags to check against; when not given, the current conversation.tags are used.

get_access_token(token_id)

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_assignable_operators(opts \\ [])

Get the list of agents and operators for this bot.

This list only includes people that have a direct operator or agent role on the organisation to which this bot belongs, and are currently set to available.

Options:

  • :within_office_hours: Filter the list to only users for whom it's currently within office hours.
  • :presence: Filter the list to users that match the given presence. Valid values include: "online", "offline", and "away".
  • :emails: Filter the list to only users with the given list of emails.

Examples:

_users = get_assignable_users(presence: "online", within_office_hours: true)
assign_conversation(random(_users))

_users =
  get_assignable_users(
    emails: [
      "agent1@example.com",
      "agent2@example.com"
    ],
    within_office_hours: true,
  )

get_attachments()

Get the list of all attachments that the user uploaded in this conversation.

get_available_operators()

List all operators which are on call, e.g. which have indicated to be available and are within their indicated office hours.

Returns a list of maps with the fields id, name, profile_picture, timezone and status. Status can be online when they are logged in into the studio, or offline when they are not logged in.

get_conversation_transcript()

Get a transcript of the current conversation as a text string.

It's possible for messages that have arrived right before calling this function to be missing from the transcript. This happens because the messages are fetched from Elasticsearch, which takes a bit of time to make the messages searchable after insertion. On most channels this won't be noticable, because we can wait a bit longer until they've been made searchable. However, on voice channels (such as phone calls), waiting is not an option, so you may encounter this issue there.

get_dialog_locale()

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

get_full_token(token_id)

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

See API integrations

get_next_office_hours_timeslot(office_hours, opts \\ [])

Get the next pair of opening and closing times from a given date. Returns a list containing two items: the opening datetime and the closing datetime.

The office_hours variable must be a 7-item array in which each item represents an opening/closing hour. The first (0th) element in the array is sunday, the last is saturday.

Options:

  • :timezone - The timezone to consider (defaults to user.timezone or bot.timezone)
  • :date - The reference date to consider (defaults to date_now())

get_operator_by_uuid(uuid)

Retrieve a studio user's details by its UUID

get_phone_number_type(phone, default_country \\ nil)

Try to determine for the given phone number what type of number it is.

If the given string cannot be parsed as a valid phone number (or something other than a string was passed in), then this function will return :error. Otherwise, it will return one of the following:

  • :fixed_line
  • :mobile
  • :fixed_line_or_mobile
  • :toll_fee
  • :premium_rate
  • :shared_cost
  • :voip
  • :personal_number
  • :pager
  • :uan
  • :voicemail
  • :unknown

get_token_info(token_id)

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

log get_token_info(user.tokens.google)

See API integrations

get_users_by_email(email)

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

glob_scripts(pattern, opts \\ [])

Return the titles of all scripts that match the given pattern.

Examples:

glob_scripts("flows/*")
glob_scripts("*.test")

Options:

  • :type - restrict by valid script MIME type (text/bubblescript, text/yaml+data, application/json+data, etc)

group_name(parts)

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 DialoX Inbox.

json_build(data)

Convert a given value to a string encoded as JSON.

json_parse(data)

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

jwt_build(payload, opts \\ [])

Builds a JSON Web Token (JWT).

Returns a token string on success, or nil on failure.

Note that the payload of the JWT is not encrypted, and is therefore readable to everyone that has access the token.

Options:

  • :signature_secret: The secret key to use to validate the token. Defaults to the REST-API channel token. If a signature was not given and the REST-API channel is not configured, an error is raised.
  • :expires_at: An optional datetime string that indicates when the token should be expired. Raises an error if an invalid datetime was passed in. Translates to the JWT exp claim.
  • :not_before: An optional datetime string that indicates when the token should become valid. Raises an error if an invalid datetime was passed in. Translates to the JWT nbf claim.
  • :issuer: String containing the iss field of the JWT. Defaults to nil. Translates to the JWT iss claim.
  • :issued_at: When false, do not fill the iat claim with the current time.

Examples:

token = jwt_build(%{my_data: "here"},
  signature_secret: "hunter2",
  expires_at: date_shift(date_now(), days: 1),
  not_before: date_now(),
  issuer: "Me"
)

jwt_parse(token, opts \\ [])

Parses a JSON Web Token (JWT).

Returns a parsed map containing the payload on success, or nil on failure.

Options:

  • :signature_secret: The secret key to use to validate the token. Defaults to the REST-API channel token. If a signature was not given and the REST-API channel is not configured, an error is raised.
  • :verify_signature: Boolean to indicate if the token should be validated. Defaults to true.

Examples:

token = jwt_build(%{my_data: "here"}, signature_secret: "hunter2")
result = jwt_parse(token, signature_secret: "hunter2")
result.my_data == "here"
result = jwt_parse(token, verify_signature: false)
result.my_data == "here"

Link the given user address to the current user.

If there is no conversation (or actually, a user_frontend) yet for the given addr, a user_frontend entry will be created and linked to the given user.

In case the given address already belongs to the current user, nothing happens.

In case the given address belongs to another user, the target user is merged into the current user.

Returns true if linking was successful, or false when an error happened.

liquid(template, context)

Render a liquid template with the given variables.

log(value)

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("user@example.com", "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:

  • :cc - a list of email addresses to put in the CC field
  • :bcc - a list of email addresses to put in the BCC field
  • :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.
  • :attachments - List of attachments to send with the email. Each entry must be a user-uploaded attachment or an object with type (one of image, audio, video, file) and url fields. It's also possible to send a string as attachment using type: :memory and the :content, :content_type and :filename fields.
  • :locale - The locale to localize the unsubscribe link in. Defaults to en.
mail("user@example.com", "Subject", "Body", link_url: "http://example.com", image_url: "http://example.com/test.jpg")

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.

oauth_link(alias)

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

phone_format(phone, format \\ :national, default_country \\ nil)

Format a number to a specific format.

Returns :error if the given string cannot be parsed as a valid phone number.

The allowed formats are:

  • :e164
  • :international
  • :national
  • :rfc3966

Examples:

iex> phone_format("0612345678", :national)
"06 12345678"
iex> phone_format("+31612345678", :national)
"06 12345678"
iex> phone_format("0612345678", :e164)
"+31612345678"
iex> phone_format("0612345678", :rfc3966)
"tel:+31-6-12345678"

phone_parse(phone, default_country \\ nil)

Parse a phone number and return it in normalized, international format.

phone_parse("0612345678")"+31612345678"

When no country code is given in the input, the number is assumed to be local to the bot's region.

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

Use pre-escalate to indicate to external inbox channels that a chat is being qualified and will soon be waiting for a chat operator.

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"
end

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_script(title)

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.

resolve_gpt_local_intent(text, intents, opts \\ [])

Deprecated, please use resolve_llm_intent() instead

resolve_llm_intent(text, opts \\ [])

Check if the given text resolves to any of the given intents using GPT

Options: - question: The question that the bot asks - prompt: Override the GPT prompt used (default: classify_llm_intents) - locale: Override the locale to use - intents: the list of intents to restrict to (defaults to all LLM intents)

resolve_qna_intents(text, opts \\ [])

Check if the given text resolves to one or more QnA intents

Returns the list of matched intents, in order of confidence.

Options:

  • provider_agent - Name of an alternative qna provider_agent, when not given the default agent is used.

  • :locale - a locale string to override the locale that is selected for selecting the QnA model.

shorten_url(url, opts \\ [])

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.

Expiration date:

It's possible to give a date at which point the URL stops working (and will return HTTP 404). The date given with :expires_at must be in the future. When using :ttl, it will add the given number of seconds to the current date.

Example:

shorten_url(url, ttl: 86400)
# The above :ttl is the same as:
shorten_url(url, expires_at: date_shift(date_now(), seconds: 86400))

sms(phone, message, opts \\ [])

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 alphanumeric sender "DialoX".

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

Options:

  • sender - Override the SMS sender using the given alfanumeric sender string or phone number. Only works with Enreach SMS and when the sender is part of the SMS sender allowlist of the organisation.

sms_notify(phone, message)

Deprecated, please use sms() instead

spawn_function(function, args)

Run a function asynchronously

Runs the given function asynchronously. When the function finishes, its return value is sent to the calling process as an event.

The name of the event is returned as the return value of spawn_function().

dialog main do
  # spawn the function in the background
  _eventname = spawn_function(:worker, ["some_arg"])

  say "We are processing your request, one moment"
  _result = await(event(_eventname))
  say("HTTP worker result = #{_result.payload}")
end

function worker(_arg) do
  log "Going to post in the background.."
  _result = http_post @url
  log "done"
  return _result.body
end

As the name of the event is dynamic, the event should be awaited on in the main conversation using await or with the wait control.

@constants are available in the spawned function, as well as the global variables. However, the global variables CANNOT be changed: they are set to a snapshot of the globals at time the function was spawned. Any changes to the globals not carried over to the main conversation, these are lost when the spawned function is done.

The lifecycle of a spawned function is limited to the lifecycle of the conversation: as soon as the conversation finishes (via close or similar), all still running spawned functions will exit.

Side effects like tag and logging is supported in spawned functions. However, the remember and forget statements are forbidden, as these could cause race conditions.

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

Spawn a group process.

strip_emoji(string)

Remove any emoji from a given string.

strip_html(string)

Remove HTML tags from a given string.

strip_markdown(string)

Remove Markdown formatting from a given string.

strip_speechmarkdown(string)

Remove any Speech Markdown formatting from a given string.

tag?(tag)

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"

testing?()

Helper function for checking whether the bot is running as part of a test case

Returns true if that is the case, or false otherwise.

Using this function can help you switching parts of your bot (mocking data, HTTP calls etc.) when the bot tests are being run.

text_to_speech(smd, opts \\ [])

Perform text-to-speech on the given speech markdown string.

Returns the URL to the stored MP3 audio recording. Results are cached so that performing the same text-to-speech twice will return the same URL.

text to speech can fail because the requested locale does not have a corresponding voice configuration, or the Google TTS backend returns an error. In both cases, nil is returned to the caller.

Options:

  • :locale — The locale to speak in. Must have a voice configured in the corresponding connected channel. (if the conversation is not on a voice channel, it is assumed the REST API channel is enabled which also has a voices configuration).

transcribe(input, request_params \\ [])

Transcribe the given audio attachment or URL into a %Bubble.Message{} struct.

Options:

  • locale - use recognition in given locale (defaults to locale of conversation)
  • provider - Either google, microsoft_openai, google_ai or deepgram.
  • model - the name of the speech model (default: latest_long for Google, whisper-1 for Microsoft OpenAI, nova-2 for Deepgram, gemini-1.5-flash for GoogleAI)

See the transcribe REST API docs for more information on all available transcribe parameters.

unidecode(text)

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

whatsapp(phone, template_id, opts \\ [])

Send the given Whatsapp template message to the given phone number.

The current bot must have a valid 360dialog Whatsapp connection setup up in order for this function to work. Furthermore, the given

The given whatsapp template identifier (template_id) must exist in the conversation's locale (or with the overridden locale: option).

Options:

  • :parameters - a map of numbered body parameters, e.g. %{"1" => "Pete", "2" => "example"}; can only used for basic text-only templates. Will be ignored if :components option is given.

  • :components - A full list of template component parameters (https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#template-object)

  • :locale - a locale string to override the locale that is selected for sending the template message.

within_office_hours(office_hours, opts \\ [])

Calculate whether the given date is within the given week day office hours.

The office_hours variable must be a 7-item array in which each item represents an opening/closing hour. The first (0th) element in the array is sunday, the last is saturday.

Options:

  • timezone - The timezone to consider (defaults to user.timezone or bot.timezone)
  • date - The reference date to consider (defaults to date_now())

write_script(title, contents, opts \\ [])

Write a script file by name.

This function is primarily meant for writing migrations that work on content scripts. It only works given the following conditions:

  • The script (by title) must already exist, or the type: option must be given
  • The function is called within the DialoX studio, in preview mode (debugging)
  • The user that calls the script must be allowed to change the script

The function only works for existing scripts. The content type of the script is unchanged, and the content must be formatted in the right format; e.g. the caller must know that the file is JSON, bubblescript, YAML, etc. The draft version of the script is written; e.g. a manual publish is still required to put the change 'live'.

Options:

  • :type - a valid script MIME type (text/bubblescript, text/yaml+data, application/json+data, etc)

yaml_build(data)

Convert a given value to a string encoded as YAML.

yaml_parse(string)

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