Skip to main content

YAML Overview

A Texter bot is defined by a single YAML file. The file describes who the bot is, how it behaves, and what nodes (steps) the conversation flows through.


Structure of a bot YAML

Every bot file has two main sections: bot-level configuration (top of the file) and nodes (the conversation steps).

identifier: whatsper-bot
start_node: start
apiVersion: v1.1

working_time:
office:
sun-thu: 08:00-17:00

prompt_retries: 2

pending_message:
text: "We received your message and will reply shortly."
everyMins: 5

abandoned_bot_settings:
first_retry:
timeout: 7
text:
- "Hi, I'm waiting for your response 😊"
abandoned:
timeout: 12
node: abandoned_bot_sequence_1

smart_resolved:
node: smart_resolved

nodes:
start:
type: func
func_type: system
func_id: checkWorkingTime
on_complete: main_menu
on_failure: outside_working_hours

main_menu:
type: prompt
prompt_type: choice
interactive: buttons
messages:
- "How can we help?"
choices:
- title: "Sales"
on_select: sales_menu
- title: "Support"
on_select: support_menu
on_complete: agent_handoff

Node types

Every node has a type field that determines what it does:

TypePurpose
promptSends a message and waits for user input
notifySends a message without waiting for input
funcExecutes a function (system, CRM, chat, or utils)
whatsapp:flowLaunches an interactive WhatsApp Flow form

How nodes connect

Nodes route to each other using these fields:

FieldWhen it fires
on_completeAfter the node finishes successfully
on_failureWhen the node fails (e.g., outside working hours, CRM lookup miss, user exceeded retries)
on_selectWhen a specific choice is selected (inside choices)

The value of each routing field is the name of another node in the same YAML file, or a built-in action like handoff or resolved.

Here's how the example bot above flows:

Built-in actions

ActionWhat it does
handoffTransfers the chat to a human agent (sets status to PENDING)
resolvedMarks the chat as resolved/closed
danger

You can't use the built-in actions as the value of an on_failure field - you must route to another node.

If you must, use a noop func node with on_complete: resolved field.


Common node fields

These optional fields can be added to any node type (notify, prompt, func, whatsapp:flow):

FieldTypeDescription
titlestringA human-readable display name for the node. Appears in Texter's UI when selecting nodes (e.g., in template reply "go to branch" selections and resolve-and-go-to-bot dropdowns)
startablebooleanMarks whether this node can be used as an entry point. Only nodes with startable: true appear in Texter's branch selection lists (resolve & go to bot, template reply "go to branch"). Useful for bots with many branches where you only want to show relevant entry nodes
departmentstringAssigns the chat to a department when this node executes
agentstringAssigns the chat to a specific agent (email address or CRM ID as defined in the Texter agents manager)
main_menu:
title: "Main Menu"
startable: true
type: prompt
prompt_type: choice
messages:
- "How can we help?"
choices:
- title: "Sales"
on_select: sales_menu
- title: "Support"
on_select: support_menu
on_failure: agent_handoff
tip

If your bot has many branches, use startable: true only on the entry nodes you want agents to see in the branch selection lists. Nodes without startable (or with startable: false) won't appear there.


Func nodes

Func nodes execute logic. They are further categorized by func_type:

func_typePurposeExample func_ids
systemBuilt-in system functionsswitchNode, botStateSplit, storeValue, request, sendWebhook, checkWorkingTime, keywordsRoute, matchExpression, sendEmail, formatDate, noop, shareFile, setLanguage, parseCrmData
crmCRM adapter operationsgetCustomerDetails, newOpportunity, updateLead, updateRecord
chatChat-level operationslabels, externalBot, sensitiveSession
utilsUtility functionsrandomCode, matchValues
departmentDepartment-level working hours checkcheckWorkingTime

Data injection

You can inject dynamic data into any string value using the %provider:path% syntax:

messages:
- "Hello %chat:title%, how can we help?"

Providers include chat, state, messages, and time. You can also pipe data through transformers:

value: '%chat:phone|formatPhone("smart","IL")%'

See the Data Injection section for full details.