Supporto tecnico

Lista degli argomenti:


Integrazione del “Client Generico” con il tuo programma PHP

L’integrazione del Client Generico in una pagina PHP è estremamente semplice. Nell’esempio seguente ho realizzato una pagina PHP di base, includendo tutti i file necessari per garantire il corretto funzionamento del sistema. L’unico requisito è la presenza di una versione aggiornata di jQuery. È fondamentale prestare attenzione ai seguenti punti:

  • verificare il corretto inserimento dei tre require_once() o include() all’inizio del codice PHP (vedi righe 4..6)
  • verificare la personalizzazione di inc_chiedimi_config.php e inc_chiedimi_rulesets.php (vedi anche questa sezione)
  • impostare la costante USE_DOM_PURIFY per indicare al codice se adottare o meno (true/false) lo script JavaScript dedicato alla purificazione del testo restituito dalle API (vedi riga 8, qualora si decidesse di utilizzarlo, il modulo purify.min.js deve essere caricato come visibile alla riga 23)
  • inserire tra i tag <style></style> l’include CSS (vedi riga 26)
  • inserire tra i tag <script></script> il modulo inc_chiedimi_function.js (vedi riga 30) che contiene le funzioni necessarie per l’invio e la ricezione del messaggio, la formattazione dei dati ricevuti e la gestione dello scroll della ChatBox
  • inserire prima del tag </script>, se non già presente, un blocco $(document).ready(function() {}) all’interno del quale includere il file inc_chiedimi_ready.js che si occupa della inizializzazione e gestione degli eventi di input dell’Utente (verdi riga 32)
  • inserire prima del tag </body> il modulo inc_chiedimi_html.php che si incarica di disegnare la ChatBox
<?php
// Include i moduli per il BOT CHIEDIMI
//-------------------------------------
require_once('inc_chiedimi_config.php');
require_once('inc_chiedimi_rulesets.php');
require_once('inc_chiedimi.php');

define('USE_DOM_PURIFY', true);

?>
<!DOCTYPE html>
<html lang="it">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Client Generico</title>

    <!-- jQuery 3.7.1 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    <!-- DOMPurify 3.1.6 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.6/purify.min.js" integrity="sha512-jB0TkTBeQC9ZSkBqDhdmfTv1qdfbWpGE72yJ/01Srq6hEzZIz2xkz1e57p9ai7IeHMwEG7HpzG6NdptChif5Pg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <style>
      <?php include('inc_chiedimi.css'); ?>
    </style>
    
    <script>
      <?php include('inc_chiedimi_function.js'); ?>
      $(document).ready(function() {
			      <?php include('inc_chiedimi_ready.js'); ?>
      });
    </script>
</head>

<body>
    <header><h1>Esempio di CLIENT GENERICO</h1></header>
    <p>
        Questo Client Generico ha come unica dipendenza jQuery. Le classi CSS di Bootstrap necessarie per la visualizzazione della ChatBox sono state replicate ed inserite nel file CSS.
    </p>
	<hr>
		<?php for ($x=1; $x < 2000; $x++) {echo 'bla ';} // Semplice testo per riempire la pagina ?>
		<?php include('inc_chiedimi_html.php'); ?>
    </body>
</html>

E’ presente più avanti una descrizione leggermente più approfondita del “Client Generico”.


Messaggi/Codici d’errore più comuni

Questi messaggi d’errore possono essere stati generati dall’API o dal modulo PHP inc_chiedimi.php raggruppati per codice di errore.

  • 400
    • “Invalid configuration info” => i dati di sessione passati via COOKIE sono stati alterati
    • “Non posso risponderti perché […]” => sessione scaduta
    • “Invalid JSON format” => il formato del file JSON non è corretto
    • “Errore cURL: [messaggio]” => problemi con l’esecuzione della chiamata API
    • “HTTP error [codice]” => errore durante l’invio della richiesta o ricezione della risposta
    • “Errore nella decodifica della risposta JSON” => il file JSON contenente la risposta ha un formato non valido
    • “ID di sessione non valido” => problemi con il recupero della sessione (probabile corruzione puntatore in COOKIE)
    • “Sessione non valida o scaduta” => timeout di sessione
    • “Hash non valido” => il ruleset indicato non sembra essere valido
    • “Dati configurazione assenti” => problemi con risoluzione id del Cliente
    • “Errore interno del server” => generico, può essere generato da varie cause, contattare il supporto tecnico
    • “Errore durante la connessione al database” => problemi con database, contattare il supporto tecnico
  • 403
    • “Accesso non autorizzato per l’indirizzo IP” => l’indirizzo IP dal quale è stata chiamata l’API non è autorizzato ad operare con la auth key utilizzata
    • “Chiave API non valida” => la auth key utilizzata non esiste (errata o revocata)
    • “Chiamata API non valida” => formato della chiamata API non valido
  • 404
    • “Richiesta GET non valida[…]” => problemi di “config” (/3 o /4) o di “ruleset” (/1 o /2)
  • 405
    • “Metodo non supportato” => Chiamata API con un metodo diverso da GET o POST
  • 427
    • “E’ stato raggiunto il limite di richieste per unità di tempo per questa sessione[…]” => troppe richieste dallo stesso client
  • 428
    • “E’ stato raggiunto il limite di richieste per unità di tempo. Prova[…]” => troppe richieste in assoluto
  • 429
    • “E’ stato raggiunto il limite di richieste per indirizzo IP” => troppe richieste dallo stesso IP (anche se da client diversi)
  • 500
    • “Parsing dell’URI non riuscito” => chiamata API formattata non correttamente


Documentazione modulo “Client Generico”

Nel caso in cui i due moduli ChatBox disponibili non rispondessero alle esigenze specifiche della tua realtà, di seguito trovi la documentazione completa del “Client Generico”, suddivisa modulo per modulo. In questo modo potrai procedere autonomamente allo sviluppo del software necessario.

1. Panoramica

Il modulo client è progettato per fornire un’interfaccia di chat che consente agli utenti di inviare messaggi a un endpoint API (gestito in apirequest.php) e ricevere risposte formattate. L’interfaccia, realizzata in client.php, integra risorse di JavaScript e CSS per gestire la comunicazione asincrona, il parsing del contenuto e la visualizzazione dinamica dei messaggi.

2. Struttura dei File

  • client.php
    Punto di ingresso principale che include e richiama tutti gli script e gli stili necessari.
  • apirequest.php
    Endpoint che riceve le richieste POST in formato JSON contenenti il messaggio inviato dall’utente, elabora la richiesta e restituisce una risposta in formato JSON.
  • inc_chiedimi_function.js
    Contiene le funzioni fondamentali per:
    • Inviare il messaggio all’API tramite una chiamata AJAX.
    • Gestire la risposta ricevuta, inclusa la purificazione e il parsing del testo Markdown in HTML.
      (Vedi funzione sendMessageToAPI e parseMarkdown)
  • inc_chiedimi_ready.js
    Gestisce gli eventi di input dell’utente. In particolare:
    • Ascolta l’evento keypress sul campo di input e il click sul pulsante di invio.
    • Invia il messaggio dell’utente e lo visualizza nel container della chat.
      (Vedi gestione degli eventi)
  • inc_chiedimi.css
    Definisce lo stile dell’interfaccia, compresi il layout della chat, la formattazione dei messaggi (utente, assistente, sistema) e l’aspetto della finestra di dialogo.
    (Per dettagli sugli stili, vedi il file CSS)
  • Altri file (es. inc_chiedimi_config.php, inc_chiedimi_html.php, inc_chiedimi_rulesets.php, inc_chiedimi.php)
    Forniscono configurazioni e funzionalità aggiuntive che integrano il comportamento complessivo del modulo.

3. Flusso di Esecuzione

  • Inserimento del Messaggio
    L’utente digita un messaggio nel campo di input (identificato da #msgBox) e preme il tasto Enter oppure clicca sul pulsante di invio (#msgBtn).
  • Gestione dell’Evento
  • In inc_chiedimi_ready.js viene catturato l’evento:
    • Il gestore dell’evento keypress intercetta il tasto Enter e attiva il click del pulsante.
    • L’evento click invoca la funzione che preleva il testo, lo visualizza nel container della chat (tramite appendMessage) e lo invia al server.
  • Invio della Richiesta all’API
    La funzione sendMessageToAPI (definita in inc_chiedimi_function.js) esegue una chiamata AJAX:
    • Il messaggio viene incapsulato in un oggetto JSON e inviato in POST all’endpoint apirequest.php.
    • Viene specificato il contentType come application/json per garantire la corretta interpretazione della richiesta.
      (Vedi funzione sendMessageToAPI)
  • Elaborazione della Risposta
    Al ricevimento della risposta dal server:
    • Il codice controlla la presenza di un array choices[] nella risposta JSON.
    • Se presente, estrae il contenuto del messaggio dalla prima scelta (data.choices[0].message.content), lo purifica (utilizzando DOMPurify se configurato ed abilitato) e lo converte in HTML grazie alla funzione parseMarkdown.
    • Se la risposta è troncata (finish_reason uguale a “length”), viene mostrato un messaggio di avviso che suggerisce all’utente di scrivere “continua” per ricevere il resto della risposta.
    • Il messaggio elaborato viene quindi visualizzato nel container della chat mediante appendMessage.
      (Vedi funzione sendMessageToAPI)
  • Visualizzazione del Messaggio
    La funzione appendMessage aggiunge il messaggio al container #dialogue:
    • I messaggi dell’utente vengono visualizzati immediatamente.
    • I messaggi dell’assistente sono animati con un effetto “word-by-word”, che incrementa progressivamente la visibilità del testo per migliorare l’esperienza utente.
  • Gestione degli Errori
    Se si verifica un errore durante l’invio o la ricezione della risposta:
    • Vengono catturati errori AJAX e errori di struttura della risposta.
    • Un messaggio di errore viene visualizzato all’interno del container, informando l’utente del problema.

4. Funzioni Chiave e Loro Responsabilità

4.1. sendMessageToAPI(message)

  • Scopo: Invia una richiesta POST all’API (apirequest.php) con il messaggio dell’utente.
  • Dettagli:
    • Converte il messaggio in formato JSON.
    • Gestisce la risposta: in caso di successo, estrae il contenuto e invoca il parsing Markdown; in caso di errore, visualizza un messaggio di errore.
  • Note: Gestisce anche il logging (es. conteggio dei token) e il controllo su eventuali risposte troncate.

4.2. parseMarkdown(markdown)

  • Scopo: Converte il testo in formato Markdown in HTML.
  • Dettagli:
    • Purifica il testo per prevenire iniezioni di codice.
    • Gestisce diversi elementi Markdown (code blocks, codice inline, titoli, immagini, link, grassetto, corsivo, liste e citazioni).
    • Limita la nidificazione delle liste a due livelli.
  • Note: Fondamentale per presentare le risposte in un formato leggibile e ben formattato.

4.3. appendMessage(sender, text, className, isHTML)

  • Scopo: Aggiunge un nuovo messaggio al container della chat, applicando stili e animazioni in base al tipo di mittente.
  • Dettagli:
    • Differenzia tra messaggi dell’utente, dell’assistente e di sistema.
    • I messaggi dell’assistente vengono visualizzati progressivamente con un effetto “word-by-word”.
  • Note: garantisce che l’area di dialogo scorra automaticamente verso i messaggi più recenti.

4.4. scrollToBottom()

  • Scopo: Assicura che il container della chat sia sempre scorrevole fino al messaggio più recente.
  • Dettagli: Richiamata durante l’aggiunta di nuovi messaggi per migliorare l’usabilità.

5. Sicurezza e Purificazione

  • Purificazione dell’Input/Output:
    • Conversione dei caratteri speciali HTML in entità per evitare iniezioni di codice.
    • Uso di DOMPurify (se abilitato) per purificare l’output HTML prima della visualizzazione.
  • Parsing Markdown:
    • Pulizia approfondita del testo per neutralizzare eventuali tag HTML pericolosi.

6. Modifica files di configurazione

I moduli inc_chiedimi_config.php e inc_chiedimi_rulesets.php contengono le informazioni necessarie per autenticare la chiamata API ed accedere alla giusta KB.

inc_chiedimi_config.php contiene dati di configurazione e necessita dei seguenti parametri tutti obbligatori:

  • CHIEDIMI_AUTH_KEY => la Auth Key generata da “Gestione chiavi di autorizzazione” del Pannello di controllo
  • CHIEDIMI_PANEL_TITLE => Il titolo della finestra della ChatBox
  • CHIEDIMI_SALT_KEY => numero causale a 128 bit rappresentato come stringa esadecimale di 32 caratteri, utilizzata per crittografare dati esposti
  • CHIEDIMI_SALT_KEY_CHECKSUM => numero causale a 128 bit rappresentato come stringa esadecimale di 32 caratteri (differente dal precedente), utilizzata per crittografare dati esposti
<?php
/* 
   INC_CHIEDIMI_CONFIG.PHP
   -----------------------
 */
define('CHIEDIMI_AUTH_KEY',          '[auth_key]');
define('CHIEDIMI_PANEL_TITLE',       'Chiedimi - Assistente'); // Titolo della finestra
define('CHIEDIMI_SALT_KEY',          '[32_bytes_salt_key]');   // 128 bit/16 coppie di caratteri esadecimali
define('CHIEDIMI_SALT_KEY_CHECKSUM', '[32_bytes_salt_key]');   // 128 bit/16 coppie di caratteri esadecimali

A puro titolo di esempio ecco come dovrebbe apparire il modulo una volta configurato:

<?php
/* 
   INC_CHIEDIMI_CONFIG.PHP
   -----------------------
 */
define('CHIEDIMI_AUTH_KEY',          'ca997e87dcbfe40e98f4a23cba5aa67fec099fad94e56bc2a3a5b1dfff09dba3');
define('CHIEDIMI_PANEL_TITLE',       'Chiedimi - Assistente'); // Titolo della finestra
define('CHIEDIMI_SALT_KEY',          '0CD92CA6A6B788764A323B9EFAFE4FEA');
define('CHIEDIMI_SALT_KEY_CHECKSUM', '9BC4E2A6789BCADE9472D3D57BF90900');

inc_chiedimi_rulesets.php contiene l’elenco dei rulesets che dovranno essere utilizzati per ogni pagina, rappresentati come array associativo [nome modulo] => [ID ruleset]. Gli ID dei ruleset si ottengono sempre dal Pannello di Controllo, dopo aver selezionato il ruleset richiesto, facendo click sull’icona Informazioni

<?php
/*
   INC_CHIEDIMI_RULESETS.PHP
   -------------------------
*/
$rule_sets = array(
                    '[nomemodulo0.php]' => '[ruleset_0]',
                    '[nomemodulo1.php]' => '[ruleset_1]',
                    '[nomemodulo2.php]' => '[ruleset_2]',
                  );

Tutti i moduli che visualizzeranno una ChatBox devono essere descritti in questo array associativo e devono essere collegati ad un ruleset. Uno stesso ruleset può essere associato a più moduli, se necessario.

7. Considerazioni per l’Implementazione in Altri Linguaggi

Per sviluppare un modulo equivalente in altri ambienti o linguaggi, è utile seguire la stessa logica e struttura:

  • Gestione della Comunicazione con l’API:
    • Implementare una funzione per inviare richieste HTTP in maniera asincrona.
    • Utilizzare un formato di dati strutturato (es. JSON) e impostare il corretto content type.
  • Elaborazione della Risposta:
    • Verificare la presenza di un campo (es. array choices) nella risposta JSON.
    • Estrarre il contenuto utile e gestire eventuali risposte troncate.
  • Parsing e Visualizzazione del Testo:
    • Convertire il testo (eventualmente in Markdown) in un formato adatto alla visualizzazione.
    • Utilizzare librerie per il parsing Markdown o implementare una logica simile.
    • Adottare una logica di purificazione per prevenire vulnerabilità di tipo XSS.
  • Interfaccia Utente e Aggiornamento Dinamico:
    • Gestire gli eventi di input (Enter o click) per inviare il messaggio.
    • Implementare un effetto “typewriter” per la visualizzazione graduale delle risposte.
    • Assicurarsi che l’interfaccia aggiorni dinamicamente l’area di visualizzazione dei messaggi.
  • Error Handling:
    • Prevedere meccanismi per rilevare e gestire errori durante la comunicazione con l’API.
    • Visualizzare messaggi di errore chiari per l’utente in caso di problemi.

8. Conclusioni

Il modulo client descritto in questo documento rappresenta un esempio di interfaccia di chat basata su richieste AJAX, parsing del Markdown e aggiornamento dinamico del DOM. La separazione delle funzionalità (invio, elaborazione, visualizzazione e purificazione) permette una facile manutenzione e rende il modulo facilmente trasponibile in altri linguaggi o ambienti di sviluppo.

Per implementare un modulo equivalente in un altro linguaggio, è importante replicare:

  • La logica di invio e gestione delle richieste HTTP.
  • Il meccanismo di conversione del testo (Markdown → HTML).
  • Le funzioni di gestione degli eventi e di aggiornamento dinamico dell’interfaccia.