Assist
OpenReplay Assist te permite dar soporte a tus usuarios viendo su pantalla en vivo y entrando al instante en una llamada (WebRTC) con ellos sin necesidad de ningún software de compartición de pantalla de terceros.
Instalación
Section titled Instalaciónnpm i @openreplay/tracker-assist
Con el fragmento de JavaScript
Section titled Con el fragmento de JavaScriptSi tu tracker de OpenReplay está configurado mediante el fragmento de JS, simplemente reemplaza la aparición de .../openreplay.js por .../openreplay-assist.js. A continuación se muestra un ejemplo de cómo debería verse el script después del cambio:
<!-- 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>
Con NPM
Section titled Con NPMInicializa el tracker y luego carga el plugin @openreplay/tracker-assist.
Si tu sitio web es una Single Page Application (SPA)
Section titled Si tu sitio web es una Single Page Application (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();
Si tu aplicación web se renderiza en el servidor (SSR)
Section titled Si tu aplicación web se renderiza en el servidor (SSR)Sigue el siguiente ejemplo si tu aplicación es SSR. Asegúrate de que tracker.start()
se llame una vez que la aplicación esté en el entorno del navegador (es decir, mediante useEffect o 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();
}, [])
//...
}
Opciones
Section titled OpcionesEl plugin de assist admite las siguientes opciones:
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;
})
Personalización de los widgets
Section titled Personalización de los widgetsLa vista en vivo, el control remoto, así como los widgets de llamada, los que ve el usuario final, se pueden personalizar por completo.
Widget de vista en vivo
Section titled Widget de vista en vivoEstablece requestConfirm: true para requerir el permiso del usuario antes de que un agente pueda ver su sesión en vivo. Assist se inicia y se conecta como de costumbre, pero la sesión permanece invisible para el agente hasta que el usuario apruebe el popup de confirmación, que se muestra en cuanto el primer agente se conecta. Una vez aceptado, el seguimiento se reinicia y el agente puede entonces ver la sesión del usuario en vivo.
La aprobación se recuerda por pestaña (en sessionStorage) hasta que se llama a stop(), que la revoca, por lo que el siguiente start() volverá a solicitarla.
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"),
}));
El texto y el estilo del popup se pueden personalizar mediante la opción sessionConfirm, que toma el siguiente objeto 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'})
}
Widget de control remoto
Section titled Widget de control remotoEl texto y el estilo del popup se pueden personalizar mediante la opción controlConfirm, que toma el siguiente objeto 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'})
}
Widget de llamada
Section titled Widget de llamadaEl texto y el estilo del popup se pueden personalizar mediante la opción callConfirm, que toma el siguiente objeto 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'})
}
Es posible personalizar todos los aspectos de este widget mediante el siguiente conjunto de ids y classes. Los Ids sirven como anclas para botones/elementos individuales, mientras que las classes pueden usarse para contenedores de grupo.
| Tipo HTML | Nombre(s) | Descripción |
|---|---|---|
| id | or-assist | Contenedor del widget |
| class | card, border-dark, shadow y drag-area | Estilos para el borde y la sombra de la tarjeta |
| id | controls | Contenedor de la parte de llamada dentro del widget |
| class | card-header | Estilos para la cabecera de la tarjeta del widget de llamada (la que muestra el nombre del agente junto a un temporizador) |
| id | agent-name | Contenedor del nombre del agente |
| id | duration | Contenedor del temporizador |
| id | video-container | Contenedor del propio feed de video del usuario |
| id | remote-stream | Feed de video del agente |
| class | card-footer | Contenedor para los botones Silenciar, Video, Finalizar llamada |
| id | audio-btn | Botón de silenciar |
| id | video-btn | Botón de video |
| id | end-call-btn | Botón de finalizar llamada |
| id | remote-control-row | Fila para los controles remotos |
| id | end-control-btn | Id para el botón de finalizar control |
Callbacks
Section titled CallbacksAquí está la lista de todos los callbacks:
callConfirm: Personaliza el texto y/o el diseño del popup de solicitud de llamada.controlConfirm: Personaliza el texto y/o el diseño del popup de solicitud de control remoto.config: Contiene la configuración personalizada del servidor ICE/TURN. Por defecto es{ 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }], 'sdpSemantics': 'unified-plan' }.onAgentConnect: () => (()=>void | void): Esta función de callback se dispara en cuanto comienza una sesión en vivo y devuelve los detalles del agente (email, nombre y query). También puede devolveronAgentDisconnect, que se llamará cuando la sesión se desconecte. En caso de una conexión inestable, esto puede llamarse varias veces. A continuación se muestra un ejemplo:
onAgentConnect = ({ email, name, query }) => {
console.log("Live session started")
const onAgentDisconnect = () => console.log("Live session stopped")
return onAgentDisconnect
}
onCallStart: ({ email, name, query }) => (()=>void | void): Esta función de callback se dispara en cuanto comienza una llamada (webRTC) y devuelve los detalles del agente (email, nombre y query). También puede devolveronCallEnd, que se llamará cuando la llamada termine. En caso de una conexión inestable, esto puede llamarse varias veces. A continuación se muestra un ejemplo:
onCallStart: () => {
console.log("Call started")
const onCallEnd = () => console.log("Call ended")
return onCallEnd
}
onRemoteControlStart: ({ email, name, query }) => (()=>void | void): Esta función de callback se dispara en cuanto comienza una sesión de control remoto y devuelve los detalles del agente (email, nombre y query). También puede devolveronRemoteControlEnd, que se llamará cuando se revoquen los permisos de control remoto. A continuación se muestra un ejemplo:
onRemoteControlStart: () => {
console.log("Remote control started")
const onControlEnd = () => console.log("Remote control ended")
return onControlEnd
}
onCallDeny?: () => any;: Esta función de callback se dispara cuando el usuario deniega la llamada durante la fase de solicitud.
onCallDeny: () => {
console.log("Call denied")
}
onRemoteControlDeny?: (agentInfo: Record<string, any>) => any;: Esta función de callback se dispara cuando el usuario deniega la sesión de control remoto durante la fase de solicitud y devuelve los detalles del agente (email, nombre y query).
onRemoteControlDeny: ({ email, name, query }) => {
console.log("Remote control request denied for", email)
}
onRecordingDeny?: (agentInfo: Record<string, any>) => any;: Esta función de callback se dispara cuando el usuario deniega la sesión de grabación durante la fase de solicitud y devuelve los detalles del agente (email, nombre y query).
onRecordingDeny: ({ email, name, query }) => {
console.log("Recording session denied")
}
onSessionConfirmApprove?: (agentInfo: Record<string, any>) => any;: Esta función de callback se dispara cuando el usuario aprueba la visualización de la sesión (en modorequestConfirm) y devuelve los detalles del agente (email, nombre y query).
onSessionConfirmApprove: ({ email, name, query }) => {
console.log("Session viewing approved for", email)
}
onSessionConfirmDeny?: (agentInfo: Record<string, any>) => any;: Esta función de callback se dispara cuando el usuario deniega la visualización de la sesión (en modorequestConfirm) y devuelve los detalles del agente (email, nombre y query).
onSessionConfirmDeny: ({ email, name, query }) => {
console.log("Session viewing denied")
}
onDragCamera?: (dx: number, dy: number) => any;: Esta función espera un handler que defina el comportamiento de un botón del ratón mantenido pulsado dentro de un canvas de Three.js para control remoto. El handler recibe dx y dy, que indican los deltas de movimiento del ratón.
onDragCamera: (dx, dy) => {
moveCamera(dx, dy)
}
Métodos
Section titled Métodostracker.use() devuelve la instancia de assist, que expone métodos para controlar assist en tiempo de ejecución:
const assist = tracker.use(trackerAssist(options));
assist.stop();
assist.start();
start(): (Re)inicia assist. No hace nada si el propio tracker aún no está activo (assist se iniciará junto con el tracker). En el modoAutostart.Continuation, persiste un flag ensessionStoragepara que assist continúe automáticamente entre recargas de página. Unstart()explícito también anula cualquier aplazamiento deignoreAnonymous.stop(): Detiene assist desconectando el socket y limpiando todas las conexiones. Assist no se reiniciará automáticamente hasta que se llame astart(). En el modoAutostart.Continuation, esto también borra el flag persistido, por lo que una recarga no continuará automáticamente. En el modorequestConfirm, también revoca la aprobación del usuario, por lo que el siguientestart()volverá a solicitarla.
¿Tienes preguntas?
Section titled ¿Tienes preguntas?¿Tienes problemas para configurar este plugin? Conéctate a nuestro Slack o consulta nuestro Foro y obtén ayuda de nuestra comunidad.