Préparation automatisée de réunion
Ceci est unAI Summarization, Multimodal AIworkflow d'automatisation du domainecontenant 39 nœuds.Utilise principalement des nœuds comme If, Set, Code, Merge, Slack. Préparation automatique de réunions du calendrier vers Slack via Attio CRM avec GPT-5 et Gemini Research
- •Token Bot Slack ou URL Webhook
- •Compte Google et informations d'identification Gmail API
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
Nœuds utilisés (39)
Catégorie
{
"meta": {
"instanceId": "2b4a3d81eafa60e4b2dfa202fdf88e491b785e2a2a6ca005b137d831a6faa7c0",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "47c89bf1-e539-438a-a42a-fbf7a7f56a95",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1248,
832
],
"parameters": {
"color": 4,
"width": 784,
"height": 896,
"content": "## AI-Powered Meeting Preparation Automation\n\nThis workflow automatically researches your daily meetings and creates comprehensive briefing documents.\n\n### How it works\n1. **Triggers daily** at 6 AM on weekdays\n2. **Fetches calendar events** for today from Google Calendar\n3. **Filters for external meetings** (meetings with attendees outside your organization)\n4. **Researches each attendee** using:\n - Attio CRM for contact history and notes\n - Gmail for email correspondence\n - Google Calendar for past meetings\n - Perplexity for company/person research when needed\n5. **Generates meeting briefs** with key context, objectives, and talking points\n6. **Sends formatted summary** to Slack channel\n\n### Requirements\n- **Google Calendar** - OAuth2 credentials\n- **Gmail** - OAuth2 credentials \n- **Slack** - Bot token with channel access\n- **Attio CRM** - API bearer token\n- **OpenRouter** - API key for AI models\n- **Perplexity** - API key for research\n\n### Setup Instructions\n1. Configure all credential connections\n2. Update calendar email in \"Fetch Today's Calendar Events\" node\n3. Set your Slack channel ID in both Slack nodes\n4. Adjust OpenRouter models in AI nodes based on your preferences\n5. Test with a day that has meetings\n\n### Important Notes\n- **OpenRouter Models**: This template uses various models (GPT-5, Gemini 2.5 Flash). Adjust model names in all OpenRouter nodes based on availability and your preferences\n- **Costs apply** for AI model usage"
},
"typeVersion": 1
},
{
"id": "3433401d-acb7-4024-82b0-a0a58cc446a3",
"name": "Note adhésive 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
1136
],
"parameters": {
"color": 7,
"width": 200,
"height": 120,
"content": "### Daily Schedule Trigger\n\nRuns Monday-Friday at 6:00 AM\n\nCron: `0 6 * * 1-5`"
},
"typeVersion": 1
},
{
"id": "f8946089-bb50-4c22-a478-7af2c5063746",
"name": "Déclencheur Quotidien en Semaine",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-272,
976
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 6 * * 1-5"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "6b95d889-9211-41f8-bcef-08ceae8b3a44",
"name": "Note adhésive 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
1152
],
"parameters": {
"color": 7,
"width": 236,
"height": 168,
"content": "### Calendar Integration\n\nFetches today's events and filters for external meetings\n\n**Important**: Update the calendar email to your own"
},
"typeVersion": 1
},
{
"id": "9383e71f-5295-4a7d-b77f-721b20584c73",
"name": "Récupérer les Événements du Calendrier du Jour",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-48,
976
],
"parameters": {
"options": {},
"timeMax": "={{ $today.plus({ day: 1 }) }}",
"timeMin": "={{ $today }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "YOUR_EMAIL@example.com",
"cachedResultName": "Your Calendar"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "6xS7duivt7JLMnVF",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "ed5d80d8-0a1a-4a95-9abb-b6c365b304ae",
"name": "Filtrer uniquement les Réunions Externes",
"type": "n8n-nodes-base.filter",
"notes": "Keep only events with attendees (external meetings)",
"position": [
176,
976
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "filter-external",
"operator": {
"type": "array",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.attendees }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "19d444c5-a678-4a50-97b9-53e7750b00ee",
"name": "Vérifier les Réunions Externes",
"type": "n8n-nodes-base.if",
"position": [
400,
976
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-meetings",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.id }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d8cbaffb-b551-4cbb-bc2b-e04f86718d2f",
"name": "Envoyer un Message 'Aucune Réunion'",
"type": "n8n-nodes-base.slack",
"position": [
624,
1072
],
"webhookId": "7b03e845-9984-46ce-92e8-9338a54b5362",
"parameters": {
"text": "Good morning! No external meetings scheduled for today. Enjoy your focus time!",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-channel"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "I1AdBji1W6jc0rm7",
"name": "Slack account"
}
},
"typeVersion": 2.3
},
{
"id": "0461c547-f1da-4872-9141-abfb63482e99",
"name": "Note adhésive 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
832,
640
],
"parameters": {
"color": 7,
"width": 920,
"height": 1056,
"content": "### AI Meeting Research\n\nWhen meetings are found, this agent:\n- Searches CRM for attendee information\n- Reviews email history\n- Checks past calendar interactions\n- Uses Perplexity for external research\n- Generates comprehensive meeting briefs\n\n**Note**: Adjust OpenRouter models as needed"
},
"typeVersion": 1
},
{
"id": "ba5434a0-0365-427c-8dff-97d98db9fa70",
"name": "Séparer les Réunions Individuelles",
"type": "n8n-nodes-base.splitOut",
"position": [
624,
880
],
"parameters": {
"include": "allOtherFields",
"options": {},
"fieldToSplitOut": "id"
},
"typeVersion": 1
},
{
"id": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"name": "Agent IA de Recherche de Réunion",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1104,
880
],
"parameters": {
"text": "=You are a meeting preparation assistant. Analyze this meeting and prepare comprehensive research:\n\nMeeting Details:\n- Summary: {{ $json.summary }}\n- Start: {{ $json.start.dateTime }}\n- End: {{ $json.end.dateTime }}\n- Attendees: {{ $json.attendees.filter(a => a.email !== 'YOUR_EMAIL@example.com').map(a => a.email).join(', ') }}\n\nYour tasks:\n1. Research each attendee using the available tools (Attio CRM to find people, list notes, and get their notes. And Gmail history and past calendar meetings)\n\nIf there has been no interaction in the past, you can use Perplexity to get a better sense of the organization and the person. This isn't always necessary if I have met or corresponded with them to a good extent before. If it is first time meeting or we have little comms, then use perplexity.\n\n2. Identify the company they work for and research the company\n3. Find any previous interactions or context\n4. Prepare relevant key talking points and questions, primarily based on where our last interaction left off\n5. Identify potential goals and outcomes for this meeting\n\nAnalyze the meeting preparation data and create a concise one-page dossier. Focus on:\n1. Essential attendee information only\n2. Most recent and relevant interactions\n3. 4-5 specific talking points based on where the last conversation ended\n4. Clear, actionable next steps\nKeep descriptions brief and bullet points concise.",
"options": {
"systemMessage": "=You are an expert meeting preparation assistant with access to CRM, email, calendar, and company research tools. Your goal is to help the user be fully prepared for their upcoming meetings by providing comprehensive research and context."
},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2
},
{
"id": "e3e3d48b-a1d7-4542-89fe-fb18efb38dbb",
"name": "Outil de Recherche d'Historique du Calendrier",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
960,
1232
],
"parameters": {
"options": {
"query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query', ``, 'string') }}"
},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "YOUR_EMAIL@example.com",
"cachedResultName": "Your Calendar"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "6xS7duivt7JLMnVF",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "be879b39-6d7c-4857-ab64-dae2570e1e99",
"name": "Outil de Recherche d'Historique Gmail",
"type": "n8n-nodes-base.gmailTool",
"position": [
1104,
1200
],
"webhookId": "d8202913-d1a2-44c8-aed2-e728f6275348",
"parameters": {
"limit": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Limit', ``, 'number') }}",
"simple": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Simplify', ``, 'boolean') }}",
"filters": {
"q": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search', ``, 'string') }}"
},
"options": {},
"operation": "getAll"
},
"credentials": {
"gmailOAuth2": {
"id": "b9yf4q17pTJEgqEE",
"name": "MO Gmail"
}
},
"typeVersion": 2.1
},
{
"id": "5283bd0a-1a60-4038-aec1-4ebdf727dcb5",
"name": "Modèle IA Principal",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
912,
1056
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {
"maxRetries": 3
}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "c38c28bf-d2f7-405e-898e-2c46b3a4139f",
"name": "Modèle IA Secondaire",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1936,
1376
],
"parameters": {
"model": "openai/gpt-5",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "0980b927-4f40-462e-a0a7-3b6bacc468f9",
"name": "Outil de Recherche Perplexity",
"type": "n8n-nodes-base.perplexityTool",
"position": [
1248,
1248
],
"parameters": {
"model": "sonar-pro",
"options": {},
"messages": {
"message": [
{
"content": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('message0_Text', ``, 'string') }}"
}
]
},
"requestOptions": {}
},
"credentials": {
"perplexityApi": {
"id": "Lp8s8pOa5dCRCcUm",
"name": "Perplexity account"
}
},
"typeVersion": 1
},
{
"id": "68a07c67-b348-4b3d-b17e-f6c740a4fd26",
"name": "Modèle IA de Rechange",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
848,
1280
],
"parameters": {
"model": "openai/gpt-5",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "b1fc1ba5-37e9-4835-a9ce-7f8de724e24f",
"name": "Analyseur de Données de Réunion",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1472,
1280
],
"parameters": {
"autoFix": true,
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"meetingTitle\": {\n \"type\": \"string\",\n \"description\": \"Brief meeting title format: 'Person1 <> Person2/Company'\"\n },\n \"meetingDateTime\": {\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Date in format: Wednesday, August 27, 2025\"\n },\n \"time\": {\n \"type\": \"string\",\n \"description\": \"Time range with timezone: 10:00 AM - 10:30 AM PDT\"\n }\n },\n \"required\": [\"date\", \"time\"]\n },\n \"attendees\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"email\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\",\n \"description\": \"Their title and company\"\n },\n \"lastInteraction\": {\n \"type\": \"string\",\n \"description\": \"Date and context of last interaction, or 'First Meeting'\"\n },\n \"keyPoints\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"3-4 key background points\",\n \"maxItems\": 4\n }\n },\n \"required\": [\"name\", \"email\", \"role\"]\n }\n },\n \"companyOverview\": {\n \"type\": \"string\",\n \"description\": \"2-3 sentence company overview\"\n },\n \"relationshipContext\": {\n \"type\": \"string\",\n \"description\": \"Brief context of relationship history and how you connected\"\n },\n \"meetingObjective\": {\n \"type\": \"string\",\n \"description\": \"Primary goal for this meeting in one sentence\"\n },\n \"discussionTopics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"4-5 key talking points based on last interaction\",\n \"minItems\": 3,\n \"maxItems\": 5\n },\n \"potentialOutcomes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"2-3 potential next steps\",\n \"maxItems\": 3\n }\n },\n \"required\": [\n \"meetingTitle\",\n \"meetingDateTime\",\n \"attendees\",\n \"meetingObjective\",\n \"discussionTopics\"\n ]\n}"
},
"typeVersion": 1.3
},
{
"id": "ccd2cc06-14e9-46ad-9a57-ee0cefcc7217",
"name": "Modèle IA d'Analyse",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1408,
1488
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "316d6a09-3cbb-465d-86f0-e5dd4ced4477",
"name": "Outil Attio List Notes",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1056,
1520
],
"parameters": {
"url": "https://api.attio.com/v2/notes",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"queryParameters": {
"parameters": [
{
"name": "parent_object",
"value": "people"
},
{
"name": "parent_record_id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters1_Value', `Record ID of person found in attio_search_people`, 'string') }}"
}
]
},
"toolDescription": "Use this to list out Notes related to the records you find using attio_search_people"
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "795dbcbf-b6c5-4347-8999-b6230ca14554",
"name": "Outil Attio Search People",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1360,
1168
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records/query",
"method": "POST",
"options": {},
"jsonBody": "={\n \"filter\": {\n \"email_addresses\": \"{{ $fromAI(\"single_email_address\", \"Email address of individual to find in the CRM\", \"string\") }}\"\n },\n \"limit\": 1,\n \"offset\": 0\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"toolDescription": "Search my CRM for information on a single person",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "e425b9f4-d99d-416c-bbdd-9d37f34e870d",
"name": "Outil Attio Read Notes",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1200,
1520
],
"parameters": {
"url": "=https://api.attio.com/v2/notes/{{ $fromAI(\"note_id\", \"the A UUID which identifies the note from attio_list_note\") }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"toolDescription": "Use this to get contents of a Note related to the Notes you find using attio_list_note"
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "5fcf9176-4643-46fc-897a-24f281450699",
"name": "Formater le Compte-rendu de Réunion",
"type": "n8n-nodes-base.code",
"position": [
1584,
880
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Format structured output into Attio markdown\nconst data = $json.output;\n\n// Helper function to format attendees\nconst formatAttendees = (attendees) => {\n return attendees.map(a => {\n let attendeeBlock = `**${a.name}** (${a.email})\\n*${a.role}*\\n`;\n if (a.lastInteraction) {\n attendeeBlock += `Last interaction: ${a.lastInteraction}\\n`;\n }\n if (a.keyPoints && a.keyPoints.length > 0) {\n attendeeBlock += a.keyPoints.map(point => `• ${point}`).join('\\n');\n }\n return attendeeBlock;\n }).join('\\n\\n');\n};\n\n// Build the markdown document\nconst markdown = `# ${data.meetingTitle}\n\n**${data.meetingDateTime.date}** \n**${data.meetingDateTime.time}**\n\n---\n\n## Attendees\n\n${formatAttendees(data.attendees)}\n\n## Context\n\n${data.companyOverview ? `**Company:** ${data.companyOverview}\\n\\n` : ''}${data.relationshipContext ? `**Relationship:** ${data.relationshipContext}` : ''}\n\n## Meeting Objective\n\n**${data.meetingObjective}**\n\n## Discussion Topics\n\n${(data.discussionTopics || []).map((topic, i) => `${i + 1}. ${topic}`).join('\\n')}\n\n## Potential Next Steps\n\n${(data.potentialOutcomes || []).map(outcome => `→ ${outcome}`).join('\\n')}`;\n\nreturn {\n markdown: markdown,\n structured: data\n};"
},
"typeVersion": 2
},
{
"id": "4d4c2ab2-f5c6-4659-ab1f-4d3570c889ae",
"name": "Note adhésive 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
576
],
"parameters": {
"color": 7,
"width": 1584,
"height": 468,
"content": "### CRM Integration\n\nThe workflow includes these Attio CRM integration points:\n- Search for people by email\n- Create person records if missing\n- List existing notes\n- Read note contents\n- Create new meeting prep notes\n\nRequires Attio API bearer token"
},
"typeVersion": 1
},
{
"id": "0f98c98c-15fb-4849-8459-74e2488ab563",
"name": "Filtrer les Participants Externes",
"type": "n8n-nodes-base.set",
"position": [
1920,
784
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "22f8e8d1-b14f-47f5-ab45-4cfad5d27bbc",
"name": "attendees",
"type": "array",
"value": "={{ $('Split Individual Meetings').item.json.attendees.filter(a => a.email !== 'YOUR_EMAIL@example.com') }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f011a1fb-e804-4078-8dba-09ce75b41e01",
"name": "Séparer les Participants Individuels",
"type": "n8n-nodes-base.splitOut",
"position": [
2208,
784
],
"parameters": {
"include": "allOtherFields",
"options": {},
"fieldToSplitOut": "attendees"
},
"typeVersion": 1
},
{
"id": "aab6d0d7-8936-42da-8515-100cc336587f",
"name": "Trouver une Personne dans le CRM",
"type": "n8n-nodes-base.httpRequest",
"position": [
2704,
784
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records/query",
"method": "POST",
"options": {},
"jsonBody": "={\n \"filter\": {\n \"email_addresses\": \"{{ $json.attendees.email }}\"\n },\n \"limit\": 1,\n \"offset\": 0\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "b0d83ab6-d2a5-49c1-9edb-4454ed81e796",
"name": "Vérifier si la Personne Existe dans le CRM",
"type": "n8n-nodes-base.if",
"position": [
2928,
784
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "eef23392-13a0-44e9-aa40-1d086dd245ac",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.data[0].id.record_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c7d63acc-ef54-474e-bd16-9f1834c84dca",
"name": "Créer un Nouvel Enregistrement de Personne",
"type": "n8n-nodes-base.httpRequest",
"position": [
3152,
848
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records",
"method": "POST",
"options": {},
"jsonBody": "={\n \"data\": {\n \"values\": {\n \"email_addresses\": [\n {\n \"email_address\": \"{{ $json.attendees.email }}\"\n }\n ]\n }\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"name": "Combiner les Enregistrements de Personnes",
"type": "n8n-nodes-base.merge",
"position": [
3376,
784
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "3a01bc50-a7e7-4792-8654-b52087a43c1b",
"name": "Créer une Note de Préparation de Réunion",
"type": "n8n-nodes-base.httpRequest",
"position": [
3808,
784
],
"parameters": {
"url": "https://api.attio.com/v2/notes",
"method": "POST",
"options": {},
"jsonBody": "={\n \"data\": {\n \"parent_object\": \"people\",\n \"parent_record_id\": \"{{ $json.data[0].id.record_id }}\",\n \"title\": \"Meeting Prep\",\n \"content\": \"{{ JSON.stringify($('Format Meeting Brief').item.json.markdown).slice(1,-1) }}\",\n \"format\": \"markdown\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "7a65b970-c858-40bf-9021-a77c7937c6ab",
"name": "Combiner Tous les Comptes-rendus de Réunion",
"type": "n8n-nodes-base.aggregate",
"position": [
1920,
976
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "markdown"
}
]
}
},
"typeVersion": 1
},
{
"id": "0c04c553-a2a0-4194-bef6-eafd36452a11",
"name": "Note adhésive 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2688,
1440
],
"parameters": {
"color": 7,
"width": 388,
"height": 256,
"content": "### Slack Integration\n\nFinal step sends formatted meeting briefs to Slack:\n- Rich Block Kit formatting\n- Includes meeting times, objectives, and key context\n- Sends summary of all meetings for the day\n\n**Important**: Update channel ID to your own"
},
"typeVersion": 1
},
{
"id": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"name": "Optimiseur de Compte-rendu de Réunion",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2144,
1104
],
"parameters": {
"text": "=You are a meeting brief optimizer. You will receive multiple meeting preparations separated by markdown headers.\n\nInput contains {{ $json.markdown.length }} meetings to process.\n\nHere are ALL the meetings:\n{{ $json.markdown.join('\\n\\n---NEXT MEETING---\\n\\n') }}\n\nCreate a brief for EACH meeting you find above. Each meeting starts with a # header containing names.\n\nFor EACH meeting, extract:\n1. Meeting title - Keep it short and professional\n2. Meeting time - Already in PST, just extract it\n3. Purpose - Why this meeting matters NOW (2-3 sentences max)\n4. Key context - The 1-2 most critical facts about this person/company\n5. Action - The ONE main goal you must accomplish\n6. Watch for - A specific signal, question to ask, or opportunity to identify\n\nNote:\n- Keep writing tone clear and concise. Focus on essential information.\n- Order your meetings in your output from earliest to latest in the day.\n\nImportant: Return an array with one brief object for each meeting found.",
"options": {},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "dcd9ae8d-7a65-4c52-a41d-675fe1282b4a",
"name": "Modèle IA d'Optimisation de Compte-rendu",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
2016,
1616
],
"parameters": {
"model": "openai/gpt-5-mini",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "465e5ceb-d79f-4743-8a0c-b5fc843f6c73",
"name": "Analyseur de Structure de Compte-rendu",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2272,
1360
],
"parameters": {
"autoFix": true,
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"meetings\": {\n \"type\": \"array\",\n \"description\": \"Array of meeting briefs, one for each meeting\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"meetingTitle\": {\n \"type\": \"string\",\n \"description\": \"Brief professional title: 'Name (Company) - Topic' format\"\n },\n \"meetingTimePST\": {\n \"type\": \"string\",\n \"description\": \"Meeting time in PST format: 'Day, Month DD @ HH:MM AM/PM PST'\"\n },\n \"purpose\": {\n \"type\": \"string\",\n \"description\": \"2-3 sentences explaining why this meeting matters right now\"\n },\n \"keyContext\": {\n \"type\": \"string\",\n \"description\": \"1-2 most critical facts that will influence the conversation\"\n },\n \"action\": {\n \"type\": \"string\",\n \"description\": \"The single most important outcome to achieve\"\n },\n \"watchFor\": {\n \"type\": \"string\",\n \"description\": \"One specific thing to observe or ask about\"\n }\n },\n \"required\": [\n \"meetingTitle\",\n \"meetingTimePST\",\n \"purpose\",\n \"keyContext\",\n \"action\",\n \"watchFor\"\n ]\n }\n }\n },\n \"required\": [\"meetings\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "bd04e88e-16a8-43f9-af73-fc8430fcbc63",
"name": "Modèle IA d'Analyse de Compte-rendu",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
2352,
1584
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "7c9ffbe0-9905-406e-92fa-7d43cdb71ef4",
"name": "Formater le Message Slack Block Kit",
"type": "n8n-nodes-base.code",
"notes": "Converts AI Agent output to Slack Block Kit format",
"position": [
2608,
1232
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Format meeting summaries for Slack Block Kit\nconst data = $json.output || $json;\nconst meetings = data.meetings || data;\n\n// Helper to truncate text to avoid Slack's block limits\nconst truncateText = (text, maxLength = 3000) => {\n if (text && text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '';\n};\n\n// Helper function to format date nicely\nconst formatDate = () => {\n const date = new Date();\n return date.toLocaleDateString('en-US', { \n weekday: 'long', \n year: 'numeric', \n month: 'long', \n day: 'numeric' \n });\n};\n\n// Extract time from the meetingTimePST field (e.g., \"Wednesday, August 27 @ 09:00 AM PST\")\nconst extractTime = (timeString) => {\n const match = timeString.match(/@\\s*(\\d{1,2}:\\d{2}\\s*[AP]M)/i);\n return match ? match[1] : timeString;\n};\n\n// Build the blocks array\nlet blocks = [\n {\n \"type\": \"header\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"Today's Meeting Brief\"\n }\n },\n {\n \"type\": \"context\",\n \"elements\": [\n {\n \"text\": formatDate(),\n \"type\": \"mrkdwn\"\n }\n ]\n },\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": `${meetings.length} meetings today. If someone watched you for a week would they think you're serious about achieving your goals?`\n }\n },\n {\n \"type\": \"divider\"\n }\n];\n\n// Add each meeting as a rich formatted section\nmeetings.forEach((meeting, index) => {\n const time = extractTime(meeting.meetingTimePST);\n \n // Meeting header section\n blocks.push({\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": `*${time}*`\n }\n });\n \n // Build rich text elements for meeting details\n let richTextElements = [];\n \n // Who section (meeting title)\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": meeting.meetingTitle,\n \"style\": {\n \"code\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": \"\\n\"\n }\n ]\n });\n \n // Purpose in quote block\n richTextElements.push({\n \"type\": \"rich_text_quote\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Purpose:\",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": `\\n${truncateText(meeting.purpose, 500)}`\n }\n ]\n });\n \n // Context section\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"\\nContext: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.keyContext, 500),\n \"style\": {\n \"italic\": true\n }\n }\n ]\n });\n \n // Action items in list\n richTextElements.push({\n \"type\": \"rich_text_list\",\n \"style\": \"bullet\",\n \"elements\": [\n {\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Action: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.action, 400)\n }\n ]\n },\n {\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Watch For: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.watchFor, 400),\n \"style\": {\n \"italic\": true\n }\n }\n ]\n }\n ]\n });\n \n // Add empty section for spacing\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": []\n });\n \n blocks.push({\n \"type\": \"rich_text\",\n \"elements\": richTextElements\n });\n \n // Add divider between meetings (except after last)\n if (index < meetings.length - 1) {\n blocks.push({\n \"type\": \"divider\"\n });\n }\n});\n\n// Add footer\nblocks.push({\n \"type\": \"divider\"\n});\n\n// Create the full Block Kit JSON object\nconst blockKitJson = {\n \"blocks\": blocks\n};\n\n// Return the properly formatted JSON for n8n Slack node\nreturn {\n // This is the key output - the full JSON object as a string\n blocksUi: JSON.stringify(blockKitJson),\n \n // Also include for debugging/reference\n rawBlocks: blocks,\n blockKitObject: blockKitJson,\n \n // Metadata\n meetingCount: meetings.length,\n meetings: meetings,\n hasContent: meetings.length > 0\n};"
},
"typeVersion": 2
},
{
"id": "568c833a-1558-489b-b888-682a88b7e014",
"name": "Envoyer le Compte-rendu de Réunion vers Slack",
"type": "n8n-nodes-base.slack",
"notes": "Configure your channel ID and credentials. The 'text' field is required as fallback for notifications.",
"position": [
2928,
1264
],
"webhookId": "3d69e6d7-54ba-4142-8e78-f98321cd2e24",
"parameters": {
"text": "Daily meeting brief",
"select": "channel",
"blocksUi": "={{ $json.blocksUi }}",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-channel"
},
"messageType": "block",
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "I1AdBji1W6jc0rm7",
"name": "Slack account"
}
},
"typeVersion": 2.3
}
],
"pinData": {
"Daily Weekday Trigger": [
{
"Hour": "06",
"Year": "2025",
"Month": "August",
"Minute": "00",
"Second": "00",
"Timezone": "America/Los_Angeles (UTC-07:00)",
"timestamp": "2025-08-29T06:00:00.006-07:00",
"Day of week": "Friday",
"Day of month": "29",
"Readable date": "August 29th 2025, 6:00:00 am",
"Readable time": "6:00:00 am"
}
]
},
"connections": {
"ccd2cc06-14e9-46ad-9a57-ee0cefcc7217": {
"ai_languageModel": [
[
{
"node": "b1fc1ba5-37e9-4835-a9ce-7f8de724e24f",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"5283bd0a-1a60-4038-aec1-4ebdf727dcb5": {
"ai_languageModel": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"68a07c67-b348-4b3d-b17e-f6c740a4fd26": {
"ai_languageModel": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"aab6d0d7-8936-42da-8515-100cc336587f": {
"main": [
[
{
"node": "b0d83ab6-d2a5-49c1-9edb-4454ed81e796",
"type": "main",
"index": 0
}
]
]
},
"c38c28bf-d2f7-405e-898e-2c46b3a4139f": {
"ai_languageModel": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"b1fc1ba5-37e9-4835-a9ce-7f8de724e24f": {
"ai_outputParser": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"5fcf9176-4643-46fc-897a-24f281450699": {
"main": [
[
{
"node": "0f98c98c-15fb-4849-8459-74e2488ab563",
"type": "main",
"index": 0
},
{
"node": "7a65b970-c858-40bf-9021-a77c7937c6ab",
"type": "main",
"index": 0
}
]
]
},
"316d6a09-3cbb-465d-86f0-e5dd4ced4477": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"e425b9f4-d99d-416c-bbdd-9d37f34e870d": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"bd04e88e-16a8-43f9-af73-fc8430fcbc63": {
"ai_languageModel": [
[
{
"node": "465e5ceb-d79f-4743-8a0c-b5fc843f6c73",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"f8946089-bb50-4c22-a478-7af2c5063746": {
"main": [
[
{
"node": "9383e71f-5295-4a7d-b77f-721b20584c73",
"type": "main",
"index": 0
}
]
]
},
"465e5ceb-d79f-4743-8a0c-b5fc843f6c73": {
"ai_outputParser": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"8a0df435-807c-41dc-ac78-f1a7ec11163a": {
"main": [
[
{
"node": "3a01bc50-a7e7-4792-8654-b52087a43c1b",
"type": "main",
"index": 0
}
]
]
},
"b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0": {
"main": [
[
{
"node": "7c9ffbe0-9905-406e-92fa-7d43cdb71ef4",
"type": "main",
"index": 0
}
]
]
},
"795dbcbf-b6c5-4347-8999-b6230ca14554": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"dcd9ae8d-7a65-4c52-a41d-675fe1282b4a": {
"ai_languageModel": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"c7d63acc-ef54-474e-bd16-9f1834c84dca": {
"main": [
[
{
"node": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"type": "main",
"index": 1
}
]
]
},
"0980b927-4f40-462e-a0a7-3b6bacc468f9": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb": {
"main": [
[
{
"node": "5fcf9176-4643-46fc-897a-24f281450699",
"type": "main",
"index": 0
}
]
]
},
"0f98c98c-15fb-4849-8459-74e2488ab563": {
"main": [
[
{
"node": "f011a1fb-e804-4078-8dba-09ce75b41e01",
"type": "main",
"index": 0
}
]
]
},
"be879b39-6d7c-4857-ab64-dae2570e1e99": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"ba5434a0-0365-427c-8dff-97d98db9fa70": {
"main": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "main",
"index": 0
}
]
]
},
"7a65b970-c858-40bf-9021-a77c7937c6ab": {
"main": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "main",
"index": 0
}
]
]
},
"f011a1fb-e804-4078-8dba-09ce75b41e01": {
"main": [
[
{
"node": "aab6d0d7-8936-42da-8515-100cc336587f",
"type": "main",
"index": 0
}
]
]
},
"19d444c5-a678-4a50-97b9-53e7750b00ee": {
"main": [
[
{
"node": "ba5434a0-0365-427c-8dff-97d98db9fa70",
"type": "main",
"index": 0
}
],
[
{
"node": "d8cbaffb-b551-4cbb-bc2b-e04f86718d2f",
"type": "main",
"index": 0
}
]
]
},
"e3e3d48b-a1d7-4542-89fe-fb18efb38dbb": {
"ai_tool": [
[
{
"node": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"type": "ai_tool",
"index": 0
}
]
]
},
"b0d83ab6-d2a5-49c1-9edb-4454ed81e796": {
"main": [
[
{
"node": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"type": "main",
"index": 0
}
],
[
{
"node": "c7d63acc-ef54-474e-bd16-9f1834c84dca",
"type": "main",
"index": 0
}
]
]
},
"9383e71f-5295-4a7d-b77f-721b20584c73": {
"main": [
[
{
"node": "ed5d80d8-0a1a-4a95-9abb-b6c365b304ae",
"type": "main",
"index": 0
}
]
]
},
"ed5d80d8-0a1a-4a95-9abb-b6c365b304ae": {
"main": [
[
{
"node": "19d444c5-a678-4a50-97b9-53e7750b00ee",
"type": "main",
"index": 0
}
]
]
},
"7c9ffbe0-9905-406e-92fa-7d43cdb71ef4": {
"main": [
[
{
"node": "568c833a-1558-489b-b888-682a88b7e014",
"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é - 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
Harry Siggins
@harrysiggins-onetwogrowthPartager ce workflow