BotreamDocs Website Türkçe v0.1.1

Variables and data types

Variables hold the data a task works with: text read from a page, a number to add up, a list of files, a table from a database, a window or a browser page to act on. This page lists the types, how to declare and fill them, and how tasks pass values to each other.

Declaring a variable

Declare a variable with set, giving its --type and, if you like, an initial value:

set --name:customer --type:string --value:"ACME Ltd"
set --name:total --type:number --value:0
set --name:today --type:datetime --value:now

In the editor, use Add variable in the VARIABLES tab, or New variable in the Insert variable dialog (F2): Botream adds the set command at the top of the task for you.

  • Names start with a letter or _ and contain only letters, digits and _ (orderId, _temp2). When the task runs, names are not case-sensitive.
  • set without --type changes a variable that already exists and keeps its type: set --name:total --value:42.
  • Many commands create variables themselves through --output, and loops through --variable. You do not need to declare those first.

Read a variable by writing its name between dollar signs: $customer$. See Variables in values for fields ($order.Total$), items ($items[0]$), .Count and .Length.

Types

Type Holds Initial value (--value)
string Text Any text; may contain $variables$. Empty when not set
number Whole or decimal number 42, -3.14. 0 when not set
boolean true or false true or false. false when not set
datetime Date and time now, 2026-09-30, 2026-09-30 14:30 or 2026-09-30 14:30:00. The time the command runs when not set
list Ordered items A JSON array: ["a", "b", 3]. Empty when not set
dictionary Key → value pairs A JSON object: {"env": "prod", "retries": 3}. Empty when not set
record One row of named fields A JSON object: {"Name": "Ali", "Age": 30}. Empty when not set
datatable Rows and columns {"columns": ["Name", "Age"], "rows": [["Ali", 30]]}. Empty when not set
file A file path A path, such as C:\In\orders.xlsx
window A desktop window --title and/or --path instead of --value
browser A browser page Filled by browser --action:open --output
credential A user name and password from a vault --vault and --credential instead of --value

Instead of a literal, any initial value can be a single reference to another variable (--value:$other$); it is converted to the declared type when the task runs. The editor checks literals as you type: set --type:number --value:abc is an error.

Text, numbers, booleans and dates

set --name:greeting --type:string --value:"Hello $customer$"
set --name:rate --type:number --value:0.18
set --name:isTest --type:boolean --value:true
set --name:deadline --type:datetime --value:"2026-12-31 17:00"

Numbers use a dot as the decimal separator. Use the string command to convert text: --action:tonumber, --action:todatetime --format:dd.MM.yyyy, --action:toboolean; number --action:tostring and datetime --action:format turn values back into text.

Lists

set --name:countries --type:list --value:["DE", "AT", "CH"]
list --action:add --name:countries --value:FR
log --message:"First: $countries[0]$, total: $countries.Count$"
loop --type:list --list:$countries$ --variable:country
    log --message:$country$
endloop

JSON literals are written without quotes around the whole value, even with spaces inside. References may appear in them: ["$first$", "b"].

Dictionaries and records

Both are written as a JSON object and read with a dot: $config.env$, $person.Name$. A dictionary is a free set of keys; a record is one row of named fields, as loops over Excel rows, data tables, files and queue items give you. Field names are matched without regard to case.

set --name:config --type:dictionary --value:{"env": "prod", "retries": 3}
set --name:person --type:record --value:{"Name": "Ali", "Age": 30}
dictionary --action:addkey --name:config --key:region --value:eu-west
log --message:"$person.Name$ ($person.Age$) on $config.env$"

A key with spaces or other characters cannot follow a dot; read it with getvalue:

dictionary --action:getvalue --name:config --key:"Order No" --output:orderNo

Data tables

A data table has named columns and rows. Write it as columns and rows, or as a list of objects with the same keys:

set --name:people --type:datatable --value:{"columns": ["Name", "Age"], "rows": [["Ali", 30], ["Veli", 25]]}
set --name:prices --type:datatable --value:[{"Item": "Pen", "Price": 1.5}, {"Item": "Pad", "Price": 3}]

Column names must be unique. In the editor, Create table opens a grid with typed columns and Paste from Excel.

  • $people[0].Name$ reads a cell, $people[1]$ a row (a record), $people.Count$ the number of rows.
  • loop --type:datatable --table:$people$ --variable:row runs once per row; read cells as $row.Name$.
  • capture --action:gettable, database --action:query, csv --action:read, excel --action:readrange and json --action:todatatable return data tables.
  • Join, group, look up and total them with the datatable actions; see Joining, grouping and looking up data tables.

Files

A file variable holds a path. loop --type:eachfile gives each file as a record with Name, NameWithoutExtension, Extension, Path, Directory, Size, CreatedDate and ModifiedDate; loop --type:eachfolder gives Name, Path, Parent, FileCount and CreatedDate.

set --name:report --type:file --value:C:\Reports\daily.xlsx
loop --type:eachfile --folder:C:\In --filter:*.pdf --variable:pdf
    log --message:"$pdf.Name$ is $pdf.Size$ bytes"
endloop

Windows

A window variable describes which desktop window commands act on. Declare it with a title and/or a program path; * is a wildcard in both:

set --name:notepad --type:window --path:"C:\Windows\notepad.exe" --title:"*Notepad*"
sendkeys --window:$notepad$ --keys:"Hello[ENTER]"

Or start or attach to a program and receive the window:

window --action:open --path:C:\Apps\erp.exe --output:erp
window --action:attach --title:"*Invoice*" --output:invoiceWindow
window --action:getproperty --window:$erp$ --property:Title --output:erpTitle

window --action:getproperty reads Title, Path, ProcessId, X, Y, Width, Height, IsMinimized, IsMaximized and Handle. In the editor, New next to a window field creates a window variable from one of the windows open on the agent machine. See Desktop automation.

Browser pages

browser --action:open --output:shop opens a browser and puts its page into $shop$; every web command then targets it with --browser:$shop$. Without --browser, a web command uses the page used last.

browser --action:open --url:"https://shop.example.com" --output:shop
capture --browser:$shop$ --action:click --dompath:"#login"

Warning: set --type:browser alone holds no page. The editor warns when a --browser:$page$ variable is never filled by browser --action:open --output. See Web automation.

Credentials

A credential variable reads a user name and password from a vault when the set command runs:

set --name:login --type:credential --vault:Production --credential:PortalUser
capture --browser:$portal$ --action:settext --dompath:"#user" --value:$login.Username$
capture --browser:$portal$ --action:settext --dompath:"#password" --value:$login.Password$

The password is never written to logs: wherever it would appear (log lines, error messages, the error variable of a catch, task outputs) it is replaced with ***. Commands with a --credential parameter (such as mail and restapi) take the whole variable: --credential:$login$; mail also takes the vault and the credential's name directly (--vault:"Mail" --credential:"Robot mailbox"). Whether a run may read a vault depends on the user who started it; see Vaults.

Command outputs

Commands that produce a value write it into the variable named by --output. The type depends on the command:

Command Output
restapi A record: StatusCode, IsSuccess, Body, Json, Headers, ContentType, ElapsedMs, File
capture --action:gettable, database --action:query, csv --action:read, excel --action:readrange, json --action:todatatable, datatable --action:join/groupby/distinct A data table
capture --action:gettext, getproperty, ocr --action:read, clipboard --action:gettext, ai --action:ask Text
browser --action:open / window --action:open, attach A browser page / a window
mail --action:read (each item is what loop --type:mail gives) A list of records: Id, From, FromName, To, Cc, Subject, Date, Body, HtmlBody, IsRead, Attachments
queue --action:next (and loop --type:queue) A record: Found, Id, Reference, Data, Attempt, Priority, Status
pdf --action:getinfo A record: PageCount, Title, Author, …
ocr --action:find A record: Found, Text, X, Y, Width, Height, CenterX, CenterY
mouse --action:getposition A record: X, Y
ai --action:extract / classify A record of the requested fields / Label, Confidence, Reason
messagebox The button chosen: yes, no, ok, cancel or timeout
restapi --action:get --url:"https://api.example.com/orders/$id$" --output:response
if --condition:$response.IsSuccess$
    log --message:"Status $response.StatusCode$ in $response.ElapsedMs$ ms"
endif

See the command reference for every command's output.

Working with variables: string, number, list…

Each variable type has its own command, with only the actions that fit it: string, number, boolean, list, dictionary (also records), datetime and datatable. --name is the variable worked on; in the editor its list shows only variables of that type. With --output the result goes into another variable; without it, the variable is updated in place. Actions that give something else back (a length, true/false, an item) need --output.

number --action:increment --name:count
number --action:increment --name:count --by:5
string --action:uppercase --name:code
string --action:replace --name:text --old:";" --new:"," --output:cleaned
string --action:split --name:line --separator:";" --output:parts
datetime --action:adddays --name:today --value:-1 --output:yesterday
datatable --action:filter --name:orders --column:Total --operator:">" --value:1000 --output:bigOrders
Command Actions
string trim, trimleft, trimright, uppercase, lowercase, titlecase, replace, substring, between, concat, insert, remove, padleft, padright, repeat, reverse, split, length, isempty, isnumber, contains, startswith, endswith, indexof, lastindexof, regex, regexmatch, regexreplace, format, base64encode, base64decode, urlencode, urldecode, hash, tonumber, toboolean, todatetime
number increment, decrement, add, subtract, multiply, divide, modulo, power, min, max, round, floor, ceiling, truncate, abs, sqrt, random, format (e.g. {0:N2}), tostring
boolean toggle, not, and, or, tostring
list add, insert, setat, remove, removeat, clear, getat, count, isempty, contains, indexof, sort, reverse, join
dictionary addkey, removekey, getvalue, containskey, keys, values, count, isempty, clear
datetime now, parse, adddays, addhours, addminutes, addseconds, addmonths, addyears, datediff, getpart, format
datatable addrow, removerow, getrow, getcell, setcell, rowcount, columncount, columns, addcolumn, removecolumn, getcolumn, filter, sort, reverse, isempty, clear, join, distinct, groupby, lookup, aggregate

The command reference lists the parameters of each action. Tasks written with the older all-in-one variable command (variable --action:uppercase …) keep working unchanged; new blocks use the commands above.

Joining, grouping and looking up data tables

Reports and reconciliations — sales per region, invoices matched to payments, employees without a manager — are a few datatable blocks. Each gives a new data table (or a value); without --output the table is replaced.

datatable --action:join --name:orders --with:$customers$ --on:"CustomerId=Id" --type:left --output:ordersWithCustomers
datatable --action:distinct --name:applicants --columns:"Email" --output:uniqueApplicants
datatable --action:groupby --name:sales --columns:"Region" --aggregates:"Total=sum(Amount), Orders=count(), Average=avg(Amount)" --output:summary
datatable --action:addcolumn --name:lines --column:Total --value:=$row.Price$ * $row.Qty$
datatable --action:lookup --name:rates --column:Currency --value:$invoice.Currency$ --return:Rate --default:1 --output:rate
datatable --action:aggregate --name:sales --function:sum --column:Amount --output:totalSales
Action What it gives
join Every row of the table with the matching rows of --with. --on names the column both tables share (CustomerId), or Left=Right when the names differ (Id=CustomerId); several pairs are separated by commas. --type:inner (default) keeps only rows with a match, left every row of the table (empty values where nothing matches), full also the rows of --with that matched nothing. The columns of --with are added; a name that is already taken gets a suffix, e.g. Name_2.
distinct The table without duplicate rows; with --columns only those columns are compared (e.g. the e-mail address). The first row of each is kept.
groupby One row per group of equal --columns values, with the calculations of --aggregates: Name=function(Column), comma separated. Functions: sum, count, avg, min, max, first, last; count() counts the rows of the group. In the editor, Calculations per group is a list: choose the calculation and the column, and the name of the result column.
addcolumn A new column; with --value every row gets a value. A formula is calculated for each row, and $row.Column$ is the value of that row: --value:=$row.Price$ * $row.Qty$, --value:=if($row.Days$ > 30, "Late", "On time"). A value without = is the same for every row (it may still use $row.Column$).
lookup The --return value of the first row whose --column equals --value (like Excel's VLOOKUP), or the whole row as a record when --return is empty. --default is the result when no row matches.
aggregate One number from a column: --function:sum, count, avg, min or max. count without --column counts the rows.

How values are compared: column names ignore case; numbers match numbers also when one is written as text (1 and "1.0"), but codes with leading zeros such as 007 stay text; text ignores case and spaces at the ends; empty values never match in a join. Empty cells are skipped by the calculations; sum and count of nothing are 0, avg, min and max of nothing are empty.

Tip: $row$ in addcolumn --value is the row being calculated, with the table's columns as fields (the formula builder lists them). If the task has its own variable called row, it keeps its value.

In the editor, column fields list the columns the table is known to have — from Create table, the Extract data wizard, or an earlier join or group by — and any other name can be typed. These actions need an agent from this version; an older agent is refused the task with a message asking to update it.

Excel workbooks

The excel command opens a workbook under a session name, and every following excel block (and loop --type:excelrows) uses that name:

excel --action:open --file:"C:\Reports\Sales.xlsx" --session:Sales
excel --action:readrange --session:Sales --output:sales
excel --action:writerange --session:Sales --range:"H1" --data:$summary$
excel --action:close --session:Sales --save:true

readrange gives a data table whose columns are the first row (with --header:false, a list of rows). writerange writes a data table as its column names and its rows, so readrange → datatable blocks → writerange round-trips a sheet.

There are two ways to open a workbook (--engine on open):

Engine What it does
file (default) Reads and writes the .xlsx file directly. Excel does not need to be installed, nothing is shown, and it is the fastest.
excel Works through Microsoft Excel on the agent machine: any file Excel opens (.xlsx, .xlsm, .xls, .xlsb, .csv), formulas calculated by Excel, and four more actions: runmacro, refreshall, exportpdf and autofit. --visible:false works without showing the Excel window.
excel --action:open --file:"C:\Reports\Sales.xlsm" --session:Sales --engine:excel --visible:false
excel --action:refreshall --session:Sales
excel --action:runmacro --session:Sales --macro:"Module1.FormatReport" --args:"2026, 10"
excel --action:autofit --session:Sales --range:"A:F"
excel --action:exportpdf --session:Sales --file:"C:\Reports\Sales.pdf" --scope:workbook
excel --action:close --session:Sales --save:true
  • runmacro runs a VBA macro of the workbook (Module1.FormatReport or just FormatReport); --args passes values to it (a list variable or comma-separated values) and --output receives what a Function returns.
  • refreshall refreshes every data connection, query and pivot table and waits until Excel has finished.
  • exportpdf saves the active sheet (--scope:sheet, the default) or every sheet (--scope:workbook) as a PDF.
  • autofit makes the columns as wide as their contents.

Botream starts its own Excel for each session, turns off Excel's questions (such as "Update links?"), and always closes it again — after close, when the task ends and when it fails — so no Excel is left running in the background. Changes are only saved with save, saveas or close --save:true.

Note: The excel engine needs Microsoft Excel installed on the agent machine and the agent running in a signed-in Windows session. A task with --engine:excel needs an agent from this version. Macros run only when Excel allows them for the file (Trust Center).

Task inputs and outputs

A task can take values from its caller and give values back. Declare them at the top of the task with input and output:

input --name:invoiceNo --type:string
input --name:maxRetries --type:number --default:3 --required:false
output --name:bookingNo --type:string
  • --required (default true): the run fails with "Required input … was not provided" when the caller gives no value and there is no --default.
  • --default is written like set --value.
  • Give an output its value like any other variable, for example set --name:bookingNo --value:$result.Number$.

When you start the task from the editor, the run dialog asks for the inputs under INPUTS, filled in with their defaults.

Calling another task

runtask calls a task by name (or by folder path, such as Finance/Invoices/Import, when several folders have a task of that name). Pass inputs as --<input>:value and receive outputs as --<output>To:variable:

runtask --name:BookInvoice --invoiceNo:$row.InvoiceNo$ --maxRetries:5 --bookingNoTo:booking
log --message:"Booked as $booking$"

The called task runs with its own variables; only the mapped outputs come back. In the properties panel, Choose task picks the task and Mappings lists its inputs and outputs; Auto map fills empty mappings from same-named variables. An error in the called task fails the runtask command, with its type kept (see Error handling).

System variables

Every task has the built-in $System$ without declaring it, like the system variables of other RPA tools. Its fields are read when they are used, so $System.Date$ is always the current time.

log --message:"Started on $System.Machine$ as $System.UserName$ at $System.Hour$:$System.Minute$"
file --action:copy --source:C:\In\report.xlsx --destination:"$System.DesktopFolder$\report-$System.Year$-$System.Month$.xlsx"
Field Type Value
$System.Date$ datetime Now: the current date and time
$System.Year$, Month, Day number The current date (month 1 to 12)
$System.Hour$, Minute, Second, Millisecond number The current time (hour 0 to 23)
$System.DayOfWeek$ string The day of the week in English, such as Monday
$System.Machine$ string The name of the computer the task runs on
$System.UserName$ string The Windows user the agent runs as
$System.Domain$ string The Windows domain (or the computer name when there is none)
$System.OSName$ string The Windows edition and version, such as Windows 11 Pro 24H2
$System.CPUUsage$ number Processor use of the whole computer, in percent (measured over a quarter of a second)
$System.RAMUsage$ number Memory in use, in percent
$System.TotalRAM$, AvailableRAM number Memory of the computer and free memory, in MB
$System.Clipboard$ string The text on the clipboard
$System.TempFolder$, DesktopFolder, DocumentsFolder, DownloadsFolder string Folders of the agent user
$System.TaskName$ string The name of the running task (a called task sees its own name)
$System.ExecutionId$ string The id of the run, as in the execution history
$System.AgentName$ string The name of the agent running the task
$System.NewLine$, Tab string A line break and a tab character

$System$ is read-only, and no variable may be named System. The editor offers its fields after $System..

Global values

Values that many tasks share — a folder, a web address, a limit, a list of recipients — are kept once on the Global values page (Manage global values permission, Developer by default) and read in any task as $Global.Name$:

loop --type:eachfile --folder:$Global.InvoiceFolder$ --filter:*.pdf --variable:file
    if --condition:"$file.Size$ > $Global.MaxFileSize$"
        mail --action:send --to:$Global.SupportMail$ --subject:"Invoice too large: $file.Name$"
    endif
endloop
  • Each value has a name, a type (string, number, boolean, datetime, list, dictionary, record or data table), the value and a description. The value is entered with the same editors as a variable's initial value.
  • A run gets the values of the moment it starts; a change applies to the next runs, without editing or pushing any task.
  • $Global$ is read-only in a task (set --name:Global is refused) and no variable may be named Global. The editor offers the names after $Global..
  • Creating, changing and deleting global values is recorded in the audit log.

Note: Global values are not secret: everyone with Manage global values sees them, and they may appear in logs. Keep passwords and keys in vaults.

The error of a catch

There is no built-in error variable: a catch names the variable that receives the error, such as catch --error:err, and then $err.Message$, $err.Type$, $err.CommandLine$, $err.CommandType$ and $err.Timestamp$ describe it. See Error handling and retries.

Inspecting variables

  • While debugging, the VARIABLES pane shows every variable when the run stops.
  • When a run fails, the execution page shows the variables at the moment of the failure. Passwords are masked in both, and long values are shortened.
Botream 0.1.1 · Generated 2026-10-14