React Native
El paquete @kavchat/react-native añade a tu aplicación un chat de soporte basado en guiones: un proveedor, una pantalla de chat y un botón flotante opcional. Las respuestas vienen de los guiones que publicas en el panel de control y se ejecutan en el dispositivo.
Instalación
El paquete está escrito íntegramente en JavaScript, sin código nativo propio ni biblioteca de iconos, por lo que funciona igual en una aplicación de React Native convencional y en Expo. Dependencias pares: react a partir de la versión 18 y react-native a partir de la versión 0.72.
React Native CLI (sin Expo)
yarn add @kavchat/react-native @react-native-async-storage/async-storage
cd ios && pod installAsyncStorage es un módulo nativo: pod install lo enlaza en iOS, y en Android el enlace es automático.
Expo
Funciona en Expo Go y en compilaciones de desarrollo:
yarn add @kavchat/react-native
npx expo install @react-native-async-storage/async-storageSin AsyncStorage
AsyncStorage conserva la versión publicada y la conversación entre sesiones. No es obligatorio instalarlo: sin él, el paquete guarda todo en memoria, así que el bot funciona, pero vuelve a descargar la versión cada vez que se inicia. Para usar otro almacenamiento, como MMKV, pasa en la propiedad storage cualquier objeto { getItem, setItem, removeItem? }, síncrono o asíncrono:
import { MMKV } from 'react-native-mmkv';
const mmkv = new MMKV();
const storage = {
getItem: (k: string) => mmkv.getString(k) ?? null,
setItem: (k: string, v: string) => mmkv.set(k, v),
removeItem: (k: string) => mmkv.delete(k),
};
<KavchatProvider publicKey="pk_live_..." storage={storage}>Uso
import { KavchatProvider, KavchatChat, KavchatLauncher, useKavchat } from '@kavchat/react-native';
export default function App() {
return (
<KavchatProvider publicKey="pk_live_..." onScreen={(screen, id) => navigation.navigate(screen, { id })}>
<Navigation />
{/* floating button, bottom end corner; opens the chat in a modal */}
<KavchatLauncher />
</KavchatProvider>
);
}
// or as a screen in your own navigator
function SupportScreen() {
return <KavchatChat />;
}
// or your own button
function HelpButton() {
const { available, open } = useKavchat();
if (!available) return null; // bot is off, limited to testers, or over quota
return <Button title="Help" onPress={open} />;
}Propiedades de KavchatProvider
| Propiedad | Descripción |
|---|---|
publicKey | pk_live_... del panel de control. Puedes incluirla en la aplicación. |
apiBase | Valor predeterminado: https://api.kavchat.com. |
locale | Idioma de la interfaz (he, en, ar, ru, es, fr, de, pt, it, tr). Por defecto: el idioma del dispositivo y, si no hay traducción, el idioma del bot. La búsqueda de coincidencias con los guiones siempre se hace en el idioma del bot. |
userToken, userName | Identificación del usuario; consulta más abajo. |
onScreen(screen, targetId?) | Se llama al pulsar un botón de tipo "Pantalla" en el guion. Sin esta función, esos botones no hacen nada. |
screens | Pantallas que la aplicación puede abrir, para la lista desplegable del editor. Consulta Lista de pantallas en el editor. |
onEvent(event) | ready, unavailable, effect, ticket. |
storage | Cualquier objeto { getItem, setItem, removeItem? }, síncrono o asíncrono. Por defecto: AsyncStorage y, si no está instalado, la memoria. |
theme | Personalización de colores; consulta Colores y RTL. |
useKavchat() devuelve { status, available, offline, locale, isOpen, open, close, toggle, setUser, startNewConversation, openContactForm, controller }.
Propiedades de KavchatChat: onClose? (muestra un botón de cierre), hideHeader? y style?. Propiedades de KavchatLauncher: style? (posición), onPress? (para abrir tu propia pantalla en lugar de la ventana integrada) y attention? (false desactiva el mensaje).
Cuando configuras en el panel de administración un mensaje junto al botón del chat (una burbuja de diálogo o texto curvo sobre el botón), KavchatLauncher lo muestra tras el tiempo de espera establecido, como máximo una vez al día. Cerrar el mensaje o abrir el chat lo oculta hasta el día siguiente. El mensaje no aparece mientras el chat está abierto. Si el dispositivo tiene activada la reducción de movimiento, el mensaje se muestra sin animación. Con la opción "No mostrar en teléfonos" activada, el mensaje solo aparece en tablets (cuando el lado más corto de la pantalla mide 600 puntos o más).
Token de identidad
Sin token, el usuario es un invitado y el formulario de contacto le pide un correo electrónico o un teléfono. Para identificar a un usuario que ha iniciado sesión, firma un JWT de corta duración en tu servidor con la clave secreta (nunca en la aplicación; consulta Identificación de usuarios) y pásalo así:
<KavchatProvider publicKey="pk_live_..." userToken={session?.kavchatToken} userName={session?.firstName}>Cambiar userToken (al iniciar o cerrar sesión) vuelve a cargar la versión, porque el grupo de usuarios de prueba depende de la identidad del usuario. También puedes llamar a useKavchat().setUser({ token, name }). El token solo se envía en el encabezado Authorization: Bearer y no se guarda en el dispositivo. Una conversación guardada está vinculada a una huella del token, por lo que otro usuario en el mismo dispositivo inicia una conversación nueva.
Enlaces, pantallas y formulario de contacto
- Los botones de tipo
linksolo abren direccioneshttps:ytel:, medianteLinking.openURL. No se abren otros tipos de direcciones. - Los botones de tipo
screenllaman aonScreen. El chat permanece donde estaba. - El botón "Contactar con el equipo" abre el formulario de contacto con la conversación adjunta. Tras el envío, se muestra el número de ticket.
Lista de pantallas en el editor
Declara una sola vez las pantallas que la aplicación puede abrir en la propiedad screens de KavchatProvider. El SDK envía la lista a Kavchat automáticamente, y el editor de guiones ofrece esas pantallas en una lista desplegable con sus nombres, en lugar de un campo de texto libre. El editor también pide un identificador de elemento cuando una pantalla lo necesita y avisa si un botón lleva a una pantalla no declarada. No hay que introducir la lista de pantallas a mano en el panel de control.
const screens = [
{ id: 'orders', label: 'My orders' },
{ id: 'product', label: 'Product page', needsTarget: true }, // the button also carries a product id
];
<KavchatProvider
publicKey="pk_live_..."
screens={screens}
onScreen={(screen, targetId) => navigation.navigate(screen, targetId ? { id: targetId } : undefined)}
>ides el valor que recibeonScreen: letras latinas, dígitos,_,.y-, hasta 40 caracteres.labeles el nombre que ve el administrador, hasta 60 caracteres. Hasta 100 pantallas. Las entradas no válidas y los identificadores duplicados se omiten.needsTarget: el botón también incluye un identificador de elemento (por ejemplo, el de un producto), que llega aonScreencomotargetId.- La lista se envía en segundo plano después de cargar la versión, solo cuando cambia o una vez por semana. Si el envío falla, no se muestra ningún aviso y se vuelve a intentar en el siguiente inicio. El usuario no ve nada.
- Las pantallas registradas aparecen en el panel de control, en Bot, Configuración, "Pantallas de la aplicación", junto con las plataformas que informaron de cada pantalla. Desde ahí puedes eliminar una pantalla que hayas quitado de la aplicación.
Colores y RTL
Los colores vienen de la configuración del bot en el panel de control (primaryColor), y el color del texto que aparece sobre él se elige según el contraste WCAG. Puedes cambiar cualquiera de ellos: primary, background, botBubble, userBubble, text, muted, accent, onPrimary y error:
<KavchatProvider
publicKey="pk_live_..."
theme={{ primary: '#0f766e', background: '#ffffff' }}
>El paquete no cambia la dirección de la distribución de tu aplicación. Sigue I18nManager.isRTL (estilos start y end), y cada texto se alinea según su idioma, de modo que el hebreo y el árabe se leen correctamente incluso en una aplicación de izquierda a derecha. Si tu aplicación está en hebreo o árabe, configura RTL una vez como de costumbre: I18nManager.forceRTL(true) y reinicia la aplicación.
La etiqueta "Con tecnología de Kavchat by maxsave" aparece en todos los planes, con un enlace a kavchat.com. En Premium puedes ocultarla en la configuración del bot.
Chat con un agente
No necesitas configurar nada para empezar. Al activar el chat con agentes en el panel de administración, la opción aparece en el chat de la aplicación igual que en el widget del sitio web.
- La opción: "Hablar con un agente" aparece antes de "Contactar con el equipo", solo después de que el servidor confirme que hay un agente disponible. La disponibilidad se comprueba de nuevo al pulsar el botón. Fuera del horario de atención, o cuando todos los agentes están ocupados, solo se muestra el formulario de contacto con una breve explicación y la hora de regreso del equipo, si se conoce. Cuando se agota la cuota mensual, el formulario se muestra sin explicación.
- La solicitud: los invitados dejan un correo electrónico o un teléfono por si ningún agente queda libre a tiempo. También pueden añadir un nombre y un primer mensaje. Si hay más de un departamento abierto, eligen uno. Los usuarios identificados (
userToken) no necesitan introducir datos de contacto. Si ningún agente puede atender el chat, se abre el formulario de contacto con los datos ya introducidos. - La espera: se muestra "Esperando a un agente" con una cuenta regresiva hasta el final del tiempo de espera que hayas configurado, junto a los botones "Dejar un mensaje en su lugar" y "Finalizar chat". El usuario puede escribir mientras espera. Cuando se acaba el tiempo, la conversación se convierte automáticamente en un ticket. Se muestran el número de ticket y una explicación de que ningún agente quedó libre a tiempo.
- La conversación: nombre del agente, mensajes, indicador de escritura, transferencia a otro agente y finalización del chat. Todo lo que llega del servidor se muestra como texto sin formato, sin enlaces.
- En tiempo real: una conexión Server-Sent Events mediante
XMLHttpRequest(o fetch en streaming, donde esté disponible). Si se pierde la conexión, el chat vuelve a conectarse a intervalos cada vez más largos y recupera todo lo que falta. Así, ningún mensaje se pierde ni aparece dos veces. En redes que bloquean esta conexión, el chat pasa a consultas repetidas (long-poll). Cada mensaje tiene un identificador, por lo que un reintento no crea duplicados. Los mensajes que no se envían quedan marcados y se pueden reenviar con un toque. - Segundo plano y reinicio: cuando la aplicación pasa a segundo plano, la conexión se cierra. Al volver, el chat recupera lo que falta. La credencial de acceso a la conversación es válida durante un máximo de 12 horas o hasta que termine la conversación, y se guarda en el almacenamiento que elijas. Así, al reiniciar la aplicación, una conversación abierta vuelve a aparecer en pantalla. La credencial no se guarda en la URL ni se escribe en los registros.
- Esta versión no incluye notificaciones push: los mensajes del agente solo llegan mientras la aplicación está abierta.
Se recomienda guardar la credencial de acceso en un almacenamiento seguro (Keychain en iOS, Keystore en Android). Si no configuras secureStorage, la credencial se guarda en el mismo almacenamiento que la conversación. Un botón propio para hablar con un agente abre el formulario de solicitud cuando hay un agente disponible. Si no lo hay, se abre el formulario de contacto con la explicación:
import * as SecureStore from 'expo-secure-store';
// expo-secure-store allows only [A-Za-z0-9._-] in keys
const safe = (k: string) => k.replace(/[^A-Za-z0-9._-]/g, '_');
const secureStorage = {
getItem: (k: string) => SecureStore.getItemAsync(safe(k)),
setItem: (k: string, v: string) => SecureStore.setItemAsync(safe(k), v),
removeItem: (k: string) => SecureStore.deleteItemAsync(safe(k)),
};
<KavchatProvider publicKey="pk_live_..." secureStorage={secureStorage} livePage="checkout">
// your own button
const { openLive } = useKavchat();
<Button title="Chat with us" onPress={openLive} />Eventos: onEvent recibe { type: 'live', phase } cada vez que cambia el estado de la conversación (queued, active, closed, ticket, replaced, expired).
Preguntas, condiciones y leads
No necesitas configurar nada en la aplicación. Un guion puede pedir datos (nombre, teléfono, correo electrónico, número o texto), decidir cómo continuar según condiciones (Premium) y enviar un lead. Todo se ejecuta en el dispositivo.
- Teclado adecuado: cuando el bot espera una respuesta, el campo de texto muestra un teclado de teléfono, correo electrónico o números, con autocompletado. Si la respuesta no es válida, el bot explica qué falta y el campo queda resaltado. Las preguntas opcionales muestran un botón "Omitir".
- Lead: cuando hay un texto de consentimiento, aparecen los botones "Enviar" y "No, gracias". Si no hay conexión a la red, el lead se guarda en el dispositivo y se envía cuando vuelve la conexión, sin duplicados.
- Datos precargados: las respuestas que el usuario ya ha dado rellenan el formulario de contacto y el formulario de solicitud de chat con un agente, y se adjuntan al ticket y a la conversación con el agente. El nombre, el correo electrónico y el teléfono del token de identidad se consideran respuestas conocidas, por lo que el bot no vuelve a preguntarlos.
- Pantalla actual:
livePagetambién indica la pantalla que comprueban las condiciones y que se envía con los leads. Al cambiar la propiedad, se actualiza ese valor.
Respuestas de IA (Premium)
No hay nada que configurar en la aplicación. Al activar las respuestas de IA en el panel de administración (con tu propia clave de un proveedor de IA), las preguntas que ningún guion responde se envían a Kavchat. Durante la espera, de hasta 20 segundos, el chat muestra que el bot está escribiendo. La respuesta aparece como texto sin formato con una pequeña etiqueta "Respuesta de IA" en el idioma de la interfaz. Debajo se muestran un botón para un tema relacionado, si lo hay, y el botón "Contactar con el equipo".
Si no hay respuesta, o si la solicitud falla, tarda demasiado o supera el límite (10 respuestas por conversación cada 15 minutos), el chat muestra su mensaje habitual de "No encontré una respuesta". La pregunta sigue apareciendo en el informe de preguntas sin respuesta, y las respuestas de IA se guardan en la conversación como cualquier otro mensaje.
Comportamiento
- La versión publicada se guarda en caché con su ETag (
If-None-Match, 304). Sin conexión, se muestra la versión guardada con un aviso. - La conversación se guarda en el dispositivo y se restaura durante 24 horas, siempre que no cambien la versión ni el usuario.
- El recorrido de la conversación se envía 2 segundos después de la última acción y también cuando la aplicación pasa a segundo plano.
- Las solicitudes no envían encabezados personalizados, solo
Authorization,Content-TypeyIf-None-Match.