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 Summarize Weekly Google Docs Updates → Send Email",
"nodes": [
{
"id": "setup-instructions",
"name": "설정 안내",
"type": "n8n-nodes-base.stickyNote",
"position": [
200,
80
],
"parameters": {
"width": 280,
"height": 240,
"content": "📄 **SETUP REQUIRED:**\n\n1. **Google Docs Setup:**\n - Add document IDs in 'Get Docs' node\n - Enable Google Drive API access\n - Connect Google OAuth credentials\n\n2. **OpenAI API Key:**\n - Get from platform.openai.com\n - Uses GPT-4 for better summaries\n\n3. **Email Recipients:**\n - Update recipients in Gmail node\n - Customize email template\n\n4. **Schedule:**\n - Runs every Monday at 9 AM\n - Adjust cron expression if needed\n\n🎯 Perfect for team weekly updates!"
},
"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": "Docs 목록 준비",
"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": "Doc 콘텐츠 가져오기",
"type": "n8n-nodes-base.googleDocs",
"position": [
600,
340
],
"parameters": {
"fileId": "={{ $json.id }}",
"operation": "get",
"authentication": "oAuth2"
},
"typeVersion": 2
},
{
"id": "get-doc-metadata",
"name": "Doc 메타데이터 가져오기",
"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": "Doc 데이터 처리",
"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": "업데이트된 Docs 통합",
"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-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-docs": {
"main": [
[
{
"node": "generate-ai-summary",
"type": "main",
"index": 0
}
]
]
},
"weekly-trigger": {
"main": [
[
{
"node": "prepare-docs-list",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
중급 - AI 요약, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
GPT-4를 사용하여 Zoom 녹화 자동 요약 및 Slack 및 이메일로 전송
GPT-4를 사용하여 Zoom 녹화 자동 요약 및 Slack 및 이메일로 전송
Code
Gmail
Slack
+
Code
Gmail
Slack
6 노드David Olusola
AI 요약
Zoom을 통해 GPT-4, Google Docs 및 Slack으로 AI 회의록 생성
Zoom을 통해 GPT-4, Google Docs 및 Slack을 사용하여 AI 회의 기록 생성
Code
Slack
Open Ai
+
Code
Slack
Open Ai
6 노드David Olusola
AI 요약
Gmail 이메일 자동 번역
OpenAI GPT-3.5를 사용하여 수신 Gmail 이메일을 영어로 자동 번역
If
Code
Gmail
+
If
Code
Gmail
9 노드David Olusola
멀티모달 AI
Zoom 녹화를 Google 드라이브에 자동 저장 및 Airtable에 회의 기록
Zoom 녹화를 Google 드라이브에 자동 저장 및 Airtable에 회의 기록
Code
Webhook
Airtable
+
Code
Webhook
Airtable
7 노드David Olusola
파일 관리
Stripe 결제 트리거 및 Gmail을 사용하여 PDF 인보이스 자동 발송
Stripe 결제 트리거 및 Gmail을 사용하여 PDF 인voice 자동 발송
Code
Gmail
Webhook
+
Code
Gmail
Webhook
5 노드David Olusola
청구서 처리
고객에게 인보이스 자동 발송
OCR.Space, GPT-4 및 Google Drive에서 Gmail로 인보이스 처리 자동화
If
Set
Code
+
If
Set
Code
29 노드Michael Taleb
AI 요약
워크플로우 정보
난이도
중급
노드 수10
카테고리2
노드 유형7
저자
David Olusola
@dae221I 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에서 보기 →
이 워크플로우 공유