Pre-call API
La Pre-call API carica automaticamente dati del chiamante prima che la conversazione inizi, permettendo personalizzazione immediata.
Come Funziona
1. Cliente chiama → 2. Grip estrae numero → 3. Chiama tua API → 4. AI saluta con dati caricati
Tempo totale: ~1-2 secondi
Setup
1. Crea Endpoint sul Tuo Server
Grip farà una richiesta GET al tuo endpoint:
GET https://api.tuodominio.com/grip/caller-context?phone=%2B393331234567
Authorization : Bearer YOUR_SECRET_TOKEN
2. Implementa la Logica
app . get ( '/grip/caller-context' , authenticate , async ( req , res ) => {
const phone = req . query . phone ; // +393331234567
// Cerca cliente
const customer = await db . customers . findOne ({ phone });
if ( ! customer ) {
return res . json ({ is_known: false });
}
// Restituisci dati
res . json ({
is_known: true ,
name: customer . name ,
tier: customer . tier ,
language: customer . language || 'it'
});
});
@app.route ( '/grip/caller-context' )
def caller_context ():
phone = request.args.get( 'phone' )
customer = db.customers.find_one({ 'phone' : phone})
if not customer:
return jsonify({ 'is_known' : False })
return jsonify({
'is_known' : True ,
'name' : customer[ 'name' ],
'tier' : customer.get( 'tier' , 'standard' ),
'language' : customer.get( 'language' , 'it' )
})
Route :: get ( '/grip/caller-context' , function ( Request $request ) {
$phone = $request -> query ( 'phone' );
$customer = Customer :: where ( 'phone' , $phone ) -> first ();
if ( ! $customer ) {
return response () -> json ([ 'is_known' => false ]);
}
return response () -> json ([
'is_known' => true ,
'name' => $customer -> name ,
'tier' => $customer -> tier ?? 'standard' ,
'language' => $customer -> language ?? 'it'
]);
});
3. Configura in Grip
Dashboard → Strumenti → Pre-call API
URL: https://api.tuodominio.com/grip/caller-context
Method: GET
Authentication: Bearer Token
Token: your_secret_token_123
Timeout: 2000ms
4. Usa i Dati nel Prompt
Aggiungi al system prompt:
## Dati Pre-caricati
All'inizio di ogni chiamata hai accesso a:
- is_known: true/false
- name: Nome cliente
- tier: "standard", "VIP", "enterprise"
- language: Codice lingua
## Comportamento
SE is_known = true:
- Saluta per nome: "Buongiorno [ name ]"
- SE tier = "VIP": "sono [ nome ] dal servizio Premium"
- ALTRIMENTI: saluto standard
SE is_known = false:
- Saluto generico: "Buongiorno, [ Azienda ]"
- Raccogli nome ed email
Cliente Conosciuto
{
"is_known" : true ,
"customer_id" : "CUST-123" ,
"name" : "Mario Rossi" ,
"email" : "[email protected] " ,
"tier" : "VIP" ,
"language" : "it"
}
Cliente Sconosciuto
{
"is_known" : false ,
"phone" : "+393331234567"
}
Campi Opzionali Utili
Puoi aggiungere qualsiasi dato utile:
{
"is_known" : true ,
"name" : "Mario Rossi" ,
"tier" : "VIP" ,
"open_tickets" : 2 ,
"last_order" : {
"id" : "ORD-12345" ,
"status" : "shipped" ,
"date" : "2024-12-15"
},
"notes" : "Cliente preferisce chiamate al mattino"
}
L’AI può usare questi dati nella conversazione.
Importante: L’endpoint deve rispondere in meno di 2 secondi per non ritardare il saluto iniziale.
Ottimizza le Query
// ❌ Lento - multiple query seriali
const customer = await db . customers . findOne ({ phone });
const orders = await db . orders . find ({ customer_id });
const tickets = await db . tickets . find ({ customer_id });
// ✅ Veloce - query parallele
const [ customer , orderCount , ticketCount ] = await Promise . all ([
db . customers . findOne ({ phone }),
db . orders . count ({ customer_id }),
db . tickets . count ({ customer_id , status: 'open' })
]);
Usa Cache
// Cache con Redis (5 minuti)
const cached = await redis . get ( `caller: ${ phone } ` );
if ( cached ) return JSON . parse ( cached );
const data = await fetchCustomerData ( phone );
await redis . setex ( `caller: ${ phone } ` , 300 , JSON . stringify ( data ));
Indici Database
CREATE INDEX idx_customers_phone ON customers(phone);
Security
Valida sempre il Bearer Token: if ( req . headers . authorization !== `Bearer ${ SECRET } ` ) {
return res . status ( 401 ). json ({ error: 'Unauthorized' });
}
Grip accetta solo endpoint HTTPS: ✅ https://api.tuodominio.com
❌ http://api.tuodominio.com
Troubleshooting
Causa: Query database lentaFix:
Aggiungi indici
Cache con Redis
Query parallele
Riduci dati restituiti
Causa: Formato telefono diversoIn DB: 3331234567
Da Grip: +393331234567 Fix: Normalizza prima di cercareconst normalized = phone . replace ( / ^ \+ 39/ , '' );
Verifica:
Dati arrivano? (Dashboard → Logs → Pre-call)
Prompt configurato per usarli?
Campi corretti nel JSON?
Esempio Completo
app . get ( '/grip/caller-context' , authenticate , async ( req , res ) => {
const phone = req . query . phone ;
try {
// Query veloce con join
const result = await db . query ( `
SELECT
c.id, c.name, c.email, c.tier,
COUNT(DISTINCT o.id) as total_orders,
COUNT(DISTINCT t.id) FILTER (WHERE t.status = 'open') as open_tickets
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
LEFT JOIN tickets t ON t.customer_id = c.id
WHERE c.phone = $1
GROUP BY c.id
` , [ phone ]);
if ( result . rows . length === 0 ) {
return res . json ({ is_known: false , phone });
}
const customer = result . rows [ 0 ];
res . json ({
is_known: true ,
customer_id: customer . id ,
name: customer . name ,
email: customer . email ,
tier: customer . tier ,
total_orders: customer . total_orders ,
open_tickets: customer . open_tickets
});
} catch ( err ) {
console . error ( err );
res . json ({ is_known: false , phone }); // Fallback sicuro
}
});
Prossimi Passi