Структура контекста + JSON Path

JSON Path

Если в значении переменной находится JSON-массив или JSON-объект, то можно получить конкретное свойство этого объекта, просто дописав его путь к переменной через точку.

Например для такого объекта object со значением

{"users":[{"id":123,"name":"Киррил"},{"id":234,"name":"Кир"}],"club":123456}

Значение идентификатора первого пользователя можно получить так:

{var:object.users[0].id}

Для поиска значений используется библиотека JMESPath: примеры и документация.

В названиях переменных и полей нельзя использовать точки именно по этой причине. Точка - это погружение внутрь объекта переменной.

Краткий мануал по JSON для новичков (Формат и типы данных)

Формат данных контекста - JSON. Одинаково удобен как для пользователя так и для обработки сервисом. Если вы никогда не работали с этим форматом представления данных, можете ознакомиться с ним в этом кратком мануале.

Базовые типы данных + их условные обозначения в примерах:

  • Текст - обрамлен двойными кавычками. Пример: "Какой-то текст"

  • Натуральное число - не обрамляется ничем, содержит только цифры. Пример: 123

  • Число - не обрамляется, содержит цифры и точку как разделитель дробей. Пример: 123.45

  • Да / Нет - булевый тип, где true = Да, а false = Нет.

  • Ничего - null - значение не задано, формат не определен.

Собирательные типы данных:

  • Массив - ["text", 123, 123.45, true, null] - несколько разных значений (иногда даже с разными типами) в одном списке. Условное обозначение - квадратные скобки. Разделитель элементов внутри - запятая.

  • Объект - {"text":"text", "int": 123, "float": 123.45, "bool":true} - ассоциативный набор свойств - пар «ключ:значение», разделенных запятыми. Объект обрамляется фигурными скобками. Ключи (названия свойств) всегда строковые (поэтому обрамляются двойными кавычками). Значения свойств могут быть любого типа и оформляться соответственно.

Массивы могут находится внутри массивов и объекты могут находится внутри объектов. Перекрестная вложенность тоже поддерживается. Уровень вложенности не ограничен.

Однако собирательные типы (массив, объект) не могут находится внутри базовых (текст, число)!

Данные изнутри объектов можно доставать через JSON PATH, Это когда погружение внутрь объекта происходит через точку. Например чтобы достать число id, которое внутри объекта chat, который внутри объекта platform, нужно написать: platform.chat.id

Все JSON объекты, которые приведены ниже (и спрятаны под спойлерами), разобраны на примере события Входящее сообщение и запроса из Телеграм.

Объект события

Самые важные данные события, для использования в схеме

Часто используемые переменные:

  • {var:object.id} - ID объекта (сообщения, комментария и т. п.)

  • {var:object.text} - текст события (например, текст сообщения)

  • {var:object.type} - тип объекта. Например, есть такие типы:

    • message - сообщение

    • comment - комментарий

    • post - пост

    • notice - уведомление (в чате)

    • admin - объект администратора чата (с правами)

    • invite_link - пригласительная ссылка

  • {var:object.post.id} - ID поста где произошло событие (например, пост комментария)

Пример структуры данных

Данные объекта события {var:object} - для сообщения /start

{
  "id": 184, 
  "text": "/start", 
  "type": "message"
}

Данные платформы

Обработанные данные входящих запросов

Часто используемые переменные :

  • {var:platform.short_name} - мессенджер в котором произошло событие

  • {var:platform.contact.type} - тип контакта, по которому событие ищет пользователя

  • {var:platform.integration.id} - внешний ID бота (или аккаунта), с которым произошло событие

  • {var:platform.chat.id} - текущий чат - в котором произошло событие

  • {var:platform.author.id} - автор отвеченного сообщения - ID пользователя (на внешней платформе), который написал сообщение, на которое ответили.

Пример структуры данных

Данные платформы где произошло события {var:platform} (например мессенджера) а также исполнителей

{
  "short_name": "tg",
  "contact": {"type": "tg_id"},
  "event": {"id": 850471250, "type": "message"},
  "integration": {"id": 12345},
  "user": {
    "id": 399640976,
    "profile_type": "user",
    "first_name": "Кирилл",
    "last_name": "Аксёнов",
    "title": null,
    "language_code": "ru",
    "username": "kir_axenov",
    "is_premium": true
  },
  "chat": {
    "id": 399640976,
    "profile_type": "user",
    "first_name": "Кирилл",
    "last_name": "Аксёнов",
    "title": "Кирилл Аксёнов",
    "language_code": null,
    "username": "kir_axenov"
  },
  "author": null,
}

Данные изнутри можно доставать через JSON PATH

Объект блок-схемы

Внутренние идентификаторы для локальных проверок

ID пользователя здесь - это ID пользователя в проектеЧасто используемые переменные :

  • {var:graph.item.id} - ID текущей блок-схемы

  • {var:graph.integration.id} - ID интеграции, которая запустила события

  • {var:platform.short_name} - тип платформы интеграции (находится в объекте платформы)

  • {var:graph.project.id} - ID проекта в котором была запущена схема

  • {var:graph.event.localId} - Системный номер блока (#) события, которое запустило схему

  • {var:graph.restore.localId} - Системный номер блока (#), который восстановил* схему

  • {var:graph.path} - Путь пользователя по схеме в рамках ветки, в виде массива localId. Учитываются все типы объектов схемы: порты, блоки, стрелки, контейнеры.

  • {var:graph.template.id} - ID текущего шаблона

  • {var:template} - все переменные текущего шаблона

Пример структуры данных

Полный объект пользователей события {var:graph}

{
  "item": {
    "id": 101
  },
  "project": {
    "id": 3
  },
  "integration": {
    "id": 2
  },
  "event": {
    "localId": 1
  },
  "restore": {
    "localId": 123
  },
  "template": {
    "id": 123
  },
  "path": [1,3,2,4,6,5,7]
}

* - Работа схемы останавливается например, когда пользователь попадает на входящий порт события. Этот момент можно назвать “началом ожидания события“. Когда событие наконец происходит, схема восстанавливается со всеми данными начиная с номера блока этого (промежуточного) события.

Объект пользователей сервиса

Пользователи сервиса, с которыми произошло событие (в рамках проекта).

ID пользователя здесь - это ID пользователя в проекте

Часто используемые переменные :

  • {var:users.user.id} - ID пользователя в проекте

  • {var:users.user.first_name} - Имя пользователя в проекте

  • {case:{var:users.user.appeal}|обращение на Вы|женщинам|мужчинам} - разный текст в зависимости от пола пользователя (для многих мессенджеров, чтобы это заработало пол надо спросить у пользователя и сохранить в профиль)

  • {var:users.user.contact.tg_id[0]} - первый контакт указанного типа Типы контактов:

    • tg_id - ID в Telegram

    • vk_id - ID в VK

    • phone - номер телефона

    • email - электронный адрес

Пример структуры данных

Полный объект = все пользователи события {var:users}

{
  "user": {
    "id": 4,
    "project_id": 3,
    "language_code": "ru",
    "profile_type": "user",
    "first_name": "Кирилл",
    "last_name": "Аксёнов",
    "title": "",
    "appeal": 0,
    "photo_url": "",
    "contact": {
      "tg_id": [
        "850471250"
      ],
      "phone": [
        "+79876543210"
      ]
    },
    "contacts": [
      {
        "bot_id": 0,
        "type": "tg_id",
        "value": "850471250",
        "public_name": "kir_axenov",
        "last_message_at": 0
      },
      {
        "bot_id": 0,
        "type": "phone",
        "value": "+79876543210",
        "public_name": "",
        "last_message_at": 0
      }
    ],
    "ignore": 0,
    "source_id": 0,
    "created_at": 1673845546,
    "created_by": 0,
    "updated_at": 1675152183,
    "updated_by": 0,
    "deleted_at": 0,
    "deleted_by": 0
  }
}

Внимание: Данные пользователя можно перезаписывать функциями бота. Но будьте внимательны, назад надо возвращать вручную, предварительно сохранив исходное значение.

В пути к переменным контактов как правило добавляется [0] потому что мы достаем первый из контактов определенного типа. Например у пользователя может быть несколько номеров телефона или несколько аккаунтов в телеграм. Для настроек, где важно получать определенный контакт, лучше доставать ID-шку из данных платформы

Входящий запрос

Необработанные данные входящего запроса (события).

{var:request} — оригинальный входящий запрос полностью.

Пример структуры данных
{
  "update_id": 850471250,
  "message": {
    "message_id": 184,
    "from": {
      "id": 399640976,
      "is_bot": False,
      "first_name": "Кирилл",
      "last_name": "Аксёнов",
      "username": "kirmaslov",
      "language_code": "ru",
      "is_premium": True
    },
    "chat": {
      "id": 399640976,
      "first_name": "Кирилл",
      "last_name": "Аксёнов",
      "username": "kir_axenov",
      "type": "private"
    },
    "date": 1662362234.000,
    "text": "/start",
    "entities": [{"offset": 0, "length": 6, "type": "bot_command"}]
  }
}

Данные изнутри можно доставать через JSON PATH

​Например, вам нужно достать имя отправителя.

Получится переменная:{var:request.message.from.first_name}

Или проверить купил ли он Телеграм премиум:{var:request.message.from.is_premium}

Результат действия

Каждое действие (в том числе сообщение и таймер) перезаписывает в контексте три переменных:

1) Успешно ли выполнилось действие:

{var:ok}

где:

  • ok = true - нет ошибок, всё хорошо, можно работать дальше

  • ok = false - есть ошибки, смотрите детали в {var:error.message}

В условиях рекомендуется проверять через «Числовую переменную» где true это 1 а false это 0

2) Полезная нагрузка действия:

{var:result}

Каждое действие выполняет какую-то операцию. И возвращает какие-то полезные данные. Возможно вы захотите использовать их, проверять в следующем блоке или сохранить их часть в собственные переменные для использования по всей схеме.

3) Важные данные из результата работы конкретного типа действия:

{var:effect}

Например, исходящее сообщение записывает сюда внешний идентификатор отправленного сообщения (в рамках платформы) для более удобного редактирования этого сообщения позже:

{var:effect.message.id}

4) Детали ошибки. Если ошибки не было, то {var:error} будет равно None

{var:error}

При этом {var:error} содержит различную системную информацию, из которой самое важное это сообщение с описанием проблемы.

{var:error.message}

Пример использования

Можно визуально выделить успешный результат выполнения действия при помощи этой комбинации литералов:

Результат выполнения действия {case:{var:ok}|❌|✅}

Пример готового текста сообщения для полного результата действия:

Результат: {case:{var:ok}|❌|✅}
<code>{var:result}</code>
_______
Ошибка: <code>{var:error.message}</code>

Второй пример результата, где ошибка показывается только если действие выполнено не успешно. Когда всё ОК, показывается только результат

Результат: 
{var:result}
{case:{var:ok}|______
<code>{var:error.message}</code>|}

Результат условия

Условия тоже имеют результат выполнения, но для удобства записывают его в отдельную переменную: {var:condition}

1) Условие отработало без ошибок:

{var:condition.ok}

2) Результат проверки условия. Возможные значения: true, false, null, которые, собственно, и влияют на то, по какому выходу пойдет пользователь:

{var:condition.result}

3) Детали ошибки, если ошибки есть. Если нет вернет undefined

{var:condition.error.message}

Всё работает аналогично как и в действиях, только немного другой путь к переменным

Last updated