Automatización de formulario a blog usando Dumpling AI y Google Docs

Avanzado

Este es unContent Creation, Multimodal AIflujo de automatización del dominio deautomatización que contiene 17 nodos.Utiliza principalmente nodos como Code, Wait, Limit, SplitOut, Aggregate. Usar Dumpling AI, OpenAI y Google Docs para automatizar la creación de contenido para blog a partir de palabras clave

Requisitos previos
  • Pueden requerirse credenciales de autenticación para la API de destino
  • Clave de API de OpenAI
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
{
  "id": "hCUgw7o0NPlNWR0K",
  "meta": {
    "instanceId": "a1ae5c8dc6c65e674f9c3947d083abcc749ef2546dff9f4ff01de4d6a36ebfe6",
    "templateCredsSetupCompleted": true
  },
  "name": "Form to Blog Automation using Dumpling AI and Google Docs",
  "tags": [],
  "nodes": [
    {
      "id": "5e40b2b3-8d03-46b0-b1da-a1111997da55",
      "name": "Envío de Formulario (Palabras Clave)",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -416,
        32
      ],
      "webhookId": "1efeb31a-b7f2-4750-8c8a-5aabbdafd57d",
      "parameters": {
        "options": {},
        "formTitle": "Blog form",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Keywords"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4e2c4c76-6d22-4a6b-abd1-8771b2ff21f7",
      "name": "Autocompletado de Dumpling AI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -192,
        32
      ],
      "parameters": {
        "url": "https://app.dumplingai.com/api/v1/get-autocomplete",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $json.Keywords }}"
            },
            {
              "name": "country",
              "value": "US"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "RLFzAcGRepr5eXZB",
          "name": "Dumpling AI-n8n"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "99e4b141-da82-4131-a38e-d65e14307049",
      "name": "Dividir Sugerencias de Autocompletado",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        32,
        32
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "suggestions"
      },
      "typeVersion": 1
    },
    {
      "id": "cc647e9e-fb05-4ea0-ac9c-c5c619ff0d7c",
      "name": "Bucle de Sugerencias",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        256,
        32
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "dd3edb69-ea7c-4d45-9fec-28400e9c16d7",
      "name": "Retraso entre Solicitudes",
      "type": "n8n-nodes-base.wait",
      "position": [
        464,
        32
      ],
      "webhookId": "7ec6dbb9-5d73-43f1-aec9-ba1d6d6c7890",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "2e768d0f-a2fa-4236-a25f-1ed2ae36a9f1",
      "name": "Noticias Google de Dumpling AI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        672,
        32
      ],
      "parameters": {
        "url": " https://app.dumplingai.com/api/v1/search-news",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $json.value }}"
            },
            {
              "name": "country",
              "value": "US"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "RLFzAcGRepr5eXZB",
          "name": "Dumpling AI-n8n"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4cc5e45e-3fd1-444b-b872-83ca62196b41",
      "name": "Dividir Artículos de Noticias",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        864,
        32
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "news"
      },
      "typeVersion": 1
    },
    {
      "id": "3f03dc09-2cbc-4c6a-a798-1a61b81a8073",
      "name": "Filtrar Artículos (1-2 Días de Antigüedad)",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        32
      ],
      "parameters": {
        "jsCode": "// Works in n8n Code node\n// Filters only articles that are between 1 and 2 days old\n\nfunction parseRelative(relative, baseNow) {\n  if (typeof relative !== 'string') return null;\n  const s = relative.trim().toLowerCase();\n\n  // quick rejects\n  if (s.includes('yesterday')) {\n    // treat \"yesterday\" as exactly 1 day ago\n    return new Date(baseNow.getTime() - 24 * 3600000);\n  }\n  if (s.includes('week') || s.includes('month') || s.includes('year')) return null;\n\n  // match \"15 hours ago\", \"2 days ago\", etc.\n  const m = s.match(/(\\d+)\\s*(second|seconds|sec|secs|minute|min|minutes|mins|hour|hours|day|days)\\s*ago$/);\n  if (!m) return null;\n\n  const amount = parseInt(m[1], 10);\n  const unit = m[2];\n\n  const msMap = {\n    second: 1000, seconds: 1000, sec: 1000, secs: 1000,\n    minute: 60000, minutes: 60000, min: 60000, mins: 60000,\n    hour: 3600000, hours: 3600000,\n    day: 86400000, days: 86400000,\n  };\n\n  const ms = msMap[unit];\n  if (!ms) return null;\n\n  return new Date(baseNow.getTime() - amount * ms);\n}\n\n// Collect articles from either shape\nlet articles = [];\nif (items.length === 1 && Array.isArray(items[0].json)) {\n  articles = items[0].json;\n} else {\n  articles = items.map(i => i.json);\n}\n\n// Determine \"now\" (or override with present_date if provided)\nlet baseNow = new Date();\nconst present = items?.[0]?.json?.present_date;\nif (typeof present === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(present)) {\n  const [y, m, d] = present.split('-').map(n => parseInt(n, 10));\n  baseNow = new Date(y, m - 1, d, 12, 0, 0, 0);\n}\n\n// Define boundaries\nconst twoDaysAgo = new Date(baseNow.getTime() - 2 * 24 * 3600000);\nconst oneDayAgo = new Date(baseNow.getTime() - 1 * 24 * 3600000);\n\nconst out = [];\nfor (const a of articles) {\n  const rel = a.date || a.published_time || a.publishedAt || a.pubDate || a.time || '';\n  const abs = parseRelative(rel, baseNow);\n  if (!abs) continue;\n\n  // Keep only if between 1 and 2 days ago\n  if (abs >= twoDaysAgo && abs < oneDayAgo) {\n    const url = a.link || a.url || a.uri;\n    if (!url) continue;\n\n    out.push({ json: { URL: String(url), score: 10 } });\n  }\n}\n\nreturn out;\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "a62c05a4-a000-4e0a-af8d-834f0623802c",
      "name": "Limitar Artículos",
      "type": "n8n-nodes-base.limit",
      "position": [
        1328,
        32
      ],
      "parameters": {
        "maxItems": 2
      },
      "typeVersion": 1
    },
    {
      "id": "30ba63a3-5ac6-4a80-ab09-39ead3320774",
      "name": "Extractor de Dumpling AI",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1568,
        32
      ],
      "parameters": {
        "url": "https://app.dumplingai.com/api/v1/scrape",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "url",
              "value": "={{ $json.URL }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "RLFzAcGRepr5eXZB",
          "name": "Dumpling AI-n8n"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f1ad7937-7877-4c35-9840-27b8ac21d447",
      "name": "Limpiar y Preparar Contenido del Artículo",
      "type": "n8n-nodes-base.code",
      "position": [
        1776,
        32
      ],
      "parameters": {
        "jsCode": "// n8n Code node, JavaScript\n\n// If the incoming item is a single item whose .json is an array,\n// make it our working array. Otherwise assume multiple items.\nconst raw = Array.isArray(items[0]?.json) ? items[0].json : items.map(i => i.json);\n\nfunction cleanMarkdown(md) {\n  if (!md || typeof md !== \"string\") return \"\";\n\n  let text = md;\n\n  // Remove markdown images ![alt](url) and bare images ![](url)\n  text = text.replace(/!\\[[^\\]]*?\\]\\([^)]+\\)/g, \"\");\n\n  // Replace markdown links [text](url) with just \"text\"\n  text = text.replace(/\\[([^\\]]+)\\]\\((?:https?:\\/\\/|mailto:)[^)]+\\)/g, \"$1\");\n\n  // Remove bare URLs\n  text = text.replace(/https?:\\/\\/\\S+/g, \"\");\n\n  // Cut everything after non article sections\n  const cutMarkers = [\n    /^##\\s*More videos\\b/mi,\n    /^##\\s*Related Articles\\b/mi,\n    /^##\\s*More Regional News\\b/mi,\n    /^\\s*Share This Article\\b/mi,\n    /^##\\s*About Me\\b/mi,\n  ];\n  for (const rx of cutMarkers) {\n    const idx = text.search(rx);\n    if (idx !== -1) {\n      text = text.slice(0, idx);\n      break;\n    }\n  }\n\n  // Drop common clutter lines\n  const dropStarts = [\n    \"Skip to content\",\n    \"Skip to main content\",\n    \"Share\",\n    \"Watch later\",\n    \"Copy link\",\n    \"Include playlist\",\n    \"More videos\",\n    \"You are signed out\",\n    \"CancelConfirm\",\n    \"Search\",\n    \"Shopping\",\n    \"Info\",\n    \"Tap to unmute\",\n    \"If playback does not begin\",\n    \"Video Player is loading\",\n    \"Play Video\",\n    \"Stream Type\",\n    \"Seek to live\",\n    \"Remaining Time\",\n    \"Playback Rate\",\n    \"Chapters\",\n    \"Captions\",\n    \"Audio Track\",\n    \"Fullscreen\",\n    \"Close Modal Dialog\",\n    \"Topic:\",\n  ];\n  text = text\n    .split(\"\\n\")\n    .filter(line => {\n      const L = line.trim();\n      if (!L) return true;\n      return !dropStarts.some(s => L.startsWith(s));\n    })\n    .join(\"\\n\");\n\n  // Remove heading markers but keep their words\n  text = text.replace(/^#{1,6}\\s*/gm, \"\");\n\n  // Remove blockquote markers\n  text = text.replace(/^\\s*>\\s?/gm, \"\");\n\n  // Remove leftover image captions such as \"(Image by ...)\"\n  text = text.replace(/\\((?:Image by|Photo|GIF|Video)[^)]+\\)\\s*/gi, \"\");\n\n  // Compress extra blank lines\n  text = text.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n  return text;\n}\n\nconst out = raw.map(a => {\n  const title = a.title || \"\";\n  const content = a.content || \"\";\n  return {\n    json: {\n      title,\n      article: cleanMarkdown(content),\n    },\n  };\n});\n\nreturn out;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e122251c-5540-4dd3-be3f-59620c1aacf2",
      "name": "Agregar Artículos",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        496,
        -208
      ],
      "parameters": {
        "include": "specifiedFields",
        "options": {},
        "aggregate": "aggregateAllItemData",
        "fieldsToInclude": "article",
        "destinationFieldName": "article"
      },
      "typeVersion": 1
    },
    {
      "id": "acf43fa6-f8d4-4533-8522-68640916877c",
      "name": "OpenAI: Generar Borrador de Blog",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        752,
        -208
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "=You are a professional content writer. I will provide you with raw scraped content from different articles. Your job is to create a polished, original blog post based on the ideas and insights in that content.\n\nOutput Requirements:\n- Return ONLY valid JSON (no explanations, no markdown formatting outside JSON, no comments).\n- JSON must have exactly these keys:\n  {\n    \"Blog_post\": \"Markdown formatted blog post\",\n    \"title\": \"A clear, engaging blog post title\"\n  }\n\nWriting Instructions:\n1. Write the blog post in engaging, professional, and conversational language.\n2. Use Markdown formatting: \n   - Headings (#, ##, ###) for sections\n   - Bold or italic where necessary\n   - Lists where it improves readability\n3. Do not copy the scraped text directly. Rewrite it in your own words while keeping the meaning.\n4. Exclude clutter such as “related articles,” “share this,” or video references.\n5. Organize with a strong introduction, clear body sections, and a compelling conclusion.\n6. Add smooth transitions between sections so the blog post flows naturally.\n\n"
            },
            {
              "content": "=---\nHere is the scraped content to base the blog post on:\n{{ JSON.stringify($json.article) }}\n---\n"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "openAiApi": {
          "id": "dd8NvMC6rvx8RITo",
          "name": "OpenAi account 2"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "04ee4323-3527-401c-a963-a726c7f1dad6",
      "name": "Documentos Google: Crear Archivo de Blog",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        1104,
        -208
      ],
      "parameters": {
        "title": "={{ $json.message.content.title }}",
        "folderId": "1NU00YbKNiHJptNuQZH6kgVUhLvDzE0ka"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "id": "Ofx9WFXGfyxTK2fk",
          "name": "Google Docs account"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "bacf9175-722d-4f93-a571-4a5e4e555995",
      "name": "Documentos Google: Insertar Contenido del Blog",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        1312,
        -208
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $('OpenAI: Generate Blog Draft').item.json.message.content.Blog_post }}",
              "action": "insert"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $json.id }}"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "id": "Ofx9WFXGfyxTK2fk",
          "name": "Google Docs account"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "cac11f57-cf15-40ec-9c0a-49ad02b48564",
      "name": "Nota Adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -208
      ],
      "parameters": {
        "width": 624,
        "height": 368,
        "content": "## Agent Branch\n\nThis branch starts with a form submission.  \nThe entered keyword is expanded using **Dumpling AI Autocomplete**, then news articles are fetched with **Dumpling AI Google News**.  \n\nThe workflow splits suggestions and articles, filters them to keep only fresh items (1–2 days old), and prepares them for content creation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d382d3f0-74fc-47d3-8b32-8e3c48f5bf40",
      "name": "Nota Adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        -384
      ],
      "parameters": {
        "width": 752,
        "height": 256,
        "content": "## Blog Branch\n\nFrom each filtered article, the workflow scrapes and cleans content with **Dumpling AI Scraper**.  \nThe articles are aggregated and passed to **OpenAI**, which generates a polished blog draft.  \n\nThe final post is saved into **Google Docs**, creating and updating a document with the finished blog content.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {
    "Dumpling AI Autocomplete": [
      {
        "json": {
          "credits": 1,
          "suggestions": [
            {
              "value": "ai agents"
            },
            {
              "value": "ai agents explained"
            },
            {
              "value": "ai agents vs agentic ai"
            },
            {
              "value": "ai agents course"
            },
            {
              "value": "ai agents examples"
            },
            {
              "value": "ai agents startup science machine"
            },
            {
              "value": "ai agents reddit"
            },
            {
              "value": "ai agents directory"
            },
            {
              "value": "ai agents tools"
            },
            {
              "value": "ai agents in action"
            }
          ],
          "searchParameters": {
            "q": "AI agents",
            "gl": "us",
            "type": "autocomplete",
            "engine": "google"
          }
        }
      }
    ],
    "Form Submission (Keywords)": [
      {
        "json": {
          "Keywords": "AI agents",
          "formMode": "test",
          "submittedAt": "2025-08-23T10:19:28.477+10:00"
        }
      }
    ]
  },
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "34bb81b5-d086-4f95-b702-3f42cb606281",
  "connections": {
    "a62c05a4-a000-4e0a-af8d-834f0623802c": {
      "main": [
        [
          {
            "node": "30ba63a3-5ac6-4a80-ab09-39ead3320774",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cc647e9e-fb05-4ea0-ac9c-c5c619ff0d7c": {
      "main": [
        [
          {
            "node": "e122251c-5540-4dd3-be3f-59620c1aacf2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "dd3edb69-ea7c-4d45-9fec-28400e9c16d7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e122251c-5540-4dd3-be3f-59620c1aacf2": {
      "main": [
        [
          {
            "node": "acf43fa6-f8d4-4533-8522-68640916877c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "30ba63a3-5ac6-4a80-ab09-39ead3320774": {
      "main": [
        [
          {
            "node": "f1ad7937-7877-4c35-9840-27b8ac21d447",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4cc5e45e-3fd1-444b-b872-83ca62196b41": {
      "main": [
        [
          {
            "node": "3f03dc09-2cbc-4c6a-a798-1a61b81a8073",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dd3edb69-ea7c-4d45-9fec-28400e9c16d7": {
      "main": [
        [
          {
            "node": "2e768d0f-a2fa-4236-a25f-1ed2ae36a9f1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2e768d0f-a2fa-4236-a25f-1ed2ae36a9f1": {
      "main": [
        [
          {
            "node": "4cc5e45e-3fd1-444b-b872-83ca62196b41",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4e2c4c76-6d22-4a6b-abd1-8771b2ff21f7": {
      "main": [
        [
          {
            "node": "99e4b141-da82-4131-a38e-d65e14307049",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5e40b2b3-8d03-46b0-b1da-a1111997da55": {
      "main": [
        [
          {
            "node": "4e2c4c76-6d22-4a6b-abd1-8771b2ff21f7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "acf43fa6-f8d4-4533-8522-68640916877c": {
      "main": [
        [
          {
            "node": "04ee4323-3527-401c-a963-a726c7f1dad6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "04ee4323-3527-401c-a963-a726c7f1dad6": {
      "main": [
        [
          {
            "node": "bacf9175-722d-4f93-a571-4a5e4e555995",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "99e4b141-da82-4131-a38e-d65e14307049": {
      "main": [
        [
          {
            "node": "cc647e9e-fb05-4ea0-ac9c-c5c619ff0d7c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f1ad7937-7877-4c35-9840-27b8ac21d447": {
      "main": [
        [
          {
            "node": "cc647e9e-fb05-4ea0-ac9c-c5c619ff0d7c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3f03dc09-2cbc-4c6a-a798-1a61b81a8073": {
      "main": [
        [
          {
            "node": "a62c05a4-a000-4e0a-af8d-834f0623802c",
            "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.

Flujos de trabajo relacionados recomendados

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

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

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34