Universidad ECOTEC · Marketing y Admisiones

Puente ECORE

Cómo los formularios de admisión de los tres sitios dejan de mandar nombres de carrera en texto libre y empiezan a mandar el identificador canónico de ECORE — con la cédula y el título verificados en el mismo paso.

Credencial verificada 128 carreras leídas en vivo 34 pruebas funcionales en verde Prototipo · no es el plugin todavía

Hoy cada formulario manda el nombre de la carrera como texto. Maestría en Ciberseguridad llega a Zapier como una cadena, y del otro lado nadie sabe si es la versión híbrida o la online — son dos programas distintos, con cupo, malla y precio distintos. Mientras el destino era Zendesk eso se resolvía leyendo el ticket. Con Salesforce de por medio, un lead mal atribuido es un lead perdido en el embudo equivocado.

ECORE ya publica el catálogo académico con identificadores estables. Este documento describe cómo se conecta, qué se probó con datos reales, y las decisiones que quedan abiertas.

Lo que ya está verificado

Contra el API de producción, no contra documentación.

La credencial funciona y tiene los dos permisos que el proyecto necesita. El correo de habilitación solo mencionaba datos:read, pero /whoami confirma que oferta:read también está concedido — no hay nada que pedirle al equipo de ECORE para arrancar.

GET /api/v2/whoami HTTP 200
cliente
ECOTEC (MKT)
key
prod-mkt
scopes
datos:read · oferta:read
expira
2028-07-20

El catálogo trae 128 carreras activas. Los carrera_id son únicos en las 128 filas, así que sirven directamente como External Id de Salesforce para hacer upsert idempotente.

OfertaPresencialOnlineHíbridaVirtualTotal
Grado2618246
Posgrado172935182

El recorrido de un lead

Dónde se gasta cuota del API y dónde no.

CARRIL DE IDENTIDAD Cédula campo del formulario módulo 10 local 0 llamadas al API inválida se detiene aquí válida ECORE · datos GET /datos/titulos GET /datos/civil cache 24 h por cédula CARRIL DE CARRERA Programa post o select resolver() contra catálogo en cache catálogo · 12 h carrera_id + malla_id + facultad_id payload Zapier un solo schema Zendesk hoy Salesforce después
Los dos carriles corren en paralelo y solo se juntan al armar el payload. Lo marcado en azul es lo que se agrega: la compuerta local que rechaza cédulas mal escritas sin gastar cuota, la resolución a carrera_id, y el payload unificado. Zapier y Zendesk siguen exactamente como están.

El match de carreras

La parte que hay que ver funcionando antes de confiar en ella.

Aquí está el hallazgo que define el diseño: 17 carreras del catálogo existen en dos modalidades con carrera_id distinto. No son variantes de un mismo registro; son programas separados.

CarreraPresencialOnlineHíbrida
Administración de Empresas14993
Derecho320414
Economía15796
Marketing321416
Sistemas Inteligentes31233
Maestría en Ciberseguridad109245
Maestría en Derecho Penal200118
Maestría en Marketing Estratégico197360

Son 8 de las 17; la lista completa está en el visualizador. La consecuencia es directa: la llave del mapeo es (post, modalidad), nunca solo el post. Un post de WordPress puede necesitar dos o tres identificadores según la modalidad que elija el aspirante.

Si se ignora esto

La mitad de los leads de Administración de Empresas entra a Salesforce apuntando al programa presencial cuando pidieron el online. El dato se ve limpio y está mal.

Los cuatro caminos de resolución

¿De dónde viene el programa? select de ECORE no hay match que hacer option value = carrera_id post de WordPress 1 · mapeo manual autoritativo · gana siempre 2 · nombre único un solo candidato 3 · nombre + modalidad la modalidad desempata 4 · sin resolver queda pendiente de mapeo carrera_id + malla_id + facultad_id al payload reporte de pendientes
La cadena se evalúa en orden y se detiene en el primer camino que resuelve. Lo importante: cuando el select se alimenta directo de ECORE, el problema del match desaparece — el identificador viaja en el value de la opción. El match solo hace falta en las páginas individuales de WordPress, donde el programa lo define el post.

Por qué no se puede hacer match por nombre en tiempo de envío

Los nombres que devuelve ECORE no son consistentes entre sí. Tildes irregulares, la modalidad embebida en el nombre, separadores que cambian y espacios dobles:

ADMINISTRACION DE EMPRESAS - ONLINE      ← sin tilde
ADMINISTRACIÓN DE EMPRESAS               ← con tilde
CRIMINALISTICA -  HIBRIDA                ← espacio doble, sin tilde
NEGOCIOS INTERNACIONALES - HÍBRIDA       ← con tilde
PSICOLOGÍA - ITINERARIO EN…              ← guion  (presencial)
PSICOLOGÍA, ITINERARIO EN…               ← coma   (online)

Por eso el normalizador corre en cinco pasos y solo se usa para autosugerir en la pantalla de mapeo, donde una persona confirma. Nunca decide solo en un envío.

Normalización, paso a paso resolver()
0 entrada
PSICOLOGÍA, ITINERARIO EN PSICOLOGÍA EDUCATIVA - ONLINE
1 sin tildes
PSICOLOGIA, ITINERARIO EN PSICOLOGIA EDUCATIVA - ONLINE
2 coma→guion
PSICOLOGIA - ITINERARIO EN PSICOLOGIA EDUCATIVA - ONLINE
3 sin sufijo
PSICOLOGIA - ITINERARIO EN PSICOLOGIA EDUCATIVA
4 clave
PSICOLOGIA ITINERARIO EN PSICOLOGIA EDUCATIVA
Además, el filtro del API no sirve para buscar

nombre_carrera es un LIKE al que ECORE no le agrega comodines. Enviar BIG DATA devuelve cero resultados; hay que mandar %BIG DATA%. Es otra razón para resolver contra el catálogo cacheado en lugar de consultar el API en cada envío.

Resultados de las pruebas

Casos reales contra el catálogo de producción.

Título en WordPressModalidadEstadoMétodoResultado
Maestría en Big Dataoknombre_unico117
MAESTRIA EN BIG DATA (sin tildes)oknombre_unico117
maestría  en   big   data (espacios)oknombre_unico117
Maestría en Ciberseguridadambiguo109 ó 245
Maestría en CiberseguridadOnlineoknombre_y_modalidad109
Maestría en CiberseguridadHíbridaoknombre_y_modalidad245
Maestría en CiberseguridadPresencialno existe
Maestría en Derecho PenalOnlineoknombre_y_modalidad118
Maestría en Derecho PenalPresencialoknombre_y_modalidad200
Maestría en Blockchain (no existe)sin match

El normalizador absorbe tildes y espacios sin problema. Lo que no puede absorber es la falta de modalidad: ahí se detiene y lo reporta en lugar de adivinar. Ese es el comportamiento correcto — adivinar es exactamente lo que produce el dato sucio que parece limpio.

Cédula y título

Reemplaza la pregunta autodeclarada en los cuatro formularios.

Hasta ahora el formulario de ECOTEC Online preguntaba «¿Posee un título universitario registrado en SENESCYT?» y bloqueaba si la respuesta era bachillerato. Esa pregunta desaparece: al escribir la cédula se consulta la fuente real.

La secuencia tiene una compuerta local antes de tocar el API. La validación módulo 10 rechaza cédulas mal escritas sin gastar cuota — y de paso da un mensaje de error mucho más útil que un 404.

EstadoDe dónde sale¿Bloquea?Qué significa
verificado200 · superiores ≠ ∅noTiene título de nivel superior registrado.
sin_titulo200 · superiores = ∅noCédula válida sin título en la fuente. Puede tener título extranjero no registrado.
no_encontrado404noNo está en la fuente. Extranjero, o error de digitación que pasó el módulo 10.
cedula_invalidamódulo 10 localEl único bloqueo. El dato está mal escrito y no cuesta nada detectarlo.
error_api502 · 504noLa fuente no responde. El formulario continúa.
rate_limitedthrottle localnoDemasiadas consultas desde una IP. Se envía sin validar, marcado.
La regla

Lo único que bloquea el envío es una cédula mal formada. Todo lo demás se marca y se manda. Perder un aspirante de maestría porque la fuente de datos estaba caída cuesta más que revisar un lead marcado; y un título extranjero legítimo no aparece en SENESCYT. La elegibilidad la decide admisiones con el dato al lado, no el formulario.

Lo que el navegador no ve

/datos/civil devuelve bastante más de lo que un formulario necesita: dirección domiciliaria con calle y número, nombres del padre y de la madre, estado civil, cónyuge, profesión, teléfonos y correos. /datos/titulos devuelve el historial académico completo.

El servidor filtra y solo entrega cuatro cosas al navegador: el estado, el conteo de títulos, y los tres campos que se autocompletan.

Se queda en el servidorno sale
domicilio
calle, número
filiación
padre, madre
civil
estado, cónyuge
contacto
teléfonos, correos
académico
historial completo
Llega al navegador4 campos
estado
verificado
conteo
2
nombre
autocompletar
provincia
autocompletar
Consentimiento

Se está consultando el registro nacional con la cédula de una persona. El checkbox de términos tiene que decirlo explícitamente. Si se devolviera el payload crudo al navegador, el formulario se convertiría en un servicio público de consulta de cédulas — de ahí el filtro del servidor, no es una precaución teórica.

El bloqueador de hoy

La validación de título no se puede desplegar todavía.

Al probar contra la fuente real apareció un problema que cambia el plan. /datos/titulos no responde para cédulas reales: devuelve 504 a los 25 segundos, de forma consistente en todos los intentos.

EndpointRespuestaTiempoEstado
/datos/civil200 · datos completos0,3 sfunciona
/datos/padron2000,1 sfunciona
/oferta/activa200 · 128 carreras0,4 sfunciona
/datos/titulos200 · {"message":"no"}1,5 ssolo si no halla a la persona
/datos/titulos504 · upstream-timeout25 scédula real
Consecuencia directa

El bloqueo por título no puede ser una compuerta síncrona del formulario. Aunque el servicio se recupere, 25 segundos de espera en un campo es inviable, y hoy el resultado sería un 504 para cada aspirante de posgrado. Con la regla de fail-open eso significa que nadie quedaría bloqueado — la función existiría sin funcionar.

Un bug que la documentación provoca

Cuando la fuente no encuentra a la persona, /datos/titulos responde 200 con {"message":"no"} — no el 404 que promete la documentación, y sin el objeto data.

Una implementación que siga el contrato documentado leería data.superiores como lista vacía y clasificaría a esa persona como sin_titulo. Con el bloqueo activo, la rechazaría — cuando lo cierto es que la fuente simplemente no la conoce, y ese caso debe pasar.

Las cuatro formas reales de respuesta verificado en producción
200 + data.superiores≠∅
verificado — tiene título
200 + data.superiores=∅
sin_titulo — existe, sin título
200 + message:no
no_encontrado — la fuente no lo conoce
504 upstream-timeout
error_api — hoy, lo normal
Propuesta

Separar la validación del envío. El lead se manda de inmediato con titulo_validacion_estado = pendiente, y un proceso en segundo plano consulta los títulos y actualiza el registro en Salesforce cuando la fuente responda. Así el formulario nunca espera 25 segundos, ningún lead se pierde por un 504, y el dato llega igual — unos minutos después. Si además se quiere bloquear, el bloqueo lo aplica admisiones sobre el lead ya marcado, no el formulario.

Para el equipo de ECORE

Vale reportar tres cosas: el 504 sostenido de /datos/titulos, que el caso «no encontrado» devuelve 200 en lugar del 404 documentado, y que los headers RateLimit-* que la documentación promete no se envían.

El payload

Qué se agrega y por qué Zendesk no se entera.

Los cuatro plugins ya normalizan su payload contra un PAYLOAD_SCHEMA fijo, precisamente para que Zapier vea siempre la misma firma. Los campos nuevos hay que agregarlos a ese schema, no solo inyectarlos por el filtro — si no, aparecen de forma intermitente y rompen el mapeo.

Campo nuevoEjemploPara qué sirve en Salesforce
ecore_carrera_id109External Id del programa. Upsert idempotente.
ecore_malla_id154Versión de malla. Cambia con los años; el carrera_id no.
ecore_facultad_id23Agrupación para reportes y asignación de asesor.
ecore_ofertaPosgradoGrado · Posgrado · Nivelación.
ecore_modalidadOnlineLo que distingue los 17 pares duplicados.
ecore_carrera_nombreMAESTRÍA EN…Solo lectura humana. Nunca como llave.
ecore_match_metodonombre_y_modalidadAuditoría: cómo se resolvió este lead.
titulo_validacion_estadoverificadoReemplaza la pregunta autodeclarada.
titulo_tiene_superior1Booleano para reglas de asignación.
linea_negocio_stdposgradoDiscriminante único entre los cuatro plugins.
Riesgo de despliegue: bajo

Zapier ignora los campos que no estén mapeados en el Zap. Los ecore_* pueden empezar a llegar hoy mismo y el flujo actual hacia Zendesk sigue idéntico, sin tocar el Zap. Cuando llegue el conector de Salesforce, los campos ya llevan meses llegando limpios y solo hay que mapearlos.

Los cuatro plugins no hablan el mismo idioma

PluginSitioCampo de carreraPrefijo
ecotec-formsecotec.edu.eccarrera + carrera_slug + campusewf_
ecotec-webmaster-formsecoteconline.edu.eccarrera + oferta + facultad + linea_negocioewf_
ecotec-posgrado-formsposgrado.ecotec.edu.ecprograma + modalidadepf_
ecotec-homologacion-formspor confirmarcarrera + carreras_homologacionehf_

Posgrado manda programa y no manda carrera en absoluto. Los cuatro exponen el filtro que hace falta para inyectar los campos nuevos, aunque ehf_zapier_payload pasa un solo argumento y necesita un ajuste menor.

La cuota es ciega

60 peticiones por minuto que no se pueden medir.

El límite es por API key, y hay una sola key para ecotec.edu.ec, ecoteconline.edu.ec y posgrado.ecotec.edu.ec. Los tres sitios comparten el mismo presupuesto.

Y hay un detalle que la documentación de ECORE no refleja:

Hallazgo

ECORE documenta headers RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset en cada respuesta. No los envía. Lo único que llega es x-request-id. La cuota hay que presupuestarla, no medirla — vale la pena reportarlo al equipo de ECORE.

LlamadaCuándoDefensa
POST /oferta/activa1 cada 12 hCache del catálogo completo. 128 carreras, sin paginación.
GET /datos/titulos1 por cédula nuevaCache 24 h + throttle 8/10 min por IP + módulo 10 antes.
GET /datos/civiligual que arribaMisma defensa. Se puede omitir si no se autocompleta.

Sin estas defensas, un bot en el campo de cédula agota en un minuto la cuota de toda la institución. Los plugins ya tienen honeypot y nonce en EWF_Security, así que es extender lo que existe.

Otro dato sucio: las URLs de admisiones

De las 128 carreras, 80 traen un url_admissions que apunta a un entorno que no es producción. La documentación advierte la posibilidad; los datos la confirman.

HostCarrerasUsable
dev-admisiones.ecotec.edu.ec53no
demo-admisiones.ecotec.edu.ec27no
admisiones-nbs.ecotec.edu.ec39
null9vacío

Si se va a redirigir aspirantes con ese campo hay que validar el host contra una lista blanca y caer a una URL propia en el resto de los casos.

Del prototipo al plugin

Qué es esto y qué falta para producción.

Lo que está corriendo es un prototipo en Python que consulta ECORE en vivo: valida cédulas, resuelve carreras contra el catálogo real y arma el payload completo. Sirve para ver el mecanismo funcionando con datos de producción antes de escribir el plugin.

Aclaración

El prototipo no es el plugin. Está en Python porque la máquina de desarrollo no tiene PHP instalado. La lógica se traduce pieza por pieza; el código de producción es PHP dentro de WordPress.

PrototipoWordPress
ecore.ClienteEcore_Client sobre wp_remote_get/post
ecore.Catalogoset_transient(…, 12 * HOUR_IN_SECONDS)
ecore.resolver()Ecore_Mapping::resolver()
mapeo-carreras.jsonpost meta _ecore_carrera_id por (post, modalidad)
ecore.validar_titulo()Ecore_Titulos + wp_ajax_nopriv con nonce
payload_estandar()filtro *_zapier_payload + PAYLOAD_SCHEMA
.envdefine('ECOTEC_ECORE_API_KEY', …) en wp-config.php
La API key nunca en el plugin

Un archivo .env dentro de wp-content/plugins/ es descargable por HTTP en la mayoría de configuraciones de Nginx y Apache. En producción la key va como constante en wp-config.php, y todas las llamadas salen del servidor.

Decisiones tomadas

Cerradas el 24 de agosto de 2026.

DecisiónResueltoQué implica
Instalaciones 3 WordPress separados La key va en tres wp-config.php. El mapeo vive en cada sitio. Los tres comparten los 60 req/min de la misma credencial.
Bloqueo sin título Sí, en Posgrado Solo cuando la oferta exige título. «No pudimos verificar» no bloquea: no_encontrado, error_api y rate_limited pasan marcados. Hoy inaplicable — ver el bloqueador.
Homologación ecoteconline.edu.ec Ese sitio mezcla Grado y Posgrado, así que el bloqueo depende de la carrera elegida, no del dominio.
Autocompletar Nombre, apellido y provincia desde /datos/civil, que responde en 0,3 s. Solo esos tres campos salen al navegador.
Lo que sigue

El plugin ecotec-ecore-connect en PHP: cliente, catálogo cacheado, pantalla de mapeo y los filtros de payload. La validación de título queda diseñada pero desactivada hasta que /datos/titulos responda.