LUA Basics

Lua Basics

Flow Builder advanced actions are written in Lua, an easy-to-learn scripting language. The Lua documentation itself is at, although it's not all that approachable. This intro should help you with enough to get going.


There are two ways to print in the Advanced Actions. The standard Lua print is good to know, and this will probably print to Flow Builder in future versions. Debug.print prints to the channel (WhatsApp, for instance.)

print("Hello World") -- regular print in Lua (not available in Flow Builder yet)
Debug.print("Hello world") -- send this message to a channel


Comments in Lua are a bit different from other programming languages, and start with a --

--this is a comment
print("hello") --this is another comment
-- the next line will not do anything because it is commented out


Lua has the usual types such as numbers and strings. The word local at the beginning is not strictly necessary but is recommended in order to help Flow Builder understand the program. An important data type is nil, which represents "no value".

local x = 10 --number
local name = "john doe" --string
local isAlive = false -- boolean
local a = nil --no value or invalid value


For numbers, math operators are as follows:

  • + addition
  • - minus
  • * multiply
  • / divide
  • ^ power
  • % modulus
-- examples
local a = 1
local b = 2
local c = a + b
print(c) -- 3

local d = b - a
print(d) -- 1

local x =  1 * 3 * 4 -- 12

local y = (1+3) * 2 -- 8

print(10/2) -- 5
print (2^2) -- 4
print(5%2) -- 1

print(-b) -- -2
ℹ️ local level = 1 level = level + 1 print(level) -- 2

String concatenation is with two dots (..).

-- concatenate strings
local phrase = "My name is "
local name = "John Doe"
print(phase .. name) -- My name is John Doe

-- strings and numbers
local age = 12
local name = "Billy"
print(name .. " is " .. age .. " years old") -- Billy is 12 years old


Booleans are used for yes/no values.

local isAlive = true
print(isAlive) --true
isAlive = false
print(isAlive) --false

Conditional statements

A conditional statement is for splitting up the execution depending on a condition. A conditional statement looks at a condition (a block of text) between if and then, and executes the following block of text until the end word only if that condition is true. It's easier to see how it works by looking at an example.

--number comparisions
local age = 10
if age < 18 then
  print("over 18") --this will not be executed

--elseif and else
age = 20
if age > 18 then
elseif age == 18 then

Comparison operators

To see if two things (strings, numbers, etc.) are equal, you use ==. (Not =!) To if they are not equal, you use ~=.

  • == equality
  • < less than
  • > greater than
  • <= less than or equal to
  • >= greater than or equal to
  • ~= inequality

Combining statements

Statements can be combined by using and:

local x = 10
if x == 10 and x < 0 then --both are true
elseif x == 100 or x < 0 then --1 or more are true

Nested statements

You can have one if statement inside another if statement:

local x = 10
local isAlive = true
if x==10 then
  if isAlive == true then

Invert value

You can invert the logic of the match by using not:

local x = 10
if not x == 10 then


You can group your code into functions in Flow Builder. However, functions can at the moment only be used within the same action, and are not re-usable across the rest of the Flow. (This might change.)

function printTax(price)
  local tax = price * 0.21
  print("tax:" .. tax)


Functions may return values that you can use in other calculations.

--function that returns a value
function calculateTax(price)
  return price * 0.21

local result = calculateTax(100)

--reusing the function but this time using variables
local bread = 130
local milk = 110

local breadTax = calculateTax(bread) --27.3
local milkTax = calculateTax(milk) --23.1

print("Bread Tax = " .. breadTax) 
print("Milk Tax = " .. milkTax)

Functions may take multiple parameters. They can only have one return value. (Although you can always return a table of values - see "tables" below.)

--multiple parameters
function displayInfo(name, age, country)
  print(name .. " is " .. age .. " years old and is from " .. country)

displayInfo("Billy", 12, "Jupiter")

Variable scope

Variables are only valid inside the block where they are declared. In this case, the variable "a" is only available inside the function. Once outside the function, its value is lost. (We say that it's no longer "in scope")

function foo()
  local a = 10

print(a) --nil


A table is a list-like structure, which we can use to store information. To access a particular item in a table, we use square brackets with the element index (the item number from left to right) as shown in the following example. The number of elements in a list is available by using the # symbol next to the table name.

ℹ️ **Lua is 1-indexed** Unlike in other programming languages, element indices start at 1.
--basic table
local colors = { "red", "green", "blue" }

print(colors[1]) --red
print(colors[2]) --green
print(colors[3]) --blue

--using a loop to iterate though your table
for i=1, #colors do

We can insert values at the end of a table using insert

local colors = { "red", "green", "blue" }
table.insert(colors, "orange")
local index = #colors --4 (this is the last index in the table)
print(colors[index]) --orange

If we give insert a number as the second argument, this number is stored at a specific position in the list.

--insert at index
local colors = { "red", "green", "blue" }
table.insert(colors, 2, "pink")
for i=1, #colors do
--red, pink, green, blue
local colors = { "red", "green", "blue" }
table.remove(colors, 1)
for i=1, #colors do
-- "green", "blue"

Key tables

A key table is like a dictionary that helps you store things by name and then retrieve them later.

local teams = {
    ["teamA"] = 12,
    ["teamB"] = 15

print(teams["teamA"]) -- 12

for key,value in pairs(teams) do
  print(key .. ":" .. value)

Insert an item into a key table

--insert into key table
teams["teamC"] = 1
--remove key from table
teams["teamA"] = nil
function getTeamScores()
  local scores = {
    ["teamA"] = 12,
    ["teamB"] = 15
  return scores

local scores = getTeamScores()
local total = 0
for key, val in pairs(scores) do
  total += val
print("Total score of all teams:" .. total)


Math is available using the math module, which is built into Flow Builder.

abs (absolute value)

local x = -10
print(math.abs(x)) --result: 10
local a = 10
print(math.abs(a)) --result: 10

ceil (round up a decimal value)

local x = 1.2
print(math.ceil(x)) --result: 2

floor (round down a decimal value)

local x = 1.2
print(math.floor(x)) --result: 1

pi (the constant)

print(math.pi) --3.1415926535898

random (random number generation)

--random value between 0 and 1
print(math.random()) --result: 0.0012512588885159

--random integer value from 1 to 100 (both inclusive)
print(math.random(100)) --result: 20

--random integer value from 20 to 100 (both inclusive)
print(math.random(20, 100)) --result: 54

sqrt (square root)

print(math.sqrt(100)) --result: 10