Servicio "Componente IA Externo" (Web Services)
Tipo: servicio externo de Web Services (configuración Admin UI, sin código)
Ubicación: ambiente de Pruebas — https://campusvirtual.metaversodenegocios.com
Alcance: 3 — Agente IA
Estado: Configurado en Pruebas
Propósito
Dar al agente IA (cuya interfaz conversacional es el Drawer IA) acceso
de solo lectura al contexto del estudiante — matriculaciones, entregas,
calificaciones, progreso, finalización — más la capacidad de enviarle mensajes,
todo vía REST con token. El agente nunca consulta tablas mdl_* directamente.
Cómo consume el agente
Todas las consultas van al mismo endpoint:
POST https://campusvirtual.metaversodenegocios.com/webservice/rest/server.php
wstoken=<token>
wsfunction=<nombre_funcion>
moodlewsrestformat=json
...parámetros propios de la función
El modelo es pull: los Web Services de Moodle no emiten eventos hacia afuera (el core no tiene webhooks salientes), por lo que el agente consulta periódicamente y aplica sus reglas sobre la respuesta. El disparo push (event-driven, latencia cero) requiere la capa custom del plugin con observadores de eventos, definida en ADR-001; las funciones y reglas del agente no cambian entre un modelo y otro.
Configuración del servicio
Creado en Administración del sitio → Servidor → Servicios web → Servicios externos (/admin/settings.php?section=externalservices), nombre
"Componente IA Externo", con estas funciones autorizadas:
| Función | Da acceso a |
|---|---|
core_webservice_get_site_info | Validación del token, info del sitio y funciones disponibles |
core_user_get_users_by_field | Perfil del usuario, incluido lastaccess |
core_enrol_get_users_courses | Cursos del usuario con progress, startdate, lastaccess |
core_enrol_get_enrolled_users | Matriculados de un curso con roles y lastcourseaccess |
core_course_get_courses_by_field | Datos de un curso por id/shortname/categoría |
core_course_search_courses | Catálogo de cursos visibles |
core_course_get_contents | Secciones y actividades del curso (estructura de módulos) |
core_completion_get_activities_completion_status | Estado de completitud por actividad |
core_completion_get_course_completion_status | Finalización del curso (requiere criterios configurados) |
gradereport_user_get_grade_items | Ítems de calificación con graderaw/grademax |
core_message_send_instant_messages | Envío de mensajes a usuarios (la acción del agente) |
core_badges_get_user_badges | Insignias otorgadas a un usuario |
mod_assign_get_assignments | Tareas de un curso |
mod_assign_get_submissions | Entregas de las tareas con status y timemodified |
mod_quiz_get_user_quiz_attempts | Intentos de quiz de un usuario |
mod_quiz_get_user_attempts está deprecada en Moodle 5.1 (el selector de
funciones no la sugiere); su reemplazo es mod_quiz_get_user_quiz_attempts.
Token
"Token Componente IA Externo", administrado en
/admin/webservice/tokens.php, asociado al usuario Pruebas IA
(wdulfrey04@gmail.com). El valor del token no se versiona ni se documenta:
se entrega por canal seguro al operador del agente.
Permisos del usuario de servicio
El usuario del token está matriculado como docente en los cursos de prueba. Es requisito para:
core_enrol_get_enrolled_users— exigemoodle/course:viewparticipantsen el contexto del curso.mod_assign_get_assignments/mod_assign_get_submissions— exigenmod/assign:view(ymod/assign:gradepara ver entregas ajenas), que solo se obtienen con un rol dentro del curso.core_message_send_instant_messages— exigemoodle/site:sendmessage(incluida por defecto en el rol Usuario autenticado) y la mensajería del sitio habilitada.
Demo: respuesta que obtiene el agente por trigger
Correspondencia entre los triggers de la matriz del requerimiento y la respuesta JSON que el agente obtiene del servicio. Los JSON marcados como verificado son respuestas reales del ambiente de Pruebas, recortadas a los campos que usa la regla; los marcados como forma documentada muestran la estructura definida por el core para escenarios aún no provocables en Pruebas.
| Evento_Trigger | Función core Moodle | Respuesta JSON (demo) | Regla del agente |
|---|---|---|---|
user_enrolment_created | core_enrol_get_enrolled_users | verificado: [{"id":4,"fullname":"Estudiante (Karina) Pruebas","lastcourseaccess":1781126110,"roles":[{"shortname":"student"}]}] | Diff de matriculados entre corridas; el nuevo recibe la bienvenida |
assessable_submitted | mod_assign_get_submissions (+ mod_assign_get_assignments) | verificado: {"assignments":[{"assignmentid":26,"submissions":[{"userid":4,"status":"new","timemodified":1779306200}]}]} | Entregas con status nuevo desde la última corrida (ver límite sobre "new" abajo) |
course_completed | core_completion_get_course_completion_status | forma documentada: {"completionstatus":{"completed":true,"completions":[{"complete":true,"timecompleted":...}]}} | completed == true dispara la sugerencia de ruta |
status_change_inactive | core_user_get_users_by_field | verificado: [{"id":4,"fullname":"Estudiante (Karina) Pruebas","lastaccess":1781126110}] | ahora − lastaccess > 5 días notifica al tutor |
grade_updated_low | gradereport_user_get_grade_items | verificado: {"usergrades":[{"gradeitems":[{"itemname":"INTRODUCCIÓN","graderaw":null,"grademax":100}]}]} | graderaw / grademax < 0.60 dispara el refuerzo |
slow_progress_early | core_enrol_get_users_courses | verificado: [{"id":3,"progress":6.82,"startdate":1652763600,"lastaccess":1781126110}] | progress < 20 y ahora − startdate > 7 días |
milestone_reached | core_completion_get_activities_completion_status (+ core_course_get_contents) | verificado: {"statuses":[{"cmid":45,"state":1,"timecompleted":1780667948},{"cmid":52,"modname":"assign","state":0}]} | Todas las actividades del módulo con state = 1; el badge lo otorga Moodle por criterios nativos |
external_search_fail | core_message_send_instant_messages (es la acción; el trigger nace en el propio agente) | forma documentada: [{"msgid":57,"useridto":4,"text":"...foro de dudas...","errormessage":null}] | Búsqueda sin resultados en el agente sugiere el foro |
dropout_risk_high | compuesto: core_enrol_get_users_courses + gradereport_user_get_grade_items + core_user_get_users_by_field | lo construye el agente: {"alumnos_en_riesgo":[{"userid":4,"progress":6.82,"dias_inactivo":1,"nivel_riesgo":"alto"}]} | Heurística sobre inactividad + progreso + notas; reporte al docente |
content_gap | mod_quiz_get_user_quiz_attempts (+ mod_quiz_get_attempt_review) | verificado (sin intentos): {"attempts":[],"warnings":[]} | Requiere desarrollo custom: las estadísticas por pregunta no se exponen por WS nativo |
| Estadísticas para el chatbot del admin | función externa custom del plugin (ADR-001) | propuesto: {"resumen":{"cursos":2,"estudiantes_activos":1,"en_riesgo":1}} | Requiere la capa de datos custom del Alcance 3 |
Prerrequisitos y límites detectados
- Entregas en
status: "new": cuando una tarea no exige presionar "Enviar tarea", la entrega del estudiante queda enstatus: "new"en vez de"submitted". La regla deassessable_submitteddebe definir con el cliente sinew+timemodifiedreciente cuenta como entrega. course_completedrequiere criterios: si el curso no tiene criterios de finalización configurados,core_completion_get_course_completion_statusresponde el errornocriteriaset. Configurar los criterios del curso es prerrequisito de ese trigger.- Sin WS nativo para estadísticas agregadas:
content_gap(fallos por pregunta de quiz) y las estadísticas del chatbot del admin no tienen función nativa; los cubre la capa custom de funciones externas del Alcance 3 (ADR-001).
Drawer IA
La interfaz conversacional del agente se denomina Drawer IA y
corresponde al elemento Aside - NavigationDrawer (AI Assistant Chat Panel)
del diseño en Figma.
El chat embebido con @n8n/chat es una
exploración previa de esa experiencia.
Relacionados
- ADR-001: Capa Web Services — la capa custom que complementa este servicio (push event-driven y datos agregados).
- Agente IA (índice del alcance)
- Chat embebido (prueba de concepto)