> For the complete documentation index, see [llms.txt](https://doc.nextbot.ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.nextbot.ru/functional/functions/sending-result/python-v.2.md).

# Python v.2

Скрипт, как и раньше, получает входные данные через `args`, а результат работы передаёт через переменную `result`, но теперь код стал ближе к обычному Python и лучше подходит для написания и поддержки пользовательских скриптов.

\
Основные изменения:

* Убраны дополнительные ограничения на импорт;
* Для логов можно использовать `print(...)`;
* Добавлена возможность генерировать и редактировать Python Script с помощью ИИ (подробнее по [ссылке](/functional/functions/sending-result/python-v.2/generaciya-koda-s-ii.md));
* Скрипт может выполнять действия внутри Nextbot, а не только возвращать текстовый результат ([подробнее](#undefined-4));
* Добавлена инструкция для ИИ при работе с генерацией кода (подробнее по [ссылке](/functional/functions/sending-result/python-v.2/instrukciya-dlya-ai-assistenta.md)).

Скрипт позволяет:

* обращаться к внешним API через библиотеку requests;
* читать данные диалога, заявки и пользовательские переменные;
* управлять диалогом: отправлять сообщения, ставить на паузу, переключать агентов, уведомлять администратора и многое другое;
* изменять переменные и поля формы сбора данных ([ссылка](/functional/functions/sending-result/forma-personalnykh-dannykh.md) на документацию по форме сбора данных, [ссылка](/functional/setting-up-agent.md#polzovatelskie-peremennye) на документацию по переменным).

### Где подключается скрипт <a href="#undefined" id="undefined"></a>

Скрипт можно подключить в трёх контекстах:

| Контекст             | Где настраивается       | Когда вызывается                   |
| -------------------- | ----------------------- | ---------------------------------- |
| `function`           | Действие функции агента | Когда LLM вызывает tool            |
| `scenario`           | Шаг сценария            | При срабатывании триггера сценария |
| `personal_data_form` | Обработка формы данных  | При отправке формы пользователем   |

### Что доступно <a href="#undefined" id="undefined"></a>

В среде выполнения доступны стандартная библиотека Python и следующие внешние пакеты:

* `requests`
* `jsonpath-ng`
* `python-dateutil`
* `pytz`
* `jsonschema`
* `supabase==1.2.0`
* `gspread==5.12.0`
* `oauth2client==4.1.3`

{% hint style="info" %}

### Подключение сторонних библиотек по согласованию (напишите в тех поддержку)

{% endhint %}

### Как импортировать модули

Если Вам нужен модуль, импортируйте его стандартным способом:

```python
import requests
import json
import re
from datetime import datetime, timezone
```

\
Состав полей в `args` зависит от:

* канала связи;
* подключённых интеграций;
* контекста вызова скрипта;

Для безопасного чтения всегда используйте `args.get("ключ")`.

```
name = args.get("name")
city = args.get("city") or "Москва"
```

{% hint style="warning" %}
Всегда используйте args.get(...), а не args\["ключ"].
{% endhint %}

### Пользовательские переменные <a href="#undefined" id="undefined"></a>

Пользовательские переменные доступны в `args.get("variables")`.

```
variables = args.get("variables") or {}
agent_vars = variables.get("agent") or {}
dialog_vars = variables.get("dialog") or {}

lead_score = dialog_vars.get("lead_score") or 0
client_name = dialog_vars.get("ClientName") or ""
```

### Данные формы <a href="#undefined" id="undefined"></a>

Раздел актуален только для контекста `personal_data_form`.

```
form = dict(args.get("form_data") or {})
phone = form.get("phone")
email = form.get("email")
```

### Обязательная переменная `result` <a href="#result" id="result"></a>

Для корректной работы скрипта, рекомендуем присвоить переменную `result` на каждой ветке выполнения.

### Список доступных действий внутри Nextbot <a href="#undefined" id="undefined"></a>

Скрипт может вернуть простое значение, например строку, число, список или словарь. Такое значение будет использовано как результат функции.

Если нужен расширенный сценарий управления диалогом, верните structured contract — словарь со служебными полями.

| Поле                      | Тип              | Назначение                                                    |
| ------------------------- | ---------------- | ------------------------------------------------------------- |
| `tool_result`             | `str`            | Результат для LLM — модель строит ответ клиенту на его основе |
| `send_message`            | `str` или `dict` | Прямое сообщение клиенту, минуя LLM                           |
| `info_message`            | `str`            | Служебная запись в диалоге                                    |
| `system_message`          | `str`            | Контекст для модели с тегом `python_script_context`           |
| `variables`               | `dict`           | Плоский патч переменных: `{"ключ": значение}`                 |
| `form_data`               | `dict`           | Патч полей формы, только для `personal_data_form`             |
| `silent`                  | `bool`           | Применить side-effects без ответа клиенту                     |
| `pause`                   | `bool`           | Поставить диалог на паузу                                     |
| `resume`                  | `bool`           | Снять диалог с паузы                                          |
| `block_user`              | `bool`           | Заблокировать пользователя                                    |
| `clear_dialog`            | `bool`           | Очистить и перезапустить диалог                               |
| `switch_agent`            | `str` или `dict` | Переключить на другого агента                                 |
| `handoff_to_operator`     | `bool`           | Передать диалог оператору, только для Bitrix24                |
| `delayed_message`         | `dict`           | Запланировать отложенное сообщение                            |
| `cancel_delayed_messages` | `bool`           | Отменить все отложенные сообщения диалога                     |
| `notify_admin`            | `dict`           | Уведомить администратора                                      |
| `tags`                    | `list[str]`      | Добавить теги к диалогу                                       |

### Примеры скриптов <a href="#undefined" id="undefined"></a>

Безопасный запрос к внешнему API

```python
import requests

print("Начало выполнения функции")
print(f"Получены аргументы: {args}")

api_url = args.get("api_url") or "https://jsonplaceholder.typicode.com/posts/1"

try:
    print(f"Отправка HTTP-запроса к API: {api_url}")
    response = requests.get(api_url, timeout=10)
    response.raise_for_status()
    data = response.json()
    print(f"Получен ответ от API: {data}")

    processed_data = {
        "post_info": f"Заголовок: {data.get('title', '')}",
        "word_count": len((data.get("body") or "").split()),
    }

    print(f"Данные обработаны: {processed_data}")

    result = {
        "status": "success",
        "message": "Функция выполнена успешно",
        "processed_data": processed_data,
    }

except requests.RequestException as e:
    print(f"Ошибка при выполнении запроса: {str(e)}")
    result = {
        "status": "error",
        "message": str(e),
    }

print("Выполнение функции завершено")
```

Фоновое действие без ответа

```python
result = {
    "silent": True,
    "variables": {"lead_checked": True},
    "tags": ["checked"],
}
```

Отложенное сообщение через 1 час

```python
result = {
    "send_message": {"text": "Заявка принята! Менеджер свяжется с вами."},
    "delayed_message": {
        "message": "Напоминаем о вашей заявке. Чем можем помочь?",
        "delay_ms": 60 * 60 * 1000,
        "delete_after_user_message": True,
        "restriction_policy": "next_window_start",
        "restriction_policy_time": "09:00",
    },
    "tags": ["follow_up_scheduled"],
}
```

Передача оператору

```python
result = {
    "handoff_to_operator": True,
    "pause": True,
    "tags": ["operator_handoff"],
    "notify_admin": {
        "messager": "telegram",
        "message": "Клиент запросил оператора.",
    },
}
```

Смена агента

```python
result = {
        "switch_agent": {
            "agent_hash": "88725312-2b64-4bd2-8aaf-1e0c2fc571c5",
        },
        "tags": ["switched_by_python"],
        "tool_result": "Диалог переключён на другого агента"
}
```

### Приоритет ответа клиенту <a href="#undefined" id="undefined"></a>

Платформа определяет ответ в следующем порядке:

1. Если задан `send_message`, сообщение отправляется напрямую, LLM не запускается.
2. Если задано `silent: true`, либо используется `block_user` или `clear_dialog`, клиенту ничего не отправляется, LLM не запускается.
3. Во всех остальных случаях `tool_result` передаётся в LLM для генерации ответа.

### Типичные ошибки и решения

| Ошибка                                             | Причина                                                                   | Решение                                                                                                                                                              |
| -------------------------------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Не указан `codeId` для выполнения Python-скрипта   | Скрипт не сохранён или не привязан к шагу                                 | Откройте настройки функции или сценария, вставьте код и нажмите **Сохранить**                                                                                        |
| `result` не определён                              | Ветка кода не присваивает `result`                                        | Добавьте присваивание `result` во все ветки `if/else` и `try/except`                                                                                                 |
| `KeyError: 'phone'`                                | Используется `args["phone"]` вместо `args.get("phone")`                   | Всегда используйте `args.get(...)`                                                                                                                                   |
| `send_message` не работает, клиент видит ответ LLM | Поле `send_message` не задано, используется `tool_result`                 | Проверьте, что используете именно `send_message`                                                                                                                     |
| Переменная не обновляется                          | Ключ переменной не существует в каталоге агента                           | Создайте пользовательскую переменную в **Настройках агента**                                                                                                         |
| `handoff_to_operator` не работает                  | Bitrix24 не подключён                                                     | Действие работает только при подключённом Bitrix24                                                                                                                   |
| `subprocess` вызывает ошибку                       | Shell-команды запрещены в RestrictedPython                                | Используйте только встроенные модули Python                                                                                                                          |
| `SyntaxError` при сохранении или запуске           | Ошибка в синтаксисе Python: лишняя/пропущенная скобка, кавычка или отступ | Проверьте код на наличие незакрытых скобок, кавычек и корректность отступов. Используйте **«Генерацию кода с ИИ»** — она подсветит проблему и предложит исправление. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.nextbot.ru/functional/functions/sending-result/python-v.2.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
