Hook e ricerca live
Oltre agli helper integrati, l’assistente espone alcuni hook: helper i cui valori predefiniti non fanno nulla, così il widget si comporta esattamente come prima finché non li sostituisci. Li sostituisci come qualsiasi altro helper (in settings.extensions.helpers, oppure assegnando skdwn.instance.helpers.<name> a runtime dalla pagina che lo integra). Il core li richiama in momenti precisi, quindi non devi collegare nulla in un template.
Hook di evento
| Hook | Quando si attiva | Cosa riceve |
|---|---|---|
onQuerySubmitted(query) | Subito dopo che l’utente invia una domanda. | query: il testo inviato. |
onResponseReceived(result) | Quando arriva una risposta. | result: { query, reply, references }. |
onFormSubmitted(formId, values) | Dopo l’invio di un modulo. | formId e l’oggetto values inviato. |
Non restituiscono nulla: usali per effetti collaterali come analisi, la tua interfaccia o per notificare la pagina ospitante. Ad esempio, per inoltrare ogni domanda e risposta al tuo sistema di analisi:
// settings.extensions.helpers
{
onQuerySubmitted: (query) => window.analytics?.track('assistant_question', { query }),
onResponseReceived: (result) =>
window.analytics?.track('assistant_answer', {
query: result.query,
sources: (result.references || []).length,
}),
onFormSubmitted: (formId, values) =>
window.analytics?.track('assistant_form', { formId, ...values }),
}
I valori predefiniti non fanno nulla
Ogni hook viene fornito come funzione vuota, quindi lasciarlo com’è non cambia nulla. Paghi solo per ciò che sostituisci.
Ricerca live: searchProvider
searchProvider trasforma il campo di ricerca in un box di suggerimenti istantanei: mentre l’utente digita, l’assistente chiama il tuo provider (con debounce) e mostra ciò che restituisce in un menu a tendina sotto il campo, prima ancora che l’utente invii una domanda completa. È disattivato finché non ne fornisci uno.
Contratto
// (query: string, ctx: { assistantId }) => Promise<Item[]> | Item[] | undefined
searchProvider: async (query) => {
const res = await fetch(`https://example.com/search?q=${encodeURIComponent(query)}`);
const rows = await res.json();
return rows.map((r) => ({
title: r.name, // shown text (and the query run if the row has no url)
url: r.href, // optional — see below
summary: r.excerpt, // optional secondary line
image: r.thumbnail, // optional thumbnail
metadata: { price: r.price }, // optional free-form, passed to the template
}));
}
Ogni elemento è { title, url?, summary?, image?, metadata? }:
title: il testo mostrato e la domanda eseguita quando si clicca una riga senza URL (o il suo pulsante
Ask).
url: facoltativo. Presente → la riga è un link e cliccarla porta alla pagina (nella stessa scheda).
Assente → cliccare la riga esegue il titolo come domanda.
summary: seconda riga facoltativa.image: miniatura facoltativa.metadata: oggetto libero facoltativo (prezzo, badge, valutazione…). L’intero elemento viene
passato al template suggestion, quindi tutto ciò che inserisci qui è disponibile quando ridisegni le righe.
Cosa vede l’utente
- Mentre il provider è in esecuzione, nel menu a tendina compare uno skeleton di caricamento, così il box non è mai
vuoto.
- Ogni riga ha anche un pulsante "Ask" che apre l’assistente con il titolo di quella riga come
domanda: comodo per trasformare un risultato in una domanda più ricca.
- Il menu a tendina si chiude quando l’utente clicca fuori o apre l’overlay.
Limita i risultati con settings.suggestionsLimit (predefinito 5). È un valore disponibile solo nelle impostazioni: impostalo nella configurazione dell’assistente; non esiste un controllo nell’interfaccia.
Ridisegna le righe sostituendo il template suggestion (una riga): il contenitore esterno suggestions resta invariato. L’intero elemento è disponibile come item, quindi puoi visualizzare i tuoi metadata:
{% comment %} settings.extensions.templates.suggestion {% endcomment %}
<div class="skdwn-suggestion-row" role="option">
<a class="skdwn-suggestion" href="{{ item.url }}" onclick="skdwn.instance.helpers.dismissSuggestions()">
<span class="skdwn-suggestion-text">
<span class="skdwn-suggestion-title">{{ item.title | escape }}</span>
{% if item.metadata.price %}<span class="skdwn-suggestion-summary">{{ item.metadata.price }}</span>{% endif %}
</span>
</a>
<button type="button" class="skdwn-suggestion-ask" data-query="{{ item.title | escape }}"
onclick="skdwn.instance.helpers.askSuggestion(this)">{{ 'ask' | t: 'Ask' }}</button>
</div>
Inoltra l’identità del visitatore al tuo servizio di ricerca
Un searchProvider viene eseguito nel browser, quindi può chiamare qualsiasi endpoint raggiungibile dalla pagina. Se la tua ricerca ha bisogno dell’utente autenticato, passa un token tramite startOptions.params e leggilo dal tuo provider: è lo stesso meccanismo usato dai servizi collegati.