¿Qué hace CounterCall - LlamadaVerificada?
Pak Yanto se tomó la mañana libre, viajó cuarenta minutos al mostrador de Samsat y fue rechazado porque su fotocopia era tamaño folio en lugar de A4. Perdió un día de ingresos, y todavía no sabía qué más le faltaba para mañana.
Los mostradores de servicios públicos publican listas de requisitos que son incompletas, desactualizadas o contradichas silenciosamente en la ventanilla. La única fuente confiable es la línea telefónica de la oficina, y esa línea está ocupada, protegida por IVR, y se responde al cuarto intento. Así que la gente no llama. Viajan, hacen fila, y son rechazados por un solo documento.
Esta habilidad hace la llamada en su lugar, y devuelve una lista de verificación que la persona puede capturar y llevar consigo.
Es una buena opción para el diseño de CALL-E: trabajo telefónico de baja frecuencia, personal y de alto riesgo contra un número que un humano de otro modo tendría que marcar toda la mañana.
Antes de empezar
Esta habilidad realiza una llamada telefónica real a una oficina pública real. Confirma con el usuario:
- qué procedimiento está consultando, en las propias palabras de la oficina
- qué oficina, y el número de teléfono en formato E.164, desde la página publicada de la oficina
- que desea que se realice una llamada ahora
Nunca infieras un número de teléfono. Ni de un directorio, ni de una oficina similar, ni adivinando un código de país. Un número ingresa en el flujo solo cuando un humano lo ha leído directamente de la página publicada de la oficina. Llamar al número equivocado significa que un llamante automatizado contacta a un extraño, que es lo peor que esta habilidad puede hacer.
Límites de seguridad
Esta habilidad recopila únicamente requisitos de mostrador.
- No presenta una solicitud, reserva una cita, paga una tarifa ni compromete al usuario a nada. Pregunta e informa.
- No brinda asesoría legal ni de inmigración. Si un funcionario sugiere una alternativa, repórtalo textualmente como algo que dijo el funcionario, nunca como una recomendación.
- La respuesta oral de un funcionario es informativa, no vinculante legalmente, y cada resultado generado lo dice. Los requisitos cambian y los mostradores individuales aplican discreción.
- Al inicio de la llamada declara claramente que es un asistente automatizado, y por qué está llamando. Si la persona se niega a responder, le agradece y finaliza la llamada. No insiste, vuelve a preguntar ni llama de nuevo el mismo día.
- Una llamada por oficina por procedimiento por día. Estas son líneas de servicio público atendidas por personas que tienen una cola frente a ellas. La clave de idempotencia lo garantiza; no la elimines.
- Cuando el funcionario no está seguro, el resultado dice "no está seguro". Nunca llena un vacío con lo típico, y nunca presenta una ambigüedad como un hecho. Una persona puede viajar al otro lado de una ciudad basándose en esta respuesta.
- Llama a las oficinas solo durante su horario de atención publicado. Una línea pública que suena a las 22:00 no es un dato, es una molestia.
Lee references/safety.md antes de adaptar esta habilidad a una nueva institución. Algunos
destinatarios no son objetivos apropiados para un llamante automatizado.
Qué lo hace diferente de una transcripción
La mayoría de las habilidades de llamada devuelven prosa y dejan que el lector interprete. Esta devuelve un objeto validado y fijo, y se niega a devolver cualquier otra cosa.
El result_schema del Goal establece additionalProperties: false y restringe cuatro campos a
enumeraciones — payment_method, appointment_required, originals_or_copies y
clerk_certainty, cada una de las cuales incluye un valor para "el funcionario no lo sabía".
Si la llamada regresa con una forma diferente, el resultado se pone en cuarentena en lugar de
mostrarse. Una lista de verificación mal parseada es peor que ninguna lista, porque el usuario
actúa en base a ella.
El contrato completo está en references/result-contract.md.
Flujo de trabajo
1. Recopilar la solicitud
Requerido: el nombre del procedimiento, el nombre de la oficina, el número de teléfono de la oficina en formato E.164, y la URL de la fuente publicada de donde se obtuvo el número.
Valida el número antes de que ocurra cualquier otra cosa. E.164 es un signo más, un dígito de código de país distinto de cero,
luego de 7 a 14 dígitos más: ^\+[1-9]\d{7,14}$. Rechaza cualquier otra cosa y pídele al
usuario. Nunca adivines un código de país. Un número en formato local que llega al marcador es
cómo se llama a la persona equivocada.
Ejecuta scripts/preflight.mjs para verificar el número y el contrato sin marcar.
2. Verificar que el contrato publicado no haya cambiado
Antes de cada ejecución, lee la interfaz Goal en vivo y compárala con el contrato para el que se escribió esta habilidad.
import { diffContract, publishedRunSpec } from './scripts/_lib.mjs';
const goal = await client.goals.get(GOAL_ID);
const drift = diffContract(PINNED_CONTRACT, publishedRunSpec(goal));
if (drift.length) throw new ContractDrift(drift); // negarse a marcar
Usa el helper publishedRunSpec(goal), no goal.published_run_spec directamente.
El formato de cable y la documentación lo escriben published_run_spec.result_schema; el SDK de TypeScript
lo convierte a camelCase como publishedRunSpec.resultSchema. Leer solo el nombre documentado
contra el cliente TS devuelve undefined en lugar de lanzar una excepción — entonces la
protección concluye "sin especificación publicada" y se niega a marcar cada vez mientras parece
que funciona. El helper lee ambas ortografías.
Esto nos costó un día; está documentado en FEEDBACK.md en la raíz del repositorio.
La documentación de CALL-E recomienda esta comparación antes de implementar un cambio de variable. Hacerlo en cada ejecución cuesta una llamada API y convierte un fallo silencioso en un rechazo evidente. Marcar a una persona real con un esquema obsoleto produce un resultado que parece correcto y está silenciosamente equivocado.
3. Realizar una llamada
goals.run con una Idempotency-Key limitada a oficina, procedimiento y fecha, para que un reintento
nunca marque doble a una línea pública:
countercall:{office}:{procedure}:{yyyy-mm-dd}:v1
4. Consultar hasta obtener un resultado o un error
goals.waitForResult tiene una regla de finalización: detenerse cuando result o error sea
distinto de nulo. Una llamada completada puede devolver brevemente ambos nulos mientras CALL-E
analiza el resultado estructurado, así que no trates esa ventana como un fallo.
5. Mostrar, o fallar honestamente
Los ocho códigos publicados de GoalRunError se dirigen a un resultado distinto. El conjunto a
continuación es el que implementa scripts/render.mjs — mantenlos sincronizados si CALL-E agrega
un código.
| Resultado | Lo que ve el usuario |
|---|---|
| resultado válido | la lista de verificación, con la línea textual del funcionario y la URL de la fuente |
no_answer | "la línea no respondió". Sin lista de verificación |
declined | "la oficina se negó a responder a un llamante automatizado". Sin lista de verificación |
result_invalid | la llamada se completó pero la respuesta no coincidió con el contrato. En cuarentena |
result_unavailable | la llamada se completó pero no produjo una respuesta estructurada. Sin lista de verificación |
result_failed | la respuesta no pudo procesarse en una lista de verificación. Sin lista de verificación |
timed_out | "sin respuesta utilizable" antes de la fecha límite. Sin lista de verificación |
call_failed | la llamada no pudo completarse. Sin lista de verificación |
canceled | cancelada antes de producir una respuesta. Sin lista de verificación |
Ninguna rama muestra una lista de verificación parcial. Ejemplos prácticos de cada uno están
en references/examples.md.
Ejecutarlo
scripts/call.mjs está en modo simulado de forma predeterminada. Imprime la solicitud exacta
que enviaría y no realiza ninguna llamada. Marcar requiere un --live explícito:
# simulación — imprime la solicitud que enviaría, no marca nada, no necesita credenciales
node scripts/call.mjs --office <id> --procedure "<procedimiento>"
# realmente suena un teléfono
node scripts/call.mjs --office <id> --procedure "<procedimiento>" --live
Una habilidad que marca por defecto es una habilidad que marca por accidente.
data/offices.json se envía con su número de teléfono enmascarado (+62XXXXXXXXXX), por lo que
la entrada inicial no puede marcar y cada comando contra ella sale con código 3 y
REFUSING TO DIAL. Esto es deliberado: un número ingresa en el archivo solo cuando un humano lo ha leído
directamente de la página publicada de la oficina y ha registrado source_url y source_checked. Agrega
una entrada propia antes de ejecutar nada.
Para ver la salida de la simulación inmediatamente, el fixture de prueba incluye un número ficticio válido:
node scripts/call.mjs --offices ../../test/fixtures/offices.test.json \
--office fixture-sourced --procedure "perpanjangan paspor"
Cuándo no usar esto
- Emergencias. Esto es una consulta de requisitos con una latencia de varios minutos. No es una forma de contactar a alguien urgentemente.
- Oficinas con una página publicada de requisitos confiable, actual y precisa. Si el sitio web es correcto, lee el sitio web. La llamada está justificada solo donde se sabe que la respuesta publicada está incompleta.
- Cualquier institución que haya solicitado no ser contactada por sistemas automatizados, o donde la ley local restrinja las llamadas automatizadas. Verifica antes de agregar una oficina.
- Consultas de alto volumen. Una oficina por procedimiento por día es el límite por diseño. Si necesitas volumen, necesitas un acuerdo de intercambio de datos, no un teléfono.
- Cualquier cosa donde equivocarse sea barato. El valor aquí proviene del costo de un viaje perdido. Si el usuario simplemente puede ir y averiguar, déjalo.
Limitaciones honestas
- La cobertura se limita a las oficinas en el archivo inicial, cada una con una URL de fuente publicada.
- Las tasas de respuesta en líneas de servicio público varían según la oficina y la hora del día, y una gran parte de las llamadas no serán respondidas. Esa falta de fiabilidad es la razón por la que existe esta habilidad, y se informa en lugar de ocultarse.
- El resultado es la respuesta de un funcionario en un día. Es evidencia, no una garantía.