Skip to main content

Building Flows

Overview

The ZappFlux Flow Editor is a visual drag-and-drop builder that lets you create complex, multi-channel chatbot interactions and automation sequences without writing code. Flows are composed of Blocks — individual units of logic, content, or action — connected together to form a conversation path. Architecture:
ZappFlux Editor
└── Canvas (drag-and-drop workspace)
    ├── Blocks (Bubbles, Inputs, Logic, Integrations)
    │   └── Connected via arrows to define flow direction
    ├── Variables (store and reuse data throughout the flow)
    ├── Groups (organize blocks into logical sections)
    └── Publish (make the flow live to end users)
What you can build with flows:
  • AI-powered chatbots for WhatsApp, Web, Instagram, and more
  • Lead capture forms with conditional branching
  • Customer support triage systems with human handoff
  • Appointment booking and scheduling workflows
  • E-commerce assistants with payment collection
  • Onboarding sequences and interactive surveys

Getting Started

Creating a New Flow

  1. Navigate to Dashboard → Tools → ZappFlux → Flows
  2. Click New Flow (or the + button)
  3. Give your flow a name
  4. Choose a starting template or start from blank
  5. The flow editor opens automatically

Editor Layout

AreaDescription
CanvasThe main workspace where you place and connect blocks
Block Panel (left sidebar)The palette of available blocks, organized by category
Properties Panel (right sidebar)Settings and configuration for the currently selected block
Variable PanelAccessible via the {{ shortcut — view and manage all flow variables
Toolbar (top)Zoom controls, undo/redo, preview, and publish button

Canvas Navigation

  • Pan: Click and drag on empty canvas space
  • Zoom: Scroll wheel or pinch gesture (trackpad)
  • Select Block: Click on a block
  • Move Block: Click and drag a block to reposition
  • Connect Blocks: Drag from the output handle (right side) of one block to the input handle (left side) of another
  • Delete Connection: Click on the arrow between blocks and press Delete

Block Types

Blocks are organized into four categories: Bubbles, Inputs, Logic, and Integrations.

💬 Bubbles — Sending Content to Users

Bubble blocks send content to the user. The flow does not pause at these blocks — they execute and immediately move to the next block.

Text

Sends a plain text or formatted message to the user. Properties:
  • Message content (supports Markdown formatting)
  • Variable interpolation using {{variable_name}}
  • Optional typing delay (simulates realistic response time)
Example:
"Hello, {{user_name}}! Welcome to our support chat. 👋"

Image

Displays an image to the user within the conversation. Properties:
  • Image source: Upload a file (PNG, JPG, GIF, WebP) or enter a public URL
  • Alt text for accessibility
  • Optional caption below the image

Video

Embeds a video in the conversation flow. Properties:
  • Supported sources: YouTube, Vimeo, or direct video file URL
  • Autoplay option
  • Video title/caption

Audio

Plays an audio message or clip in the conversation. Properties:
  • Audio source: Upload a file (MP3, WAV, OGG) or enter a URL
  • Displays as a standard audio player widget

Embed

Embeds external web content using an iframe directly inside the flow. Properties:
  • URL to embed (must support iframe embedding)
  • Dimensions (width and height)
  • Useful for embedding calendars, maps, or product pages

📥 Inputs — Collecting Information from Users

Input blocks pause the flow and wait for the user to respond before continuing. The response is automatically stored in a variable for use later in the flow.

Text Input

Captures free-form text from the user. Properties:
  • Placeholder text shown in the input field
  • Variable to store the response
  • Optional character limit
  • Button label (“Send”, “Submit”, or custom text)

Number

Captures a numeric value with optional validation. Properties:
  • Min and max value constraints
  • Error message shown if validation fails
  • Variable to store the response

Email

Captures an email address with automatic format validation. Properties:
  • Built-in email format validation (rejects malformed entries)
  • Custom error message for invalid input
  • Variable to store the response

Phone

Captures a phone number with country code selection. Properties:
  • Country code selector (optional — can be locked to a specific country)
  • Format validation
  • Variable to store the response

Date / Time

Displays a calendar or time picker for the user to select a date and/or time. Properties:
  • Mode: Date only, Time only, or Date + Time
  • Min and max date constraints
  • Variable to store the selected value

Buttons

Presents a set of predefined options for the user to choose from. This is one of the most commonly used input blocks for menu navigation and decision trees. Properties:
  • Up to 10 button options
  • Each button has a label and an optional value (can differ from display label)
  • Multiple vs. single choice mode
  • Variable to store the selected option(s)
Tips:
  • Keep button labels short (under 40 characters) for consistent rendering across channels
  • Use buttons instead of free-text inputs wherever possible to improve data quality and reduce ambiguous responses

Picture Choice

A visual version of Buttons — users select from image-based options. Properties:
  • Each option has an image (upload or URL) and a label
  • Single or multiple selection
  • Variable to store the selection(s)

File Upload

Allows the user to upload a file within the conversation. Properties:
  • Accepted file types (PDF, images, documents, etc.)
  • Max file size limit
  • Variable to store the uploaded file URL

Payment

Collects payment from the user without leaving the conversation. Supported processors:
  • Stripe — Credit/debit cards, Apple Pay, Google Pay
  • PayPal — PayPal balance, linked bank accounts, cards
Properties:
  • Amount (fixed or pulled from a variable)
  • Currency
  • Item name / description
  • Variable to store the payment status and transaction ID
Payment blocks require Stripe or PayPal credentials to be configured in Flow Settings → Integrations before use.

Rating

Collects a rating from the user (star rating or numeric scale). Properties:
  • Rating type: Stars (1–5) or Number (1–10)
  • Optional label per rating value
  • Variable to store the rating

⚡ Logic — Controlling Flow Behavior

Logic blocks control how the flow executes, branches, and processes data. They do not send visible content to the user.

Set Variable

Creates or updates a variable value without user input. Properties:
  • Variable name to set
  • Value: a static value, another variable, or a JavaScript expression
Common uses:
  • Initializing counter variables (set count = 0)
  • Formatting values (set full_name = "{{first_name}} {{last_name}}")
  • Storing timestamps or calculated values

Condition

Branches the flow based on a logical comparison — the ZappFlux equivalent of an If/Else statement. Properties:
  • Left side: a variable
  • Operator: equals, not equals, contains, greater than, less than, is empty, is not empty
  • Right side: a value or another variable
  • Multiple conditions can be chained with AND / OR
Example:
IF {{plan_type}} equals "Pro"
    → Show Pro features path
ELSE
    → Show upgrade prompt path

Redirect

Sends the user to an external URL, ending the flow session. Properties:
  • Target URL (static or built from variables)
  • Open in: same tab or new tab
  • Optional delay before redirect

Script

Executes custom JavaScript within the flow context. Properties:
  • Custom JavaScript code block
  • Access to all flow variables via variables.variable_name
  • Can set variables using setVariable('variable_name', value)
Use cases:
  • Complex string formatting or parsing
  • Math calculations beyond simple expressions
  • Date manipulation and formatting
  • Calling browser APIs (for web flows)
Script blocks execute in a sandboxed environment. Access to external APIs from within a Script block is not supported — use the Webhook block for API calls instead.

Wait

Introduces a time delay before the flow proceeds to the next block. Properties:
  • Duration: seconds, minutes, or hours
  • Optional message displayed to the user during the wait

Jump

Teleports the flow execution to another block within the same flow, or to the start of a different flow (sub-flow). Properties:
  • Target: a specific block ID within the current flow, or an entire other flow
Common uses:
  • Looping back to a menu after a path completes
  • Linking to a reusable sub-flow (e.g., a shared FAQ flow)
  • Creating circular loops for retry logic

Webhook

Makes an HTTP request to an external API or service. Properties:
  • Method: GET, POST, PUT, PATCH, DELETE
  • URL: endpoint to call (supports variable interpolation)
  • Headers: key-value pairs (e.g., Authorization, Content-Type)
  • Body: JSON payload (for POST/PUT/PATCH methods)
  • Response mapping: extract values from the response and store them in variables
Example use cases:
  • Sending lead data to a CRM (HubSpot, Salesforce)
  • Looking up user data from your own database
  • Triggering an order in an e-commerce platform
  • Posting data to a Zapier or Make webhook
Connects this flow to another flow, executing it as a nested sub-flow before returning. Properties:
  • Select the target flow from a dropdown
  • Variable mapping: pass variables from the current flow into the sub-flow
  • After the sub-flow completes, execution returns to the next block in the parent flow

🔌 Integrations — Native Connectors

Integration blocks are pre-built connectors for popular tools and services. They abstract away the complexity of raw webhook calls with purpose-built interfaces.

OpenAI (ChatGPT)

Generates AI-powered responses using the OpenAI API. Properties:
  • Model selection (GPT-5.4, GPT-5.4 Mini, GPT-4o, etc.)
  • System prompt (define the AI’s personality and constraints)
  • User message: the input to send to the model (usually a variable containing the user’s last message)
  • Response variable: where the AI’s reply is stored
  • Advanced: temperature, max tokens, conversation history mode
Common patterns:
  • Pass {{user_message}} to OpenAI and display the response in a Text bubble
  • Use a system prompt to constrain the AI to a specific domain (e.g., “You are a customer service agent for Acme Corp. Only answer questions about our products.”)
  • Enable conversation history mode to maintain context across multiple exchanges

Google Sheets

Reads from or writes to a Google Sheets spreadsheet. Properties:
  • Action: Insert Row, Update Row, Get Row, or Get All Rows
  • Spreadsheet and sheet selection (from your connected Google account)
  • Column mapping: map flow variables to spreadsheet columns
Requires a Google account connected in Flow Settings → Integrations → Google Sheets.

Google Analytics

Sends a custom event to your Google Analytics 4 property. Properties:
  • Event name
  • Custom parameters (key-value pairs, supports variables)
Common events to track:
  • flow_started — when a user begins the flow
  • lead_captured — when contact info is collected
  • payment_completed — when a successful payment is made
  • human_requested — when a user asks for a human agent

Zapier / Make

Triggers a webhook in Zapier or Make.com, connecting your flow to thousands of third-party apps. Properties:
  • Webhook URL (from your Zap or Make scenario)
  • Data payload: select which variables to send

Chatwoot

Transfers the conversation to a human agent in a Chatwoot inbox. Properties:
  • Chatwoot API URL and access token
  • Inbox to assign the conversation to
  • Agent assignment (optional)
  • Custom attributes to pass to Chatwoot

Send Email

Sends a transactional email from within the flow. Properties:
  • From name and email address
  • To address (supports variables)
  • Subject line (supports variables)
  • Body: HTML or plain text (supports variables)
  • Provider: configured SMTP or SendGrid credentials from Flow Settings

ZappWay Actions

Performs actions specific to the ZappWay ecosystem. Available actions:
  • Update the current contact’s variables
  • Assign a conversation to a specific agent
  • Add or remove tags from a contact
  • Trigger a notification to the ZappWay Inbox

Variables

Variables are the memory of your flow. They store information collected from users and data retrieved from integrations, and can be referenced anywhere in your flow.

Using Variables in Text

To insert a variable into any text field, type {{ and select the variable from the autocomplete dropdown:
"Hi {{user_name}}, your order #{{order_id}} has been confirmed!"

Variable Types

TypeExample ValuesNotes
Text”John Smith”, “example@email.comDefault type for most captured data
Number42, 3.14Use Number input blocks for numeric data
Booleantrue, falseSet via conditions or script blocks
List[“option1”, “option2”]Returned by multi-select input blocks

System Variables

ZappWay automatically populates a set of built-in variables for every session:
VariableDescription
{{session_id}}Unique identifier for the current conversation session
{{channel}}The channel the user is on (whatsapp, web, instagram, etc.)
{{current_date}}Current date in ISO format
{{current_time}}Current time in the organization’s timezone

Flow Branching & Conditional Logic

Most real-world flows are not linear — they branch based on user responses and conditions.

Simple Branch (Buttons)

The simplest branching pattern: each Button option connects to a different path.
[Button Block: "What do you need help with?"]
├── "Track my order" → [Order tracking path]
├── "Return a product" → [Returns path]
└── "Speak to a human" → [Chatwoot handoff]

Condition-Based Branch

Use the Condition block when the branch depends on variable values rather than direct button clicks.
[Set Variable: plan = {{selected_plan}}]
[Condition: IF plan equals "Enterprise"]
├── YES → [Enterprise onboarding path]
└── NO  → [Standard onboarding path]

Nested Conditions

Conditions can be chained to handle complex scenarios:
[Condition: IF score >= 8]
├── YES → [Promoter path (NPS)]
└── NO  → [Condition: IF score >= 5]
           ├── YES → [Passive path]
           └── NO  → [Detractor path]

Publishing a Flow

Changes made in the editor are automatically saved as a draft but are not visible to end users until you publish. To publish:
  1. Finish editing your flow
  2. Click Publish in the top-right corner of the editor
  3. Confirm the dialog if prompted
  4. Your flow is now live at its public URL
Publishing a flow immediately makes your changes live for all active users. If you are making significant changes to a flow with active traffic, consider duplicating the flow, editing the copy, and swapping it in when ready.

Preview Mode

Before publishing, test your flow using the built-in Preview feature:
  1. Click the Preview button (play icon) in the toolbar
  2. A live preview of the flow opens in a side panel or new tab
  3. Interact with the flow exactly as an end user would
  4. All blocks execute normally in preview, including integrations
Preview mode does execute real integration actions (e.g., it will write to Google Sheets, send emails, and call webhooks). If you want to test without triggering real actions, temporarily disable integration blocks by right-clicking them and selecting Disable.

Best Practices

1. Start with a Clear Conversation Map Before opening the editor, sketch the conversation on paper or a whiteboard. Define the goal of each path, the data you need to collect, and the possible decision points. Flows built without a plan become unmaintainable quickly. 2. Use Buttons Over Free Text Inputs Whenever the user’s choice can be constrained to a known set of options, use Buttons instead of Text Input. This produces cleaner data, reduces errors, and makes conditional logic simpler. 3. Always Handle the Unexpected Add an “Other” or “Something else” button to any menu, and use Text Input fallbacks for open questions. Users will always say something you didn’t anticipate — make sure the flow handles it gracefully. 4. Name Variables Clearly and Consistently Use descriptive, lowercase, underscore-separated names: user_email not email2 or Email. Consistent naming makes flows easier to maintain and reduces bugs in conditional logic. 5. Test Every Path Before Going Live Use Preview Mode to walk through every branch of your flow, not just the happy path. Specifically test edge cases: empty inputs, invalid emails, very long text responses, and unexpected button clicks. 6. Keep Flows Focused A single flow should accomplish a single goal (lead capture, support triage, order lookup). Use Jump and Typebot Link blocks to modularize complex flows into smaller, reusable sub-flows.
Pro Tip: Use the Script block with console.log(variables) to dump all current variable values during debugging. Open your browser console (F12) while in Preview Mode to see the output in real-time — it’s the fastest way to diagnose why a condition isn’t branching as expected.

Troubleshooting

Issue: Flow Not Responding to User Input

Symptoms:
  • Messages are sent but the flow does not advance
  • Input block appears to be stuck
Solutions:
  1. Verify the input block has a variable assigned — blocks without a target variable may not save responses correctly
  2. Check that the block output is connected to the next block
  3. Preview the flow and check the browser console for errors
  4. Ensure the channel is properly connected in Settings → Channels
  5. Republish the flow after making fixes

Issue: Condition Block Not Branching Correctly

Symptoms:
  • Flow always takes the same branch regardless of the variable value
  • Unexpected behavior in conditional logic
Solutions:
  1. Use the Script block before the condition to log the variable value: console.log(variables.your_variable)
  2. Check for case sensitivity — “Pro” does not equal “pro” in an exact equals comparison; use lowercase consistently
  3. Verify the variable is actually being set before the condition block executes
  4. Check for leading or trailing whitespace in the variable value — use the Script block to trim it: setVariable('plan', variables.plan.trim())

Issue: Webhook Block Returns an Error

Symptoms:
  • Webhook block shows a red error indicator
  • Integration data is not being sent or received
Solutions:
  1. Click the Webhook block to view the response in the properties panel — check the HTTP status code and error message
  2. Verify the URL is correct and accessible from the internet
  3. Check that required headers (e.g., Authorization: Bearer your_token) are included
  4. Validate the JSON body structure using a tool like JSONLint
  5. Test the webhook endpoint independently using Postman or curl before adding it to the flow

Issue: OpenAI Block Not Generating Responses

Symptoms:
  • AI block appears to hang or returns empty responses
  • “Invalid API key” error in the block
Solutions:
  1. Verify the OpenAI API key is correctly saved in Flow Settings → Integrations → OpenAI
  2. Check your OpenAI account for billing issues — a depleted quota causes all API calls to fail
  3. Ensure the model selected in the block is available on your OpenAI plan
  4. Check that the user message input variable is not empty when the block executes

Support

Need help building flows? Contact ZappWay Support:
  • Email: support@zappway.ai
  • Include: Flow name, screenshots of the blocks in question, and a description of the expected vs. actual behavior
Provide These Details When Reporting Issues:
  • Which block type is causing the issue
  • The channel you are testing on
  • Whether the issue occurs in Preview Mode, live, or both
  • Any error messages shown in the block or browser console
Additional Resources:
Last Updated: March 2026 Platform: ZappFlux Flow Builder | ZappWay Dashboard