Assist

Как настроить OpenReplay Assist и поддерживать ваших конечных пользователей через экран в реальном времени и WebRTC.

Assist

OpenReplay Assist позволяет вам поддерживать ваших пользователей, видя их экран в реальном времени и мгновенно начиная звонок (WebRTC) с ними без необходимости в каком-либо стороннем ПО для демонстрации экрана.

npm i @openreplay/tracker-assist

С помощью JavaScript-сниппета

Section titled С помощью JavaScript-сниппета

Если ваш трекер OpenReplay настроен с помощью JS-сниппета, просто замените вхождение .../openreplay.js на .../openreplay-assist.js. Ниже приведён пример того, как должен выглядеть скрипт после изменения:

<!-- OpenReplay Tracking Code -->
<script>
var initOpts = { projectKey: "GxPpaDARdn2345fgt321" };
var startOpts = { userID: "" };
(function(A,s,a,y,e,r){
  r=window.OpenReplay=[e,r,y,[s-1, e]];
  s=document.createElement('script');s.src=A;s.async=!a;
  ...
})("//static.openreplay.com/latest/openreplay-assist.js", 1, 0, initOpts, startOpts);
</script>

Инициализируйте трекер, а затем загрузите плагин @openreplay/tracker-assist.

Если ваш веб-сайт является одностраничным приложением (SPA)

Section titled Если ваш веб-сайт является одностраничным приложением (SPA)
import trackerAssist from '@openreplay/tracker-assist';
import { tracker } from '@openreplay/tracker';

tracker.configure({
  projectKey: 'YOUR_PROJECT_KEY',
  ingestPoint: "https://openreplay.mydomain.com/ingest", // when dealing with the self-hosted version of OpenReplay
});
tracker.use(trackerAssist(options)); // check the list of available options below

tracker.start();

Если ваше веб-приложение использует серверный рендеринг (SSR)

Section titled Если ваше веб-приложение использует серверный рендеринг (SSR)

Следуйте приведённому ниже примеру, если ваше приложение использует SSR. Убедитесь, что tracker.start() вызывается, когда приложение находится в среде браузера (то есть через useEffect или componentDidMount).

import trackerAssist from '@openreplay/tracker-assist';
import { tracker } from '@openreplay/tracker';

tracker.configure({
  projectKey: 'YOUR_PROJECT_KEY',
  ingestPoint: "https://openreplay.mydomain.com/ingest", // when dealing with the self-hosted version of OpenReplay
});
tracker.use(trackerAssist(options)); // check the list of available options below

//...
function MyApp() {
  useEffect(() => { // use componentDidMount in case of React Class Component
    tracker.start();
  }, [])
//...
}

Плагин assist поддерживает следующие опции:

trackerAssist({
  callConfirm?: string|ConfirmOptions;
  controlConfirm?: string|ConfirmOptions;
  config?: object;
  onAgentConnect?: () => (()=>void | void);
  onCallStart?: () => (()=>void | void);
  onRemoteControlStart?: () => (()=>void | void);
  onCallDeny?: () => any;
  onRemoteControlDeny?: (agentInfo: Record<string, any>) => any;
  onRecordingDeny?: (agentInfo: Record<string, any>) => any;
  onDragCamera?: (dx: number, dy: number) => any;
  callUITemplate?: string
  /** 
   * enables gzip compression for big batches on client side
   * */
  compressionEnabled: boolean;
  /**
   * Minimum amount of MESSAGES in a batch to trigger compression run
   * @default 5000
   * */
  compressionMinBatchSize: number;
  /**
   * Show only the first part of an agent's name in the call popup
   * (e.g. "One Two" -> "One").
   * @default false
   */
  agentShortNames: boolean;
  /**
   * Postpone assist start until a userID is set on the session.
   * @default false
   */
  ignoreAnonymous: boolean;
  /**
   * When assist connects to the server:
   * - Autostart.Auto (default): always on tracker start.
   * - Autostart.Disabled: only via an explicit start() call.
   * - Autostart.Continuation: only via assist.start(), but the choice is remembered
   *   in sessionStorage so it auto-continues across page reloads until assist.stop().
   * @default Autostart.Auto
   */
  autostart: Autostart;
  /**
   * Require explicit user confirmation before anything is shared with an
   * agent: assist starts and opens the socket as usual, but no messages are
   * sent through it until the user approves the confirmation popup, which is
   * shown as soon as the first agent connects to the session. The approval
   * is remembered per-tab (sessionStorage) until stop() is called.
   * @default false
   */
  requestConfirm: boolean;
  /** Text/style customization for the session view confirmation popup. */
  sessionConfirm?: ConfirmOptions;
  /** Called when the user approves session viewing (requestConfirm mode). */
  onSessionConfirmApprove?: (agentInfo: Record<string, any>) => any;
  /** Called when the user denies session viewing (requestConfirm mode). */
  onSessionConfirmDeny?: (agentInfo: Record<string, any>) => any;
})

Настройка виджетов

Section titled Настройка виджетов

Просмотр в реальном времени, удалённое управление, а также виджеты звонков, которые видит конечный пользователь, можно полностью настроить.

Виджет просмотра в реальном времени

Section titled Виджет просмотра в реальном времени

Установите requestConfirm: true, чтобы требовать разрешения пользователя, прежде чем агент сможет просматривать его сессию в реальном времени. Assist запускается и подключается как обычно, но сессия остаётся невидимой для агента до тех пор, пока пользователь не подтвердит запрос во всплывающем окне, которое показывается, как только к сессии подключается первый агент. После принятия отслеживание перезапускается, и агент может видеть сессию пользователя в реальном времени.

Разрешение запоминается для каждой вкладки (в sessionStorage) до вызова stop(), который его отзывает, поэтому следующий вызов start() снова покажет запрос.

tracker.use(trackerAssist({
  requestConfirm: true,
  sessionConfirm: { text: 'A support agent would like to view your screen. Allow?' },
  onSessionConfirmApprove: ({ email, name, query }) => console.log("Session viewing approved"),
  onSessionConfirmDeny: ({ email, name, query }) => console.log("Session viewing denied"),
}));

Текст и стиль всплывающего окна можно настроить с помощью опции sessionConfirm, которая принимает приведённый ниже объект ConfirmOptions:

type ConfirmOptions = {
  text?:string,
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
  confirmBtn?: ButtonOptions, 
  declineBtn?: ButtonOptions
}

type ButtonOptions = HTMLButtonElement | string | {
  innerHTML?: string, // to pass an svg string or text
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
}

Виджет удалённого управления

Section titled Виджет удалённого управления

Текст и стиль всплывающего окна можно настроить с помощью опции controlConfirm, которая принимает приведённый ниже объект ConfirmOptions:

type ConfirmOptions = {
  text?:string,
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
  confirmBtn?: ButtonOptions, 
  declineBtn?: ButtonOptions
}

type ButtonOptions = HTMLButtonElement | string | {
  innerHTML?: string, // to pass an svg string or text
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
}

Текст и стиль всплывающего окна можно настроить с помощью опции callConfirm, которая принимает приведённый ниже объект ConfirmOptions:

type ConfirmOptions = {
  text?:string,
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
  confirmBtn?: ButtonOptions, 
  declineBtn?: ButtonOptions
}

type ButtonOptions = HTMLButtonElement | string | {
  innerHTML?: string, // to pass an svg string or text
  style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
}

Можно настроить каждый аспект этого виджета с помощью приведённого ниже набора ids и classes. Ids служат якорями для отдельных кнопок/элементов, тогда как classes могут использоваться для групповых контейнеров.

Тип HTMLИмя(имена)Описание
idor-assistКонтейнер виджета
classcard, border-dark, shadow и drag-areaСтили для границы и тени карточки
idcontrolsКонтейнер для части звонка внутри виджета
classcard-headerСтили для заголовка карточки виджета звонка (того, что показывает имя агента рядом с таймером)
idagent-nameКонтейнер для имени агента
iddurationКонтейнер для таймера
idvideo-containerКонтейнер собственного видеопотока пользователя
idremote-streamВидеопоток агента
classcard-footerКонтейнер для кнопок «Без звука», «Видео», «Завершить звонок»
idaudio-btnКнопка отключения звука
idvideo-btnКнопка видео
idend-call-btnКнопка завершения звонка
idremote-control-rowСтрока для удалённого управления
idend-control-btnId для кнопки завершения управления

Вот список всех колбэков:

  • callConfirm: Настройте текст и/или макет всплывающего окна запроса звонка.
  • controlConfirm: Настройте текст и/или макет всплывающего окна запроса удалённого управления.
  • config: Содержит пользовательскую конфигурацию сервера ICE/TURN. По умолчанию { 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }], 'sdpSemantics': 'unified-plan' }.
  • onAgentConnect: () => (()=>void | void): Эта функция обратного вызова срабатывает, как только начинается живая сессия, и возвращает данные агента (email, имя и query). Она также может вернуть onAgentDisconnect, которая будет вызвана при отключении сессии. В случае нестабильного соединения она может быть вызвана несколько раз. Ниже приведён пример:
onAgentConnect = ({ email, name, query }) => {
  console.log("Live session started")
  const onAgentDisconnect =  () => console.log("Live session stopped")
  return onAgentDisconnect
}
  • onCallStart: ({ email, name, query }) => (()=>void | void): Эта функция обратного вызова срабатывает, как только начинается звонок (webRTC), и возвращает данные агента (email, имя и query). Она также может вернуть onCallEnd, которая будет вызвана при завершении звонка. В случае нестабильного соединения она может быть вызвана несколько раз. Ниже приведён пример:
onCallStart: () => {
  console.log("Call started")
  const onCallEnd = () => console.log("Call ended")
  return onCallEnd
}
  • onRemoteControlStart: ({ email, name, query }) => (()=>void | void): Эта функция обратного вызова срабатывает, как только начинается сессия удалённого управления, и возвращает данные агента (email, имя и query). Она также может вернуть onRemoteControlEnd, которая будет вызвана при отзыве разрешений на удалённое управление. Ниже приведён пример:
onRemoteControlStart: () => {
  console.log("Remote control started")
  const onControlEnd = () => console.log("Remote control ended")
  return onControlEnd
}
  • onCallDeny?: () => any;: Эта функция обратного вызова срабатывает, когда пользователь отклоняет звонок на этапе запроса.
onCallDeny: () => {
  console.log("Call denied")
}
  • onRemoteControlDeny?: (agentInfo: Record<string, any>) => any;: Эта функция обратного вызова срабатывает, когда пользователь отклоняет сессию удалённого управления на этапе запроса, и возвращает данные агента (email, имя и query).
onRemoteControlDeny: ({ email, name, query }) => {
  console.log("Remote control request denied for", email)
}
  • onRecordingDeny?: (agentInfo: Record<string, any>) => any;: Эта функция обратного вызова срабатывает, когда пользователь отклоняет сессию записи на этапе запроса, и возвращает данные агента (email, имя и query).
onRecordingDeny: ({ email, name, query }) => {
  console.log("Recording session denied")
 
}
  • onSessionConfirmApprove?: (agentInfo: Record<string, any>) => any;: Эта функция обратного вызова срабатывает, когда пользователь подтверждает просмотр сессии (в режиме requestConfirm), и возвращает данные агента (email, имя и query).
onSessionConfirmApprove: ({ email, name, query }) => {
  console.log("Session viewing approved for", email)
}
  • onSessionConfirmDeny?: (agentInfo: Record<string, any>) => any;: Эта функция обратного вызова срабатывает, когда пользователь отклоняет просмотр сессии (в режиме requestConfirm), и возвращает данные агента (email, имя и query).
onSessionConfirmDeny: ({ email, name, query }) => {
  console.log("Session viewing denied")
}
  • onDragCamera?: (dx: number, dy: number) => any;: Эта функция ожидает обработчик, который определяет поведение удерживаемой кнопки мыши внутри canvas Three.js для удалённого управления. Обработчик получает dx и dy, указывающие на дельты движения мыши.
onDragCamera: (dx, dy) => {
  moveCamera(dx, dy)
}

tracker.use() возвращает экземпляр assist, который предоставляет методы для управления assist во время выполнения:

const assist = tracker.use(trackerAssist(options));

assist.stop();
assist.start();
  • start(): (Пере)запускает assist. Это безоперационный вызов, если сам трекер ещё не активен (assist запустится вместе с трекером). В режиме Autostart.Continuation он сохраняет флаг в sessionStorage, чтобы assist автоматически продолжал работу при перезагрузках страницы. Явный вызов start() также отменяет любую отсрочку ignoreAnonymous.
  • stop(): Останавливает assist, отключая сокет и очищая все соединения. Assist не перезапустится автоматически до вызова start(). В режиме Autostart.Continuation это также очищает сохранённый флаг, поэтому перезагрузка не приведёт к автопродолжению. В режиме requestConfirm это также отзывает разрешение пользователя, поэтому следующий вызов start() снова покажет запрос.

Возникли трудности с настройкой этого плагина? Присоединяйтесь к нашему Slack или загляните на наш Форум и получите помощь от нашего сообщества.