Menu Nodes
Build interactive menus, wizards, and navigation systems. These nodes handle user choices, pagination, multi-step forms, and complex menu hierarchies.
Why Use Menu Nodes?â
Menu nodes provide a structured way to build interactive experiences:
- â User-Friendly: Visual buttons instead of text commands
- â State Management: Auto-tracks menu navigation
- â Built-in Navigation: Back buttons, breadcrumbs
- â Pagination: Handle large lists elegantly

đ Show Menu (menu.show)â
The core menu node that displays options and handles user selection.
Configurationâ
| Setting | Description |
|---|---|
| Message | Text to show above buttons |
| Items | Array of menu options |
| Columns | Buttons per row (1-3) |
| AllowBack | Show "â Back" button |
| ParseMode | Markdown/HTML formatting |
Item Formatâ
Each menu item is an object:
{
"label": "đĻ View Products",
"data": "show_products",
"url": "https://shop.com" // Optional link
}
Dynamic Outputsâ
The node creates output sockets for each menu item:
- One output per item (based on
datafield) Backoutput (if enabled)Canceloutput (optional)
Example: Main Menuâ
menu.show:
Message: "Welcome! What would you like to do?"
Items: [
{ label: "đī¸ Browse Products", data: "products" },
{ label: "đ Contact Support", data: "support" },
{ label: "âšī¸ About Us", data: "about" }
]
Columns: 2
Outputs:
products â [Show ProductsCatalog]
support â [Start Support Chat]
about â [Send About Info]
[Screenshot: menu.show node showing 3 items and their corresponding output sockets]
đ§ Multi-Step Wizard (menu.wizard)â
Your all-in-one solution for collecting information step-by-step â like a guided form that remembers where users left off!
Why Use Wizards?â
Perfect for:
- đ Registration Forms â Collect name, email, preferences
- đ Checkout Flows â Shipping address, payment, confirmation
- đ Surveys â Multi-question questionnaires
- âī¸ Onboarding â Walk new users through setup
- đĢ Booking Systems â Date, time, guest count
Configurationâ
| Setting | Description |
|---|---|
| Steps | Array of step configurations (see below) |
| SaveToVar | Save collected data to this variable |
| MaxRetries | Global retry limit (can override per-step) |
| AllowBack | Show "â Previous Step" button |
đ Step Configurationâ
Each step has these options:
| Field | What It Does | Example |
|---|---|---|
| id | Unique step name | "email_step" |
| title | Question to ask | "What's your email?" |
| type | Input type (see types below) | "email" |
| required | Must answer to continue? | true |
| validation | Custom rule (expression) | "len(value) > 5" |
| error_message | Show if validation fails | "Email must be valid" |
| show_if | Only show if condition met | "plan == 'premium'" |
| next_step | Jump to specific step | "payment_step" |
| max_retries | Retry limit for this step | 3 |
| default | Pre-fill value | "United States" |
| options | Choices (for select/confirm) | See examples below |
đ¨ Input Typesâ
| Type | What It Accepts | Example Use |
|---|---|---|
| text | Any text | Name, address |
| number | Numbers only | Age, quantity |
| Valid email format | user@example.com | |
| phone | Phone number | +1-555-0100 |
| url | Web link | https://example.com |
| select | Multiple choice | Plan selection |
| confirm | Yes/No | Agree to terms? |
| photo | User uploads image | Profile picture |
Outputsâ
| Output | Description | Type |
|---|---|---|
| Complete | All steps finished | Flow |
| Cancelled | User cancelled wizard | Flow |
| FormData | All collected answers | Object |
| CurrentStep | Current step number | Number |
| TotalSteps | Total step count | Number |
| ErrorText | Error message if any | String |
đ Complete Examplesâ
Example 1: Simple Registrationâ
{
"steps": [
{
"id": "name",
"title": "đ What's your name?",
"type": "text",
"required": true
},
{
"id": "email",
"title": "đ§ Enter your email:",
"type": "email",
"required": true,
"error_message": "Please enter a valid email address"
},
{
"id": "age",
"title": "đ How old are you?",
"type": "number",
"required": true,
"validation": "value >= 18",
"error_message": "You must be 18 or older"
}
],
"save_to_var": "var.user_registration"
}
Result: When complete, var.user_registration contains:
{
"name": "John Doe",
"email": "john@example.com",
"age": 25
}
Example 2: Product Order with Branchingâ
{
"steps": [
{
"id": "product",
"title": "đī¸ What would you like to order?",
"type": "select",
"options": [
{ "label": "đĨī¸ Laptop", "value": "laptop" },
{ "label": "đą Phone", "value": "phone" },
{ "label": "â Watch", "value": "watch" }
]
},
{
"id": "laptop_spec",
"title": "đģ Choose RAM:",
"type": "select",
"show_if": "product == 'laptop'",
"options": [
{ "label": "8GB - $999", "value": "8gb" },
{ "label": "16GB - $1299", "value": "16gb" }
]
},
{
"id": "phone_color",
"title": "đ¨ Choose color:",
"type": "select",
"show_if": "product == 'phone'",
"options": [
{ "label": "Black", "value": "black" },
{ "label": "White", "value": "white" },
{ "label": "Blue", "value": "blue" }
]
},
{
"id": "confirm",
"title": "â
Confirm your order?",
"type": "confirm"
}
]
}
How it works:
- User selects "Laptop"
- Wizard shows
laptop_spec(becauseshow_ifcondition is true) - Wizard SKIPS
phone_color(becauseshow_ifis false) - Goes to confirm
Example 3: Survey with Smart Branchingâ
{
"steps": [
{
"id": "satisfied",
"title": "đ Are you satisfied with our service?",
"type": "select",
"options": [
{ "label": "đ Very Satisfied", "value": "very" },
{ "label": "đ Satisfied", "value": "ok" },
{ "label": "đ Unsatisfied", "value": "bad" }
]
},
{
"id": "what_good",
"title": "đŦ What did you like most?",
"type": "text",
"show_if": "satisfied == 'very' || satisfied == 'ok'"
},
{
"id": "what_wrong",
"title": "đ What went wrong?",
"type": "text",
"show_if": "satisfied == 'bad'",
"required": true
},
{
"id": "recommend",
"title": "Would you recommend us?",
"type": "confirm"
}
]
}
Smart flow:
- Happy customers â "What did you like?"
- Unhappy customers â "What went wrong?"
- Everyone â "Would you recommend?"
⨠Advanced Featuresâ
đ Retry Handlingâ
Set retry limits to prevent frustration:
{
"id": "password",
"title": "đ Create a strong password:",
"type": "text",
"validation": "len(value) >= 8",
"error_message": "Password must be at least 8 characters",
"max_retries": 3
}
After 3 failed attempts â Goes to Cancelled output
đŗ Dynamic Navigationâ
Jump to different steps based on answers:
{
"id": "account_type",
"title": "Choose account type:",
"type": "select",
"options": [
{ "label": "Personal", "value": "personal" },
{ "label": "Business", "value": "business" }
],
"next_step": "business_info" // Skip to business questions
}
đž Accessing Collected Dataâ
After the wizard completes, access the data:
FormData output â {
"name": "John",
"email": "john@example.com",
"plan": "premium"
}
In templates:
Welcome {{FormData.name}}!
Your plan: {{FormData.plan}}
In variables:
If you set save_to_var: "var.signup", then:
{{var.signup.name}}
{{var.signup.email}}
đ¯ Best Practicesâ
1. Keep It Shortâ
â Don't: 20-step registration â Do: 3-5 essential questions
2. Show Progressâ
The wizard automatically shows:
Step 2 of 4
3. Use Validation Earlyâ
{
"type": "email", // â Validates email format automatically
"validation": "not includes(value, 'spam')" // â Extra custom check
}
4. Smart Branchingâ
Only ask relevant questions:
{
"show_if": "country == 'USA'", // â Only for US users
"title": "What's your state?"
}
5. Provide Defaultsâ
{
"id": "country",
"default": "United States" // â Pre-filled
}
đ Real-World Use Casesâ
Hotel Bookingâ
1. Check-in date
2. Check-out date
3. Number of guests
4. Room type (economy/deluxe/suite)
5. Breakfast? (yes/no)
6. Confirm booking
Event Registrationâ
1. Full name
2. Email
3. Company name
4. Meal preference (vegetarian/non-veg/vegan)
5. T-shirt size (if attending in-person)
6. Confirm registration
Support Ticketâ
1. Issue category (billing/technical/other)
2. Describe issue
3. Upload screenshot (optional)
4. Priority (low/medium/high)
5. Submit ticket
đ Paginated List (menu.paginated_list)â
Display large lists with navigation buttons (Next/Previous).
Configurationâ
| Setting | Description |
|---|---|
| Items | Array of all items |
| PageSize | Items per page (default: 5) |
| ItemTemplate | How to format each item |
| Header | Message above list |
Outputsâ
| Output | Description |
|---|---|
ItemSelected | User clicked an item |
SelectedItem | The selected item data |
SelectedIndex | Item's array index |
Example: Product Catalogâ
menu.paginated_list:
Items: [
{ name: "Laptop", price: 999 },
{ name: "Mouse", price: 25 },
{ name: "Keyboard", price: 75 },
... 50 more products
]
PageSize: 5
ItemTemplate: "{{name}} - ${{price}}"
Header: "đī¸ Our Products (Page {{page}}/{{total_pages}})"
Shows:
Page 1/10
đī¸ Our Products
Laptop - $999
Mouse - $25
Keyboard - $75
Monitor - $350
Webcam - $120
[âī¸ Previous] [Next âļī¸]
[Screenshot: Paginated list showing Page 2 of 5 with navigation buttons]
Use Cases:
- Product catalogs
- Search results
- User lists
- Content browse
đ Menu Router (menu.router)â
Route to different submenus based on user selection, creating hierarchical navigation.
Configurationâ
| Setting | Description |
|---|---|
| Routes | Map of data â submenu |
| DefaultRoute | Fallback menu |
Example: Multi-level Navigationâ
Main Menu
â
[menu.router]
products â Product Categories Menu
support â Support Options Menu
settings â Settings Menu
Use Case: Complex navigation trees (e-commerce, help centers)
âŦ
ī¸ Navigate Back (menu.navigate_back)â
Return to the previous menu in the navigation stack.
Configurationâ
| Setting | Description |
|---|---|
| Message | Optional text when going back |
How It Worksâ
BotGami automatically tracks menu navigation history. This node pops the stack:
User flow:
Main â Products â Category â Item
â
[Navigate Back]
Goes back to: Category
Example: Breadcrumb Navigationâ
Every menu.show has AllowBack: true
â
Each "Back" output connects to menu.navigate_back
â
Automatic breadcrumb trail
[Screenshot: Menu showing "â Back" button with breadcrumb path]
đ Reset Menu (menu.reset)â
Clear navigation history and return to a specific menu (usually main).
Configurationâ
| Setting | Description |
|---|---|
| TargetMenu | Menu ID to reset to |
| Message | Optional reset message |
Example: Return to Mainâ
User finishes checkout
â
[menu.reset â main_menu]
â
"â
Order complete! Returning to main menu..."
Use Cases:
- After completing a workflow
- Timeout/idle cleanup
- Error recovery
â Confirmation Dialog (menu.confirm)â
Simple Yes/No confirmation prompt.
Configurationâ
| Setting | Description |
|---|---|
| Message | Question to ask |
| YesLabel | Custom "Yes" button text |
| NoLabel | Custom "No" button text |
Outputsâ
| Output | Description |
|---|---|
Yes | User confirmed |
No | User declined |
Example: Delete Confirmationâ
menu.confirm:
Message: "đī¸ Delete this item? This cannot be undone."
YesLabel: "â
Yes, delete it"
NoLabel: "â No, keep it"
Yes â [Execute deletion]
No â [Cancel action]
[Screenshot: Confirmation dialog with styled Yes/No buttons]
đ Search Menu (menu.search)â
Let users search through a list and select results.
Configurationâ
| Setting | Description |
|---|---|
| SearchableFields | Which fields to search |
| Items | Data source array |
| ResultTemplate | How to display results |
| MaxResults | Limit displayed results |
Example: User Searchâ
menu.search:
Items: [ ...array of users ]
SearchableFields: ["name", "email"]
ResultTemplate: "{{name}} ({{email}})"
MaxResults: 10
User types: "john"
â
Shows: John Doe (john@example.com)
John Smith (jsmith@example.com)
Use Cases:
- User directory
- Product search
- Content discovery
Toggle Switch (menu.toggle)â
ON/OFF switch for settings.
Configurationâ
| Setting | Description |
|---|---|
| Variable | Which var to toggle |
| OnLabel | Text when ON |
| OffLabel | Text when OFF |
Example: Notifications Settingâ
menu.toggle:
Variable: "var.notifications_enabled"
OnLabel: "đ Notifications ON"
OffLabel: "đ Notifications OFF"
Current state shown with appropriate icon/label
User clicks â Value toggles
đ Dynamic Menu from Data (menu.from_data)â
Generate menu items dynamically from an array or API response.
Configurationâ
| Setting | Description |
|---|---|
| DataSource | Array or object to generate from |
| LabelTemplate | How to format button labels |
| DataTemplate | What to put in callback data |
Example: Category Menu from Databaseâ
[HTTP GET /api/categories]
â Response: [
{ id: 1, name: "Electronics" },
{ id: 2, name: "Clothing" },
{ id: 3, name: "Books" }
]
â
[menu.from_data]
DataSource: (connected to HTTP response)
LabelTemplate: "{{name}}"
DataTemplate: "cat_{{id}}"
â
Generates menu:
đˇī¸ Electronics (callback: cat_1)
đˇī¸ Clothing (callback: cat_2)
đˇī¸ Books (callback: cat_3)
[Screenshot: Dynamic menu generated from API data]
Use Cases:
- Database-driven menus
- Dynamic catalogs
- User-generated content lists
Best Practicesâ
1. Keep Menus Simpleâ
- Max 6-8 buttons per menu
- Use pagination for more
- Clear, concise labels
2. Always Provide "Back"â
menu.show:
AllowBack: true
Each menu connects its Back output to menu.navigate_back
3. Use Wizards for Multi-Stepâ
Don't build complex flows manually â use menu.wizard:
â manual.question â question â question â ...
â
menu.wizard (automatic state, navigation, validation)
4. Icons in Labelsâ
Makes menus more visual:
Items: [
{ label: "đī¸ Shop", data: "shop" },
{ label: "đĻ Orders", data: "orders" },
{ label: "âī¸ Settings", data: "settings" }
]
5. Handle Menu Timeoutâ
[menu.show]
â (after 5 minutes)
[menu.reset]
Message: "Session expired. Returning to main menu."
Common Patternsâ
Pattern 1: Main Menu â Submenusâ
[Main Menu]
ââ products â [Product Categories Menu]
â ââ electronics â [Electronics List]
â ââ clothing â [Clothing List]
ââ support â [Support Menu]
ââ settings â [Settings Menu]
Pattern 2: List â Detail â Actionâ
[Paginated Product List]
â Select Item
â [Product Detail Menu]
ââ Add to Cart
ââ View Specs
ââ â Back to List
Pattern 3: Wizard â Confirmation â Resultâ
[Registration Wizard]
â Collect: name, email, plan
â [Confirmation: "Create account with these details?"]
ââ Yes â [Create Account] â [Success Menu]
ââ No â [Back to Wizard]
Quick Referenceâ
| Node | Use For |
|---|---|
menu.show | Basic choice menus |
menu.wizard | Multi-step forms |
menu.paginated_list | Long lists (products, search) |
menu.router | Hierarchical navigation |
menu.navigate_back | Back button behavior |
menu.reset | Return to main/start |
menu.confirm | Yes/No dialogs |
menu.search | Searchable lists |
menu.toggle | ON/OFF settings |
menu.from_data | Dynamic menus from data |
Next Stepsâ
- Creating a Wizard Tutorial â â Step-by-step wizard example
- Advanced Topics: Menus â â Deep dive into menu patterns
- Flow Control â â Control conversation flow