Сравнение версий

Ключ

  • Эта строка добавлена.
  • Эта строка удалена.
  • Изменено форматирование.

Оглавление

Описание

В данной статье рассмотрены необходимые методы и инструменты для интеграции с панелью оператора.

Это может быть необходимо для подключения функционала панели оператора в свой интерфейс (например, окно оператора в едином окне CRM)

Интеграция

Основные шаги интеграции

Авторизация

Чтобы использовать панель оператора, нужно 
1. Авторизоваться используя эндпоинт /auth/login. Детали в доке https://iam.dev.twin24.ai/docs/index.html
2. Подключиться к прослушиванию событий из центрифуги - передавая токен авторизации
3. Передавать во всех запросах токен авторизации полученный при атворизации

Основные методы

...

нужно получить авторизационный токен оператора. 

Для этого можно воспользоваться методом авторизации:

Важно:

- У токена есть время жизни

- Рекомендуем устанавливать время жизни токена 24 часа и обновлять за 15 минут до окончания

- Также токен нужно обновлять при получении 403 ошибки от любого метода Twin

- Для обновления можно использовать тот же метод или метод обновления по рефреш токену

Управление оператором и работа с сообщениями

  • Для управления оператором, получения информации о чатах, об очередях переписок можно воспользоваться методами из раздела "Управление оператором и очередями
  • Для работы с сообщениями нужно:
    • Подключиться к соккет-серверу для получения событий от бота (подробнее в разделе "Live события")
    • Использовать методы из раздела "Работа с сообщениями" для отправки, редактирования и удаления сообщений

Основные методы API

Полная документация по всем доступным эндпоинтам (раздел "Chat API")

Управление оператором и очередями 
Якорь
manage
manage

  • /users/me - получить

...

  • информацию о текущем оператора
  • /timestamp - получить время сервера(полезно для таймеров, отсчетов, и понимания разницы)
  • /users/me/activate - сменить статус текущего оператора

...

  • на возможность приема входящих сессий
  • /users/me/pause - поставить оператора на паузу(прекратить получать входящие сессии)
  • /sessions/${sessionId}/operators/${userId} - перевести сессию на конкретного пользователя
  • /sessions/${sessionId}/names/${name} - переименовать сессию
  • /sessions - получить список сессий(всех сессий, даже завершенных)
  • /sessions/${sessionId}/operators/${userId} - перевести сессию на другого оператора
  • /sessions/${sessionId}/groupoperators/${userId} - перевести сессию на группу операторов
  • /users - получить список операторов
  • /groups - получить список групп операторов
  • /sessions/${sessionId} - delete: завершить сессию
  • /clients/${clientId}/ban - заблокировать клиента
  • /clients/${clientId}/unban - разблокировать клиента

Работа с сообщениями
Якорь
msgs
msgs

  • /sessions/${id}/messages - получить список сообщений по id сессии
  • /clients/${id}/messages - получить список сообщений по id клиенту
  • /sessions/${sessionId}/operators/messages - отправить сообщение в сессию
  • /sessions/${sessionId}/operators/messages/${messageId} - put:редактировать сообщение
  • /sessions/${sessionId}/operators/messages/${messageId} - delete:удалить сообщение

...

Live события 
Якорь
live
live

Подключение к соккет-серверу

Для работы с соккет-сервером используется инструмент Centrifuge. 

Подробности о доступных SDK для работы с Centrifuge можно получить в официальной документации Centrifuge

Эндпоинт для подключения: wss://twin24.ai/centrifugo/connection/websocket 

Пример на js

1.

Полная дока по всем доступным эндпоинтам здесь https://chats-api.dev.twin24.ai/docs/

Live события

Для работы, используем centrifuge

Создаем экземпляр класса Centrifuge, передаем ему URL сервера и создаем подключение:

Блок кода
languagejavascript
const centrifuge = new Centrifuge(

...


  `wss://

...

twin24.ai/centrifugo/connection/

...

websocket `,

...


  {

...


    data: {

...


      application: 'notifications',

...


      settings: { token: 'your_auth_token_here' },

...


    },

...


  },

...


)

2. Обрабатываем connection, и publication события, в самом publication получаем и реагируем на события

Блок кода
languagejavascript
centrifuge.on('connected', () => {

...


  // some logic when connected

...


})

...


centrifuge.on('publication', (publication) => {

...


  const payload = publication.data

...



  switch (payload.event) {

...


    case 'chatMessageRead':

...


      // handle chatMessageRead event

...


      break

...


    default:

...


      console.warn('Unknown event type:', payload.event)

...


  }

...


})


Список событий

События, которые

...

получает оператор

  • chatSessionStarted - Оператору пришла новая сессия чата (при этом не факт, что оператору, может быть просто в помощь)

...

  • Блок кода
    languagejavascript
    titlechatSessionStarted
    collapsetrue
    chatSessionStarted: {
      event: 'chatSessionStarted',
      data: {
        id: string;
        chatId: string;
        clientId: string | null;
        name: string;
        markedAsSpam: boolean;
        operatorId: string | number | null;
        operatorType?: string;
        channel: string;
        botStatus?: string | null;
        status: string;
        startedAt: string;
        clientOnlineAt?: string | null;
        clientOfflineAt?: string | null;
        lastMessageCreatedAt: string | null;
        lastMessage?: Unknown | null;
        clientExternalId?: string | null;
        clientBanned?: boolean | null;
        referer?: string;
        clientIp?: string | null;
        coordinates?: {
          city?: string | null;
          latitude?: number | null;
          zip_code?: string | null;
          longitude?: number | null;
          time_zone?: string | null;
          region_name?: string | null;
          country_code?: string | null;
          country_name?: string | null;
        } | null;
        unreadClientMessageCount?: number | null;
        unreadClientMessageExists?: boolean | null;
        messengerType?: string | null;
        whatsappPhone?: string | null;
        timerFirstAnswer?: number;
        timerNextAnswers?: number;
        lastOperatorMessage?: Unknown | null;
        firstClientMessageAfterLastOperatorMessage?: Unknown | null;
        operatorAssignedAt: string | null;
        previousOperator?: {
          id?: string | null;
          name?: string | null;
        } | null;
      }
    }
  • operatorNotFound - Сессия не нашла оператора и упала в помощь
    Блок кода
    languagejavascript
    titleoperatorNotFound
    collapsetrue
    operatorNotFound: {
      action: 'operatorNotFound';
      data: {
        botStatus: string; // например, 'HELP'
        chatId: string;
        operatorType: string;
        sessionId: string;
        status: string;
      };
    }
  • chatSessionAdded - Сессия пришла оператору
    Блок кода
    languagejavascript
    titlechatSessionAdded
    collapsetrue
    chatSessionAdded: {
      action: 'chatSessionAdded';
      data: {
        id: string;
        chatId: string;
        clientId: string | null;
        name: string;
        markedAsSpam: boolean;
        operatorId: string | number | null;
        operatorType?: string;
        channel: string;
        botStatus?: string | null;
        status: string;
        startedAt: string;
        clientOnlineAt?: string | null;
        clientOfflineAt?: string | null;
        lastMessageCreatedAt: string | null;
        lastMessage?: Unknown | null;
        clientExternalId?: string | null;
        clientBanned?: boolean | null;
        referer?: string;
        clientIp?: string | null;
        coordinates?: {
          city?: string | null;
          latitude?: number | null;
          zip_code?: string | null;
          longitude?: number | null;
          time_zone?: string | null;
          region_name?: string | null;
          country_code?: string | null;
          country_name?: string | null;
        } | null;
        unreadClientMessageCount?: number | null;
        unreadClientMessageExists?: boolean | null;
        messengerType?: string | null;
        whatsappPhone?: string | null;
        timerFirstAnswer?: number;
        timerNextAnswers?: number;
        lastOperatorMessage?: Unknown | null;
        firstClientMessageAfterLastOperatorMessage?: Unknown | null;
        operatorAssignedAt: string | null;
        previousOperator?: {
          id?: string | null;
          name?: string | null;
        } | null;
      };
    }
  • chatMessageCreated - Оператору пришло новое сообщение в чате
    Блок кода
    languagejavascript
    titlechatMessageCreated
    collapsetrue
    chatMessageCreated: {
      action: 'chatMessageCreated';
      data: {
        id: string;
        sessionId: string;
        clientId: string | null;
        authorId: string;
        authorType: string;
        authorName: string | null;
        type: 'REGULAR' | 'TERMINAL';
        body: string;
        attachments: unknown[];
        createdAt: string;
        updatedAt?: string | null;
        readAt?: string | null;
        deletedAt?: string | null;
        actions?: unknown[];
        replyTo?: {
          id: string;
          authorType: string;
          body: string;
          attachments: unknown[];
          authorName: string | null;
        } | null;
        history?: {
          editedAt?: string | null;
        }[];
      }
      replyToMessage?: {
        id: string;
        authorType: string;
        body: string;
        attachments: unknown[];
        authorName: string | null;
      } | null;
    }
  • chatMessageEdited - Кто-то из операторов изменил сообщение в чате
    Блок кода
    languagejavascript
    titlechatMessageEdited
    collapsetrue
    chatMessageEdited: {
      action: 'chatMessageEdited';
      data: {
        body: string;
        messageId: string;
        attachments: unknown[];
      };
    }
  • chatMessageRead - Оператору пришло сообщение, что клиент прочитал сообщение в чате
    Блок кода
    languagejavascript
    titlechatMessageRead
    collapsetrue
    chatMessageRead: {
      action: 'chatMessageRead';
      data: {
        messageId: string;
      };
    }
  • chatSessionDeleted - Есть кейсы, когда сессия после отправки определенного сообщения уходит на бота - и тогда пропадает у оператора
    Блок кода
    languagejavascript
    titlechatSessionDeleted
    collapsetrue
    chatSessionDeleted: {
      action: 'chatSessionDeleted';
      data: {
        sessionId: string;
      };
    }
  • chatSessionSwitchedFromBotToOperator - Сессия была переключена с бота на оператора
    Блок кода
    languagejavascript
    titlechatSessionSwitchedFromBotToOperator
    collapsetrue
    chatSessionSwitchedFromBotToOperator: {
      action: 'chatSessionSwitchedFromBotToOperator';
      data: {
        operatorId: string;
        operatorName: string;
        sessionId: string;
      };
    }
  • sessionClosedByClient - Клиент закрыл сессию
    Блок кода
    languagejavascript
    titlesessionClosedByClient
    collapsetrue
    sessionClosedByClient: {
      action: 'sessionClosedByClient';
      data: {
        chatId: string;
        sessionId: string;
      };
    }
  • operatorBlocked - Оператора заблокировали на платформе — требуется выкинуть оператора из кабинета
    Блок кода
    languagejavascript
    titleoperatorBlocked
    collapsetrue
    operatorBlocked: {
      action: 'operatorBlocked',
      data: Unknown,
    }
  • chatUserExists - Кто-то зашел в текущего оператора. Текущий сеанс оператора нужно закрыть
    Блок кода
    languagejavascript
    titlechatUserExists
    collapsetrue
    chatUserExists: {
      action: 'chatUserExists';
      data: Unknown;
    }
  • typing - пользователь печатает сообщение в чате
    Блок кода
    languagejavascript
    titletyping
    collapsetrue
    typing: {
      action: 'typing',
      data: Unknown,
    }
  • operatorLoggedOut - сделать оператора офлайн
    Блок кода
    languagejavascript
    titleoperatorLoggedOut
    collapsetrue
    operatorLoggedOut: {
      action: 'operatorLoggedOut,
      data: Unknown,
    }
  • clientOnline - клиент стал онлайн
    Блок кода
    languagejavascript
    titleclientOnline
    collapsetrue
    clientOnline: {
      action: 'clientOnline',
      data: {
        id: string;
      }
    }
  • clientOffline - клиент стал офлайн
    Блок кода
    languagejavascript
    titleclientOffline
    collapsetrue
    clientOffline: {
      action: 'clientOffline',
      data: {
        id: string;
      }
    }

События, которые отправляет оператор

  • typing – отправляет оператор, когда печатает сообщение в чате

События, что отправляет оператор в центрифугу:
typing - отправляет оператор, когда печатает сообщение в чате

...

operatorNotFound: {
  action: 'operatorNotFound';
  data: {
    botStatus: string; // например, 'HELP'
    chatId: string;
    operatorType: string;
    sessionId: string;
    status: string;
  };
}

chatSessionAdded: {
  action: 'chatSessionAdded';
  data: {
    id: string;
    chatId: string;
    clientId: string | null;
    name: string;
    markedAsSpam: boolean;
    operatorId: string | number | null;
    operatorType?: string;
    channel: string;
    botStatus?: string | null;
    status: string;
    startedAt: string;
    clientOnlineAt?: string | null;
    clientOfflineAt?: string | null;
    lastMessageCreatedAt: string | null;
    lastMessage?: Unknown | null;
    clientExternalId?: string | null;
    clientBanned?: boolean | null;
    referer?: string;
    clientIp?: string | null;
    coordinates?: {
      city?: string | null;
      latitude?: number | null;
      zip_code?: string | null;
      longitude?: number | null;
      time_zone?: string | null;
      region_name?: string | null;
      country_code?: string | null;
      country_name?: string | null;
    } | null;
    unreadClientMessageCount?: number | null;
    unreadClientMessageExists?: boolean | null;
    messengerType?: string | null;
    whatsappPhone?: string | null;
    timerFirstAnswer?: number;
    timerNextAnswers?: number;
    lastOperatorMessage?: Unknown | null;
    firstClientMessageAfterLastOperatorMessage?: Unknown | null;
    operatorAssignedAt: string | null;
    previousOperator?: {
      id?: string | null;
      name?: string | null;
    } | null;
  };
}

chatMessageCreated: {
  action: 'chatMessageCreated';
  data: {
    id: string;
    sessionId: string;
    clientId: string | null;
    authorId: string;
    authorType: string;
    authorName: string | null;
    type: 'REGULAR' | 'TERMINAL';
    body: string;
    attachments: unknown[];
    createdAt: string;
    updatedAt?: string | null;
    readAt?: string | null;
    deletedAt?: string | null;
    actions?: unknown[];
    replyTo?: {
      id: string;
      authorType: string;
      body: string;
      attachments: unknown[];
      authorName: string | null;
    } | null;
    history?: {
      editedAt?: string | null;
    }[];
  }
  replyToMessage?: {
    id: string;
    authorType: string;
    body: string;
    attachments: unknown[];
    authorName: string | null;
  } | null;
}

chatMessageEdited: {
  action: 'chatMessageEdited';
  data: {
    body: string;
    messageId: string;
    attachments: unknown[];
  };
}

chatMessageRead: {
  action: 'chatMessageRead';
  data: {
    messageId: string;
  };
}

chatSessionDeleted: {
  action: 'chatSessionDeleted';
  data: {
    sessionId: string;
  };
};

chatSessionSwitchedFromBotToOperator: {
  action: 'chatSessionSwitchedFromBotToOperator';
  data: {
    operatorId: string;
    operatorName: string;
    sessionId: string;
  };
};

sessionClosedByClient: {
  action: 'sessionClosedByClient';
  data: {
    chatId: string;
    sessionId: string;
  };
}

operatorBlocked: {
  action: 'operatorBlocked',
  data: Unknown,
}

chatUserExists: {
  action: 'chatUserExists';
  data: Unknown;
}

typing: {
  action: 'typing',
  data: Unknown,
}

operatorLoggedOut: {
  action: 'operatorLoggedOut,
  data: Unknown,
}

clientOnline: {
  action: 'clientOnline',
  data: {
    id: string;
  }
}

...