Справочник по DTL: переменные, теги, фильтры

Процедуры на платформе пишутся на DTL (Django Template Language) с набором собственных тегов и фильтров поверх стандартных.
Эта статья — короткий справочник по тому, что доступно внутри процедуры: какие переменные есть в контексте узла «по умолчанию», какими тегами пользоваться чаще всего и какие фильтры пригодятся для обработки дат и строк.

Если нужно разобраться не в синтаксисе, а в самой идее переменных, атрибутов и тегов — это в статьях «Переменные в платформе» и «Атрибуты профиля и теги». Здесь пишем о синтаксисе.

Переменные, которые всегда есть в контексте

Эти переменные не нужно объявлять — они доступны в любой процедуре узла:

ПеременнаяЧто содержит
{{ platform }}Платформа пользователя: telegram, facebook, viber и т. д.
{{ messenger_first_name }} / {{ messenger_last_name }}Имя и фамилия, как пользователь назвал себя в мессенджере
{{ request.type }}Тип входящего сообщения: text, picture, video, document, location, contact, postback
{{ request.content }}Содержимое сообщения — текст, адрес файла и т. п.
{{ request.latitude }} / {{ request.longitude }}Координаты для сообщений типа location. Для передачи во внешние API используйте фильтр unlocalize, чтобы точка не экранировалась: {{ request.longitude\|unlocalize }}
{{ request.is_telegram_user }}Является ли переданный контакт телеграм-аккаунтом (тип contact, платформа Telegram)
{{ request.is_own_contact }}Прислал ли пользователь свой контакт или чужой из телефонной книги
{{ chat_id }} / {{ chat_uuid }}Внутренний ID и UUID чата
{{ cookies }}Хранилище BotCookies
{{ chat_center.session.team }}, {{ chat_center.session.operator }}, {{ chat_center.session.is_automatic }}Контекст чат-центра: команда, оператор, автоматическая ли сессия
{{ operator.is_authorized }}Авторизован ли оператор (только для операторского бота); можно использовать в
{% if operator.is_authorized %}
{{ operator.phone_number }}Номер телефона оператора (только для операторского бота)
{{ get_params }}GET-параметры, с которыми был запущен узел
{{ http_response }}Результат HTTP-запроса, сделанного в этом же узле; существует только внутри узла и никуда не сохраняется, в отличие от переменной, в которую вы явно сохраните ответ через save_variable
{{ http_response.http_status_code }} / {{ http_response.http_cookies }}Статус и куки ответа HTTP-запроса
{{ telegram_deeplink }}, {{ viber_deeplink }}, {{ facebook_deeplink }}, {{ vkontakte_deeplink }}Диплинки на бота в соответствующем канале, если он подключён
{{ bot_uuid }} / {{ bot_key }}UUID бота и его API-ключ для внешних интеграций
{{ node_id }} / {{ node_name }}ID и название текущего узла

Теги

Переменные и данные

КодОбъяснение
{% set variable_name="Привет" %}
Задаёт переменную variable_name со значением "Привет", которая живёт в рамках текущей процедуры
{% save_variable "user_choice" "premium" %}
Сохраняет переменную user_choice со значением premium в рамках всего проекта — доступна где угодно, пока её не удалят
{% save_variable "requested_discount" get_params.discount_code %}
Сохраняет в переменную requested_discount значение GET-параметра discount_code, с которым был запущен узел
{% delete_variables "user_choice" "requested_discount" %}
Удаляет обе переменные разом
{% if user_choice %}
{% switch "Сценарий для премиум-клиентов" %}
{% endif %}
Проверяет, что переменная user_choice существует и не пустая, и если да — переключает узел
{% createobj payload %}

{
"phone": "{{ attributes.profile_phone_number }}",
"source": "bot"
}
{% endcreateobj %}
Собирает JSON-объект payload из вложенного блока — удобно как тело запроса для HTTP-интеграции
{% createstring greeting %}
, {{ messenger_first_name }}!
{% endcreatestring %}
Собирает строку greeting из шаблона с подстановками

Атрибуты и теги профиля/чата

КодОбъяснение
{% set_attribute "profile_phone_number" phone_number %}
Сохраняет атрибут profile_phone_number со значением переменной phone_number
{% clear_attribute "profile_phone_number" %}
Очищает атрибут profile_phone_number
{% profile.set_tag "vip" %}
Добавляет тег vip на чат
{% profile.clear_tag "vip" %}
Убирает тег vip с чата

Навигация и выполнение

КодОбъяснение
{% switch "Сценарий с анкетой ввод email" %}
Переключает выполнение в другой узел по его названию
{% if not phone_number %}
{% stop %}
{% endif %}
Останавливает выполнение оставшихся процедур и отправку контента узла — например, если не получилось получить нужное значение

Даты и строки

КодОбъяснение
{% now as current_time %}
Записывает текущую дату и/или время в переменную current_time
{% datetime_now as current_datetime %}
Записывает текущие дату и время в переменную current_datetime
{% calc_timedelta start_date end_date as days_passed %}
Вычисляет разницу между двумя датами и сохраняет её в переменную days_passed
{% replace "С новым 2021 годом" "2021" "2022" as text %}
Заменяет "2021" на "2022" в строке и сохраняет результат во временную переменную text

Работа с клиентом и чат-центром

КодОбъяснение
{% save_phone_number phone_number %}
Сохраняет номер телефона в профиль как основной
{% check_phone_number phone_number as already_exists %}
Проверяет, существует ли такой телефон у других клиентов, и сохраняет результат проверки в переменную
.enable %}
Открывает чат-сессию с командой «Нераспределенные»
{% send_text "Спасибо за обращение! Мы скоро ответим." %}
Отправляет пользователю текстовое сообщение прямо из процедуры

Воронки и формы

КодОбъяснение
{% subscribe_to_funnel "Воронка вебинара" %}
Подписывает пользователя на автоворонку
{% unsubscribe_from_funnel "Воронка вебинара" %}
Отписывает пользователя от воронки
{% enter_input_form "Анкета регистрации" %}
Запускает анкету для пользователя
{% form_lead as lead %}
Получает данные последнего лида формы для сайта и сохраняет в переменную lead
{% form_data as data %}
Получает данные последнего лида формы для бота и сохраняет в переменную data

Фильтры

КодОбъяснение
{{ order_date\|date:"d.m.Y" }}Форматирует дату order_date по шаблону дд.мм.гггг
{{ raw_timestamp\|as_datetime }}Превращает значение в объект даты, с которым можно дальше работать
{{ start_date\|add_days:7 }}Прибавляет 7 дней к дате start_date
{{ start_date\|subtract_days:7 }}Вычитает 7 дней из даты start_date
{{ total_price\|subtract:discount }}Вычитает значение discount из total_price
{{ long_text\|keep_slash_n }}Интерпретирует переносы строк (\n) в тексте как реальные переносы — полезно для многострочных сообщений, собранных из внешних данных
{{ request.longitude\|unlocalize }}Убирает локализацию у координаты, чтобы она не экранировалась при передаче во внешний API (например, в FlexCMS или сторонний REST-сервис)

Важно: это не полный список — DTL поддерживает и стандартные теги/фильтры Django, а на платформе есть ещё кастомные под конкретные интеграции (например, для Mindbox или Usedesk). Приведённый здесь набор — то, что нужно в большинстве процедур.