> For the complete documentation index, see [llms.txt](https://docs.fstrk.io/knowledge_base/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fstrk.io/knowledge_base/instructions/old/vizualnyi-konstruktor-chat-botov/konstruktor/rabota-s-procedurami.md).

# Работа с процедурами

* [Что такое процедура?](https://fasttrack-docs.atlassian.net/wiki/spaces/developers/pages/2968125441#%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D0%B4%D1%83%D1%80%D0%B0%3F)
* [Порядок обработки кода](https://fasttrack-docs.atlassian.net/wiki/spaces/developers/pages/2968125441#%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA-%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B8-%D0%BA%D0%BE%D0%B4%D0%B0)
* [Блокирующие и неблокирующие команды](https://fasttrack-docs.atlassian.net/wiki/spaces/developers/pages/2968125441#%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B8%D0%B5-%D0%B8-%D0%BD%D0%B5%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%8B)
* [Понимание работы блока процедуры «под капотом»](https://fasttrack-docs.atlassian.net/wiki/spaces/developers/pages/2968125441#%D0%9F%D0%BE%D0%BD%D0%B8%D0%BC%D0%B0%D0%BD%D0%B8%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B-%D0%B1%D0%BB%D0%BE%D0%BA%D0%B0-%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D0%B4%D1%83%D1%80%D1%8B-%C2%AB%D0%BF%D0%BE%D0%B4-%D0%BA%D0%B0%D0%BF%D0%BE%D1%82%D0%BE%D0%BC%C2%BB)

### Что такое процедура?

Процедура — это блок кода, который всегда выполняется **после** HTTP запроса при переходе (вызове) узла. Поддерживаются все кастомные и стандартные Django теги и фильтры.

> **Примечание:** Все доступные и часто-используемые теги и фильтры описаны в этих разделах:

* Совместимость с Django Template Language (DTL)
* Теги и фильтры интеграционного слоя

Данный блок может определять дальнейшее поведение в боте:

* Преобразовать данные, полученные узлом в результате HTTP запроса;
* Обработать пользовательский ввод;
* Направить пользователя в другой узел;
* Выполнить проверку для ручного сценария автоматики в чат-центре;
* Сформировать и отправить сообщение пользователю;
* Сохранить входящий контекст из переданных GET-параметров в пользовательские переменные;
* И так далее.

<figure><img src="/files/q2qRx6zTPUawUcCI9dpr" alt=""><figcaption></figcaption></figure>

### Порядок обработки кода

Сначала код проходит через шаблонизатор, все теги превращаются в список внутренних команд.

1. Обработчик идет по списку команд сверху вниз и выполняет их;
2. *Неблокирующие* команды выполняются, не останавливая обработку кода;
3. Первая встреченная *блокирующая* команда останавливает обработку, а все последующие команды, и *блокирующие* и *неблокирующие*, не будут обработаны;
4. Если во время обработки кода не встретилась ни одна *блокирующая* команда, то обработчик останавливается и показывает пользователю контент узла.

### Блокирующие и неблокирующие команды

Команды делятся на блокирующие и неблокирующие.

* **Блокирующие команды возвращают контент:** кнопки, сообщения, карточки и пр. Это команды переключения на узел, входа в анкету, входа во FlexCMS, входа в чат с оператором. Когда обработчик встречает блокирующую команду, он останавливается и не обрабатывает все последующие команды, потому что контент уже получен в ходе выполнения блокирующей команды.
* **Неблокирующие команды** выполняют внутренние преобразования и **не возвращают контент**. Это установка и снятие cookie, сохранение переменных, отправка уведомлений администратору бота и пр. Поскольку они не возвращают контент, обработчик не останавливается на них и идет дальше, пока не встретит блокирующую команду (или пока не закончится весь код, и тогда будет отображен контент узла).

### Понимание работы блока процедуры «под капотом»

Рассмотрим поведение платформы при работе с процедурой на простом примере.

Пускай переменная `morning` существует и ее значение равно `True`. Тогда вот такой код, размещенный в интеграционном слое в блоке «Процедура»:

```
{% if morning %}
  {% send_text "Доброе утро, добрый мир!" %}
{% else %}
  {% send_text "Доброй ночи, добрый мир!" %}
  {% switch "Главное меню" %}
  {% send_text "Ты спишь?" %}
{% endif %}
```

будет преобразован во внутреннюю команду:

```
/send_text/Доброе утро, добрый мир!/
```

**— Как это получилось? Все просто!**

1. В ходе шаблонизации было выполнено условие `if`, так как переменная `morning` существует, поэтому тег `send_text` превратился во внутреннюю команду.
2. Далее, была исполнена команда `/send_text/Доброе утро, добрый мир!/`, а так как это *неблокирующая* команда, то после ее исполнения — отобразится контент узла.
3. При этом, пользователь получит тот контент, который был настроен в узле с предварительным сообщением «*Доброе утро, добрый мир!*» из процедуры.

В то же время, если мы допустим, что переменная `morning` **не** существует или ее значение равно `False`, то вот такой код, размещенный в интеграционном слое в блоке «Процедура»:

```
{% if morning %}
  {% send_text "Доброе утро, добрый мир!" %}
{% else %}
  {% send_text "Доброй ночи, добрый мир!" %}
  {% switch "Главное меню" %}
  {% send_text "Ты спишь?" %}
{% endif %}
```

будет преобразован во внутренние команды:

```
/send_text/Доброй ночи, добрый мир!/
/switch/Главное меню/
/send_text/Ты спишь?/

```

**— А такое как получилось? Так же, очень просто!**

1. В ходе шаблонизации не было выполнено условие `if`, так как переменной `morning` нет, и сработало обратное условие `else`.
2. Теги `switch` и `send_text` превратились во внутренние команды.
3. Далее, была исполнена *неблокирующая* команда `/send_text/Доброй ночи, добрый мир!/`, а сразу же после нее — *блокирующая* `/switch/Главное меню/`.
4. При этом, пользователь не получит контент текущего узла и сообщение «Ты спишь?», так как будет сразу же перенаправлен в узел «Главное меню», благодаря команде `switch`.

> **Примечание:** На платформе разрешено совершать **не более 10** переключений подряд, чтобы пользователь не вошел в рекурсию и не было проблем с производительностью бота для остальных пользователей.
