Условия виджетов в Salesbot

В данном разделе описывается способ добавление условий виджетов в шаг условия в Salesbot

Оглавление

О функционале

Во многих блоках Salesbot появляется необходимость для кастомизации под нужды интеграторов. Поэтому мы даем возможность виджетам интегрироваться в блок condition (условие). Этот функционал дает возможность интеграторам добавлять свои условия в Salesbot, не запрашивая доработок со стороны amoCRM и не делая нестандартные решения, которые имеют риск перестать работать в любой момент. Блок condition блок служит для проверки одного из параметров на соответствие, которое настроено пользователем в этом шаге.

Добавление условий, структура данных

Для добавления собственных условий, виджет в файле manifest.json должен указать в поле locations значение “salesbot_designer”.

Пример:

"locations":[
  "salesbot_designer"
],

Общая структура, как добавить свои условия

В поле salesbot_designer файла manifest.json добавляется следующая структура данных (массив “conditions”) (поле “salesbot_designer” в остальном остается как было, если его нет, то необходимо добавить):

"salesbot_designer": {
  "conditions": [
    {
      "term1": {
        "id": "{{widget.integration_code.term1_code}}",
        "option": "AD Referral",
        "is_identity_term": true // опциональное поле
      },
      "is_chat_condition": true, // опциональное поле
      "callback": "https://your-integration.com/crm/v1/salesbot/ads", // опциональное поле
      "widget_hook": "https://your-integration.com/crm/webhooks/v1/salesbot/condition/ads"
    },
    {
      "term1": {
          "id": "{{chat.profile_id}}",
          "option": "Client"
      },
      "term2": [ // опциональное поле
          {
            "id": "{{widget.integration_code.term2_code}}",
            "option": "a follower on Your Network"
          }
      ],
      "widget_hook": "https://your-integration.com/crm/webhooks/v1/salesbot/condition/follower"
    }
  ],
}

Conditions – это массив, каждый элемент которого предоставляет данные для отрисовки левой и правой частей условия Каждый объект состоит из частей:

Параметр Тип данных Описание Обязательное
term1 object Объект левой части условия
widget_hook string URL для отправки хука при выполнении условия ботом, в хуке сообщается интеграции, что было выбрано в конкретном шаге
term2 object Объект правой части условия
is_chat_condition bool булевый маркер, что условие относится к чатам
callback string URL, через который мы запросим возможные варианты условий для правой части. (term2)

term1

term1 – это левая часть условия (то поле, которое сравнивается со значением).

Значение полей объекта term1:

  • id – значение поля, по которому будет проводиться сравнение, следующей структуры:

    "{{widget.integration_code.term1_code}}";

    Это строковое значение, обернутое в двойные фигурные скобки, через точку строка “widget” (говорит о том, что условие от интеграции), код интеграции, код условия (для распознания на стороне самой интеграции)

  • option – отображаемое название поля в селекте левой части сравнения, привязанное к id. Интегратор должен позаботиться о переводе option на нужные языки – добавить переводы в файлы i18n/{id языка}.json. В противном случае, значения в селектах будут отрисованы на исходном языке.

  • is_identity_term – маркер, указывающий что будет использован идентификационный оператор сравнения (is/is not) вместо стандартных (equals/ does not equal/ contains).

  "term1": {
      "id": "{{widget.integration_code.term1_code}}",
      "option": "AD Referral",
      "is_identity_term": true
  },

В случае, если в системе уже существует условие c указанным ID или оно добавлено другими интеграциями, то option будет игнорироваться в пользу добавленного ранее, условия для правой части сравнения добавятся к тем, что уже связаны с term1.

term1 статичен и не может быть запрошен в реальном времени, term1 всегда ожидается в manifest.json.

term2

term2 – это массив с длиной от 1 элемента. В массиве содержатся объекты с id и option (по аналогии с term1)

  "term2": [
      {
        "id": "{{widget.integration_code.term2_code}}",
        "option": "a follower on Your Network"
      }
  ],

term2 будет использован, если значения правой части должны быть ограничены, всегда константны и должны быть выведены интеграцией. Если возможные значения должны быть динамическими – читайте об этом в следующем параграфе.

Динамические данные

Может потребоваться, чтобы данные из term2 запрашивались в реальном времени, например, список рекламных компаний, который может меняться в зависимости от действий пользователя, и не может статически храниться в manifest.json

Чтобы данные были актуальными, интегратор сам создает эндпоинт для получения таких данных. В поле callback указывается url для получения таких данных и последующей отрисовки правой части условия (term2).

[
  {
    callback: "https://your-integration.com/crm/v1/salesbot/ads",
  },
];

API бота ожидает данные формата:

[
  {
    id: "{{widget.integration_code.condition_name}}",
    option: "Your term title",
  },
];

Запрос на указанный адрес будет сделан с использованием одноразового токена.

Если интеграций не ответит на запрос – отрисуются уже имеющиеся условия правой части (если они были), в противном случае список значений будет пустым.

Маркер условий для чатов

Чтобы сообщить боту о том, что проверяется условие, относящееся к переписке в чатах, в объект с условием добавляется поле is_chat_condition

  {
    "is_chat_condition": true,
  },

При интерпретации бот поймет, что это условие чатов и отправит интеграции данные о активном чате.

Механика работы

Выше указано, как добавить свои условия для шага Condition в Salesbot.

Механизм выполнения устроен следующим образом: Кастомные условия из виджета первично приходят из manifest.json в запросе при инициализации конструктора Salesbot.

term1 добавляется в левую часть условия. Если у term1 есть свой список term2, то при клике на него в правом списке (term2) отрисовываются эти элементы. В случае, если у term1 уже были свои элементы для правой части, элементы term2 из manifest.json добавляются к уже существуюим. Например, вы обновляете интеграцию и указываете новое значение, а у пользователя уже было настроено старое значение. В случае, если у объекта есть свойство callback – это говорит о том, что условия (или часть условий) нужно получить асинхронно – при выборе term1 происходит запрос к бэкенду интеграции (показывается состояние загрузки), далее элементы добавляются в правую часть условия.

При сохранении конструктора мы сохраняем копию настроек, которые были указаны в manifest.json, в настройки шага.

При выполнении этого шага, бот отправляет вебхук в интеграцию, передавая ей параметры и в том числе URL, по которому можно продолжить работу бота.

Данные которые передает бот:

{
  "token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9eyJpc3MiOiJodHRwOi8vNGFjY21haW42Lm1haW42LmFt",
  "data": {
    "term1":"{{widget.integration_code.term1_code}}",
    "term2":"{{widget.integration_code.term2_code}}",
    "operation":"=",
    "is_chat_condition":"1",
    "term_type":"dynamic",
    "account_id":"124325",
    "origin":"tiktok-kommo",
    "source_id":"13266779",
    "contact_id":"1655064249",
    "chat_id":"46c3aa86-ffs226-4e15-a4a7-4324324",
    "talk_id":"228",
    "entity_id":675189643,
    "entity_type":2
  },
  "return_url":"http:\/\/subdomain.amocrm.ru\/api\/v4\/salesbot\/534543543\/continue\/60565"
}

Параметры: operation – один из операторов сравнения, подробнее – обработчики salesbot term_type со значением “dynamic”, говорит о том, что это условие запрашивалось от интеграции динамически, для обычных условий из манифеста – “static”.

Часть данных передается только при условии работы с чатом и параметра is_chat_condition установленного в true в манифесте виджета:

  "data": {
    ...rest,
    "chat_id":"46c3aa86-ffs226-4e15-a4a7-4324324",
    "talk_id":"228",
    "origin":"tiktok-kommo",
    "source_id":"13266779",
    "contact_id":"1655064249",
  }

Для продолжения работы бота требуется отправить POST запрос с Access Token на URL, указанный в параметре return_url:

тело запроса для положительного решения

{
  result: "success";
}

тело запроса для отрицательного решения (отличное от success, любой ответ кроме этого будет считаться отрицательным), пример:

{
  result: "fail";
}

запрос должен содержать авторизационные данные:

headers: {
  Authorization: "Bearer {access_token}"
}

access_token вставляется в строку в поле Authorization

Пример запроса:

headers: {
  Authorization: "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9eyJpc3MiOiJodHRwOi8vNGFjY21"
},
data: {
  result: "success";
}