Il nodo Codice consente agli sviluppatori di eseguire logica JavaScript personalizzata all'interno di un flusso di conversazione. È il nodo più potente e flessibile di Convos, che consente di interrogare le API, eseguire trasformazioni complesse, gestire la logica condizionale e creare messaggi dinamici.
Cosa fa questo nodo?
Ogni volta che viene eseguito, il nodo riceve informazioni dal contesto del dialogo, consentendo allo sviluppatore di accedere a:
Dati del contatto.
Variabili precedentemente acquisite o definite.
Informazioni sulla campagna transazionale.
Messaggi in arrivo.
Alla fine del blocco di codice, il nodo deve chiamare la funzione output(), che indica cosa fare successivamente: salvare lo stato, acquisire nuove variabili, inviare messaggi, ecc.
Variabili disponibili
Queste variabili sono disponibili globalmente nello script e rappresentano il contesto del flusso:
Variabile | Descrizione |
variables | Oggetto con tutte le variabili precedentemente acquisite nel dialogo, sia dai nodi di acquisizione che generate dal codice. |
persisted | Informazioni persistenti da campagne transazionali. Ad esempio: persisted.input.orderId. Utile per continuare i flussi basati sulle campagne. |
contact | Informazioni del profilo del contatto. Accessibili tramite contact.phone, contact.firstname, contact.field_1, fino a contact.field_100. |
state | Un oggetto che memorizza informazioni di stato tra le esecuzioni dello stesso nodo. Permette di suddividere la logica in fasi (stage). |
inboundMessage | Oggetto completo del messaggio ricevuto dal sistema. Contiene metadati, tipo, ecc. |
inboundMessageBody | Solo il testo semplice del messaggio in arrivo. Utile per catturare risposte rapide. |
Metodi disponibili
output({ state, variables, messages, ticket })
Questo è obbligatorio. Chiude il nodo di codice e consente di:
Mantenere un nuovo stato (state) per le future esecuzioni dello stesso nodo.
Creare o modificare variabili (variables) accessibili ad altri nodi.
Inviare messaggi al contatto (messages).
Esempio:
output({
state: {
stage: 1,
wait: true
},
variables: {
age: inboundMessageBody
},
messages: [
{
type: 'text',
text: {
body: 'Quanti anni hai?'
}
}
],
ticket: {}
});
✅ wait: true indica che il nodo deve essere rieseguito la prossima volta che il contatto risponde.
fetch(url, options)
Consente di effettuare chiamate HTTP sincrone (tipo await fetch). Ideale per utilizzare API esterne e personalizzare il flusso.
Esempio:
const params = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email: contact.email })
};
const response = await fetch('https://api.miapp.com/user', params);
const data = JSON.parse(response);
mail(to, subject, html)
Consente di inviare un'email. Ideale per notifiche email o integrazioni.
Esempio:
const html = '<h1>Nuovo registro</h1>';
mail(‘[email protected]’, 'Nuovo registro', html);
Struttura dei messaggi
È possibile inviare solo messaggi interattivi (non template pre-approvati da Meta).
Invio di messaggi facoltativo
L'invio di messaggi all'interno del nodo di codice non è obbligatorio.
È possibile utilizzare questo nodo esclusivamente per eseguire la logica di programmazione, ad esempio:
• Calcolo di variabili complesse.
• Esecuzione di convalide silenziose.
• Interrogazione di API esterne.
• Arricchimento del dialogo con dati prima di continuare.
Questo è particolarmente utile quando non è necessario interagire direttamente con l'utente in quel punto del flusso, ma piuttosto preparare le informazioni per i passaggi successivi.
Esempio senza messaggi:
const risultato = 42;
output({
state: { wait: false },
variables: {
risultato: risultato
}
});
⚠️ Ricorda che anche se non invii messaggi, devi comunque eseguire output() per terminare correttamente il nodo.
Lista dei messaggi interattivi disponibili
Tipo | Struttura |
text | { |
image | { |
contacts | { |
document | { |
location | { |
buttons | { |
list | { |
Puoi anche inviare più messaggi:
messages: [
{
type: 'image',
media: { link: 'https://...' }
},
{
type: 'text',
text: { body: 'Gracias por tu compra' }
}
];
Estructura de ticket
Se hai bisogno di creare un ticket dal nodo codice puoi usare la key ticket
output({
state: {
wait: true
},
variables: {},
messages: [
{
type: 'text',
text: {
body: 'Lo conectamos con un agente para que lo ayude'
}
}
],
ticket: {
inboxId: 1,
tags: ['vip']
}
});
Variabili:
inboxId: la variabile inboxId è necessaria per determinare a quale casella di posta assegnare il ticket.
tag: la variabile tags è facoltativa e può essere utilizzata per aggiungere automaticamente tag al ticket.
Casi d'uso comuni
Raccolta a stadi
Utilizzando state.stage, è possibile suddividere il flusso in più fasi:
if (!state.stage || state.stage === 0) {
output({
state: { stage: 1, wait: true },
messages: [{ type: 'text', text: { body: '¿Cuál es tu edad?' } }]
});
} else if (state.stage === 1) {
output({
state: { stage: 2, wait: true },
variables: { age: inboundMessageBody },
messages: [{ type: 'text', text: { body: '¿Cuál es tu DNI?' } }]
});
} else {
output({
state: { wait: false },
variables: { document: inboundMessageBody },
messages: [{ type: 'text', text: { body: '¡Gracias por responder!' }}]
});
}
Invio di feedback con dati transazionali
const params = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
contact: persisted.input.phone,
rating: variables.rating,
feedback: variables.feedback ?? ''
})
};
await fetch('https://api.externo.com/feedback', params);
output({ state: { wait: false } });
Ricerca di ordine tramite e-mail o ID
let search = variables.value_to_search;
let isEmail = search.includes('@');
let query = isEmail
? `{ orders(first: 1, query: "email:${search}") { edges { node { id, fulfillments { trackingInfo { url } } } } } }`
: `{ order(id: "gid://shopify/Order/${search}") { id, fulfillments { trackingInfo { url } } } }`;
const response = await fetch('https://shopify.com/graphql', {
method: 'POST',
headers: { Authorization: 'Basic XXXXXX' },
body: JSON.stringify({ query })
});
const data = JSON.parse(response);
const link = isEmail
? data.data.orders.edges[0]?.node.fulfillments[0]?.trackingInfo[0]?.url
: data.data.order?.fulfillments[0]?.trackingInfo[0]?.url;
output({
state: { wait: false },
messages: [{
type: 'text',
text: { body: link ? `Tu código de seguimiento es: ${link}` : 'No encontramos tu orden.' }
}]
});
Procedure consigliate
Utilizzare state.wait = true quando il flusso è in attesa di un'altra risposta dall'utente.
Evitare di dichiarare una variabile denominata state all'interno del codice (è già riservata).
Utilizzare try/catch durante il fetch per evitare errori di runtime.
Se si utilizzano dati sensibili, assicurarsi che non vengano esposti nei messaggi al cliente.
Utilizzare nomi di variabile chiari e semantici per facilitare la manutenzione del flusso.
Utilizzare punti e virgola alla fine di ogni riga di codice per garantirne il corretto funzionamento.
Struttura di base consigliata
try {
// lógica principal
output({
state: { wait: false },
variables: { ... },
messages: [ ... ]
});
} catch (error) {
output({
state: { wait: false },
messages: [{
type: 'text',
text: { body: 'Ocurrió un error inesperado. Por favor, intenta nuevamente más tarde.' }
}]
});
}
