8
n8n 中文网amn8n.com

AI每周汇总Google Docs更新 → 发送邮件

中级

这是一个AI Summarization, Multimodal AI领域的自动化工作流,包含 10 个节点。主要使用 Code, Cron, Gmail, OpenAi, GoogleDocs 等节点。 使用GPT-4从Google Docs生成每周文档摘要并通过邮件发送

前置要求
  • Google 账号和 Gmail API 凭证
  • OpenAI API Key
  • Google Drive API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "name": "AI 每周汇总 Google Docs 更新 → 发送邮件",
  "nodes": [
    {
      "id": "setup-instructions",
      "name": "设置说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        200,
        80
      ],
      "parameters": {
        "width": 280,
        "height": 240,
        "content": "📄 **需要设置:**"
      },
      "typeVersion": 1
    },
    {
      "id": "weekly-trigger",
      "name": "每周一上午 9 点触发器",
      "type": "n8n-nodes-base.cron",
      "position": [
        200,
        340
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "prepare-docs-list",
      "name": "准备文档列表",
      "type": "n8n-nodes-base.code",
      "position": [
        400,
        340
      ],
      "parameters": {
        "jsCode": "// Define Google Docs to monitor\nconst docsToMonitor = [\n  {\n    id: 'DOC_ID_1_HERE',\n    name: 'Project Status Doc',\n    category: 'Projects'\n  },\n  {\n    id: 'DOC_ID_2_HERE', \n    name: 'Meeting Notes',\n    category: 'Meetings'\n  },\n  {\n    id: 'DOC_ID_3_HERE',\n    name: 'Team Updates',\n    category: 'Updates'\n  }\n  // Add more docs as needed\n];\n\n// Calculate date range for last week\nconst now = new Date();\nconst lastWeek = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));\n\nconsole.log(`Checking docs for updates between ${lastWeek.toISOString()} and ${now.toISOString()}`);\n\nconst docsList = {\n  docs: docsToMonitor,\n  check_date_start: lastWeek.toISOString(),\n  check_date_end: now.toISOString(),\n  total_docs: docsToMonitor.length\n};\n\nreturn docsToMonitor.map(doc => ({ json: doc }));"
      },
      "typeVersion": 2
    },
    {
      "id": "get-doc-content",
      "name": "获取文档内容",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        600,
        340
      ],
      "parameters": {
        "fileId": "={{ $json.id }}",
        "operation": "get",
        "authentication": "oAuth2"
      },
      "typeVersion": 2
    },
    {
      "id": "get-doc-metadata",
      "name": "获取文档元数据",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        600,
        480
      ],
      "parameters": {
        "fileId": "={{ $json.id }}",
        "options": {
          "fields": "modifiedTime,lastModifyingUser,version"
        },
        "operation": "get",
        "authentication": "oAuth2"
      },
      "typeVersion": 3
    },
    {
      "id": "process-doc-data",
      "name": "处理文档数据",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        340
      ],
      "parameters": {
        "jsCode": "// Combine doc content with metadata and check if updated\nconst docContent = $('Get Doc Content').item.json;\nconst docMetadata = $('Get Doc Metadata').item.json;\nconst docInfo = $input.first().json;\n\n// Check if doc was modified in the last week\nconst lastModified = new Date(docMetadata.modifiedTime);\nconst oneWeekAgo = new Date(Date.now() - (7 * 24 * 60 * 60 * 1000));\nconst wasUpdated = lastModified > oneWeekAgo;\n\nif (!wasUpdated) {\n  console.log(`Document ${docInfo.name} not updated in last week, skipping`);\n  return null;\n}\n\n// Extract text content from Google Docs structure\nlet textContent = '';\nif (docContent.body && docContent.body.content) {\n  docContent.body.content.forEach(element => {\n    if (element.paragraph && element.paragraph.elements) {\n      element.paragraph.elements.forEach(textElement => {\n        if (textElement.textRun && textElement.textRun.content) {\n          textContent += textElement.textRun.content;\n        }\n      });\n    }\n  });\n}\n\n// Clean up text content\ntextContent = textContent.replace(/\\s+/g, ' ').trim();\n\nconst processedDoc = {\n  id: docInfo.id,\n  name: docInfo.name,\n  category: docInfo.category,\n  content: textContent,\n  last_modified: docMetadata.modifiedTime,\n  modified_by: docMetadata.lastModifyingUser?.displayName || 'Unknown',\n  version: docMetadata.version,\n  word_count: textContent.split(' ').length,\n  was_updated: wasUpdated,\n  content_preview: textContent.substring(0, 200) + '...'\n};\n\nconsole.log(`Processed doc: ${processedDoc.name} (${processedDoc.word_count} words, updated: ${processedDoc.was_updated})`);\n\nreturn {\n  json: processedDoc\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "aggregate-docs",
      "name": "汇总更新的文档",
      "type": "n8n-nodes-base.code",
      "position": [
        1000,
        340
      ],
      "parameters": {
        "jsCode": "// Aggregate all processed docs for AI summarization\nconst allDocs = $input.all();\nconst updatedDocs = allDocs.filter(item => item.json.was_updated);\n\nif (updatedDocs.length === 0) {\n  console.log('No documents were updated this week');\n  return {\n    json: {\n      has_updates: false,\n      message: 'No documents were updated this week.',\n      summary: 'No weekly summary needed - all documents remain unchanged.'\n    }\n  };\n}\n\n// Prepare content for AI summarization\nlet combinedContent = 'WEEKLY DOCUMENT UPDATES SUMMARY REQUEST:\\n\\n';\n\nupdatedDocs.forEach((doc, index) => {\n  combinedContent += `DOCUMENT ${index + 1}: ${doc.json.name} (${doc.json.category})\\n`;\n  combinedContent += `Last Modified: ${new Date(doc.json.last_modified).toLocaleDateString()} by ${doc.json.modified_by}\\n`;\n  combinedContent += `Word Count: ${doc.json.word_count}\\n`;\n  combinedContent += `Content: ${doc.json.content}\\n\\n---\\n\\n`;\n});\n\nconst aggregatedData = {\n  has_updates: true,\n  total_updated_docs: updatedDocs.length,\n  docs_summary: updatedDocs.map(doc => ({\n    name: doc.json.name,\n    category: doc.json.category,\n    modified_by: doc.json.modified_by,\n    last_modified: doc.json.last_modified\n  })),\n  combined_content: combinedContent,\n  week_range: `${new Date(Date.now() - (7 * 24 * 60 * 60 * 1000)).toLocaleDateString()} - ${new Date().toLocaleDateString()}`\n};\n\nconsole.log(`Aggregated ${aggregatedData.total_updated_docs} updated documents for AI summary`);\n\nreturn {\n  json: aggregatedData\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "generate-ai-summary",
      "name": "生成 AI 摘要",
      "type": "n8n-nodes-base.openAi",
      "position": [
        1200,
        340
      ],
      "parameters": {
        "resource": "chat",
        "operation": "create",
        "requestBody": {
          "model": "gpt-4",
          "messages": [
            {
              "role": "system",
              "content": "You are an executive assistant creating weekly document update summaries. Create a professional, concise summary highlighting key changes, updates, and action items from the provided documents. Format as a business email body with clear sections and bullet points."
            },
            {
              "role": "user",
              "content": "{{ $json.combined_content }}\n\nPlease create a professional weekly summary email covering:\n1. Executive Summary\n2. Key Updates by Document\n3. Important Changes\n4. Action Items (if any)\n5. Next Week's Focus\n\nKeep it concise but informative for team leadership."
            }
          ],
          "max_tokens": 1500,
          "temperature": 0.3
        }
      },
      "typeVersion": 1
    },
    {
      "id": "prepare-email-content",
      "name": "准备邮件内容",
      "type": "n8n-nodes-base.code",
      "position": [
        1400,
        340
      ],
      "parameters": {
        "jsCode": "// Prepare final email content\nconst summaryData = $('Aggregate Updated Docs').item.json;\nconst aiResponse = $input.first().json;\n\nif (!summaryData.has_updates) {\n  return {\n    json: {\n      send_email: false,\n      subject: 'Weekly Document Updates - No Changes',\n      body: summaryData.message\n    }\n  };\n}\n\nconst aiSummary = aiResponse.choices[0].message.content;\n\n// Create professional email\nconst emailContent = {\n  send_email: true,\n  subject: `📄 Weekly Document Updates Summary - ${summaryData.week_range}`,\n  body: `Dear Team,\\n\\nHere's your weekly document updates summary for ${summaryData.week_range}:\\n\\n${aiSummary}\\n\\n📊 UPDATED DOCUMENTS (${summaryData.total_updated_docs}):\\n${summaryData.docs_summary.map(doc => `• ${doc.name} (${doc.category}) - Updated by ${doc.modified_by} on ${new Date(doc.last_modified).toLocaleDateString()}`).join('\\n')}\\n\\n---\\nThis summary was automatically generated by your n8n workflow.\\nTo modify monitored documents, update the workflow configuration.\\n\\nBest regards,\\nYour Automation Assistant`,\n  html_body: `\n    <div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n      <h2>📄 Weekly Document Updates Summary</h2>\n      <p><strong>Period:</strong> ${summaryData.week_range}</p>\n      \n      <div style=\"background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0;\">\n        ${aiSummary.replace(/\\n/g, '<br>')}\n      </div>\n      \n      <h3>📊 Updated Documents (${summaryData.total_updated_docs})</h3>\n      <ul>\n        ${summaryData.docs_summary.map(doc => `<li><strong>${doc.name}</strong> (${doc.category})<br><small>Updated by ${doc.modified_by} on ${new Date(doc.last_modified).toLocaleDateString()}</small></li>`).join('')}\n      </ul>\n      \n      <hr>\n      <p style=\"color: #666; font-size: 12px;\">This summary was automatically generated by your n8n workflow.</p>\n    </div>\n  `\n};\n\nconsole.log('Prepared email summary:', {\n  subject: emailContent.subject,\n  docs_count: summaryData.total_updated_docs\n});\n\nreturn {\n  json: emailContent\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "send-summary-email",
      "name": "发送摘要邮件",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1600,
        340
      ],
      "parameters": {
        "email": "team@yourcompany.com,manager@yourcompany.com",
        "message": "={{ $json.body }}",
        "options": {
          "htmlMessage": "={{ $json.html_body }}"
        },
        "subject": "={{ $json.subject }}",
        "operation": "send"
      },
      "typeVersion": 2.1
    }
  ],
  "active": true,
  "settings": {
    "timezone": "UTC"
  },
  "versionId": "1",
  "connections": {
    "Get Doc Content": {
      "main": [
        [
          {
            "node": "Process Doc Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Doc Metadata": {
      "main": [
        [
          {
            "node": "Process Doc Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Doc Data": {
      "main": [
        [
          {
            "node": "Aggregate Updated Docs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Docs List": {
      "main": [
        [
          {
            "node": "Get Doc Content",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Doc Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate AI Summary": {
      "main": [
        [
          {
            "node": "Prepare Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Email Content": {
      "main": [
        [
          {
            "node": "Send Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Updated Docs": {
      "main": [
        [
          {
            "node": "Generate AI Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Monday 9AM Trigger": {
      "main": [
        [
          {
            "node": "Prepare Docs List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - AI 摘要总结, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量10
分类2
节点类型7
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
David Olusola

David Olusola

@dae221

I help ambitious businesses eliminate operational bottlenecks and scale faster with AI automation. My clients typically see 40-60% efficiency gains within 90 days. Currently accepting 3 new projects this quarter - david@daexai.com

外部链接
在 n8n.io 查看

分享此工作流