# JavaScript API

Кілька блоків чат-бота виконують ваш код на JavaScript. Код рахує, розбирає відповіді сторонніх сервісів, змінює змінні й теги контакту, надсилає повідомлення і вирішує, куди сценарію йти далі. Цей розділ — довідник для того, хто пише такий код.

## Де виконується код

| Де | Коли запускається код | Що йому доступно, крім функцій |
|---|---|---|
| Блок [«Інтерпретатор JavaScript»](https://support.watbot.org/uk/chatbots/blocks/developer/javascript) | Контакт дійшов до блоку | Дані контакту |
| Блок [«HTTP-запит»](https://support.watbot.org/uk/chatbots/blocks/developer/http), поле «Опрацювати відповідь за допомогою JavaScript» | Сервер відповів на запит | Дані контакту й відповідь сервера `response` |
| Блок [«Вхідний Webhook»](https://support.watbot.org/uk/chatbots/blocks/developer/incoming-webhook) | На адресу блоку надійшов запит | Запит `request`, а дані контакту — після того, як код його знайде |
| Блок [«Читання записів з Google Таблиці»](https://support.watbot.org/uk/chatbots/blocks/lists/google-sheet-reader), поле «JavaScript для обробки таблиці» | Блок знайшов рядки в таблиці | Дані контакту й знайдені рядки `sheet.data` |

Що лежить у цих даних — на сторінці [«Вбудовані змінні»](https://support.watbot.org/uk/api/javascript/builtins). Функції однакові в усіх блоках:

| Сторінка | Функції |
|---|---|
| [Змінні](https://support.watbot.org/uk/api/javascript/variables) | `getContactVariable`, `setContactVariable`, `deleteContactVariable`, `getGlobalVariable`, `setGlobalVariable`, `deleteGlobalVariable` |
| [Теги](https://support.watbot.org/uk/api/javascript/tags) | `getContactTags`, `hasContactTag`, `setContactTag`, `deleteContactTag` |
| [Повідомлення й переходи](https://support.watbot.org/uk/api/javascript/messages) | `sendMessage`, `goToBlock`, `disableContinue` |
| [Вибір контакту](https://support.watbot.org/uk/api/javascript/contact) | `setContactById` та інші — лише в блоці «Вхідний Webhook» |
| [Підписи й Base64](https://support.watbot.org/uk/api/javascript/crypto) | `hash_hmac`, `base64_encode`, `base64_decode` |

## Як виконується код

1. Код виконується повністю на окремому сервері. Функції не змінюють контакт одразу, а запам'ятовують, що зробити: які змінні й теги записати, які повідомлення надіслати, до якого блоку перейти.
2. Код завершився без помилки — бот записує змінні й теги контакту та глобальні змінні бота, потім у порядку викликів надсилає повідомлення й переводить контакт у блок із `goToBlock`. Після цього спрацьовує зв'язок «Продовжити», якщо код його не вимкнув.
3. Код завершився з помилкою — не застосовується нічого, навіть те, що код встиг викликати до помилки.

Усередині одного запуску функції читання вже бачать те, що код записав раніше: після `setContactVariable('букет', 'Троянди')` виклик `getContactVariable('букет')` поверне `'Троянди'`, хоча контакту змінну ще не записано.

Код запускається наново під час кожного проходу через блок. Звичайні змінні JavaScript (`var`) між запусками не зберігаються — те, що треба запам'ятати, записуйте в змінні контакту або в глобальні змінні бота.

## Мова

Код виконується як JavaScript стандарту ES5. З новіших стандартів немає:

- `let` і `const` — оголошуйте змінні через `var`;
- стрілкових функцій — пишіть `function (x) { return x * 2; }`;
- шаблонних рядків у зворотних лапках — з'єднуйте рядки через `+`;
- класів, деструктуризації, `Promise`, `async`/`await`, `setTimeout`;
- методів із новіших стандартів: `includes`, `startsWith`, `padStart`, `find`, `Object.assign`, `Array.from` і подібних. Замість `includes` і `startsWith` підійде `indexOf`.

Є все з ES5: `JSON.parse` і `JSON.stringify`, `Math`, `Date`, методи рядків і масивів `split`, `replace`, `trim`, `map`, `filter`, `forEach`, `reduce`, `indexOf`, `sort`. Директива `'use strict'` не заважає, але суворого режиму не вмикає.

Запитів у мережу з коду зробити не можна: `fetch`, `XMLHttpRequest` і `require` недоступні. Для запитів є блок «HTTP-запит».

### Дати

`Date` рахує час у часовому поясі сервера, тому для розрахунків беріть методи з `UTC`: `getUTCHours()`, `getUTCDate()`. Рядок вигляду `2026-01-31 12:00:00` (так виглядає `created_at`) `Date` не розбирає — замініть пробіл на `T` і додайте `Z`:

```js
var created = new Date(created_at.replace(' ', 'T') + 'Z');
var days = Math.floor((new Date() - created) / 86400000);
```

### Регулярні вирази

Регулярні вирази виконуються рушієм RE2, і частина можливостей JavaScript у ньому не працює. Код із таким записом зупиниться з помилкою `Invalid regular expression`:

| Запис | Що це |
|---|---|
| `(?=...)`, `(?!...)` | Перегляд уперед |
| `(?<=...)`, `(?<!...)` | Перегляд назад |
| `\1`, `\2` | Зворотні посилання на групу |

`\w`, `\b` і `\d` розуміють лише латиницю й цифри: `/\w+/` не знайде слово «троянди». Для українських літер перелічіть їх явно: `/[а-щьюяґєії']+/i`.

## Обмеження

| Що | Межа |
|---|---|
| Довжина коду | 16 384 символи в кожному полі з кодом |
| Час виконання | 5 секунд. Код, який не вклався, зупиняється з помилкою `Script execution time exceeded` |
| `sendMessage` | 10 повідомлень за запуск |
| `goToBlock` | Один виклик за запуск |
| Функції вибору контакту | Один виклик за запит, лише в блоці «Вхідний Webhook» |

## Помилки й налагодження

Що сталося під час запуску, видно в розділі «Лог виконання» в налаштуваннях блоку: вихідний код, значення останнього виразу, виконані дії й текст помилки.

Значення останнього виразу — головний інструмент налагодження. Допишіть у кінець коду ім'я змінної або вираз, і його значення потрапить у лог. Об'єкт чи масив спершу перетворіть на рядок, інакше в логу буде `[object Object]`:

```js
var bouquet = { name: 'Троянди', count: 7 };
JSON.stringify(bouquet);
```

`console.log` помилки не спричиняє, але в лог нічого не пише.

Куди йде помилка, залежить від блоку:

| Блок | Що відбувається в разі помилки |
|---|---|
| «Інтерпретатор JavaScript» | Текст помилки йде контакту в чат, зв'язок «Продовжити» спрацьовує |
| «HTTP-запит» | Текст помилки йде контакту в чат, зв'язок «Продовжити» не спрацьовує |
| «Читання записів з Google Таблиці» | Текст помилки йде контакту в чат, зв'язок «Продовжити» не спрацьовує |
| «Вхідний Webhook» | Контакту нічого не надходить, блок відповідає на запит кодом `422` з текстом помилки |

У тексті синтаксичної помилки номер рядка на одиницю більший, ніж у редакторі: помилка `Line 4:5 Unexpected identifier` означає четвертий рядок мінус один — третій.

Помилку можна спричинити й навмисно — `throw new Error('Немає ціни')` зупинить код, і нічого зі зробленого ним не збережеться. У блоках, які надсилають текст помилки в чат, контакт побачить `Error: Немає ціни`.

> [!TIP]
> Перевіряйте код у попередньому перегляді бота — кнопка «Перевірити бота» в конструкторі. Так помилку побачите ви, а не ваші клієнти.
