Herramientas del asistente
En medio de una conversación, el asistente de IA de DoneTalk puede consultar o cambiar datos en su sistema: el estado de un pedido, la cuenta de un cliente, un e-mail que cambiar. Llama a una dirección suya, recibe un texto corto y le responde al contacto con ese dato.
La empresa arma la herramienta en Configuración › Herramientas: la conexión (dirección y secreto), la ruta, los campos que la IA debe averiguar y si la herramienta solo consulta o cambia datos. Esta página es para quien hace la dirección que recibe la llamada.
Lo que llega
POST /su-ruta HTTP/1.1
Content-Type: application/json
User-Agent: DoneTalk-Tools/1.0 (+https://donetalk.com/desenvolvedores)
DoneTalk-Signature: t=1792756800,v1=5f0c…{
"tool": "estado_pedido",
"contact": { "phone": "+5511999990000", "name": "Camila", "fields": {} },
"conversation": { "id": "01a3e4f5-…", "test": false },
"assistant": { "id": "01a0c0de-…", "name": "Amanda" },
"input": { "numero": "77" },
"test": false,
"sentAt": "2026-10-24T12:00:00.000Z"
}contact.phonees el número de la conversación, puesto por DoneTalk y cubierto por la firma. Use solo él para encontrar la cuenta. La IA nunca elige de quién es la cuenta; lo que ella envía va eninput.inputtrae los campos que declara la herramienta, ya con su tipo (texto, número, sí/no, lista, fecha).contact.fieldstrae solo los campos del contacto que la empresa marcó en la herramienta.confirmedaparece en las herramientas que cambian datos y piden confirmación:falsepide solo la descripción del cambio;truelo hace.test: trueviene de las pruebas ("Probar ahora" y el "Probar" del asistente): no cambie nada.
La firma
La misma de los avisos: t es la hora en segundos y v1 es el HMAC-SHA256, en hexadecimal, de t + "." + cuerpo, con el secreto de la conexión. Rechace llamadas de más de 5 minutos.
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(header, rawBody, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const age = Math.abs(Date.now() / 1000 - Number(parts.t));
const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
return age < 300 && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
}La conexión también acepta un token (Authorization: Bearer), una clave en un encabezado suyo, o la firma en el formato de Copiloto (X-Copiloto-Timestamp y X-Copiloto-Signature), para sistemas hechos para su consulta externa.
Qué responder
200 con JSON:
{
"ok": true,
"text": "Pedido 77: salió para entrega hoy a las 14 h.",
"data": { "status": "shipped" }
}textes lo único que lee la IA: lenguaje natural, sin markdown, hasta 1.500 caracteres. Diga el dato y el siguiente paso del contacto.ok: falsecontexttambién llega a la IA como un hecho ("No encontré pedido con este teléfono").dataes opcional y solo queda en el historial de llamadas.- Cualquier otra respuesta (otro estado, sin
text, más de 64 KB, más de 8 segundos por defecto) se vuelve "no disponible ahora": la IA sigue la conversación sin el dato.
Herramientas que cambian datos
La empresa elige, por herramienta, cómo confirmar:
| Elección | Lo que recibe su sistema |
|---|---|
| Confirmar con el contacto | Con "el sistema describe el cambio antes": primero confirmed: false (responda qué cambiaría, sin cambiarlo), después confirmed: true, con los mismos datos, solo después de que el contacto aceptó. Sin ella, solo la llamada con confirmed: true. |
| Una persona aprueba | Una llamada con confirmed: true, cuando alguien del equipo aprueba. |
| Sin confirmación | La llamada en cuanto la IA lo decide. |
Límites
- Hasta 5 llamadas de la misma herramienta por conversación por hora.
- Solo direcciones
httpspúblicas; las redirecciones no se siguen. - Una herramienta con el método
GETenvía la llamada en el parámetrocallde la dirección, en lugar del cuerpo; la firma cubre el valor de ese parámetro.
Cualquier API
Si su sistema ya tiene una API, la herramienta puede llamarla sin este formato: la empresa arma la ruta, los encabezados y el cuerpo con {{contact.phone}}, {{contact.name}}, {{input.campo}} y {{conversation.id}}, y elige lo que lee la IA: la respuesta entera, un campo (data.status) o una frase armada con ella.