AutomationFlowsAI & RAG › Prepare Daily AI Meeting Briefs From Google Calendar with Gpt-4o and Email

Prepare Daily AI Meeting Briefs From Google Calendar with Gpt-4o and Email

ByTakatoYamada @takato-door on n8n.io

This workflow accepts a URL via an n8n form, fetches and extracts the main text from the web page, uses OpenAI (GPT-4o) to generate a structured research card (summary, tags, quotes, actions, sentiment, reading time), then saves the result to Notion and logs it in Google Sheets.…

Cron / scheduled trigger★★★★☆ complexityAI-powered16 nodesGoogle CalendarChain LlmOpenAI ChatOutput Parser StructuredGmailSlack
AI & RAG Trigger: Cron / scheduled Nodes: 16 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16334 — we link there as the canonical source.

This workflow follows the Chainllm → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "0bc688acd333c182",
  "name": "Build an AI meeting prep brief from Google Calendar to email using OpenAI",
  "tags": [
    {
      "name": "google-calendar"
    },
    {
      "name": "meeting-prep"
    },
    {
      "name": "productivity"
    },
    {
      "name": "scheduling"
    },
    {
      "name": "gmail"
    },
    {
      "name": "daily-brief"
    },
    {
      "name": "openai"
    },
    {
      "name": "ai"
    }
  ],
  "nodes": [
    {
      "id": "8db86a1a-7f98-4c87-9366-e44e8c4d7551",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -320
      ],
      "parameters": {
        "width": 480,
        "height": 688,
        "content": "## Build an AI meeting prep brief from Google Calendar to email using OpenAI\n\n## How it works\n\n1. Triggers every morning to initiate the workflow.\n2. Fetches today's events from Google Calendar.\n3. Combines events and checks if there are any meetings.\n4. Uses OpenAI to write a preparation brief if meetings are present.\n5. Formats and sends the brief via email and optionally posts to Slack.\n\n## Setup steps\n\n- [ ] Set up Google Calendar credentials in n8n.\n- [ ] Configure OpenAI API key for LLM chain node.\n- [ ] Integrate Gmail account for sending emails.\n- [ ] Optionally configure Slack credentials for brief posting.\n\n## Customization\n\nThe workflow can be adjusted to use different email or Slack formats."
      },
      "typeVersion": 1
    },
    {
      "id": "10e47d2d-d940-4328-8c53-668b6133e3ac",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Trigger and fetch events\n\nStarts the workflow every morning and fetches events from Google Calendar."
      },
      "typeVersion": 1
    },
    {
      "id": "3a964c6e-7a6c-4a94-ab61-283e51349dba",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 496,
        "content": "## Combine and check meetings\n\nAggregates the calendar events and checks if there are any meetings for today."
      },
      "typeVersion": 1
    },
    {
      "id": "32e0db42-9ad7-41a5-bc32-1a864d09b7bf",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 544,
        "content": "## Generate and format brief\n\nUses AI to generate a meeting preparation brief and formats it for email."
      },
      "typeVersion": 1
    },
    {
      "id": "e0798c0b-2ccb-4e6b-a7ef-44beced6861a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1344,
        -320
      ],
      "parameters": {
        "color": 7,
        "width": 240,
        "height": 528,
        "content": "## Email and optional Slack post\n\nEmails the prepared brief and optionally posts it to Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "04d178c2-2e59-4fad-93dc-4ae3aeab31ff",
      "name": "When Day Starts at 7am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -40,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "triggerAtHour": 7
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4ab6d18a-4fbf-4de6-b8ed-f5af5f5ee644",
      "name": "Fetch Today's Calendar Events",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        200,
        0
      ],
      "parameters": {
        "options": {
          "orderBy": "startTime",
          "timeMax": "={{ $now.endOf('day').toISO() }}",
          "timeMin": "={{ $now.startOf('day').toISO() }}",
          "singleEvents": true
        },
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_CALENDAR"
        },
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1.3
    },
    {
      "id": "86ae1406-39aa-4ae2-927a-4acfcb834d26",
      "name": "Aggregate Calendar Events",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        448,
        0
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "321f8c95-621b-484c-8ee7-a08abab10b23",
      "name": "If Meetings Exist",
      "type": "n8n-nodes-base.if",
      "position": [
        672,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.data.length }}",
              "rightValue": 1
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "8104c630-4edb-41b0-8255-2089f0bc9f1f",
      "name": "Skip When No Meetings",
      "type": "n8n-nodes-base.noOp",
      "position": [
        672,
        208
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "788efc00-8cb1-479b-962c-7333744e1d00",
      "name": "Generate Meeting Brief",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        912,
        -64
      ],
      "parameters": {
        "text": "=You are an executive assistant preparing someone for their day. From today's calendar events below, write a one-line 'day at a glance', then for EACH meeting give: a clear objective, a 3-point agenda, 2-3 smart questions to ask, and what to prepare beforehand. Skip events with no attendees or that look like personal blocks.\n\nToday's events:\n{{ JSON.stringify($json.data).slice(0, 6000) }}",
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "f6367d0e-9ded-4c3b-a6c9-b5d876aea999",
      "name": "Use GPT-4 Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        912,
        208
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {
          "temperature": 0.4
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9d6551e8-3297-4eef-8a2b-918a6ac778d8",
      "name": "Define Output Format",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1136,
        208
      ],
      "parameters": {
        "schemaType": "fromJson",
        "jsonSchemaExample": "{\n  \"overview\": \"You have 3 meetings today; the key one is the 2pm client review.\",\n  \"meetings\": [\n    {\n      \"title\": \"Client review\",\n      \"time\": \"14:00\",\n      \"objective\": \"Agree next-quarter scope.\",\n      \"agenda\": [\n        \"Recap progress\",\n        \"Open risks\",\n        \"Next steps\"\n      ],\n      \"questions\": [\n        \"What is your top priority for Q3?\"\n      ],\n      \"prepare\": [\n        \"Pull the latest metrics deck.\"\n      ]\n    }\n  ]\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "0d0bf381-fc12-4362-8304-12f2816e9619",
      "name": "Set Brief Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1152,
        -64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "04edba75-b4ac-4c57-a18b-af76da9cb1e3",
              "name": "headline",
              "type": "string",
              "value": "=Meeting prep \u2014 {{ $now.format('yyyy-LL-dd') }}"
            },
            {
              "id": "69c50a54-8125-4a01-92db-b40d904977f7",
              "name": "overview",
              "type": "string",
              "value": "={{ $json.output.overview }}"
            },
            {
              "id": "30a72a0c-0370-4083-973d-2e5f55efa2aa",
              "name": "body",
              "type": "string",
              "value": "={{ ($json.output.meetings || []).map(m => '\u2014 ' + m.title + ' (' + m.time + ')\\nObjective: ' + m.objective + '\\nAsk: ' + (m.questions || []).join('; ') + '\\nPrep: ' + (m.prepare || []).join('; ')).join('\\n\\n') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b5e3bc53-b6d6-4191-890e-4938cd7682eb",
      "name": "Send Brief via Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1392,
        -112
      ],
      "parameters": {
        "sendTo": "you@example.com",
        "message": "={{ $json.overview }}\n\n{{ $json.body }}",
        "options": {},
        "subject": "={{ $json.headline }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d5c470ac-23ea-42a2-b1a8-793a699a34e2",
      "name": "Post Brief on Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1392,
        64
      ],
      "parameters": {
        "text": "=:calendar: {{ $json.headline }}\n{{ $json.overview }}\n\n{{ $json.body }}",
        "select": "channel",
        "resource": "message",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#daily"
        },
        "operation": "post",
        "otherOptions": {}
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Use GPT-4 Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Meeting Brief",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Set Brief Fields": {
      "main": [
        [
          {
            "node": "Send Brief via Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Meetings Exist": {
      "main": [
        [
          {
            "node": "Generate Meeting Brief",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip When No Meetings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define Output Format": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Meeting Brief",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Generate Meeting Brief": {
      "main": [
        [
          {
            "node": "Set Brief Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Day Starts at 7am": {
      "main": [
        [
          {
            "node": "Fetch Today's Calendar Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Calendar Events": {
      "main": [
        [
          {
            "node": "If Meetings Exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Today's Calendar Events": {
      "main": [
        [
          {
            "node": "Aggregate Calendar Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow accepts a URL via an n8n form, fetches and extracts the main text from the web page, uses OpenAI (GPT-4o) to generate a structured research card (summary, tags, quotes, actions, sentiment, reading time), then saves the result to Notion and logs it in Google Sheets.…

Source: https://n8n.io/workflows/16334/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This n8n-powered workflow automates the entire lifecycle of real estate lead intake, qualification, routing, assignment, and reporting across multiple channels. It brings WhatsApp inquiries and websit

Gmail, Typeform Trigger, WhatsApp Trigger +8
AI & RAG

My workflow 14. Uses rssFeedRead, chainLlm, lmChatOpenAi, openWeatherMap. Scheduled trigger; 40 nodes.

RSS Feed Read, Chain Llm, OpenAI Chat +6
AI & RAG

This workflow builds an AI meeting assistant who sends information-dense pre-meeting notifications for a user's upcoming meetings. A scheduled trigger fires hourly and checks for upcoming meetings wit

Gmail, Google Calendar, Information Extractor +3
AI & RAG

Ensure suppliers never miss a follow-up by automating overdue purchase order tracking and scheduling. 📦⏰ This workflow checks Airtable every weekday morning for open POs older than seven days without

Airtable, Slack, Google Calendar +6
AI & RAG

This workflow runs daily, pulls the latest post from an RSS feed, and uses OpenAI to repurpose it into an SEO blog rewrite, a LinkedIn post, and an X/Twitter thread, then logs the drafts to Google She

RSS Feed Read, Chain Llm, OpenAI Chat +4