Saltar al contenido principal

Exemplo: consulta e correción de tarefas de Moodle

Neste exemplo imos crear un fluxo de traballo que obtén as tarefas dun curso de Moodle e as cualifica a través da súa API REST.

Respecta os nomes dos nodos

Os fragmentos de código deste exemplo fan referencia a nodos concretos mediante o seu nome, por exemplo $('Obter tarefas'). Para que funcionen, cambia o nome dos nodos exactamente a estes valores:

  • Obter tarefas
  • Obter id de tarefas
  • Obter enlaces a ficheiros entregados

Os nomes deben coincidir exactamente, incluídos os espazos e as maiúsculas. Se utilizas outros nomes, terás que modificar tamén as expresións e o código que fai referencia a eles.

Que necesitamos​

  • Acceso ao aula virtual de Moodle.
  • Un token de API de Moodle (podes xeralo en: Moodle → Preferencias → Seguridade → Claves e tokens de servizo web).
  • O ID do curso que queres consultar (aparece na URL do curso en Moodle).

Crear o fluxo en n8n​

Paso 1: HTTP Request - Obter as tarefas do curso​

Este nodo consultará a API de Moodle para obter as tarefas do curso.

  1. Crea un novo workflow en n8n.
  2. Preme en + e busca HTTP Request.
  3. Configúrao así:
    • Method: POST
    • URL: https://o-teu-moodle.edu/webservice/rest/server.php
  4. En Query Parameters, engade os seguintes parámetros:
NomeValor
wsfunctionmod_assign_get_assignments
wstokeno teu token de API
courseids[0]123 (substitúe polo ID do teu curso)
moodlewsrestformatjson

Paso 2: Code - Obter os IDs das tarefas​

Este nodo extrae os identificadores de cada tarefa do curso.

  1. Preme no + á dereita do nodo HTTP Request.
  2. Busca Code e selecciónao.
  3. En Mode, selecciona Run Once for All Items.
  4. En Language, selecciona JavaScript.
  5. Pega o seguinte código:
let assignments = $input.first().json.courses[0].assignments

return assignments.map((a) => ({
json: {
assignment_id: a.id,
cmid: a.cmid,
name: a.name,
},
}))

Este código extrae de cada tarefa o seu id, o cmid (ID do módulo do curso) e o name (nome da tarefa).

Paso 3: HTTP Request - Obter as entregas​

Este nodo obtén as entregas de cada tarefa.

  1. Preme no + á dereita do nodo Code.
  2. Busca HTTP Request e selecciónao.
  3. Configúrao así:
    • Method: POST
    • URL: https://o-teu-moodle.edu/webservice/rest/server.php
  4. En Body Parameters, engade os seguintes parámetros:
NomeValor
wsfunctionmod_assign_get_submissions
wstokeno teu token de API
assignmentids[0]{{ $json.assignment_id }}
moodlewsrestformatjson

Paso 4: Code - Obter enlaces a ficheiros entregados​

Este nodo extrae os enlaces aos ficheiros entregados por cada alumno.

  1. Preme no + á dereita do nodo HTTP Request.
  2. Busca Code e selecciónao.
  3. En Mode, selecciona Run Once for All Items.
  4. En Language, selecciona JavaScript.
  5. Pega o seguinte código:
let submissions = $input.first().json.assignments[0].submissions
let entregas = []

submissions.forEach((submission) => {
if (submission.status !== 'submitted') return

let filePlugin = submission.plugins.find((p) => p.type === 'file')
if (!filePlugin) return

let files = filePlugin.fileareas[0]?.files
if (!files || files.length === 0) return

entregas.push({
json: {
userid: submission.userid,
filename: files[0].filename,
fileurl: files[0].fileurl,
},
})
})

return entregas

Este código filtra só as entregas con estado submitted, busca o plugin de ficheiros e devolve o userid, o nome do ficheiro e a URL de descarga para cada entrega.

Paso 5: Google Gemini - Corrixir a tarefa​

Este nodo envía o ficheiro entregado a Gemini para que o corrixa automaticamente.

  1. Preme no + á dereita do nodo Code.
  2. Busca Google Gemini e selecciónao.
  3. Configura as credenciais con a túa API key de Gemini.
  4. Configura o nodo:
    • Resource: Document
    • Operation: Analyze Document
    • Model: gemini-2.5-flash
    • Text Input (usa Expression mode):
Actúas como profesor de Bases de Datos de FP. Corrixe esta tarefa:
{{ $('Obter tarefas').item.json.courses[0].assignments[0].intro }}
Responde ÚNICAMENTE con un JSON válido sen texto adicional nin backticks con esta estrutura exacta:
{"nota": 5, "comentario": "Comentario breve de 2-3 liñas para o alumno en galego"}
  • Input Type: Document URL
  • URL (usa Expression mode):
{{ $json.fileurl + '?token=eltoken' }}
Token na URL do ficheiro

A API de Moodle require autenticación para acceder aos ficheiros. É imprescindible engadir ?token=eltoken á URL, substituíndo eltoken polo teu token de API. Sen este parámetro, Gemini non poderá abrir o documento.

Modelo alternativo

O modelo gemini-2.5-flash pode estar limitado ou non dispoñible segundo o teu plan. Nese caso, proba con outro modelo como gemini-2.0-flash-lite.

Paso 6: Code - Limpar a saída de Gemini​

Gemini pode devolver o JSON envolto en backticks ou con texto adicional. Este nodo limpa a resposta e extrae a nota e o comentario.

  1. Preme no + á dereita do nodo Google Gemini.
  2. Busca Code e selecciónao.
  3. En Mode, selecciona Run Once for All Items.
  4. En Language, selecciona JavaScript.
  5. Pega o seguinte código:
const items = $input.all()
const enlaces = $('Obter enlaces a ficheiros entregados').all()

return items.map((item, index) => {
const texto_raw = item.json.content.parts[0].text
const texto = texto_raw.replace(/`{3}json|`{3}/g, '').trim()
const resultado = JSON.parse(texto)

return {
json: {
userid: enlaces[index].json.userid,
nota: parseFloat(resultado.nota),
comentario: resultado.comentario,
},
}
})

Este código elimina posibles backticks da resposta de Gemini, parsea o JSON e combina o resultado coa referencia ao userid de cada entrega.

Paso 7: Code - Construír a petición de cualificación​

Este nodo prepara o corpo da petición para enviar as notas e comentarios á API de Moodle.

  1. Preme no + á dereita do nodo Code.
  2. Busca Code e selecciónao.
  3. En Mode, selecciona Run Once for All Items.
  4. En Language, selecciona JavaScript.
  5. Pega o seguinte código:
const items = $input.all()
const grades = {}

items.forEach((item, index) => {
grades[`grades[${index}][userid]`] = item.json.userid
grades[`grades[${index}][grade]`] = parseFloat(item.json.nota)
grades[`grades[${index}][attemptnumber]`] = -1
grades[`grades[${index}][addattempt]`] = 0
grades[`grades[${index}][workflowstate]`] = ''
grades[`grades[${index}][plugindata][assignfeedbackcomments_editor][text]`] = item.json.comentario
grades[`grades[${index}][plugindata][assignfeedbackcomments_editor][format]`] = 1
grades[`grades[${index}][plugindata][files_filemanager]`] = 0
})

grades['applytoall'] = 0

const body = Object.entries(grades)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')

return [{ json: { body } }]

Este código constrúe un corpo de petición en formato application/x-www-form-urlencoded con todas as notas e comentarios de feedback para cada alumno, listo para enviarse á API de Moodle.

Paso 8: HTTP Request - Cualificar​

Este nodo envía as notas e comentarios á API de Moodle.

  1. Preme no + á dereita do nodo Code.
  2. Busca HTTP Request e selecciónao.
  3. Configúrao así:
    • Method: POST
    • URL: https://o-teu-moodle.edu/webservice/rest/server.php
  4. En Query Parameters, engade os seguintes parámetros:
NomeValor
wsfunctionmod_assign_save_grades
wstokeno teu token de API
assignmentid{{ $('Obter id de tarefas').item.json.assignment_id }}
moodlewsrestformatjson
  1. En Body, selecciona Raw e pon o tipo de contido application/x-www-form-urlencoded. No campo de contido usa Expression mode:
{{ $json.body }}

Isto envía o corpo construído no paso anterior coas notas e comentarios de todos os alumnos.

Resultado​

O fluxo completo queda así:

Fluxo n8n para corrección de tarefas de Moodle