Menu delle guide

React Native

Il pacchetto @kavchat/react-native aggiunge alla tua app la chat di assistenza basata su script: un Provider, una schermata di chat e un pulsante flottante opzionale. Le risposte provengono dagli script che pubblichi nella dashboard, eseguiti sul dispositivo.

Installazione

Il pacchetto è scritto interamente in JavaScript, senza codice nativo proprio né librerie di icone, quindi funziona allo stesso modo in una normale app React Native e in Expo. Dipendenze peer: react dalla versione 18 e react-native dalla versione 0.72.

React Native CLI (senza Expo)

Terminal
yarn add @kavchat/react-native @react-native-async-storage/async-storage
cd ios && pod install

AsyncStorage è un modulo nativo: pod install lo collega su iOS, mentre su Android il collegamento è automatico.

Expo

Funziona in Expo Go e nelle build di sviluppo:

Terminal
yarn add @kavchat/react-native
npx expo install @react-native-async-storage/async-storage

Senza AsyncStorage

AsyncStorage conserva la versione pubblicata e la conversazione tra un avvio e l'altro. Non è obbligatorio installarlo: senza, il pacchetto mantiene tutto in memoria, quindi il bot funziona ma scarica di nuovo la versione a ogni avvio. Per usare un altro sistema di archiviazione, ad esempio MMKV, passa alla prop storage un qualsiasi oggetto { getItem, setItem, removeItem? }, sincrono o asincrono:

TSX
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}>

Utilizzo

TSX
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} />;
}

Le prop di KavchatProvider

PropDescrizione
publicKeypk_live_... dalla dashboard. Puoi includerla nell'app.
apiBaseValore predefinito: https://api.kavchat.com.
localeLingua dell'interfaccia (he, en, ar, ru, es, fr, de, pt, it, tr). Per impostazione predefinita viene usata la lingua del dispositivo oppure, se non è disponibile una traduzione, quella del bot. La corrispondenza con gli script viene sempre cercata nella lingua del bot.
userToken, userNameIdentificazione dell'utente, vedi sotto.
onScreen(screen, targetId?)Viene chiamata quando si tocca un pulsante di tipo "Schermata" nello script. Senza questa funzione, quei pulsanti non fanno nulla.
screensLe schermate che l'app può aprire, per il menu a discesa dell'editor. Vedi Elenco delle schermate nell'editor.
onEvent(event)ready, unavailable, effect, ticket.
storageQualsiasi oggetto { getItem, setItem, removeItem? }, sincrono o asincrono. Per impostazione predefinita viene usato AsyncStorage oppure, se non è installato, la memoria.
themePersonalizzazione dei colori, vedi Colori e RTL.

useKavchat() restituisce { status, available, offline, locale, isOpen, open, close, toggle, setUser, startNewConversation, openContactForm, controller }.

Le prop di KavchatChat: onClose? (mostra un pulsante di chiusura), hideHeader? e style?. Le prop di KavchatLauncher: style? (posizione), onPress? (per aprire una tua schermata al posto della finestra integrata) e attention? (false disattiva il messaggio).

Quando nel pannello di gestione è impostato un messaggio accanto al pulsante della chat (un fumetto o un testo curvo sopra il pulsante), KavchatLauncher lo mostra dopo il ritardo configurato, al massimo una volta al giorno. Chiudere il messaggio o aprire la chat lo nasconde fino al giorno successivo. Il messaggio non viene mostrato mentre la chat è aperta. Se sul dispositivo è attiva la riduzione del movimento, il messaggio viene mostrato senza animazioni. Quando è attiva l'opzione "Non mostrare sui telefoni", il messaggio appare solo sui tablet (quando il lato più corto dello schermo misura almeno 600 punti).

Token di identità

Senza token, l'utente è un ospite e il modulo di contatto gli chiede un'email o un numero di telefono. Per identificare un utente che ha effettuato l'accesso, firma un JWT di breve durata sul tuo server con la chiave segreta (mai nell'app, vedi Identificazione degli utenti) e passalo così:

TSX
<KavchatProvider publicKey="pk_live_..." userToken={session?.kavchatToken} userName={session?.firstName}>

La modifica di userToken (accesso o disconnessione) ricarica la versione, perché il gruppo degli utenti di test dipende dall'identità dell'utente. Puoi anche chiamare useKavchat().setUser({ token, name }). Il token viene inviato solo nell'header Authorization: Bearer e non viene salvato sul dispositivo. Una conversazione salvata è associata a un'impronta del token, quindi un altro utente sullo stesso dispositivo inizia una nuova conversazione.

Link, schermate e modulo di contatto

  • I pulsanti di tipo link aprono solo URL https: e tel:, tramite Linking.openURL. Gli altri tipi di URL non vengono aperti.
  • I pulsanti di tipo screen chiamano onScreen. La chat rimane dov'era.
  • Il pulsante "Contatta il team" apre il modulo di contatto con la conversazione allegata. Dopo l'invio viene mostrato il numero del ticket.

Elenco delle schermate nell'editor

Dichiara una sola volta le schermate che l'app può aprire nella prop screens di KavchatProvider. L'SDK invia automaticamente l'elenco a Kavchat e l'editor degli script propone queste schermate in un menu a discesa con i loro nomi, al posto di un campo di testo libero. L'editor chiede anche l'ID dell'elemento quando una schermata ne ha bisogno e segnala i pulsanti che rimandano a schermate non dichiarate. Non serve inserire manualmente l'elenco delle schermate nella dashboard.

TSX
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)}
>
  • id è il valore ricevuto da onScreen: lettere latine, cifre, _, . e -, fino a 40 caratteri. label è il nome visibile all'amministratore, fino a 60 caratteri. Sono ammesse fino a 100 schermate. Le voci non valide e gli ID duplicati vengono scartati.
  • needsTarget: il pulsante include anche l'ID di un elemento (ad esempio l'ID di un prodotto), che viene passato a onScreen come targetId.
  • L'elenco viene inviato in background dopo il caricamento della versione, solo se è cambiato o una volta alla settimana. In caso di errore non viene mostrato nulla e l'invio viene ritentato all'avvio successivo. L'utente non vede nulla.
  • Le schermate registrate compaiono nella dashboard in Bot, Impostazioni, "Schermate dell'app", con le piattaforme che hanno segnalato ciascuna schermata. Da lì puoi eliminare una schermata rimossa dall'app.

Colori e RTL

I colori provengono dalle impostazioni del bot nella dashboard (primaryColor) e il colore del testo sovrapposto viene scelto in base al contrasto WCAG. Puoi personalizzare ciascuno di questi colori: primary, background, botBubble, userBubble, text, muted, accent, onPrimary e error:

TSX
<KavchatProvider
  publicKey="pk_live_..."
  theme={{ primary: '#0f766e', background: '#ffffff' }}
>

Il pacchetto non modifica la direzione del layout dell'app. Segue I18nManager.isRTL (stili start ed end) e ogni testo viene allineato in base alla propria lingua, così ebraico e arabo si leggono correttamente anche in un'app con layout da sinistra a destra. Se la tua app è in ebraico o arabo, imposta RTL una sola volta come di consueto: I18nManager.forceRTL(true) e riavvia l'app.

Il badge "Powered by Kavchat by maxsave" viene mostrato in tutti i piani, con un link a kavchat.com. Con Premium puoi nasconderlo nelle impostazioni del bot.

Chat con un operatore

Non serve alcuna configurazione per iniziare. Quando attivi la chat con gli operatori nel pannello di gestione, l'opzione compare nella chat dell'app esattamente come nel widget per il sito.

  • L'opzione: "Parla con un operatore" compare prima di "Contatta il team", solo dopo che il server ha confermato la disponibilità di un operatore. La disponibilità viene verificata di nuovo quando si tocca il pulsante. Fuori dall'orario di servizio, o quando tutti gli operatori sono occupati, viene mostrato solo il modulo di contatto con una breve spiegazione e, se noto, l'orario in cui il team tornerà disponibile. Quando la quota mensile è esaurita, il modulo viene mostrato senza spiegazione.
  • La richiesta: gli ospiti lasciano un'email o un numero di telefono, nel caso in cui nessun operatore si liberi in tempo. Possono aggiungere anche un nome e un primo messaggio. Quando è aperto più di un reparto, ne scelgono uno. Gli utenti identificati (userToken) non devono inserire i recapiti. Se nessun operatore può accettare la chat, si apre il modulo di contatto con i dati già inseriti.
  • L'attesa: viene mostrato "In attesa di un operatore" con un conto alla rovescia fino al termine del tempo di attesa che hai impostato, affiancato dai pulsanti "Lascia invece un messaggio" e "Termina la chat". È possibile scrivere già durante l'attesa. Allo scadere del tempo, la chat diventa automaticamente un ticket. Vengono mostrati il numero del ticket e un messaggio che spiega che nessun operatore si è liberato in tempo.
  • La chat: nome dell'operatore, messaggi, indicatore di digitazione, trasferimento a un altro operatore e chiusura della chat. Tutto ciò che arriva dal server viene mostrato come testo semplice, senza link.
  • In tempo reale: una connessione Server-Sent Events tramite XMLHttpRequest (o fetch in streaming, dove disponibile). Se la connessione si interrompe, la chat si riconnette a intervalli crescenti e recupera tutto ciò che è stato perso. In questo modo nessun messaggio va perso o compare due volte. Sulle reti che bloccano questa connessione, la chat passa a richieste ripetute (long-poll). Ogni messaggio ha un ID, quindi un nuovo tentativo non crea duplicati. Un messaggio non inviato viene contrassegnato e può essere reinviato con un tocco.
  • Background e riavvio: quando l'app passa in background, la connessione viene chiusa. Quando torna in primo piano, la chat recupera ciò che è stato perso. La credenziale di accesso alla chat è valida fino a 12 ore o fino alla chiusura della chat e viene salvata nel sistema di archiviazione che scegli. Così, dopo il riavvio dell'app, una chat ancora aperta torna sullo schermo. La credenziale non viene inserita nell'URL né scritta nei log.
  • Nessuna notifica push in questa versione: i messaggi dell'operatore arrivano solo mentre l'app è aperta.

Ti consigliamo di salvare la credenziale di accesso in un archivio sicuro (Keychain su iOS, Keystore su Android). Se non configuri secureStorage, la credenziale viene salvata nello stesso archivio della conversazione. Un tuo pulsante per parlare con un operatore apre il modulo di richiesta quando un operatore è disponibile. Se non ci sono operatori disponibili, si apre il modulo di contatto con la spiegazione:

TSX
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} />

Eventi: onEvent riceve { type: 'live', phase } a ogni cambio di stato della chat (queued, active, closed, ticket, replaced, expired).

Domande, condizioni e lead

Non serve configurare nulla nell'app. Uno script può chiedere dati (nome, telefono, email, numero o testo), decidere come proseguire in base a condizioni (Premium) e inviare un lead. Tutto viene eseguito sul dispositivo.

  • La tastiera adatta: quando il bot attende una risposta, il campo di testo mostra una tastiera per telefono, email o numeri, con completamento automatico. Se la risposta non è valida, il bot spiega cosa manca e il campo viene evidenziato. Le domande facoltative mostrano un pulsante "Salta".
  • Lead: quando è presente un testo di consenso, compaiono i pulsanti "Invia" e "No, grazie". Se non c'è connessione di rete, il lead viene salvato sul dispositivo e inviato quando la connessione torna disponibile, senza duplicati.
  • Precompilazione: le risposte già fornite dall'utente compilano il modulo di contatto e il modulo di richiesta di un operatore e vengono allegate al ticket e alla chat con l'operatore. Nome, email e telefono presenti nel token di identità sono considerati risposte già note, quindi il bot non li chiede di nuovo.
  • Schermata corrente: livePage indica anche la schermata verificata dalle condizioni e inviata con i lead. Modificando la prop, il valore viene aggiornato.

Risposte AI (Premium)

Non c'è nulla da configurare nell'app. Quando attivi le risposte AI nel pannello di gestione (con una tua chiave di un fornitore AI), una domanda a cui nessuno script risponde viene inviata a Kavchat. Durante l'attesa, fino a 20 secondi, la chat mostra che il bot sta scrivendo. La risposta viene mostrata come testo semplice con una piccola etichetta "Risposta AI" nella lingua dell'interfaccia, seguita da un pulsante per un argomento correlato, se presente, e dal pulsante "Contatta il team".

Se non c'è una risposta, oppure la richiesta non riesce, impiega troppo tempo o supera il limite (10 risposte per conversazione ogni 15 minuti), la chat mostra il consueto messaggio "Non ho trovato una risposta". La domanda compare comunque nel report delle domande senza risposta e le risposte AI vengono conservate nella conversazione salvata come qualsiasi altro messaggio.

Comportamento

  • La versione pubblicata viene salvata nella cache con il suo ETag (If-None-Match, 304). In assenza di rete viene mostrata la versione salvata, con un messaggio che lo segnala.
  • La conversazione viene salvata sul dispositivo e ripristinata per 24 ore, purché la versione e l'utente non siano cambiati.
  • Il percorso della conversazione viene comunicato 2 secondi dopo l'ultima azione e anche quando l'app passa in background.
  • Le richieste non inviano header personalizzati, ma solo Authorization, Content-Type e If-None-Match.