Migración automatizada de contenido de documentos de ClickUp a registros de Airtable

Avanzado

Este es unContent Creation, Multimodal AIflujo de automatización del dominio deautomatización que contiene 16 nodos.Utiliza principalmente nodos como Code, ClickUp, Airtable, HttpRequest, ClickUpTrigger. Migración automatizada de contenido de documentos ClickUp a registros de Airtable

Requisitos previos
  • Clave de API de Airtable
  • Pueden requerirse credenciales de autenticación para la API de destino
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "meta": {
    "instanceId": "43bcb00c7c923df4e36c0bf713549f86f2dbcd6776a5aa1796b3cf9b1cdd7b7e"
  },
  "nodes": [
    {
      "id": "54d8ddeb-a96a-45d9-82f6-092f4fe2b738",
      "name": "Iterar sobre Páginas",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -368,
        224
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "cacb5309-604f-43d1-b173-d99268f2571d",
      "name": "Obtener Todas las Bases",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -144,
        144
      ],
      "parameters": {
        "options": {},
        "resource": "base"
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "g8X0PZu8dIVZ4LyX",
          "name": "Airtable Personal Access Token account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0372b7b0-5c72-437d-afcb-669b2b28bd26",
      "name": "Activar en Nueva Tarea de ClickUp",
      "type": "n8n-nodes-base.clickUpTrigger",
      "position": [
        -1712,
        224
      ],
      "webhookId": "ffa9e6e1-45a2-4be0-93c8-1435de0bd7cf",
      "parameters": {
        "team": "9014329600",
        "events": [
          "taskCreated"
        ],
        "filters": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "clickUpOAuth2Api": {
          "id": "cpNaV1HxXYDutqlG",
          "name": "ClickUp account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "db22385e-cd6a-4b74-83d1-7cd81ec46666",
      "name": "Obtener Detalles de Tarea",
      "type": "n8n-nodes-base.clickUp",
      "position": [
        -1456,
        224
      ],
      "parameters": {
        "id": "={{ $json.task_id }}",
        "operation": "get",
        "authentication": "oAuth2"
      },
      "credentials": {
        "clickUpOAuth2Api": {
          "id": "cpNaV1HxXYDutqlG",
          "name": "ClickUp account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2794d633-ffd8-4821-abca-0b82858a0852",
      "name": "Extraer IDs de Documento y Espacio de Trabajo desde URL",
      "type": "n8n-nodes-base.code",
      "position": [
        -1248,
        224
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n  const url = item.json.name;\n\n  const regex = /clickup\\.com\\/(\\d+)\\/v\\/dc\\/([^/]+)/;\n  const match = url.match(regex);\n\n  if (match) {\n    results.push({\n      json: {\n        clickupUrl: url,\n        workspaceId: match[1],\n        docId: match[2],\n      }\n    });\n  }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "323e614d-7ad9-4265-8981-0cd444a42a67",
      "name": "Obtener Detalles de Documento de ClickUp",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1024,
        224
      ],
      "parameters": {
        "url": "=https://api.clickup.com/api/v3/workspaces/{{$json.workspaceId}}/docs/{{$json.docId}}",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "max_page_depth",
              "value": "-2"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "clickUpApi"
      },
      "credentials": {
        "clickUpOAuth2Api": {
          "id": "cpNaV1HxXYDutqlG",
          "name": "ClickUp account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b80b1a8d-c8dd-4f62-8475-850408a43abb",
      "name": "Obtener Todas las Páginas en Documento",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -800,
        224
      ],
      "parameters": {
        "url": "=https://api.clickup.com/api/v3/workspaces/{{$json.workspace_id}}/docs/{{$json.id}}/pages",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "max_page_depth",
              "value": "-2"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "clickUpOAuth2Api"
      },
      "credentials": {
        "clickUpOAuth2Api": {
          "id": "cpNaV1HxXYDutqlG",
          "name": "ClickUp account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ae7a5381-c1de-4417-9472-fc7478b1bdab",
      "name": "Extraer Contenido de Páginas del Documento",
      "type": "n8n-nodes-base.code",
      "position": [
        -576,
        224
      ],
      "parameters": {
        "jsCode": "const output = [];\n\nfor (const item of $input.all()) {\n  const pages = item.json.pages || [];\n  const tableName = item.json.name;\n  const baseName = $('Get ClickUp Doc Details').first().json.name;\n\n  for (const page of pages) {\n    const rawContent = page.content || \"\";\n    const content = rawContent.trim();\n\n    if (content.includes(\"* * *\")) {\n      const splitContents = content.split(\"* * *\");\n\n      for (const part of splitContents) {\n        const trimmed = part.trim();\n        if (!trimmed) continue;\n\n        let contentText = trimmed;\n        let notesText = \"\";\n\n        if (trimmed.toLowerCase().includes(\"notes:\")) {\n          const [main, ...notesParts] = trimmed.split(/notes:/i);\n          contentText = main.trim();\n          notesText = notesParts.join(\"notes:\").trim();\n        }\n\n        // Remove all '*' and re-trim\n        contentText = contentText.replace(/\\*/g, '').trim();\n\n        output.push({\n          json: {\n            base: baseName,\n            table: tableName,\n            name: page.name,\n            content: contentText,\n            notes: notesText\n          }\n        });\n      }\n    } else {\n      let contentText = content;\n      let notesText = \"\";\n\n      if (content.toLowerCase().includes(\"notes:\")) {\n        const [main, ...notesParts] = content.split(/notes:/i);\n        contentText = main.trim();\n        notesText = notesParts.join(\"notes:\").trim();\n      }\n\n      // Remove all '*' and re-trim\n      contentText = contentText.replace(/\\*/g, '').trim();\n\n      output.push({\n        json: {\n          base: baseName,\n          table: tableName,\n          name: page.name,\n          content: contentText,\n          notes: notesText\n        }\n      });\n    }\n  }\n}\n\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9c8d6ff9-3f60-4576-886a-6ac21a38e247",
      "name": "Coincidir Base Airtable por Nombre",
      "type": "n8n-nodes-base.code",
      "position": [
        80,
        144
      ],
      "parameters": {
        "jsCode": "const baseRaw = $('Loop Over Pages').first().json.base.trim().toLowerCase();\nconst base = baseRaw.endsWith(' (new)')\n  ? baseRaw.slice(0, -6)\n  : baseRaw;\n\n\n\nconst output = [];\n\nfor (const item of $input.all()) {\nlet itemNameRaw = item.json.name?.trim().toLowerCase();\nconst itemName = itemNameRaw?.endsWith(' (new)')\n  ? itemNameRaw.slice(0, -6)\n  : itemNameRaw;\n  if (base === itemName) {\n    output.push(item);\n  }\n}\n\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "48f0e7b2-eb72-424f-9525-49777ca4dbdf",
      "name": "Obtener Todas las Tablas en Base Seleccionada",
      "type": "n8n-nodes-base.airtable",
      "position": [
        304,
        144
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "resource": "base",
        "operation": "getSchema"
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "g8X0PZu8dIVZ4LyX",
          "name": "Airtable Personal Access Token account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "fdc103b4-55a5-401d-93d9-31a586527e9c",
      "name": "Coincidir Tabla Airtable por Nombre",
      "type": "n8n-nodes-base.code",
      "position": [
        528,
        144
      ],
      "parameters": {
        "jsCode": "const table = $('Loop Over Pages').first().json.table.trim().toLowerCase();\n\nconst output = [];\n\nfor (const item of $input.all()) {\n  const itemName = item.json.name?.trim().toLowerCase();\n\n if (table === itemName) {\n    output.push(item);\n  }\n }\n\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b55b9fb5-3457-4eb0-8d8c-8ec5c0ef68cf",
      "name": "Encontrar Registro de 'Vertical' Correspondiente",
      "type": "n8n-nodes-base.airtable",
      "position": [
        752,
        144
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Match Airtable Base by Name').item.json.id }}"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Get All Tables in Selected Base').first().json.id }}"
        },
        "options": {
          "fields": [
            "Name"
          ]
        },
        "operation": "search",
        "filterByFormula": "={Name} = '{{ $('Loop Over Pages').item.json.name }}'"
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "g8X0PZu8dIVZ4LyX",
          "name": "Airtable Personal Access Token account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "74d12946-602f-4064-927f-e3be32329a3a",
      "name": "Crear Nuevo Registro en Airtable",
      "type": "n8n-nodes-base.airtable",
      "position": [
        960,
        224
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Match Airtable Base by Name').item.json.id }}"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Match Airtable Table by Name').item.json.id }}"
        },
        "columns": {
          "value": {
            "Text": "={{ $('Loop Over Pages').item.json.content }}",
            "Notes": "={{ $('Loop Over Pages').item.json.notes }}",
            "Status": "Testing",
            "Vertical": "={{ $json.Name }}",
            "Created Date": "={{ $now }}"
          },
          "schema": [
            {
              "id": "Text",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vertical",
              "type": "array",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Vertical",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Testing",
                  "value": "Testing"
                },
                {
                  "name": "Winner",
                  "value": "Winner"
                },
                {
                  "name": "Non-Compliant (Buyer)",
                  "value": "Non-Compliant (Buyer)"
                },
                {
                  "name": "Rejected (FB)",
                  "value": "Rejected (FB)"
                },
                {
                  "name": "Account Mover",
                  "value": "Account Mover"
                },
                {
                  "name": "Loser",
                  "value": "Loser"
                },
                {
                  "name": "Rejected (Appealed)",
                  "value": "Rejected (Appealed)"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created Date",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Created Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "typecast": true
        },
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "g8X0PZu8dIVZ4LyX",
          "name": "Airtable Personal Access Token account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "a65db100-fb6b-46c0-b69f-8b005428e1c6",
      "name": "Nota Adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2544,
        -1184
      ],
      "parameters": {
        "width": 688,
        "height": 1264,
        "content": "## Create Airtable records from new ClickUp Doc pages\n\nThis workflow automates the process of turning content from ClickUp Docs into structured data in Airtable. When a new task is created in ClickUp with a link to a ClickUp Doc in its name, this workflow triggers, fetches the entire content of that Doc, parses it into individual records, and then creates a new record for each item in a specified Airtable base and table.\n\n## Who's it for\n\nThis template is perfect for content creators, project managers, and operations teams who use ClickUp Docs for drafting or knowledge management and Airtable for tracking and organizing data. It helps bridge the gap between unstructured text and a structured database.\n\n## How it works\n\n1.  **Trigger:** The workflow starts when a new task is created in a specific ClickUp Team.\n2.  **Fetch & Parse URL:** It gets the new task's details and extracts the ClickUp Doc URL from the task name.\n3.  **Get Doc Content:** It uses the URL to fetch the main Doc and all its sub-pages from the ClickUp API.\n4.  **Process Content:** A Code node parses the text from each page. It's designed to split content by `* * *` and separate notes by looking for the \"notes:\" keyword.\n5.  **Find Airtable Destination:** The workflow finds the correct Airtable Base and Table IDs by matching the names you provide.\n6.  **Create Records:** It loops through each parsed content piece and creates a new record in your specified Airtable table.\n\n## How to set up\n\n1.  **Configure the `Set` Node:** Open the \"Configure Variables\" node and set the following values:\n    * `clickupTeamId`: Your ClickUp Team ID. Find it in your ClickUp URL (e.g., `app.clickup.com/9014329600/...`).\n    * `airtableBaseName`: The exact name of your target Airtable Base.\n    * `airtableTableName`: The exact name of your target Airtable Table.\n    * `airtableVerticalsTableName`: The name of the table in your base that holds \"Vertical\" records, which are linked in the main table.\n2.  **Set Up Credentials:** Add your ClickUp (OAuth2) and Airtable (Personal Access Token) credentials to the respective nodes.\n3.  **Airtable Fields:** Ensure your Airtable table has fields corresponding to the ones in the `Create New Record in Airtable` node (e.g., `Text`, `Status`, `Vertical`, `Notes`). You can customize the mapping in this node.\n4.  **Activate Workflow:** Save and activate the workflow.\n5.  **Test:** Create a new task in your designated ClickUp team. In the task name, include the full URL of the ClickUp Doc you want to process.\n\n## How to customize the workflow\n\n* **Parsing Logic:** You can change how the content is parsed by modifying the JavaScript in the `Parse Content from Doc Pages` Code node. For example, you could change the delimiter from `* * *` to something else.\n* **Field Mapping:** Adjust the `Create New Record in Airtable` node to map data to different fields or add more fields from the source data.\n* **Trigger Events:** Modify the `Trigger on New ClickUp Task` node to respond to different events, such as `taskUpdated` or `taskCommentPosted`."
      },
      "typeVersion": 1
    },
    {
      "id": "d1610a6f-0ed6-4060-a25a-35562abb42ab",
      "name": "Nota Adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1760,
        128
      ],
      "parameters": {
        "color": 4,
        "width": 1328,
        "height": 256,
        "content": "## Fetch Clickup Task, Doc, and Page Content\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f8ef9da3-4581-4974-9c5d-3fb55cb4cf8c",
      "name": "Nota Adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        80
      ],
      "parameters": {
        "color": 4,
        "width": 1360,
        "height": 352,
        "content": "## Move Everything to Airtable\n"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "cacb5309-604f-43d1-b173-d99268f2571d": {
      "main": [
        [
          {
            "node": "9c8d6ff9-3f60-4576-886a-6ac21a38e247",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "54d8ddeb-a96a-45d9-82f6-092f4fe2b738": {
      "main": [
        [],
        [
          {
            "node": "cacb5309-604f-43d1-b173-d99268f2571d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "db22385e-cd6a-4b74-83d1-7cd81ec46666": {
      "main": [
        [
          {
            "node": "2794d633-ffd8-4821-abca-0b82858a0852",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b80b1a8d-c8dd-4f62-8475-850408a43abb": {
      "main": [
        [
          {
            "node": "ae7a5381-c1de-4417-9472-fc7478b1bdab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "323e614d-7ad9-4265-8981-0cd444a42a67": {
      "main": [
        [
          {
            "node": "b80b1a8d-c8dd-4f62-8475-850408a43abb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9c8d6ff9-3f60-4576-886a-6ac21a38e247": {
      "main": [
        [
          {
            "node": "48f0e7b2-eb72-424f-9525-49777ca4dbdf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0372b7b0-5c72-437d-afcb-669b2b28bd26": {
      "main": [
        [
          {
            "node": "db22385e-cd6a-4b74-83d1-7cd81ec46666",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fdc103b4-55a5-401d-93d9-31a586527e9c": {
      "main": [
        [
          {
            "node": "b55b9fb5-3457-4eb0-8d8c-8ec5c0ef68cf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ae7a5381-c1de-4417-9472-fc7478b1bdab": {
      "main": [
        [
          {
            "node": "54d8ddeb-a96a-45d9-82f6-092f4fe2b738",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "74d12946-602f-4064-927f-e3be32329a3a": {
      "main": [
        [
          {
            "node": "54d8ddeb-a96a-45d9-82f6-092f4fe2b738",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "48f0e7b2-eb72-424f-9525-49777ca4dbdf": {
      "main": [
        [
          {
            "node": "fdc103b4-55a5-401d-93d9-31a586527e9c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2794d633-ffd8-4821-abca-0b82858a0852": {
      "main": [
        [
          {
            "node": "323e614d-7ad9-4265-8981-0cd444a42a67",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b55b9fb5-3457-4eb0-8d8c-8ec5c0ef68cf": {
      "main": [
        [
          {
            "node": "74d12946-602f-4064-927f-e3be32329a3a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Avanzado - Creación de contenido, IA Multimodal

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos16
Categoría2
Tipos de nodos7
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor
Fahmi Fahreza

Fahmi Fahreza

@fahmiiireza

Backend Developer turns to AI Automation Developer

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34