---
title: "Use Case 2: Branching by choice"
description: "Button menu, separate edges per branch, user_choice variable, and optionally Router by variable."
---

# Use Case 2: Branching by customer choice

**Level:** basic · **Modules:** Scenario Builder · **Nodes:** MessageKeyboard, Router (optional)

> **Before you start:** read [Edge-driven flow](/en/learn/implementer/training/concepts.md#edge-driven-flow) and [Branching: Router / switch](/en/learn/implementer/training/concepts.md#router-branching).

## Required permissions and access

| What you need | Where in the menu | Why |
|---------------|-------------------|-----|
| **Scenario Builder** | Menu → Scenario Builder | Menu, edges, Router |

If a section is missing from the menu — check your account permissions or contact ConnectiveOne support.

## Business context

The bot shows a menu: “Sales”, “Support”, “Other” — and routes the customer into different scenario branches. This is the foundation of most client bots: one entry, several business directions.

## Expected result

- Menu buttons lead to **different branches** of the scenario.
- The choice value is stored in the `user_choice` variable (for Runs and later steps).
- If the customer typed text instead of tapping a button — a clear hint (default).
- Understanding the difference: **edges from buttons** vs **Router by variable** after saving the choice.

## Flow architecture

```text
Start → MessageKeyboard (3 buttons)
   ├─ edge "sales"    → MessageKeyboard (Sales branch)
   ├─ edge "support"  → MessageKeyboard (Support branch)
   ├─ edge "other"    → MessageKeyboard (Other branch)
   └─ edge default / free text → “Choose a menu item”
```

> **Important:** for button menus — a **separate edge for each** MessageKeyboard button. Alternative — a **Router** node (`first_match` + default) after saving the choice in `user_choice`.

## Step-by-step implementation

### Step 1. MessageKeyboard — menu

**Node:** Message with buttons.

| Parameter | Value | Why |
|-----------|-------|-----|
| Text | “Choose a topic:” | Menu |
| Keyboard type | **inline** | Buttons under the message |
| Button 1 | Text: “Sales” · **payload / value:** `sales` | Stable value |
| Button 2 | “Support” · `support` | |
| Button 3 | “Other” · `other` | |
| **Output Variable** | `user_choice` | Saves the choice — check in Runs |

**Edges:**

| Edge | Where | Why |
|------|-------|-----|
| `sales` | MessageKeyboard “You chose Sales…” | Separate branch by button edge |
| `support` | “Support…” | |
| `other` | “Other…” | |
| **Default** | “Tap one of the menu buttons.” | Do not leave the customer without a reply |

---

### Step 2. Three reply branches

**Node:** MessageKeyboard (×3).

| Branch | Text (example) |
|--------|----------------|
| sales | “Sales team. Write what you’re interested in.” |
| support | “Support. Describe the problem.” |
| other | “General questions. How can we help?” |

---

### Step 3. Check in Runs

1. Each button → **its own** branch.
2. In the trace: `user_choice` = `sales` | `support` | `other`.
3. Random text → **default**.

---

### Step 4 (optional). Router — one node by `user_choice`

Instead of three separate edges after the menu, you can build a **Router** (`action_router`):

| Setting | Value |
|---------|-------|
| Mode | `first_match` |
| Rule 1 | `{{user_choice}}` equals `sales` → Sales branch |
| Rule 2 | equals `support` → Support |
| Rule 3 | equals `other` → Other |
| **Default branch** | “Choose a menu item” |

**Alternative:** Action **`switch`** with the same conditions — convenient for JSON scenarios.

> Legacy action **`if_else`** in older bots does the same; in training use **Router** or **`switch`**.

## Acceptance criteria (self-check Runs)

- [ ] Each of the three buttons leads to a **separate** branch.
- [ ] In the trace, `user_choice` matches the tapped button.
- [ ] Free text (not a button) → default edge, customer sees a hint.
- [ ] **Default** edge is connected — no “silence” after arbitrary input.
- [ ] (Optional) Router by `user_choice` gives the same result as separate edges.

## Common mistakes

| Symptom | Cause | What to do |
|---------|-------|------------|
| All buttons lead to one branch | One edge for all buttons | Separate edge per payload |
| `user_choice` empty | Output Variable not set | Enable Output Variable on MessageKeyboard |
| Bot “goes silent” after text | No default edge | Connect default → hint |
| Wrong branch in Router | Comparison with a different value | Match button payloads and Router rules |
| Always default in Router | No default branch | Enable default branch in Router |

## Related documentation

- [Edge-driven flow](/en/learn/implementer/training/concepts.md#edge-driven-flow)
- [Branching: Router / switch](/en/learn/implementer/training/concepts.md#router-branching)
- [Conditional branches (Router)](/en/scenariobuilder/explanation/router-node.md)
- [MessageKeyboard parameters](/en/scenariobuilder/reference/message-keyboard-parameters.md)
- [FAQ — branching](/en/learn/implementer/training/reference/faq.md)
- Next: [Use Case 3 — handoff to operator](/en/learn/implementer/training/basic/use-case-03-handoff-to-operator.md)
