Airtable
Valida los adjuntos de Airtable con una automatización "Run a script" que envía la URL del adjunto a Constaia y escribe el veredicto en el registro.
En Airtable, una automatización puede analizar el adjunto de un registro en cuanto se sube: la acción
Run a script envía la URL del adjunto a Constaia como file_url y escribe el veredicto y los datos extraídos en
campos del mismo registro.
Requisitos
- Una base de Airtable con permisos para crear automatizaciones.
- Una clave de test
ck_test_…del panel. Consulta Autenticación. - Una tabla, por ejemplo
Solicitudes, con estos campos:
| Campo | Tipo |
|---|---|
Documento | Attachment |
Veredicto | Single line text |
Motivos | Long text |
Nº documento | Single line text |
ID análisis | Single line text |
Crear la automatización
Elige el disparador
Crea una automatización con When a record matches conditions (condición: Documento is not empty y
Veredicto is empty) o When a record is updated sobre el campo Documento.
Añade la acción Run a script
Añade Run a script y, en Input variables, crea recordId con el Airtable record ID del disparador.
Pega el script
const API_KEY = "ck_test_..."; // ver "Seguridad" más abajo
const table = base.getTable("Solicitudes");
const { recordId } = input.config();
const record = await table.selectRecordAsync(recordId);
const attachments = record?.getCellValue("Documento") ?? [];
if (attachments.length === 0) {
output.set("status", "sin_documento");
} else {
const attachment = attachments[0];
const res = await fetch("https://api.constaia.com/v1/analyze", {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
file_url: attachment.url,
filename: attachment.filename,
options: {
expect: ["es_dni", "es_nie", "passport"],
checks: { min_age_years: 18 },
language: "es",
metadata: { airtable_record_id: recordId },
},
}),
});
const analysis = await res.json();
if (!res.ok) {
const e = analysis.error;
await table.updateRecordAsync(recordId, { Veredicto: "error", Motivos: `${e.code}: ${e.message} (${e.request_id})` });
throw new Error(e.message);
}
const verdict = analysis.verdict;
const number = analysis.fields.document_number ?? analysis.fields.nie_number;
await table.updateRecordAsync(recordId, {
Veredicto: verdict ? verdict.status : analysis.status,
Motivos: (verdict?.reasons ?? [])
.filter((r) => r.severity !== "info")
.map((r) => r.message)
.join("\n"),
"Nº documento": number?.value ?? "",
"ID análisis": analysis.id,
});
output.set("status", verdict?.status ?? analysis.status);
}Las URLs de los adjuntos de Airtable son https y descargables durante un tiempo limitado, suficiente para que
Constaia las descargue en el momento (máximo 20 MB y 15 s). Si prefieres un campo Single select para
Veredicto, escribe { name: verdict.status } en lugar del texto.
Actúa según el veredicto
Con el valor de salida status del script, añade acciones condicionales (Add conditional group):
status | Qué hacer |
|---|---|
Válido valid | Marcar la solicitud como aprobada |
No válido invalid | Enviar un correo al solicitante con los motivos |
Revisar review | Asignar el registro a una persona. Ver Revisión humana |
Si el análisis tarda más de 30 s, la API responde 202 y el script escribe queued o processing en
Veredicto (ver la sección siguiente). El significado de cada estado está en
Veredictos.
Documentos largos: async y webhook
Los scripts de automatización tienen un tiempo máximo de ejecución. Para PDFs de muchas páginas, envía
"async": true en las opciones: la API responde 202 al momento y te avisa por webhook al terminar.
- Crea otra automatización con el disparador When webhook received y registra su URL en el panel o con
POST /v1/webhook-endpoints(ver Webhooks). - Airtable no permite verificar la firma HMAC del evento, así que no te fíes de su contenido: en un
Run a script, toma
data.iddel cuerpo, comprueba que empieza poran_, vuelve a leer el análisis conGET https://api.constaia.com/v1/analyses/{id}y tu clave, y actualiza el registro indicado enmetadata.airtable_record_idde esa respuesta. - Constaia reintenta las entregas fallidas: si el registro ya tiene veredicto, no hagas nada.
No uses keep_results: false en este flujo, o la relectura devolverá 404.
Probar en modo test
Con una clave ck_test_… no se consumen créditos y la respuesta depende del nombre del fichero (filename).
Sube como adjunto cualquier imagen real con uno de estos nombres:
| Adjunto | Resultado |
|---|---|
dni_valid.jpg | Válido Nº documento = 12345678Z |
nie.jpg | Válido Nº documento = X1234567L |
dni_expired.jpg | No válido "Caducado el 15/06/2020." |
blurry.jpg | Revisar motivo low_quality |
Más escenarios en Modo test.
Seguridad
- La clave queda escrita en el script y cualquiera con permisos de creador en la base puede verla. Usa claves
ck_live_…solo en bases con acceso restringido, no en bases compartidas con externos ni en plantillas. Si no puedes restringir el acceso, haz que el script llame a un backend tuyo que guarde la clave. - Monta y prueba la automatización con una clave de test.
- Airtable guarda los datos que escribes en el registro y el adjunto original. Escribe solo los campos que
necesites. Constaia borra su copia del fichero al terminar con
storage: "none"(por defecto); ver Almacenamiento y privacidad.
Límites
- 20 MB por fichero; PDFs de hasta 30 páginas en síncrono y hasta 200 con
async: true. - 2 peticiones por segundo por clave en el plan gratuito (10 en el de pago). Si importas muchos registros de golpe y se disparan muchas automatizaciones,
puedes recibir 429 con
Retry-After. Ver Límites de uso y, para cargas masivas, lotes.
Siguientes pasos
Google Apps Script
Valida documentos de Google Drive desde Google Sheets con Apps Script y UrlFetchApp, guarda la clave en Script Properties y escribe el veredicto en la hoja.
Retool
Crea en Retool un panel interno para validar documentos con Constaia: recurso REST con la clave en variables de configuración, subida de ficheros y resultados.