Dumpling AIとGoogle Docsを使用したフォームからブログへの自動変換

上級

これはContent Creation, Multimodal AI分野の自動化ワークフローで、17個のノードを含みます。主にCode, Wait, Limit, SplitOut, Aggregateなどのノードを使用。 Dumpling AI、OpenAI、Google Docs でキーワードからブログ作成を自動化

前提条件
  • ターゲットAPIの認証情報が必要な場合あり
  • OpenAI API Key
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "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": "フォーム送信(キーワード)",
      "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": "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": "オートコンプリート提案の分割",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        32,
        32
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "suggestions"
      },
      "typeVersion": 1
    },
    {
      "id": "cc647e9e-fb05-4ea0-ac9c-c5c619ff0d7c",
      "name": "提案のループ処理",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        256,
        32
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "dd3edb69-ea7c-4d45-9fec-28400e9c16d7",
      "name": "リクエスト間の遅延",
      "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": "Dumpling AI Google ニュース",
      "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": "ニュース記事の分割",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        864,
        32
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "news"
      },
      "typeVersion": 1
    },
    {
      "id": "3f03dc09-2cbc-4c6a-a798-1a61b81a8073",
      "name": "記事のフィルタリング(1〜2日前)",
      "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": "記事数の制限",
      "type": "n8n-nodes-base.limit",
      "position": [
        1328,
        32
      ],
      "parameters": {
        "maxItems": 2
      },
      "typeVersion": 1
    },
    {
      "id": "30ba63a3-5ac6-4a80-ab09-39ead3320774",
      "name": "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": "記事コンテンツのクリーニングと準備",
      "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": "記事の集約",
      "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: ブログ下書きの生成",
      "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": "Google ドキュメント: ブログファイルの作成",
      "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": "Google ドキュメント: ブログコンテンツの挿入",
      "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": "付箋",
      "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": "付箋1",
      "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
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

上級 - コンテンツ作成, マルチモーダルAI

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

関連ワークフロー

Dumpling AI + GPT-4 を使用してキーワードに基づいて TikTok 動画の質問を検索
Dumpling AI + GPT-4 でキーワードから TikTok 動画の質問を検索
Code
Wait
Limit
+
Code
Wait
Limit
16 ノードYang
コンテンツ作成
Dumpling AI を使用してフォームから映画級の動物ビデオと音声を自動生成する
GPT-4、Dumpling AI、ElementalLabs オーディオを使用して、フォーム入力を映画のようなビデオに変換します
Set
Code
Wait
+
Set
Code
Wait
23 ノードYang
コンテンツ作成
Dumpling AIとGPT-4oを使ってYouTube動画のアイデアを生成
動画分析を使ってDumpling AIとGPT-4oでYouTubeコンテンツのアイデアを生成する
Code
Wait
Gmail
+
Code
Wait
Gmail
13 ノードYang
コンテンツ作成
WordPressブログの自動化プロフェッショナル版(先端研究)v2.1マーケットプラグイン
GPT-4o、Perplexity AI、そして多言語対応を使ったSEO最適化ブログ作成の自動化
If
Set
Xml
+
If
Set
Xml
125 ノードDaniel Ng
コンテンツ作成
キーワードからGPT-5とfal.ai画像を使ってWordPressまで自動SEOブログ生成のプロセス
GPT-5とfal.ai画像を使用したキーワードからWordPressへのSEOブログ自動化プロセス
Set
Code
Wait
+
Set
Code
Wait
96 ノードPaul
コンテンツ作成
最新のAIニュースを使用してDumpling AIとHeyGenからバーチャルキャラクター動画を生成
Dumpling AI、GPT-4o、HeyGenを使ってAIニュースバーチャルアイドビデオを作成
If
Wait
Limit
+
If
Wait
Limit
15 ノードYang
コンテンツ作成
ワークフロー情報
難易度
上級
ノード数17
カテゴリー2
ノードタイプ11
難易度説明

上級者向け、16ノード以上の複雑なワークフロー

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34