8
n8n 한국어amn8n.com

Claude AI, GoMarble MCP 및 Google 프레젠테이션을 사용한 주간 마케팅 요약 프레젠테이션 자동 생성 사본

중급

이것은Document Extraction, Multimodal AI분야의자동화 워크플로우로, 15개의 노드를 포함합니다.주로 Set, Code, Gmail, GoogleDrive, HttpRequest 등의 노드를 사용하며. Claude AI, GoMarble MCP 및 Google Slides를 사용한 주간 Meta 광고 보고서 자동화

사전 요구사항
  • Google 계정 및 Gmail API 인증 정보
  • Google Drive API 인증 정보
  • 대상 API의 인증 정보가 필요할 수 있음
  • Anthropic API Key
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "id": "AmaZWuAXZJlrGq5l",
  "meta": {
    "instanceId": "07ccff49d71cc6b20dddb867ba4ad10dc1f2bd4ad81c28a9330420f0a4ac0b51",
    "templateCredsSetupCompleted": true
  },
  "name": "Copy ofAutomate Weekly Marketing Summary Deck with Claude AI, GoMarble MCP & Google Slides",
  "tags": [],
  "nodes": [
    {
      "id": "4bf29e91-9786-4035-9cae-c795795aded5",
      "name": "AI 에이전트",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        580,
        -40
      ],
      "parameters": {
        "text": "={{ $json['Report Prompt'] }}",
        "options": {
          "systemMessage": "You are a senior digital marketing professional. You MUST always return exactly 5 slides in your JSON response. There should be no made up data or hallucination, but if insufficient data exists for a slide, use placeholder text like 'Data pending analysis' or 'No significant changes this period'."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "97d9bdf1-4758-4222-b05f-4544e8e64fcc",
      "name": "스케줄 트리거",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": ":alarm_clock: Runs every Monday at 8 AM - adjust schedule as needed",
      "position": [
        100,
        -40
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ed8dddf4-fe74-49b4-922e-a390c53a03d4",
      "name": "GoMarble MCP",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "notes": ":closed_lock_with_key: Add your GoMarble Bearer token - get it from https://www.gomarble.ai/docs/connect-to-n8n",
      "position": [
        800,
        160
      ],
      "parameters": {
        "sseEndpoint": "https://apps.gomarble.ai/mcp-api/sse",
        "authentication": "bearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "6F65J7hlA4wzSeid",
          "name": "Bearer Auth account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "21fa31be-5754-4917-bd6b-20862d3ea4bc",
      "name": "파일 다운로드",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1780,
        -40
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{$json.presentationId}}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "daPp0U6XEYaYQnlD",
          "name": "Google Drive account 2"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "5a805b50-3ae4-4488-9536-e3a569602fd4",
      "name": "Anthropic 채팅 모델",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        520,
        160
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514",
          "cachedResultName": "Claude 4 Sonnet"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "id": "XMYEac7S3M6Hi7I5",
          "name": "Anthropic account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "381eafea-79d6-46ed-b0cb-8d0802f83e9a",
      "name": "이메일 전송",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1940,
        -40
      ],
      "webhookId": "be82cd6b-8d18-4459-9b02-9ad01db01d38",
      "parameters": {
        "sendTo": "amancliff1@gmail.com",
        "message": "=Here is the Weekly Ad Performance Summary Deck - {{ $now.format('MM-DD') }}\".",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Weekly Summary Deck - {{ $now.format('MM-DD') }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "NMqbcdXNnH8EIv8G",
          "name": "Gmail account 7"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "13fde168-5855-4509-8490-2dac61abd7f1",
      "name": "리포트 프롬프트",
      "type": "n8n-nodes-base.set",
      "notes": "🔧 EDIT THIS NODE to change:\n• Account Name & ID\n• Email Recipients\n• Report Settings",
      "position": [
        420,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f2864549-d51c-4aad-b1cf-9a731e86b816",
              "name": "=Report Prompt",
              "type": "string",
              "value": "=You are a **senior performance‑marketing analyst**.\n\nVoice: sharp, concise, insight‑driven (no fluff, no marketing hype).  \nGoal: craft a weekly digest that a busy CMO can scan in < 3 min and act on immediately.  \n\nAd Account: {{ $json.accountName }}.\nTime Period: last 7 days  \n\n---\n\nCALL TOOL  \nUse **GoMarble MCP** with:  \n{\n  \"period\": \"last_7_days\"\n}  \nIt returns JSON metrics for Meta Ads.\n\n---\n\nAFTER the tool result is returned, you MUST output exactly ONE valid JSON object with EXACTLY 5 slides—nothing else:\n\n{\n  \"slides\": [\n    {\n      \"title\": \"Executive Snapshot\",\n      \"body\": \"<3‑line paragraph>  ▸ One‑sentence topline: combined spend, revenue, ROAS, and WoW % change.\\n▸ One‑sentence highlight of the biggest win.\\n▸ One‑sentence note on the main risk / action gap.\"\n    },\n    {\n      \"title\": \"Channel KPIs\",\n      \"tableData\": {\n        \"Spend\": \"$X,XXX\",\n        \"Impressions\": \"XXX,XXX\",\n        \"Clicks\": \"X,XXX\",\n        \"CTR\": \"X.XX%\",\n        \"CPC\": \"$X.XX\",\n        \"Conversions\": \"XX\",\n        \"CPA\": \"$XXX\",\n        \"Revenue\": \"$X,XXX\",\n        \"ROAS\": \"X.XX\",\n        \"WoW Change\": \"+/-XX%\"\n      }\n    },\n    {\n      \"title\": \"Top Campaigns\",\n      \"body\": \"<bullet list of the single best campaign per platform with why it won (1‑sentence each)>\"\n    },\n    {\n      \"title\": \"Under‑performers\",\n      \"body\": \"<bullet list of key weak campaigns with brief reason & WoW drop (1‑sentence each)>\"\n    },\n    {\n      \"title\": \"Action Recos\",\n      \"body\": \"<2‑3 crisp, prioritised recommendations the team should execute next week>\"\n    }\n  ]\n}\n\nCRITICAL RULES  \n– Return ONLY JSON (no Markdown fences, no explanations).  \n– EXACTLY 5 slide objects - NO MORE, NO LESS. This is mandatory.\n– For Channel KPIs: Use \"tableData\" object with key-value pairs for metrics (no pipe separators)\n– Use \\n for line breaks and keep sections tight and scannable\n– Keep each \"body\" < 120 words; use \\n for line breaks.  \n– Do NOT include any keys other than \"slides\".\n– The JSON must be valid and parseable.\n– Count your slides before responding - there must be exactly 5."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8ca128ec-4f51-4d38-9c3e-bbcff815e765",
      "name": "프레젠테이션 생성",
      "type": "n8n-nodes-base.httpRequest",
      "notes": ":bar_chart: Creates empty presentation",
      "position": [
        1080,
        -40
      ],
      "parameters": {
        "url": "https://slides.googleapis.com/v1/presentations",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"title\": \"Weekly Ad Report – {{ $now.format('MM-DD') }}\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleSlidesOAuth2Api"
      },
      "credentials": {
        "googleSlidesOAuth2Api": {
          "id": "gSaMa5Jnq7KRBH8v",
          "name": "Google Slides account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8f85ce4e-ac53-45b3-9b59-0052787abebd",
      "name": "광고 계정",
      "type": "n8n-nodes-base.set",
      "notes": "🔧 EDIT THIS NODE to change:\n• Account Name & ID\n• Email Recipients\n• Report Settings",
      "position": [
        260,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "account-name",
              "name": "accountName",
              "type": "string",
              "value": "Long Surf"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ed8739ef-8efb-466b-8ca6-99548c809e66",
      "name": "스티키 노트",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        220,
        -180
      ],
      "parameters": {
        "width": 220,
        "height": 100,
        "content": "Please add the name of the Facebook ad account in the node below for which you need the summary deck."
      },
      "typeVersion": 1
    },
    {
      "id": "632111c0-3c1e-42cb-b605-83f39d55bb0d",
      "name": "스티키 노트1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1840,
        -180
      ],
      "parameters": {
        "width": 200,
        "height": 100,
        "content": "Please add the email ID in the node below to which you want the summary deck sent."
      },
      "typeVersion": 1
    },
    {
      "id": "7319e6ac-e678-4bcb-b0ab-6648490e5cf0",
      "name": "슬라이드 출력 검증",
      "type": "n8n-nodes-base.code",
      "notes": ":lock: GUARANTEES exactly 5 slides - no more, no less",
      "position": [
        900,
        -40
      ],
      "parameters": {
        "jsCode": "console.log('Raw AI output:', $json.output);\n\ntry {\n  let jsonString = $json.output;\n  \n  // Remove markdown code fences if present\n  if (jsonString.includes('```json')) {\n    console.log('Removing markdown fences');\n    jsonString = jsonString.replace(/```json\\n?/g, '').replace(/```\\n?$/g, '');\n  }\n  \n  // Remove any leading \"json\\n\" or similar\n  jsonString = jsonString.replace(/^json\\n/g, '');\n  \n  // Clean up any extra whitespace\n  jsonString = jsonString.trim();\n  \n  console.log('Cleaned JSON string:', jsonString.substring(0, 200) + '...');\n  \n  const output = JSON.parse(jsonString);\n  console.log(`Successfully parsed! Found ${output.slides.length} slides`);\n  \n  // Return the slides directly from AI (now with tableData support)\n  return [{ json: { slides: output.slides } }];\n  \n} catch (e) {\n  console.error('JSON parsing failed:', e.message);\n  console.log('Attempting manual extraction...');\n  \n  // Try to extract JSON from between { and }\n  const match = $json.output.match(/\\{[\\s\\S]*\\}/);\n  if (match) {\n    try {\n      const output = JSON.parse(match[0]);\n      console.log('Manual extraction successful!');\n      return [{ json: { slides: output.slides } }];\n    } catch (e2) {\n      console.log('Manual extraction also failed');\n    }\n  }\n  \n  // Last resort: return fallback with table structure for Channel KPIs\n  const fallbackSlides = [\n    { \n      title: \"Executive Snapshot\", \n      body: \"Weekly performance data is currently being processed. Report will be available shortly.\" \n    },\n    { \n      title: \"Channel KPIs\", \n      tableData: {\n        \"Spend\": \"Data pending\",\n        \"Impressions\": \"Data pending\",\n        \"Clicks\": \"Data pending\",\n        \"CTR\": \"Data pending\",\n        \"CPC\": \"Data pending\",\n        \"Conversions\": \"Data pending\",\n        \"CPA\": \"Data pending\",\n        \"Revenue\": \"Data pending\",\n        \"ROAS\": \"Data pending\",\n        \"WoW Change\": \"Data pending\"\n      }\n    },\n    { \n      title: \"Top Campaigns\", \n      body: \"Campaign performance analysis is in progress. Top-performing campaigns will be highlighted once data processing is complete.\" \n    },\n    { \n      title: \"Under-performers\", \n      body: \"Performance analysis not available at this time. Underperforming campaigns will be identified in the next report.\" \n    },\n    { \n      title: \"Action Recos\", \n      body: \"Strategic recommendations will be provided once performance data analysis is complete. Please check the next scheduled report.\" \n    }\n  ];\n  \n  return [{ json: { slides: fallbackSlides } }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "7a17068d-a6ae-46e5-9b37-3c5157291bf1",
      "name": "슬라이드 데이터 형식화",
      "type": "n8n-nodes-base.code",
      "notes": ":wrench: Prepares the batch request with slide data",
      "position": [
        1440,
        -40
      ],
      "parameters": {
        "jsCode": "// Get the data from the Combine Data node\nconst presentationId = $json.presentationId;\nconst slides = $json.slides;\n\nconst requests = [\n  // Delete the default slide first\n  {\n    deleteObject: { objectId: 'p' }\n  }\n];\n\n// Create exactly 5 slides with content\nslides.forEach((slide, index) => {\n  const slideId = `slide_${index + 1}`;\n  const titleId = `${slideId}_title`;\n  \n  // Create slide\n  requests.push({\n    createSlide: {\n      objectId: slideId,\n      slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' },\n      placeholderIdMappings: [\n        { layoutPlaceholder: { type: 'TITLE', index: 0 }, objectId: titleId },\n        { layoutPlaceholder: { type: 'BODY', index: 0 }, objectId: `${slideId}_body` }\n      ]\n    }\n  });\n  \n  // Add title\n  requests.push({\n    insertText: { objectId: titleId, insertionIndex: 0, text: slide.title }\n  });\n  \n  // Handle Channel KPIs slide with table\n  if (slide.title === \"Channel KPIs\" && slide.tableData) {\n    const tableId = `${slideId}_table`;\n    \n    // Create table (2 columns, 10 rows for the metrics)\n    requests.push({\n      createTable: {\n  objectId: tableId,\n  elementProperties: {\n    pageObjectId: slideId,\n    size: { width: { magnitude: 350, unit: 'PT' }, height: { magnitude: 200, unit: 'PT' } },\n    transform: {\n      scaleX: 1, scaleY: 1, translateX: 185, translateY: 80, unit: 'PT'\n    }\n  },\n  rows: 10,\n  columns: 2\n}\n    });\n    \n    // Populate table with data\n    const metrics = Object.entries(slide.tableData);\n    metrics.forEach(([metric, value], rowIndex) => {\n      // Insert metric name in first column\n      requests.push({\n        insertText: {\n          objectId: tableId,\n          cellLocation: { rowIndex: rowIndex, columnIndex: 0 },\n          insertionIndex: 0,\n          text: metric\n        }\n      });\n      \n      // Insert metric value in second column\n      requests.push({\n        insertText: {\n          objectId: tableId,\n          cellLocation: { rowIndex: rowIndex, columnIndex: 1 },\n          insertionIndex: 0,\n          text: value\n        }\n      });\n    });\n    \n  } else {\n    // For all other slides, use regular text insertion\n    const bodyId = `${slideId}_body`;\n    requests.push({\n      insertText: { objectId: bodyId, insertionIndex: 0, text: slide.body }\n    });\n  }\n});\n\nreturn [{\n  json: {\n    presentationId: presentationId,\n    batchUpdateBody: { requests: requests }\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "cd89420c-20be-4d70-b4b3-2b7fc0a80315",
      "name": "프레젠테이션 빌드",
      "type": "n8n-nodes-base.httpRequest",
      "notes": ":page_facing_up: Executes the batch update to create all slides",
      "position": [
        1600,
        -40
      ],
      "parameters": {
        "url": "=https://slides.googleapis.com/v1/presentations/{{$json.presentationId}}:batchUpdate",
        "method": "POST",
        "options": {},
        "jsonBody": "={{JSON.stringify($json.batchUpdateBody)}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleSlidesOAuth2Api"
      },
      "credentials": {
        "googleSlidesOAuth2Api": {
          "id": "gSaMa5Jnq7KRBH8v",
          "name": "Google Slides account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "27755c4f-b75f-45c8-a674-21b3826082e9",
      "name": "프레젠테이션 정보 병합",
      "type": "n8n-nodes-base.set",
      "notes": ":link: Combines presentation ID with slide data",
      "position": [
        1260,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "presentation-id",
              "name": "presentationId",
              "type": "string",
              "value": "={{$json.presentationId}}"
            },
            {
              "id": "slides-data",
              "name": "slides",
              "type": "array",
              "value": "={{$items('Validate slide output')[0].json.slides}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "6f834adc-d3d9-466e-8f9b-36668904af1f",
  "connections": {
    "4bf29e91-9786-4035-9cae-c795795aded5": {
      "main": [
        [
          {
            "node": "7319e6ac-e678-4bcb-b0ab-6648490e5cf0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8f85ce4e-ac53-45b3-9b59-0052787abebd": {
      "main": [
        [
          {
            "node": "13fde168-5855-4509-8490-2dac61abd7f1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ed8dddf4-fe74-49b4-922e-a390c53a03d4": {
      "ai_tool": [
        [
          {
            "node": "4bf29e91-9786-4035-9cae-c795795aded5",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "21fa31be-5754-4917-bd6b-20862d3ea4bc": {
      "main": [
        [
          {
            "node": "381eafea-79d6-46ed-b0cb-8d0802f83e9a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "13fde168-5855-4509-8490-2dac61abd7f1": {
      "main": [
        [
          {
            "node": "4bf29e91-9786-4035-9cae-c795795aded5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "97d9bdf1-4758-4222-b05f-4544e8e64fcc": {
      "main": [
        [
          {
            "node": "8f85ce4e-ac53-45b3-9b59-0052787abebd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7a17068d-a6ae-46e5-9b37-3c5157291bf1": {
      "main": [
        [
          {
            "node": "cd89420c-20be-4d70-b4b3-2b7fc0a80315",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cd89420c-20be-4d70-b4b3-2b7fc0a80315": {
      "main": [
        [
          {
            "node": "21fa31be-5754-4917-bd6b-20862d3ea4bc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8ca128ec-4f51-4d38-9c3e-bbcff815e765": {
      "main": [
        [
          {
            "node": "27755c4f-b75f-45c8-a674-21b3826082e9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5a805b50-3ae4-4488-9536-e3a569602fd4": {
      "ai_languageModel": [
        [
          {
            "node": "4bf29e91-9786-4035-9cae-c795795aded5",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "7319e6ac-e678-4bcb-b0ab-6648490e5cf0": {
      "main": [
        [
          {
            "node": "8ca128ec-4f51-4d38-9c3e-bbcff815e765",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "27755c4f-b75f-45c8-a674-21b3826082e9": {
      "main": [
        [
          {
            "node": "7a17068d-a6ae-46e5-9b37-3c5157291bf1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

중급 - 문서 추출, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
중급
노드 수15
카테고리2
노드 유형10
난이도 설명

일정 경험을 가진 사용자를 위한 6-15개 노드의 중간 복잡도 워크플로우

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34