{
  "name": "Síntesis de reuniones con tareas (plano de Saphia Labs)",
  "nodes": [
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "id",
          "value": "TU_CARPETA_ID"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "trig",
      "name": "Google Drive Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        }
      },
      "id": "dl",
      "name": "Drive: descargar",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        260,
        0
      ]
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "ex",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        520,
        0
      ]
    },
    {
      "parameters": {
        "resource": "text",
        "operation": "message",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-5-5"
        },
        "messages": {
          "values": [
            {
              "role": "user",
              "content": "={{ 'Archivo: ' + ($('Google Drive Trigger').first().json.name || '') + '\\n\\nTRANSCRIPCIÓN\\n' + $json.data }}"
            }
          ]
        },
        "options": {
          "system": "Eres quien levanta las actas en [organización]. Recibes la transcripción de una reunión. Devuelve SOLO un JSON con esta forma:\n{\"resumen\": \"3 frases: qué se discutió y por qué importa\", \"decisiones\": [\"...\"], \"tareas\": [{\"tarea\": \"...\", \"responsable\": \"nombre o [por definir]\", \"fecha\": \"AAAA-MM-DD o [por definir]\"}], \"pendientes\": [\"temas que quedaron abiertos\"]}\nReglas: solo decisiones y tareas dichas explícitamente, no inferidas; usa los nombres tal como aparecen en la transcripción; si no hay fecha, no la inventes; nada fuera del JSON.",
          "maxTokens": 4000
        }
      },
      "id": "cl",
      "name": "Claude: acta",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "typeVersion": 1,
      "position": [
        780,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const texto = ($json.content || []).filter(b => b.type === 'text').map(b => b.text).join('\\n').trim();\nconst limpio = texto.replace(/^```(?:json)?\\s*/i, '').replace(/```\\s*$/, '');\nlet r; try { r = JSON.parse(limpio); } catch (e) { r = { resumen: 'No se pudo interpretar la respuesta del modelo', decisiones: [], tareas: [], pendientes: [], error: texto.slice(0, 300) }; }\nconst archivo = $('Google Drive Trigger').first().json.name || '';\nconst fecha = $now.toFormat('yyyy-LL-dd HH:mm');\nconst tareas = (r.tareas || []).map(t => ({ tarea: t.tarea || '', responsable: t.responsable || '[por definir]', fecha: t.fecha || '[por definir]' }));\nconst actaTexto = ['ACTA · ' + archivo, '', 'RESUMEN', r.resumen || '', '', 'DECISIONES', ...(r.decisiones || []).map(d => '- ' + d), '', 'TAREAS', ...tareas.map(t => '- ' + t.tarea + ' — ' + t.responsable + ' — ' + t.fecha), '', 'PENDIENTES', ...(r.pendientes || []).map(p => '- ' + p)].join('\\n');\nreturn [{ json: { fecha, archivo, resumen: r.resumen || '', decisiones: (r.decisiones || []).join(' | '), pendientes: (r.pendientes || []).join(' | '), tareas, actaTexto, error: r.error || '' } }];"
      },
      "id": "pa",
      "name": "Code: armar acta",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const a = $('Code: armar acta').first().json;\nreturn a.tareas.map(t => ({ json: { reunion: a.archivo, fecha_reunion: a.fecha, ...t } }));"
      },
      "id": "st",
      "name": "Code: una fila por tarea",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        40
      ]
    },
    {
      "parameters": {
        "resource": "draft",
        "subject": "=Acta: {{ $json.archivo }}",
        "emailType": "text",
        "message": "={{ $json.actaTexto }}",
        "options": {
          "sendTo": "TU_CORREO"
        }
      },
      "id": "dr",
      "name": "Gmail: borrador del acta",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1300,
        200
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.notion.com/v1/pages",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "notionApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ parent: { database_id: 'TU_BASE_ACTAS_ID' }, properties: { 'Reunión': { title: [{ type: 'text', text: { content: $json.archivo || 'Reunión' } }] }, 'Fecha': { date: { start: $now.toISODate() } }, 'Archivo': { rich_text: [{ type: 'text', text: { content: String($json.archivo).slice(0, 1900) } }] }, 'Resumen': { rich_text: [{ type: 'text', text: { content: String($json.resumen).slice(0, 1900) } }] }, 'Decisiones': { rich_text: [{ type: 'text', text: { content: String($json.decisiones).slice(0, 1900) } }] }, 'Pendientes': { rich_text: [{ type: 'text', text: { content: String($json.pendientes).slice(0, 1900) } }] } }, children: $json.actaTexto.split('\\n').filter(l => l.trim()).slice(0, 90).map(l => ({ object: 'block', type: l === l.toUpperCase() && l.length < 40 ? 'heading_3' : 'paragraph', [l === l.toUpperCase() && l.length < 40 ? 'heading_3' : 'paragraph']: { rich_text: [{ type: 'text', text: { content: l.slice(0, 1900) } }] } })) }) }}",
        "options": {}
      },
      "id": "na",
      "name": "Notion: crear acta",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        -120
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.notion.com/v1/pages",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "notionApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify(Object.assign({ parent: { database_id: 'TU_BASE_TAREAS_ID' }, properties: Object.assign({ 'Tarea': { title: [{ type: 'text', text: { content: $json.tarea || 'Tarea' } }] }, 'Responsable': { rich_text: [{ type: 'text', text: { content: String($json.responsable).slice(0, 1900) } }] }, 'Reunión': { rich_text: [{ type: 'text', text: { content: String($json.reunion).slice(0, 1900) } }] }, 'Estado': { select: { name: 'Pendiente' } } }, /^\\d{4}-\\d{2}-\\d{2}$/.test($json.fecha) ? { 'Fecha límite': { date: { start: $json.fecha } } } : {}) })) }}",
        "options": {}
      },
      "id": "nt",
      "name": "Notion: crear tarea",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1560,
        40
      ]
    }
  ],
  "connections": {
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Drive: descargar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive: descargar": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Claude: acta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude: acta": {
      "main": [
        [
          {
            "node": "Code: armar acta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: armar acta": {
      "main": [
        [
          {
            "node": "Notion: crear acta",
            "type": "main",
            "index": 0
          },
          {
            "node": "Code: una fila por tarea",
            "type": "main",
            "index": 0
          },
          {
            "node": "Gmail: borrador del acta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: una fila por tarea": {
      "main": [
        [
          {
            "node": "Notion: crear tarea",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "America/Bogota"
  },
  "meta": {
    "templateCredsSetupCompleted": false,
    "probadoEn": "n8n 2.41.6, octubre 2026",
    "fuente": "https://saphialabs.com/recursos/flujos/#f2",
    "preparacion": "Crea una carpeta en Drive para las transcripciones y, en Notion, dos bases compartidas con tu integración: \"Actas\" (Reunión título, Fecha date, Archivo, Resumen, Decisiones, Pendientes rich_text) y \"Tareas\" (Tarea título, Responsable rich_text, Fecha límite date, Reunión rich_text, Estado select con Pendiente/Hecha). Reemplaza TU_CARPETA_ID, TU_BASE_ACTAS_ID, TU_BASE_TAREAS_ID y TU_CORREO. Para .docx, conviértelo a Google Docs o .txt."
  }
}