Automatiser la génération de rapports de fin de journée de ClickUp et GoHighLevel vers Slack, Email et Google Drive
Ceci est uncontenant 29 nœuds.Utilise principalement des nœuds comme If, Code, Merge, Slack, ClickUp. Générez des rapports de fin de journée IA à partir de ClickUp et GoHighLevel vers plusieurs canaux
- •Token Bot Slack ou URL Webhook
- •Informations d'identification Google Drive API
- •Clé API OpenAI
Nœuds utilisés (29)
Catégorie
{
"id": "qxecimVbLMgxfjK3",
"meta": {
"instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
"templateCredsSetupCompleted": true
},
"name": "Automate End-of-Day Report Generation from ClickUp and GoHighLevel to Slack, Email, and Google Drive",
"tags": [],
"nodes": [
{
"id": "bd6d56ca-edb5-44a2-a281-0dccc2103891",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4512,
-496
],
"parameters": {
"color": 6,
"width": 389,
"height": 753,
"content": "## 📊 Automate End-of-Day Report Generation from ClickUp and GoHighLevel to Slack, Email, and Google Drive \n\nThis workflow automatically generates comprehensive End-of-Day (EOD) reports by:\n- Fetching tasks from ClickUp\n- Retrieving opportunities from GoHighLevel (GHL)\n- Merging and transforming data into a unified format\n- Using AI to analyze and generate insightful reports\n- Distributing reports via Slack, Email, and Google Drive\n\n### 🎯 Use Case\nPerfect for teams wanting automated daily summaries of:\n- Task completions and blockers\n- Sales pipeline progress\n- Team performance metrics\n- Action items for tomorrow\n\n### ⏰ Schedule\nRuns Monday-Friday at 6:00 PM (18:00)\n\n### 🔧 Setup Requirements\n1. ClickUp OAuth2 credentials\n2. GoHighLevel OAuth2 credentials\n3. Azure OpenAI API credentials\n4. Slack API credentials\n5. SMTP credentials for email\n6. Google Drive OAuth2 credentials"
},
"typeVersion": 1
},
{
"id": "379fe532-1b85-4c6d-ae9b-47a925359848",
"name": "Note adhésive1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3920,
-464
],
"parameters": {
"width": 318,
"height": 358,
"content": "## ⏰ Step 1: Schedule Trigger\n\n**Cron Expression:** `0 18 * * 1-5`\n- Runs at 6:00 PM (18:00)\n- Monday through Friday only\n- Timezone: Server default\n\n**Setup Instructions:**\n1. Click this node\n2. Adjust time if needed using cron expression\n3. Test manually using \"Execute Node\" button"
},
"typeVersion": 1
},
{
"id": "ea406065-c358-4fcf-a38a-604312920c35",
"name": "Note adhésive2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3536,
-720
],
"parameters": {
"width": 343,
"height": 497,
"content": "## 📋 Step 2: Fetch ClickUp Tasks\n\n**What it does:**\nRetrieves tasks from your ClickUp workspace for the current day.\n\n**Setup Instructions:**\n1. Connect ClickUp OAuth2 credentials\n2. Replace these IDs with your own:\n - Team ID (get from ClickUp workspace URL)\n - Space ID (from space settings)\n - Folder ID (from folder URL)\n - List ID (from list URL)\n\n**Filters Applied:**\n- Due date: Today\n- Includes subtasks\n\n**Security:** Remove hardcoded IDs before sharing!"
},
"typeVersion": 1
},
{
"id": "972b5e17-42e1-49b5-9aac-a4d01ada89d4",
"name": "Note adhésive3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3472,
160
],
"parameters": {
"width": 343.2558139534883,
"height": 339.5348837209302,
"content": "## 💼 Step 3: Fetch GHL Opportunities\n\n**What it does:**\nRetrieves won opportunities from GoHighLevel CRM.\n\n**Setup Instructions:**\n1. Connect GoHighLevel OAuth2 credentials\n2. Adjust filters if needed:\n - Current: Only \"won\" opportunities\n - Optional: Add date range filters\n\n**Limit:** 100 opportunities\n\n**Security:** Credentials are stored securely in n8n"
},
"typeVersion": 1
},
{
"id": "1646ef95-15d9-422d-9419-d84a5a9603f1",
"name": "Note adhésive4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3168,
-528
],
"parameters": {
"width": 303,
"height": 374,
"content": "## 🔀 Step 4: Merge Data Sources\n\n**What it does:**\nCombines ClickUp tasks and GHL opportunities into a single dataset.\n\n**Merge Strategy:**\n- Input 1: ClickUp tasks\n- Input 2: GHL opportunities\n- Mode: Append (combines all items)\n\n**No configuration needed** - just ensure both data sources connect here."
},
"typeVersion": 1
},
{
"id": "37efa8ec-2c49-4dd7-a2bb-11adf09b5ded",
"name": "Note adhésive5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3040,
96
],
"parameters": {
"width": 343.2558139534883,
"height": 400,
"content": "## 🔄 Step 5: Transform & Structure Data\n\n**What it does:**\nTransforms merged data into a unified format for AI analysis.\n\n**Key Transformations:**\n- Maps ClickUp tasks → GHL opportunity format\n- Extracts monetary values from custom fields\n- Normalizes status values\n- Aggregates summary statistics\n\n**Output Structure:**\n- Total items count\n- Opportunities array\n- Summary metrics (by status, source, total value)\n\n**No configuration needed** - transformation logic is built-in."
},
"typeVersion": 1
},
{
"id": "2fb72697-f98e-484c-8d9f-fac71da8c90e",
"name": "Note adhésive6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2784,
-640
],
"parameters": {
"width": 343,
"height": 501,
"content": "## 🤖 Step 6: AI Report Generation\n\n**What it does:**\nUses Azure OpenAI GPT-4o to analyze data and generate structured EOD report.\n\n**Setup Instructions:**\n1. Connect Azure OpenAI credentials\n2. Model: GPT-4o (recommended)\n3. Memory: 7-message window for context\n\n**AI Analysis Includes:**\n- Brief summary\n- Key wins\n- Important metrics\n- Blockers/issues\n- Action items for tomorrow\n\n**Output:** Structured JSON matching defined schema"
},
"typeVersion": 1
},
{
"id": "a7000d6c-e0ee-40c6-968e-f233b120e33e",
"name": "Note adhésive7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2320,
48
],
"parameters": {
"width": 343,
"height": 492,
"content": "## 📤 Step 7: Format for Distribution\n\n**What it does:**\nCreates three formatted versions of the report:\n1. **Slack**: Markdown with emojis\n2. **Email**: HTML with styling\n3. **Google Drive**: Plain text file\n\n**Each Output Contains:**\n- Title\n- Summary\n- Wins\n- Key metrics\n- Blockers\n- Action items\n- Timestamp\n\n**No configuration needed** - automatic routing."
},
"typeVersion": 1
},
{
"id": "8d3b5528-a03f-4298-a336-d1cb84324f1e",
"name": "Note adhésive8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2144,
-736
],
"parameters": {
"width": 343,
"height": 413,
"content": "## 🔀 Step 8: Route to Channels\n\n**What it does:**\nThree parallel IF nodes route data to appropriate channels.\n\n**Routing Logic:**\n- `type = \"slack\"` → Slack node\n- `type = \"email\"` → Email node\n- `type = \"google_drive\"` → Google Drive node\n\n**All three routes execute in parallel** for simultaneous delivery.\n\n**No configuration needed** - automatic based on data type."
},
"typeVersion": 1
},
{
"id": "ae1581a1-f411-4a51-a557-875e97535b8c",
"name": "Note adhésive9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1632,
-768
],
"parameters": {
"width": 343,
"height": 432,
"content": "## 💬 Step 9A: Send to Slack\n\n**Setup Instructions:**\n1. Connect Slack OAuth2 credentials\n2. **IMPORTANT:** Replace channel ID with your own:\n - Get from: Slack → Right-click channel → Copy link\n - Extract: Last part of URL (e.g., C09GNB90TED)\n3. Select channel from dropdown\n\n**Message Format:**\n- Title with icon\n- Markdown formatting\n- All report sections\n"
},
"typeVersion": 1
},
{
"id": "4614de3e-b2e4-4954-9567-32f5345a7305",
"name": "Note adhésive10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1424,
-288
],
"parameters": {
"width": 343.2558139534883,
"height": 400,
"content": "## 📧 Step 9B: Send Email\n\n**Setup Instructions:**\n1. Connect SMTP credentials (Gmail, Outlook, etc.)\n2. **IMPORTANT:** Replace these placeholders:\n - `fromEmail`: Your company email\n - `toEmail`: Recipient(s) email\n3. Customize subject line if needed\n\n**Email Features:**\n- Professional HTML template\n- Gradient header\n- Color-coded sections\n- Mobile-responsive design\n"
},
"typeVersion": 1
},
{
"id": "c8166ad6-7729-40c4-a1ac-cc5b8e7d76a9",
"name": "Note adhésive11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1584,
272
],
"parameters": {
"width": 343,
"height": 448,
"content": "## 📁 Step 9C: Upload to Google Drive\n\n**Setup Instructions:**\n1. Connect Google Drive OAuth2 credentials\n2. Select destination folder:\n - Default: Root folder\n - Recommended: Create \"EOD Reports\" folder\n3. Filename format: `EOD_Report_YYYY-MM-DD.txt`\n\n**File Content:**\n- Plain text with ASCII art borders\n- All report sections\n- Timestamp\n\n**Security:** Folder ID is safe to share (no personal data)"
},
"typeVersion": 1
},
{
"id": "8d5f5a2a-c6a7-455c-a570-c4266e64179b",
"name": "Déclencheur du rapport de fin de journée programmé",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-3568,
-112
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 18 * * 1-5"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "745ec334-f971-4a2f-9433-bcd0ae03942a",
"name": "Fusionner toutes les sources de données",
"type": "n8n-nodes-base.merge",
"position": [
-3120,
-112
],
"parameters": {},
"typeVersion": 2.1
},
{
"id": "219dad0b-4101-4203-875f-cfbb3124d9b5",
"name": "Transformer et structurer les données",
"type": "n8n-nodes-base.code",
"position": [
-2896,
-112
],
"parameters": {
"jsCode": "// n8n Code Node - Transform Merged ClickUp + GHL Data & Aggregate\n\nconst transformedItems = [];\n\n// Process each item from the merged input\nfor (const item of $input.all()) {\n const data = item.json;\n \n // Check if this is a ClickUp task (has custom_id, creator, project fields)\n // or a GHL opportunity (has pipelineId, monetaryValue, contactId)\n const isClickUpTask = data.hasOwnProperty('custom_id') && \n data.hasOwnProperty('creator') && \n data.hasOwnProperty('project');\n \n if (isClickUpTask) {\n // Transform ClickUp task to GHL opportunity format\n const transformedItem = {\n // Use ClickUp task ID as the opportunity ID\n id: data.id,\n \n // Use task name as opportunity name\n name: data.name,\n \n // Set default monetary value (you can extract from custom fields if available)\n monetaryValue: extractMonetaryValue(data.custom_fields),\n \n // Map ClickUp project to pipeline ID\n pipelineId: data.project?.id || \"YOUR_PIPELINE_ID\",\n \n // Map ClickUp status to pipeline stage\n pipelineStageId: data.status?.id || null,\n pipelineStageUId: data.status?.id || null,\n \n // Map first assignee ID\n assignedTo: data.assignees?.[0]?.id?.toString() || null,\n \n // Map ClickUp status type to GHL status\n status: mapClickUpStatusToGHL(data.status?.type),\n \n // Source information\n source: \"ClickUp\",\n \n // Timestamps - convert from milliseconds to ISO string\n lastStatusChangeAt: data.date_updated ? new Date(parseInt(data.date_updated)).toISOString() : null,\n lastStageChangeAt: data.date_updated ? new Date(parseInt(data.date_updated)).toISOString() : null,\n createdAt: data.date_created ? new Date(parseInt(data.date_created)).toISOString() : null,\n updatedAt: data.date_updated ? new Date(parseInt(data.date_updated)).toISOString() : null,\n \n // Index version\n indexVersion: 1,\n \n // Use first assignee as contact ID\n contactId: data.assignees?.[0]?.id?.toString() || null,\n \n // Location from team ID\n locationId: data.team_id || \"YOUR_LOCATION_ID\",\n \n // Custom fields\n customFields: data.custom_fields || [],\n \n // Lost reason\n lostReasonId: null,\n \n // Followers from watchers\n followers: data.watchers?.map(w => w.id.toString()) || [],\n \n // Relations - create from assignees\n relations: data.assignees?.map((assignee, index) => ({\n associationId: \"OPPORTUNITIES_CONTACTS_ASSOCIATION\",\n relationId: data.id,\n primary: index === 0,\n objectKey: \"contact\",\n recordId: assignee.id.toString(),\n fullName: assignee.username,\n contactName: assignee.username,\n companyName: data.project?.name || null,\n email: assignee.email,\n phone: null,\n tags: data.tags?.map(t => t.name) || [],\n attributed: null\n })) || [],\n \n // Primary contact from first assignee\n contact: data.assignees?.[0] ? {\n id: data.assignees[0].id.toString(),\n name: data.assignees[0].username,\n companyName: data.project?.name || null,\n email: data.assignees[0].email,\n phone: null,\n tags: data.tags?.map(t => t.name) || [],\n score: []\n } : null,\n \n // Sort fields\n sort: [\n parseInt(data.date_created),\n data.assignees?.[0]?.id?.toString() || \"\"\n ],\n \n // Attributions\n attributions: [{\n utmSessionSource: \"ClickUp\",\n isFirst: true,\n medium: \"integration\"\n }]\n };\n \n transformedItems.push(transformedItem);\n \n } else {\n // This is already a GHL opportunity - pass it through as-is\n transformedItems.push(data);\n }\n}\n\n// Helper function to map ClickUp status types to GHL status\nfunction mapClickUpStatusToGHL(statusType) {\n if (!statusType) return 'open';\n \n const statusMap = {\n 'closed': 'won',\n 'complete': 'won',\n 'done': 'won',\n 'open': 'open',\n 'in progress': 'open',\n 'to do': 'open',\n 'cancelled': 'abandoned',\n 'blocked': 'abandoned',\n 'lost': 'lost'\n };\n \n return statusMap[statusType.toLowerCase()] || 'open';\n}\n\n// Helper function to extract monetary value from custom fields\nfunction extractMonetaryValue(customFields) {\n if (!customFields || customFields.length === 0) return 0;\n \n // Look for common field names that might contain monetary value\n const moneyField = customFields.find(f => \n f.name && (\n f.name.toLowerCase().includes('value') ||\n f.name.toLowerCase().includes('amount') ||\n f.name.toLowerCase().includes('price') ||\n f.name.toLowerCase().includes('deal')\n )\n );\n \n return moneyField?.value || 0;\n}\n\n// AGGREGATION: Combine all transformed items into a single output\n// This ensures the AI Agent receives ONE item with all data\nconst aggregatedOutput = {\n totalItems: transformedItems.length,\n timestamp: new Date().toISOString(),\n opportunities: transformedItems,\n summary: {\n totalOpportunities: transformedItems.length,\n byStatus: {},\n totalMonetaryValue: 0,\n bySource: {}\n }\n};\n\n// Calculate summary statistics\ntransformedItems.forEach(item => {\n // Count by status\n aggregatedOutput.summary.byStatus[item.status] = \n (aggregatedOutput.summary.byStatus[item.status] || 0) + 1;\n \n // Sum monetary values\n aggregatedOutput.summary.totalMonetaryValue += item.monetaryValue || 0;\n \n // Count by source\n const source = item.source || 'GHL';\n aggregatedOutput.summary.bySource[source] = \n (aggregatedOutput.summary.bySource[source] || 0) + 1;\n});\n\n// Return single aggregated item for AI Agent\nreturn [{ json: aggregatedOutput }];"
},
"typeVersion": 2
},
{
"id": "1d93fe28-b9f0-4ff1-a169-542dae1f1783",
"name": "Formater les rapports pour la distribution",
"type": "n8n-nodes-base.code",
"position": [
-2208,
-112
],
"parameters": {
"jsCode": "// Extract the output data from your input format\nconst inputData = $input.first().json;\nconst output = inputData.output;\n\n// Create routing objects based on your end-of-day report structure\nconst slackReport = {\n type: 'slack',\n title: output.title,\n summary: output.briefSummary,\n wins: output.wins,\n keyMetrics: output.keyMetrics,\n blockers: output.blockers,\n actionItems: output.actionItems,\n timestamp: new Date().toISOString(),\n icon: '📊'\n};\n\nconst emailReport = {\n type: 'email',\n subject: output.title,\n body: {\n title: output.title,\n briefSummary: output.briefSummary,\n wins: output.wins,\n keyMetrics: output.keyMetrics,\n blockers: output.blockers,\n actionItems: output.actionItems\n },\n timestamp: new Date().toISOString()\n};\n\nconst googleDriveReport = {\n type: 'google_drive',\n filename: `EOD_Report_${new Date().toISOString().split('T')[0]}.txt`,\n content: `\n═══════════════════════════════════════════════════════════════════\n${output.title}\n═══════════════════════════════════════════════════════════════════\n\n📋 BRIEF SUMMARY\n─────────────────────────────────────────────────────────────────\n${output.briefSummary}\n\n✅ WINS\n─────────────────────────────────────────────────────────────────\n${output.wins}\n\n📊 KEY METRICS\n─────────────────────────────────────────────────────────────────\n${output.keyMetrics}\n\n⚠️ BLOCKERS\n─────────────────────────────────────────────────────────────────\n${output.blockers}\n\n🎯 ACTION ITEMS\n─────────────────────────────────────────────────────────────────\n${output.actionItems}\n\nGenerated: ${new Date().toISOString()}\n═══════════════════════════════════════════════════════════════════\n `,\n timestamp: new Date().toISOString(),\n mimeType: 'text/plain'\n};\n\n// Return all three routing objects\nreturn [\n { json: slackReport },\n { json: emailReport },\n { json: googleDriveReport }\n];"
},
"typeVersion": 2
},
{
"id": "77d78b5e-49f6-4779-8828-344332a262ee",
"name": "Router vers Slack",
"type": "n8n-nodes-base.if",
"position": [
-1984,
-304
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "334e8803-cf37-4a69-9a74-dc77d4541f8c",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "slack"
}
]
}
},
"typeVersion": 2
},
{
"id": "7ad743bb-a433-429c-a894-3dfef643ce2d",
"name": "Router vers Email",
"type": "n8n-nodes-base.if",
"position": [
-1984,
-112
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8b96c805-abe1-4588-a043-53c4ffeee9f3",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "email"
}
]
}
},
"typeVersion": 2
},
{
"id": "736cd539-135a-40e9-92a3-f2cc1d17e7e8",
"name": "Router vers le Drive Google",
"type": "n8n-nodes-base.if",
"position": [
-1984,
96
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a78ce4a7-5624-4f2b-9606-3eb64119a671",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "google_drive"
}
]
}
},
"typeVersion": 2
},
{
"id": "9275db81-48b1-493b-8bf9-e581e814a33f",
"name": "Envoyer le message Slack",
"type": "n8n-nodes-base.slack",
"position": [
-1760,
-320
],
"webhookId": "8be74d53-9687-40f1-a84b-09a85a145aac",
"parameters": {
"text": "=*Title:*\n{{ $json.title }} \n\n*Summary:*\n{{ $json.summary }} \n\n*Wins:*\n{{ $json.wins }} \n\n*Key Metrics:*\n{{ $json.keyMetrics }} \n\n*Blockers:*\n{{ $json.blockers }} \n\n*ActionItems:*\n{{ $json.actionItems }}\n\n",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_CHANNEL_ID",
"cachedResultName": "Select your channel"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"id": "rNqvWj9TfChPVRYY",
"name": "Slack account vivek"
}
},
"typeVersion": 2.1
},
{
"id": "447a40d6-4f69-4b6c-a239-62c595941a56",
"name": "Envoyer le rapport par Email",
"type": "n8n-nodes-base.emailSend",
"position": [
-1760,
-128
],
"webhookId": "8f1199fc-1c63-4d9f-b5af-c632cf55e1e0",
"parameters": {
"html": "=<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <style>\n body {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n background-color: #f4f4f4;\n margin: 0;\n padding: 0;\n }\n .container {\n max-width: 700px;\n margin: 0 auto;\n background-color: #ffffff;\n padding: 0;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 30px;\n text-align: center;\n }\n .header h1 {\n margin: 0;\n font-size: 28px;\n font-weight: 600;\n }\n .header p {\n margin: 8px 0 0 0;\n font-size: 14px;\n opacity: 0.9;\n }\n .content {\n padding: 30px;\n }\n .section {\n margin-bottom: 25px;\n }\n .section-title {\n font-size: 16px;\n font-weight: 700;\n color: #667eea;\n margin: 0 0 15px 0;\n padding-bottom: 10px;\n border-bottom: 2px solid #f0f0f0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .icon {\n font-size: 18px;\n }\n .summary-text {\n background-color: #f9f9f9;\n padding: 15px;\n border-left: 4px solid #667eea;\n border-radius: 4px;\n font-size: 14px;\n line-height: 1.7;\n }\n .wins-box {\n background-color: #f0fdf4;\n padding: 15px;\n border-left: 4px solid #10b981;\n border-radius: 4px;\n font-size: 14px;\n line-height: 1.7;\n }\n .blockers-box {\n background-color: #fef3c7;\n padding: 15px;\n border-left: 4px solid #f59e0b;\n border-radius: 4px;\n font-size: 14px;\n line-height: 1.7;\n }\n .metrics-text {\n background-color: #f9f9f9;\n padding: 15px;\n border-left: 4px solid #667eea;\n border-radius: 4px;\n font-size: 14px;\n line-height: 1.7;\n }\n .action-items {\n background-color: #f9f9f9;\n padding: 15px;\n border-left: 4px solid #667eea;\n border-radius: 4px;\n font-size: 14px;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n .footer {\n background-color: #f9f9f9;\n padding: 20px;\n text-align: center;\n font-size: 12px;\n color: #999;\n border-top: 1px solid #e0e0e0;\n }\n .footer p {\n margin: 5px 0;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>📊 {{ $json.body.title }}</h1>\n <p>Generated on {{ $json.timestamp }}</p>\n </div>\n <div class=\"content\">\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"icon\">📋</span>\n Brief Summary\n </div>\n <div class=\"summary-text\">\n {{ $json.body.briefSummary }}\n </div>\n </div>\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"icon\">✅</span>\n Wins\n </div>\n <div class=\"wins-box\">\n {{ $json.body.wins }}\n </div>\n </div>\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"icon\">📊</span>\n Key Metrics\n </div>\n <div class=\"metrics-text\">\n {{ $json.body.keyMetrics }}\n </div>\n </div>\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"icon\">⚠️</span>\n Blockers\n </div>\n <div class=\"blockers-box\">\n {{ $json.body.blockers }}\n </div>\n </div>\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"icon\">🎯</span>\n Action Items\n </div>\n <div class=\"action-items\">\n {{ $json.body.actionItems }}\n </div>\n </div>\n </div>\n <div class=\"footer\">\n <p><strong>End-of-Day Summary Report</strong></p>\n <p>This is an automated report generated by N8N Workflow</p>\n <p>Do not reply to this email</p>\n </div>\n </div>\n</body>\n</html>",
"options": {},
"subject": "={{ $json.subject }}",
"toEmail": "team@yourcompany.com",
"fromEmail": "noreply@yourcompany.com"
},
"credentials": {
"smtp": {
"id": "gJdU446NGTfpXScn",
"name": "SMTP account 2"
}
},
"typeVersion": 2.1
},
{
"id": "a2dcf9df-2d0c-4aa3-ab95-315b3ba5a617",
"name": "Téléverser le rapport sur le Drive Google",
"type": "n8n-nodes-base.googleDrive",
"position": [
-1536,
80
],
"parameters": {
"name": "={{ $('Route to Google Drive').item.json.filename }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"typeVersion": 3
},
{
"id": "53b786aa-1dfb-428c-b4d7-902c4d65b82b",
"name": "Récupérer les opportunités gagnées GHL",
"type": "n8n-nodes-base.highLevel",
"position": [
-3344,
-16
],
"parameters": {
"limit": 100,
"filters": {
"status": "won"
},
"resource": "opportunity",
"operation": "getAll",
"requestOptions": {}
},
"typeVersion": 2
},
{
"id": "37bf0171-f463-42bf-a7bf-3664fef59f3f",
"name": "Analyseur de sortie structurée",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-2416,
128
],
"parameters": {
"jsonSchemaExample": "{\n \"title\": \"\",\n \"briefSummary\": \"\",\n \"wins\": \"\",\n \"keyMetrics\": \"\",\n \"blockers\": \"\",\n \"actionItems\":\"\"\n}\n"
},
"typeVersion": 1.3
},
{
"id": "0471b16d-770a-479e-90a6-44931fa8a62d",
"name": "Modèle de chat Azure OpenAI",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
-2672,
128
],
"parameters": {
"model": "gpt-4o",
"options": {}
},
"typeVersion": 1
},
{
"id": "63437c56-ea42-4b38-a6f9-9fb1d37e1027",
"name": "Mémoire simple",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
-2544,
128
],
"parameters": {
"sessionKey": "\"eod_report_generator\"",
"sessionIdType": "customKey",
"contextWindowLength": 7
},
"typeVersion": 1.3
},
{
"id": "65dba1ea-9525-48b3-ba77-47eef856b341",
"name": "Agent IA : Générer le rapport de fin de journée",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-2624,
-112
],
"parameters": {
"text": "=You are given the following aggregated End-of-Day data from ClickUp (task management) and GHL (sales pipeline):\n\n{{ JSON.stringify($json.opportunities || $json, null, 2) }}\n\nPlease analyze this data and generate a structured End-of-Day (EOD) summary report.\n\n**Analysis Guidelines:**\n\n**For ClickUp Tasks:**\n- Count tasks by status (complete, in progress, blocked, etc.)\n- Calculate total time spent across all tasks\n- Identify completed tasks as wins\n- Flag blocked or delayed tasks as blockers\n- Note team members with completed work\n\n**For GHL Opportunities:**\n- Count opportunities by status (won, open, lost, abandoned)\n- Sum total monetary value of won deals\n- Identify new opportunities created today\n- Note high-value deals in progress\n- Track conversion rates if applicable\n",
"options": {
"systemMessage": "=You are an expert executive assistant AI specialized in creating comprehensive End-of-Day (EOD) summary reports.\n\nYour task is to analyze aggregated data from two systems:\n1. **ClickUp Tasks**: Project management tasks with status, assignees, time tracking, and completion details\n2. **GHL Opportunities**: Sales pipeline data with deals, monetary values, stages, and contact information\n\n**Your responsibilities:**\n- Analyze the combined data from both systems\n- Extract key metrics, wins, blockers, and action items\n- Identify patterns and trends across tasks and opportunities\n- Highlight team member contributions and achievements\n- Flag any issues or blockers that need attention\n- Provide actionable next steps\n\n**Output Requirements:**\n- Structure your response as valid JSON matching the provided schema\n- Be concise, professional, and actionable\n- Use specific numbers and metrics from the data\n- Focus on insights, not just data repetition\n- Ensure all arrays contain strings, not objects\n- Keep each item brief (1-2 sentences maximum)\n\n**Data Structure:**\n- ClickUp tasks will have fields like: id, name, status, assignees, time_spent, date_created, date_updated, project\n- GHL opportunities will have fields like: id, name, monetaryValue, status, pipelineStageId, contact, source\n\nGenerate a comprehensive but concise EOD report based on this combined dataset."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.1
},
{
"id": "46add9d4-fd38-4d52-aeac-22b47796b6d2",
"name": "Récupérer les tâches ClickUp du jour",
"type": "n8n-nodes-base.clickUp",
"position": [
-3344,
-208
],
"parameters": {
"list": "YOUR_LIST_ID",
"team": "YOUR_TEAM_ID",
"space": "YOUR_SPACE_ID",
"folder": "YOUR_FOLDER_ID",
"filters": {
"subtasks": true,
"dueDateGt": "={{ $today.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}",
"dueDateLt": "={{ $today.toFormat('yyyy-MM-dd') }}"
},
"operation": "getAll",
"authentication": "oAuth2"
},
"typeVersion": 1
},
{
"id": "4d12ff96-2f31-4984-8762-8b54519843ac",
"name": "Convertir en fichier",
"type": "n8n-nodes-base.convertToFile",
"position": [
-1760,
80
],
"parameters": {
"options": {},
"operation": "toJson"
},
"typeVersion": 1.1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "2635cb23-0e0e-4ee1-885e-5ff809150414",
"connections": {
"63437c56-ea42-4b38-a6f9-9fb1d37e1027": {
"ai_memory": [
[
{
"node": "65dba1ea-9525-48b3-ba77-47eef856b341",
"type": "ai_memory",
"index": 0
}
]
]
},
"7ad743bb-a433-429c-a894-3dfef643ce2d": {
"main": [
[
{
"node": "447a40d6-4f69-4b6c-a239-62c595941a56",
"type": "main",
"index": 0
}
]
]
},
"77d78b5e-49f6-4779-8828-344332a262ee": {
"main": [
[
{
"node": "9275db81-48b1-493b-8bf9-e581e814a33f",
"type": "main",
"index": 0
}
]
]
},
"4d12ff96-2f31-4984-8762-8b54519843ac": {
"main": [
[
{
"node": "a2dcf9df-2d0c-4aa3-ab95-315b3ba5a617",
"type": "main",
"index": 0
}
]
]
},
"736cd539-135a-40e9-92a3-f2cc1d17e7e8": {
"main": [
[
{
"node": "4d12ff96-2f31-4984-8762-8b54519843ac",
"type": "main",
"index": 0
}
]
]
},
"745ec334-f971-4a2f-9433-bcd0ae03942a": {
"main": [
[
{
"node": "219dad0b-4101-4203-875f-cfbb3124d9b5",
"type": "main",
"index": 0
}
]
]
},
"0471b16d-770a-479e-90a6-44931fa8a62d": {
"ai_languageModel": [
[
{
"node": "65dba1ea-9525-48b3-ba77-47eef856b341",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"37bf0171-f463-42bf-a7bf-3664fef59f3f": {
"ai_outputParser": [
[
{
"node": "65dba1ea-9525-48b3-ba77-47eef856b341",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"53b786aa-1dfb-428c-b4d7-902c4d65b82b": {
"main": [
[
{
"node": "745ec334-f971-4a2f-9433-bcd0ae03942a",
"type": "main",
"index": 1
}
]
]
},
"8d5f5a2a-c6a7-455c-a570-c4266e64179b": {
"main": [
[
{
"node": "53b786aa-1dfb-428c-b4d7-902c4d65b82b",
"type": "main",
"index": 0
},
{
"node": "46add9d4-fd38-4d52-aeac-22b47796b6d2",
"type": "main",
"index": 0
}
]
]
},
"219dad0b-4101-4203-875f-cfbb3124d9b5": {
"main": [
[
{
"node": "65dba1ea-9525-48b3-ba77-47eef856b341",
"type": "main",
"index": 0
}
]
]
},
"65dba1ea-9525-48b3-ba77-47eef856b341": {
"main": [
[
{
"node": "1d93fe28-b9f0-4ff1-a169-542dae1f1783",
"type": "main",
"index": 0
}
]
]
},
"46add9d4-fd38-4d52-aeac-22b47796b6d2": {
"main": [
[
{
"node": "745ec334-f971-4a2f-9433-bcd0ae03942a",
"type": "main",
"index": 0
}
]
]
},
"1d93fe28-b9f0-4ff1-a169-542dae1f1783": {
"main": [
[
{
"node": "77d78b5e-49f6-4779-8828-344332a262ee",
"type": "main",
"index": 0
},
{
"node": "7ad743bb-a433-429c-a894-3dfef643ce2d",
"type": "main",
"index": 0
},
{
"node": "736cd539-135a-40e9-92a3-f2cc1d17e7e8",
"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é ?
Avancé
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
Rahul Joshi
@rahul08Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.
Partager ce workflow