Перейти к содержимому
AISARAISAR

Встраивание чата AISAR

Как встроить полнофункциональный чат AISAR в стороннее приложение через iframe: авторизация, три режима отображения, полный сценарий интеграции.

AISAR предоставляет встраиваемый чат (embed chat) — полнофункциональный мессенджер, загружаемый в <iframe> на стороне вашего приложения. Пользователь работает с чатом внутри вашего UI, не покидая его.

Архитектура

text
Ваше приложение (бэкенд)
    │
    ├─ 1. Создать API-токен           (однократно, через AISAR UI)
    ├─ 2. Получить список юзеров      GET  /v1/users
    ├─ 3. Найти контакт по телефону   GET  /v1/contacts/lookup?q=...
    ├─ 4. Получить список каналов     GET  /v1/channels
    ├─ 5. Отправить сообщение         POST /v1/messages/send
    │
    ├─ 6. Авторизовать юзера          POST /v1/embed/auth
    │     → получить session token
    │
    └─ 7. Открыть iframe
          https://my.aisar.app/embed/chat?token=<session_token>&...

Шаги 2–3 кэшируются на вашей стороне. Шаг 4 выполняется при каждом открытии iframe (токен живёт 8 часов). Все API-запросы используют базовый URL https://api.aisar.app с префиксом /v1 и заголовок Authorization: Bearer <api_token>, выданный один раз в интерфейсе AISAR (Настройки → API-токены; раздел доступен компаниям на бизнес-тарифе с включённой функцией API). Партнёр получает ключ при подключении компании.

Эндпоинты

Список пользователей

Возвращает всех реальных пользователей компании (не сервисные аккаунты) — используйте для сопоставления ваших пользователей с пользователями AISAR.

http
GET /v1/users
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Ответ (200)
{
  "data": [
    {
      "id": 1,
      "name": "Алексей",
      "lastname": "Петров",
      "email": "alexey@company.kz",
      "availability": "online",
      "last_login_at": "2026-03-15T10:30:00.000000Z"
    }
  ]
}

id (используется в embed/auth), name, lastname, email, availability (online/offline/away).

Поиск контактов

Поиск по номеру телефона, внешнему ID или username. Результат даёт contact_id, который используется в iframe URL (режим 3).

http
GET /v1/contacts/lookup?q=<query>
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

q (обязателен, строка 2–255 символов) ищет по номеру телефона (+12025550187), external ID аккаунта (12025550187@s.whatsapp.net) и username (alexey_petrov), нечёткое совпадение (ILIKE). Ограничение: максимум 20 результатов, группы и объединённые контакты исключаются.

Ответ (200, сокращённо)
{
  "data": [
    {
      "id": 42,
      "company_id": 1,
      "firstName": "Алексей",
      "lastName": "Петров",
      "displayName": "Алексей Петров",
      "status": "active",
      "phones": [{ "phone": "+12025550187", "type": "mobile" }],
      "contactAccounts": [
        { "id": 10, "account_type": "whatsapp", "external_id": "+12025550187", "is_group": false }
      ],
      "tags": []
    }
  ]
}

Список каналов

Возвращает каналы компании, доступные текущему пользователю — для получения channel_id, нужного при отправке сообщений.

http
GET /v1/channels
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

Query-параметры (все опциональны): type (тип канала), status (active/inactive), channel_type_id, setup_state, include_setup_drafts (по умолчанию false).

Отправить сообщение

Отправляет исходящее текстовое сообщение контакту через указанный канал; если диалог отсутствует — создаётся автоматически.

http
POST /v1/messages/send
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Content-Type: application/json

{
  "channel_id": 3,
  "recipient": "+12025550187",
  "message_content": "Здравствуйте! Ваш заказ готов."
}

channel_id (обязательно, из GET /v1/channels), recipient (обязательно, номер телефона или external_id получателя, формат зависит от типа канала), message_content (обязательно, максимум 65 535 символов). Ответ 200: { "success": true }. Полный справочник этого эндпоинта (вложения, голосовые, группы WhatsApp, шаблоны) — в гайде «Отправка сообщений: справочник эндпоинтов».

Авторизация для embed

Создаёт короткоживущий session-токен для конкретного пользователя — этот токен передаётся в URL iframe.

http
POST /v1/embed/auth
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Content-Type: application/json

{
  "user_id": 1
}
Ответ (200)
{
  "token": "YOUR_EMBED_SESSION_TOKEN",
  "redirect_url": "https://my.aisar.app/embed/chat"
}
user_id обязан принадлежать реальному пользователю той же компании, что и API-токен — сервисные аккаунты и администраторы платформы не допускаются. token живёт 8 часов. Ошибки: 400 — отсутствует user_id; 403 — вызов не полным API-токеном компании, а узким токеном её служебного аккаунта (например, токеном встроенного чата), error: "This token cannot issue embed sessions"; 422 — пользователь не найден в компании. С 2026-09-28 выданный токен привязан к компании, которая его выпустила: запросы с ним всегда выполняются в этой компании, какая бы компания ни была у пользователя текущей; на платформенных эндпоинтах он не действует (403), а PUT /v1/me/current-company на другую компанию отвечает 403 с error: "token_company_bound". Если пользователь перестал состоять в компании, уже выданный токен тоже перестаёт работать (403).

Выданный session-токен имеет ограниченный scope embed:read и живёт 8 часов — этого достаточно для работы встроенного чата, но он не заменяет полноценный API-токен.

Отдельные эндпоинты отказывают embed-токену явно — 403, независимо от того, что именно перечислено в scope. Сейчас так закрыты: сводная аналитика компании (дашборд — выручка, сделки, объёмы диалогов и сообщений, нагрузка по операторам), поиск по расшифровкам звонков (q_in=transcript|all в GET /v1/calls) и очередь перезвона по пропущенным (/v1/telephony/callbacks*). Общее правило: если поверхность отдаёт коммерческую сводку по всей компании или пакетную выгрузку персональных данных, встроенному в чужой интерфейс токену она недоступна — обращайтесь к ней со своего бэкенда обычным API-токеном.

Авторизация из CRM (Bitrix24 и другие)

Альтернативный режим POST /v1/embed/auth — для встраивания чата прямо из интерфейса CRM (например, из карточки в Bitrix24), когда запрос инициирует установленное в CRM приложение, а не ваш бэкенд с API-токеном. Вместо user_id передаётся идентификатор портала CRM.

http
POST /v1/embed/auth
Accept: application/json
Content-Type: application/json

{
  "type": "bitrix24",
  "member_id": "YOUR_CRM_MEMBER_ID",
  "payload": {
    "AUTH_ID": "PORTAL_ISSUED_ACCESS_TOKEN"
  }
}

type (обязательно, тип CRM: bitrix24 и др.), member_id (обязательно, идентификатор портала CRM), payload (обязательно объект — иначе 400). Для bitrix24 поле payload.AUTH_ID обязательно и обязано быть строкой (иначе 400): это access-токен, которым личность вызывающего проверяется прямым запросом к порталу (user.current). Ответ — тот же конверт { "token": ..., "redirect_url": ... }, что и в режиме с user_id; токен также имеет scope embed:read и живёт 8 часов.

Без AUTH_ID, с невалидным AUTH_ID, либо если проверенный CRM-пользователь не замаплен на пользователя AISAR или больше не состоит в компании — 422, токен не выдаётся. Фолбэка на «первого пользователя компании» больше нет: пустой или отсутствующий payload.AUTH_ID раньше молча выдавал такой токен, сейчас — только отказ. Если в payload передан b24_user_id, он игнорируется: личность нельзя назвать с провода, она подтверждается только верификацией AUTH_ID на портале.

POST /v1/embed/auth ограничен по частоте на весь маршрут: вызовы с Bearer-токеном сервисного аккаунта (режим с user_id) — до 120 запросов в минуту на токен; анонимные вызовы этого CRM-режима — до 30 запросов в минуту на IP.

Встраивание iframe

Где можно встраивать и атрибуты iframe

С 2026-10-08 встроенный чат https://my.aisar.app/embed/chat?token=... можно встраивать в <iframe> на любом сайте по https — регистрировать домен в AISAR не нужно. Без токена в адресе страница не встраивается. Токен выдаёт сервер интегратора: POST /v1/embed/auth с ключом API сервисного аккаунта компании (в кабинете: Настройки, API-токены) и user_id сотрудника. Токен привязан к этому сотруднику и компании, даёт права только на работу встроенного чата и живёт 8 часов; держите его на сервере, не пишите в логи, а после загрузки страница сама убирает токен из адреса.

Рекомендуемые атрибуты iframe: allow="microphone; clipboard-write" (голосовые сообщения, звонки из встроенного чата и копирование в буфер). Атрибут sandbox лучше не ставить; если он нужен, разрешите allow-scripts allow-same-origin allow-popups allow-forms allow-downloads.

html
<iframe
  src="https://my.aisar.app/embed/chat?token=<session_token>"
  allow="microphone; clipboard-write"
  style="width: 100%; height: 100%; border: none;"
></iframe>
Это правило относится только к чату. Битрикс24 и amoCRM встраивают чат сами, настраивать ничего не нужно.

Три режима отображения

Режим 1 — полный чат (inbox). Полнофункциональный мессенджер со списком диалогов, фильтрами, поиском и панелью сообщений.

html
<iframe
  src="https://my.aisar.app/embed/chat?token=<session_token>"
  style="width: 100%; height: 100%; border: none;"
></iframe>

Режим 2 — чат с предзаполненным поиском. Тот же полный чат, но строка поиска сразу заполнена (параметр search).

html
<iframe
  src="https://my.aisar.app/embed/chat?token=<session_token>&search=+12025550187"
  style="width: 100%; height: 100%; border: none;"
></iframe>

Режим 3 — панель сообщений контакта. Только панель сообщений для конкретного контакта, без списка диалогов и фильтров — идеально для встраивания в карточку клиента. Параметры: contact_id (из /v1/contacts/lookup), view=messages. Поведение: загружает последний диалог контакта; если диалогов нет — показывает пустое состояние; панель полнофункциональна (отправка/редактирование сообщений, управление диалогом).

html
<iframe
  src="https://my.aisar.app/embed/chat?token=<session_token>&contact_id=42&view=messages"
  style="width: 100%; height: 100%; border: none;"
></iframe>

Дополнительные параметры

ПараметрОписание
langЯзык интерфейса: en, ru, kk. По умолчанию ru
contact_idID контакта (без view=messages — фильтрует список диалогов)
deal_idID сделки — открывает чат в контексте конкретной сделки

Полный пример интеграции (Python)

Начальная настройка (однократно)
API_TOKEN = "YOUR_API_TOKEN"
API_BASE = "https://api.aisar.app/v1"
EMBED_BASE = "https://my.aisar.app/embed/chat"

headers = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Accept": "application/json",
}

# Получите список пользователей для маппинга
response = requests.get(f"{API_BASE}/users", headers=headers)
aisar_users = response.json()["data"]

user_mapping = {
    "your_user_123": 1,   # Алексей → AISAR user ID 1
    "your_user_456": 2,   # Мария → AISAR user ID 2
}

# Найдите контакты по телефонам (кэшируйте результат)
response = requests.get(
    f"{API_BASE}/contacts/lookup",
    params={"q": "+12025550187"},
    headers=headers,
)
contacts = response.json()["data"]  # contacts[0]["id"] = 42 ← contact_id для iframe
При открытии iframe (каждый раз)
aisar_user_id = user_mapping["your_user_123"]

response = requests.post(
    f"{API_BASE}/embed/auth",
    json={"user_id": aisar_user_id},
    headers=headers,
)
session_token = response.json()["token"]

# Режим 1: полный чат
iframe_url = f"{EMBED_BASE}?token={session_token}"
# Режим 2: предзаполненный поиск
iframe_url = f"{EMBED_BASE}?token={session_token}&search=+12025550187"
# Режим 3: панель сообщений контакта
iframe_url = f"{EMBED_BASE}?token={session_token}&contact_id=42&view=messages"

Рекомендации

Кэширование

ЧтоКак часто обновлять
API-токенПостоянный (пока не отозван)
Список пользователейПри изменении состава команды
Маппинг контактовПри первом обращении + по мере необходимости
Session tokenКаждый раз при открытии iframe (живёт 8 часов)

Размеры iframe

РежимРекомендуемый размер
Полный чат (1, 2)min-width: 800px, min-height: 600px
Панель сообщений (3)min-width: 400px, min-height: 500px

Безопасность

  • Никогда не передавайте API-токен на фронтенд. Авторизация (/v1/embed/auth) должна происходить на вашем бэкенде.
  • Session-токен передаётся через URL — iframe очищает его из адресной строки сразу после загрузки.
  • Токен в адресе iframe не должен попадать в логи вашего сервера и аналитику: держите его только в памяти страницы и выдавайте на каждое открытие.
  • Session-токен имеет ограниченные права и срок жизни 8 часов.

Обработка ошибок

КодПричинаДействие
401Невалидный/истекший API-токенПроверьте API-токен в настройках AISAR
400Отсутствует обязательный параметрПроверьте user_id в embed/auth
422Пользователь/контакт не найденПроверьте ID и принадлежность к компании

Ограничения

  • Один API-токен = одна компания. Для нескольких компаний — отдельные токены.
  • contact_id относится к компании API-токена — контакты других компаний недоступны.
  • Iframe работает только с HTTPS (кроме localhost).
  • Максимум 20 результатов в /v1/contacts/lookup.