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
Grado26182—46
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 Data—oknombre_unico117
MAESTRIA EN BIG DATA (sin tildes)—oknombre_unico117
maestría  en   big   data (espacios)—oknombre_unico117
Maestría en Ciberseguridad—ambiguo—109 ó 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 localsíEl ú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.ec39sí
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.

Los tres sitios no se parecen

Leídos en vivo por su REST API. Ninguno comparte estructura con otro.

El supuesto de que los tres WordPress usan el mismo modelo era falso. Comparten el nombre del tipo de contenido en dos de ellos y nada más: las taxonomías, el vocabulario de modalidad y hasta la forma de titular las carreras cambian por sitio.

SitioCPTTaxonomíasPosts
ecotec.edu.eccarrera campus · facultad54
posgrado.ecotec.edu.ecprograma modalidad · profesor · unidad55
ecoteconline.edu.ecprograma facultad · linea-de-negocio · tipo-de-producto82

Cada sitio titula distinto

El mismo programa se llama de tres maneras según dónde viva, y ECORE lo llama de una cuarta. El normalizador absorbe tildes y espacios, pero no un prefijo que cambia el nombre entero:

ecotec.edu.ec        Administración de Empresas
ecoteconline.edu.ec  Licenciatura en Administración de Empresas
ECORE                ADMINISTRACIÓN DE EMPRESAS
ECORE (online)       ADMINISTRACION DE EMPRESAS - ONLINE
Y la regla no es «quitar el prefijo»

Quitarlo siempre resuelve 6 casos nuevos y rompe 12, porque Maestría en … sí es como ECORE nombra los posgrados. Solo se quitan los prefijos de grado — Licenciatura en, Ingeniería en — y se prueban ambas variantes antes de rendirse.

La taxonomía «modalidad» de posgrado engaña

posgrado.ecotec.edu.ec tiene una taxonomía modalidad que parecía la solución al problema de las carreras duplicadas. No lo es: su vocabulario no es el de ECORE, y usarlo para desempatar produce resultados falsos.

ProgramaDice WordPressOfrece ECORE
Maestría en Derecho PenalSemipresencial Presencial=200 · Online=118
Maestría en Administración de EmpresasSemipresencial Presencial=189 · Online=122
Maestría en Derecho ConstitucionalSemipresencial Presencial=199 · Online=120
Conclusión

Ninguno de esos programas existe en modalidad híbrida en ECORE, pero WordPress los marca «Semipresencial». Si esa taxonomía desempatara, el match devolvería modalidad inexistente en 4 casos que de otro modo resuelven. Se ignora para el match y se usa la prioridad del sitio.

Resultado con las reglas afinadas

SitioPosts en españolResueltosPendientesCobertura
ecotec.edu.ec27261 96%
ecoteconline.edu.ec41356 85%
posgrado.ecotec.edu.ec27189 67%
Total95 7916 83%
Los 9 de posgrado no son un fallo del match

Enfermería, Psicología Clínica, Periodismo Deportivo, Gestión de Ventas, Gestión Tributaria, Gestión Hospitalaria, Gestión de la Cadena de Suministro y Derecho de Familia no están en la oferta activa de ECORE — ni con ese nombre ni con otro. El sitio publica programas que el sistema académico no tiene con malla activa. Eso es contenido desactualizado o mallas sin activar, y hay que resolverlo antes de mapear nada.

Descontando esos, el matcher falla en 7 de 95. Aparte quedan 96 posts en inglés entre los tres sitios, que son las mismas carreras y necesitan mapeo manual al carrera_id de su gemela en español.

Un plugin compartido, cuatro formularios

La recomendación, con lo que se separa y lo que no.

La pregunta era si mantener plugins separados. La respuesta es que hay dos cosas distintas mezcladas hoy, y solo una debe unificarse.

UNA BASE DE CÓDIGO ecotec-ecore-connect Ecore_Client Ecore_Catalog · cache 12 h Ecore_Mapping · resolver() Ecore_Titulos Ecore_Payload se instala 3 veces TRES INSTALACIONES · UN CONFIG CADA UNA ecotec.edu.ec cpt: carrera · tax: campus, facultad modalidad: Presencial > Híbrida prefijos: — ecoteconline.edu.ec cpt: programa · tax: linea-de-negocio modalidad: Online prefijos: quitar «Licenciatura en» posgrado.ecotec.edu.ec cpt: programa · tax: modalidad (se ignora) modalidad: Presencial > Híbrida > Online prefijos: conservar «Maestría en» filtro *_zapier_payload LOS 4 FORMULARIOS · SIN TOCAR payload + campos ecore_* ecotec-forms ecotec-webmaster-forms ecotec-posgrado-forms ecotec-homologacion-forms shortcodes y renderers propios Zapier · un schema
Lo azul es lo nuevo. Los cuatro plugins de formulario se quedan como están: ya exponen el filtro por el que se inyectan los campos. Lo que cambia por sitio no es código, es un archivo de configuración.
Pieza¿Se unifica?Por qué
Cliente ECORE, catálogo, matcher, títulos sí, una vez Es idéntico en los tres sitios. Mantenerlo por triplicado garantiza que se desincronice.
Configuración por sitio un archivo cada uno CPT, taxonomías, prioridad de modalidad y prefijos cambian. Son datos, no código.
Tabla de mapeo no, es local Son post meta: los IDs de post solo existen en su instalación.
Los 4 plugins de formulario no se fusionan Distintos formularios, distintos campos, distintos sitios. Fusionarlos hace que un bug tumbe tres sitios a la vez.
PAYLOAD_SCHEMA sí, mismo schema Un solo mapeo en Zapier para los cuatro, en vez de cuatro Zaps que divergen.
Lo que más reduce el trabajo

Donde el formulario tenga un desplegable, alimentarlo desde ECORE. El carrera_id viaja en el value de la opción y no hay match que hacer, ni mapeo que mantener, ni nombres que se desincronicen. El match solo hace falta en las páginas individuales, donde el programa lo define el post.

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 Sí 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.