Basis pengetahuan GetMyBot

Formulas

Two formula languages: short {{= }} expressions and the advanced formula with functions and Russian aliases, the Compute action, and the tester.

Di halaman ini

GetMyBot has two formula languages, each with its own place:

  • Expressions: a short language for arithmetic, comparisons, and simple strings. It works in {{= expression}} directly in text, in the "Formula" mode of the "Compute" action, and in decision-table conditions.
  • Advanced formula: the full spreadsheet-style language with dozens of functions (lists, JSON, dates, hashes, LAMBDA) and Russian function name aliases. It works in the "Advanced formula" mode of the "Compute" action, in answer validation by formula, and in the tester.

Advanced-formula functions do not work inside {{= }}: {{= ROUND(total) }} is not evaluated and the construct stays in the text as is. For such calculations, compute the value with the "Compute" action and insert the result with {{ctx.key}}.

Where formulas work

WhereLanguage
{{= expression}} in message textexpressions
"Compute", "Formula" mode (expr)expressions
"Compute", "Decision table" mode (rules)expressions in "when" conditions; "then" and the default value are plain text with {{...}} substitutions
"Compute", "Advanced formula" mode (formula)advanced formula
Answer validation "Matches formula"advanced formula
Formula tester (test_formula)advanced formula

The "Compute" action

The action has three modes, and exactly one is used per action:

  • Formula (expr): a single expression.
  • Decision table (rules + default): a list of "when → then" rules. The value of the first rule whose condition is true is returned, otherwise the default value.
  • Advanced formula (formula): a formula in the full language.

The result is saved to ctx (the "Save to ctx" field, save_to_ctx) and/or to a subscriber parameter ("Save to parameter", save_to_param): at least one is required. Limits: an expression, a rule condition, and a rule value up to 4096 bytes each, an advanced formula up to 16384 bytes (a Cyrillic letter takes 2 bytes), at most 64 rules.

Example action parameters with an advanced formula:

{"type":"compute","params":{"formula":"IF({total} > 1000; \"wholesale\"; \"retail\")","save_to_ctx":"segment"}}

Expressions

Syntax

  • Operators: arithmetic + - * / %, comparisons == != < > <= >=, logic && || !, ternary condition ? yes : no, parentheses ( ).
  • Literals: numbers (42, 3.14), quoted strings ("hello" or 'hello'), booleans (true, false).
  • Data: a name is written without braces and is looked up in subscriber parameters and ctx: price * qty, ctx.total, param.total. An unknown name yields an empty string.
  • Function call: name(argument1, argument2), arguments separated by commas.

Functions

Only these, and only in lowercase: len, upper, lower, trim, concat, round, floor, ceil, abs, min, max. min and max take exactly two arguments, concat takes any number. len and LEN in an advanced formula count characters the way a reader sees them: an accented letter, a flag or an emoji built from several code points (for example, the family 👨‍👩‍👧‍👦) is one character.

Expressions have no Russian aliases. If {{= }} contains an unknown function, the construct stays in the text unchanged.

Advanced formula

Syntax

  • Arguments are separated by semicolons: IF({total} > 1000; "wholesale"; "retail").
  • Operators: arithmetic + - * /, string concatenation &, comparisons = != <> < > <= >= (equality is a single =). Logic is done with the AND, OR, and NOT functions.
  • Strings go in double or single quotes. "" inside a string is not an escaped quote: if you need a quote inside the text (for example, in an HTML attribute), use the other kind of quotes: "<a href='tg://user?id=" & r.user_id & "'>profile</a>".
  • Data is substituted in single braces: {key} is a value from ctx (and {text} or {answer} is the incoming message text), {user:key} is a subscriber parameter, {global:key} is a bot-wide global parameter.
  • LAMBDA: LAMBDA(r; expression) defines a function for FILTER, FOREACH, ARRAYFIND, and REDUCE. JSON object fields are read with a dot: r.user_id.
  • The result is converted to text. Store a list with TOJSON and read it back in the next formula with FROMJSON.
  • Function names are case-insensitive and understand Russian aliases.

Functions

Names are given in their canonical (English) form. Many functions also accept a Russian alias; case is not significant. These functions are available only in the advanced formula.

Math

SUM, AVERAGE, MAX, MIN, MOD, POW, SQRT, PI, ROUND, CEIL, FLOOR, TRUNC, ABS, RANDBETWEEN.

Text

LEN, LEFT, RIGHT, MID, LOWER, UPPER, UPPERFIRST, REPEAT, CONCAT, SUBSTITUTE, FIND, SEARCH, FIELD, TRIM, LTRIM, RTRIM, PADLEFT, PADRIGHT, SPLIT, JOIN, STARTSWITH, ENDSWITH, CONTAINS, NL.

Logic

IF, AND, OR, NOT, EMPTY, ISNUMBER, COALESCE.

Lists

SORT, RSORT, UNIQUE, FILTER, FOREACH, REDUCE, INDEX, SLICE, COUNTA, COUNTUNIQUE, ARRAYADD, ARRAYREMOVE, ARRAYREPLACE, ARRAYFIND.

Date and time

TODAY, NOW, DATEADD, DATESUB, DATEDIF, DATEFORMAT, DATEVALUE, WEEKDAY.

JSON

TOJSON, FROMJSON, JSONPATH, JP, JSONOBJECT, JSONARRAY, KEYS, VALUES.

Cryptography and encoding

HASH, TOBASE64, FROMBASE64, FROMJWT, FROMJWK.

Parameters

PARAMID, PARAMREPLACE, PARAMREMOVE.

Examples

Expressions in text:

  • Order total: {{= price * qty}}.
  • A third of the total, rounded: {{= round(total / 3)}}.
  • Condition: {{= param.total > 1000 ? "wholesale" : "retail"}}.
  • String assembly: {{= concat("Order #", ctx.order_id)}}.

Advanced formula in the "Compute" action:

  • 10% discount: ROUND({user:total} * 0.9).
  • Size of a list from ctx: COUNTA(FROMJSON({items})).
  • A stable pseudo-random order of the records that the "Find records" action put into ctx under the rows key: the order stays the same between runs until you change the "salt".
{"type":"compute","params":{"formula":"TOJSON(SORT(FOREACH(FROMJSON({rows}); LAMBDA(r; HASH(\"sha256\"; r.user_id & \"-salt\") & \"|\" & r.user_id))))","save_to_ctx":"order"}}

Answer validation "Matches formula": the formula returns the error text, and an empty result means the answer is accepted. For example, IF(ISNUMBER({answer}); ""; "Enter a number").

Formula tester

The tester checks an advanced formula and returns the result or a syntax error without saving anything:

  • in the editor: in the "Matches formula" answer-validation block, enter a sample in the "Sample answer" field and click "Test";
  • via the API: POST /api/bots/{botID}/reactions/test-formula with the body {"formula": "…", "sample_text": "…"};
  • via MCP: the test_formula tool with the bot_id, formula, and sample fields.

Response: ok (the formula evaluated), result, error, and matches (true when the result is empty, i.e. the answer would pass validation).

The formula is evaluated in an empty context: ctx, subscriber parameters, and global parameters are empty, so {key} and {user:key} yield an empty string. Only the sample text is available: {text}, {answer}, or {received_message}. Expressions ({{= }}, the "Formula" mode, decision tables) are not checked by the tester.

What's next