使用Claude AI、GoMarble MCP和Google幻灯片自动生成每周营销摘要演示文稿副本
中级
这是一个Document Extraction, Multimodal AI领域的自动化工作流,包含 15 个节点。主要使用 Set, Code, Gmail, GoogleDrive, HttpRequest 等节点。 使用Claude AI、GoMarble MCP和Google幻灯片自动化每周Meta广告报告
前置要求
- •Google 账号和 Gmail API 凭证
- •Google Drive API 凭证
- •可能需要目标 API 的认证凭证
- •Anthropic API Key
使用的节点 (15)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "AmaZWuAXZJlrGq5l",
"meta": {
"instanceId": "07ccff49d71cc6b20dddb867ba4ad10dc1f2bd4ad81c28a9330420f0a4ac0b51",
"templateCredsSetupCompleted": true
},
"name": "使用 Claude AI、GoMarble MCP 和 Google Slides 自动生成每周营销摘要演示文稿副本",
"tags": [],
"nodes": [
{
"id": "4bf29e91-9786-4035-9cae-c795795aded5",
"name": "AI Agent",
"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": "请在下方节点中添加需要生成摘要演示文稿的 Facebook 广告账户名称。"
},
"typeVersion": 1
},
{
"id": "632111c0-3c1e-42cb-b605-83f39d55bb0d",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
-180
],
"parameters": {
"width": 200,
"height": 100,
"content": "请在下方节点中添加您希望接收摘要演示文稿的电子邮件地址。"
},
"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": {
"AI Agent": {
"main": [
[
{
"node": "Validate slide output",
"type": "main",
"index": 0
}
]
]
},
"Ad Account": {
"main": [
[
{
"node": "Report Prompt",
"type": "main",
"index": 0
}
]
]
},
"GoMarble MCP": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Download file": {
"main": [
[
{
"node": "Send Email",
"type": "main",
"index": 0
}
]
]
},
"Report Prompt": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Ad Account",
"type": "main",
"index": 0
}
]
]
},
"Format Slides Data": {
"main": [
[
{
"node": " Build Presentation",
"type": "main",
"index": 0
}
]
]
},
" Build Presentation": {
"main": [
[
{
"node": "Download file",
"type": "main",
"index": 0
}
]
]
},
"Create Presentation": {
"main": [
[
{
"node": "Merge Presentation Info",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Validate slide output": {
"main": [
[
{
"node": "Create Presentation",
"type": "main",
"index": 0
}
]
]
},
"Merge Presentation Info": {
"main": [
[
{
"node": "Format Slides Data",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 文档提取, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
AI驱动股票交易自动化
使用AI技术分析和Alpaca交易自动化股票交易
Set
Code
Gmail
+24
96 节点Paul
加密货币交易
合并
使用Suno API、Claude和Telegram机器人创建完整的20首YouTube播放列表
If
Set
Code
+17
150 节点Joseph
内容创作
AI-Deepseek-R1t 会议差旅审批与费用授权申请
通过Deepseek AI、Gmail和Google Sheets自动化会议差旅审批
If
Set
Code
+11
24 节点Cheng Siong Chin
文档提取
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
✨🩷自动化社交媒体内容发布工厂 + 系统提示组合
基于动态系统提示和GPT-4o的AI驱动多平台社交媒体内容工厂
If
Set
Code
+20
100 节点Amit Mehta
内容创作
Arunava的多智能体智能Reddit自动化
使用AI品牌提及和Baserow跟踪自动评论Reddit帖子
If
Set
Code
+12
35 节点Arunava
社交媒体