Документация

Идентификация пользователей

Идентификация связывает анонимные сессии чата с реальными профилями пользователей.

Как это работает

Когда вы вызываете Respondo.identify(), переданные поля прикрепляются к диалогу. Все поля необязательны — передавайте только те, что у вас есть. Например, можно отправить только userId без email или имени. Операторы поддержки видят эти данные на панели деталей диалога.

Параметры#

СвойствоТипОбязательноеОписание
emailstringнеобязательноEmail-адрес пользователя
namestringнеобязательноОтображаемое имя
userIdstringнеобязательноВаш внутренний ID пользователя или отображаемый ID — показывается как есть в панели
userHashstringнеобязательноПодпись HMAC-SHA256 для проверки личности
metadataobjectнеобязательноПары «ключ-значение» с пользовательскими полями (plan, company и т. д.)
propertiesobjectнеобязательноПользовательские свойства контакта, заданные в настройках агента. Ключи должны совпадать с определениями свойств. Значения хранятся с префиксом cp_ и доступны для фильтрации в Инбоксе.
Пример: одностраничное приложение (SPA)javascript
// После успешного входа
async function onLogin(user) {
  await authenticateUser(user);

  Respondo.identify({
    email: user.email,
    name: user.fullName,
    userId: user.id,
    metadata: {
      plan: user.subscription.plan,
      company: user.company.name,
      role: user.role,
      signedUp: user.createdAt
    },
    properties: {                        // пользовательские свойства контакта
      account_type: user.accountType,    // должны совпадать с ключами из настроек агента
      industry: user.industry,
      contract_tier: user.tier
    }
  });
}
Со стандартным фрагментом установки identify() можно вызывать в любой момент — вызовы, сделанные до окончания загрузки widget.js, ставятся фрагментом в очередь и автоматически воспроизводятся после инициализации виджета. Данные идентификации отбрасываются (с предупреждением в консоли) только если вы загружаете widget.js самостоятельно и вызываете identify() до первого вызова init() — при ручной установке всегда сначала вызывайте init().

Анонимные посетители#

Если вы не вызываете identify(), виджет автоматически присваивает постоянный visitor ID, сохраняемый в localStorage (ключ respondoai_visitor_id). В панели диалог отображается как Guest · Web widget.

РежимОтображение в панелиТребуется HMAC
Без identify()Guest · Web widgetНет
identify({ email, name })Показываются имя + emailНет — если не включена проверка личности; тогда неподписанные email/имя молча отбрасываются, и сессия остаётся анонимной
identify({ userId })userId показывается как естьНет — если не включена проверка личности; тогда требуется валидный userHash, иначе личность отбрасывается
identify({ userId, userHash })Проверенная личность пользователяДа — криптографически проверено

Когда для канала включена проверка личности, любой вызов identify() с email или userId без валидного userHash очищается на стороне сервера, и посетитель остаётся анонимным — см. «Проверка личности (HMAC)» ниже.

Visitor ID сохраняется между сессиями в одном браузере. Он никогда не отправляется в Respondo как аутентифицированная личность — он используется только для непрерывности анонимных диалогов.

Идентификация только по userId (без email и имени)#

Если на вашей платформе нет email или имён пользователей — например, есть только внутренний отображаемый ID — можно передать только userId. Другие поля не нужны. В панели userId будет показан как есть в деталях диалога.

userId + metadata (без email и имени)javascript
// У вашей платформы есть только отображаемый ID — этого достаточно
Respondo.identify({
  userId: user.displayId,      // например «USR-4821» — показывается в панели
  metadata: {                  // необязательный дополнительный контекст
    plan: 'premium',
    region: 'eu-west'
  }
});
// email и имя не нужны — виджет работает только с userId
Чтобы предотвратить подделку userId, используйте его вместе с userHash (см. «Проверку личности» ниже). Без HMAC кто угодно может передать любой userId из консоли браузера.

Google Tag Manager / отложенный вызов identify()#

При встраивании через GTM данные пользователя могут быть недоступны в момент загрузки страницы. Два подхода:

Вариант A: localStorageKey (без единой строки JS)javascript
// Если ваша платформа уже записывает ID пользователя в localStorage:
Respondo.init({
  agentId: 'YOUR_AGENT_ID',
  localStorageKey: 'myapp_user_id'  // автоматически читает localStorage.getItem('myapp_user_id')
});
// вызов identify() не нужен — виджет сам подхватывает userId
Вариант B: отложенный identify() через dataLayerjavascript
// 1. Немедленно инициализируем виджет (тег GTM)
Respondo.init({ agentId: 'YOUR_AGENT_ID' });

// 2. Позже, когда появятся данные пользователя (например, из dataLayer или вашего приложения):
var waitForUser = setInterval(function() {
  var uid = localStorage.getItem('myapp_user_id');
  if (uid && window.Respondo && typeof window.Respondo.identify === 'function') {
    clearInterval(waitForUser);
    Respondo.identify({ userId: uid });
  }
}, 500);
localStorageKey используется только если userId ещё не задан через identify(). Явные вызовы identify() всегда имеют приоритет.

Проверка личности (HMAC)#

Без проверки кто угодно мог бы выдать себя за пользователя, передав поддельный userId или email. Проверка личности использует HMAC-SHA256, чтобы криптографически доказать, что личность пользователя задана вашим сервером, а не клиентским кодом.

Как это работает#

  1. Включите проверку личности в настройках канала — вы получите секретный ключ.
  2. На вашем сервере вычислите HMAC-SHA256(secret, userId) — секрет является ключом, userId — сообщением — и отправьте результат на фронтенд. Если вы идентифицируете пользователей только по email (без userId), подписывайте email: подписываемое значение — userId, если он задан, иначе email. Если переданы оба, подписывайте userId — он имеет приоритет.
  3. Передайте хеш как userHash в Respondo.identify().
  4. Respondo проверяет хеш на стороне сервера. Если он неверен, данные идентификации удаляются, и пользователь считается анонимным.
Никогда не раскрывайте секретный ключ в коде фронтенда. HMAC должен вычисляться на вашем бэкенде.
После включения проверки каждый вызов identify() с userId или email должен содержать валидный userHash — иначе поля идентификации отбрасываются, и посетитель считается анонимным.

Примеры на стороне сервера#

Node.jsjavascript
const crypto = require('crypto');

const SECRET = process.env.RESPONDO_IDENTITY_SECRET;

function generateUserHash(userId) {
  return crypto
    .createHmac('sha256', SECRET)
    .update(userId)
    .digest('hex');
}

// В вашем API-эндпоинте:
app.get('/api/respondo-hash', (req, res) => {
  const hash = generateUserHash(req.user.id);
  res.json({ userHash: hash });
});
Pythonpython
import hmac, hashlib, os

SECRET = os.environ['RESPONDO_IDENTITY_SECRET']

def generate_user_hash(user_id: str) -> str:
    return hmac.new(
        SECRET.encode(),
        user_id.encode(),
        hashlib.sha256
    ).hexdigest()

# В вашем представлении / эндпоинте:
user_hash = generate_user_hash(request.user.id)
Gogo
import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

func GenerateUserHash(userID, secret string) string {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write([]byte(userID))
    return hex.EncodeToString(mac.Sum(nil))
}

Использование на фронтенде#

С проверкой личностиjavascript
// Получаем хеш с ВАШЕГО сервера
const { userHash } = await fetch('/api/respondo-hash').then(r => r.json());

Respondo.identify({
  email: user.email,
  name: user.name,
  userId: user.id,
  userHash: userHash  // подпись HMAC-SHA256
});