Synthèse hebdomadaire des mises à jour Google Docs par IA → envoi par e-mail
Ceci est unAI Summarization, Multimodal AIworkflow d'automatisation du domainecontenant 10 nœuds.Utilise principalement des nœuds comme Code, Cron, Gmail, OpenAi, GoogleDocs. Générer des résumés de documents hebdomadaires à partir de Google Docs avec GPT-4 et les envoyer par e-mail
- •Compte Google et informations d'identification Gmail API
- •Clé API OpenAI
- •Informations d'identification Google Drive API
Nœuds utilisés (10)
Catégorie
{
"name": "AI Summarize Weekly Google Docs Updates → Send Email",
"nodes": [
{
"id": "setup-instructions",
"name": "Instructions de configuration",
"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": "Déclencheur hebdomadaire lundi 9h",
"type": "n8n-nodes-base.cron",
"position": [
200,
340
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1"
}
]
}
},
"typeVersion": 1
},
{
"id": "prepare-docs-list",
"name": "Préparer la liste des documents",
"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": "Obtenir le contenu du document",
"type": "n8n-nodes-base.googleDocs",
"position": [
600,
340
],
"parameters": {
"fileId": "={{ $json.id }}",
"operation": "get",
"authentication": "oAuth2"
},
"typeVersion": 2
},
{
"id": "get-doc-metadata",
"name": "Obtenir les métadonnées du document",
"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": "Traiter les données du document",
"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": "Agréger les documents mis à jour",
"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": "Générer le résumé par IA",
"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": "Préparer le contenu de l'e-mail",
"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": "Envoyer l'e-mail de résumé",
"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
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Intermédiaire - Résumé IA, IA Multimodale
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
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
Partager ce workflow