This workflow corresponds to n8n.io template #16088 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"id": "93WJ5MeVEIgDObFL",
"name": "AI Assistance for google workspace",
"tags": [
{
"id": "AyPfkIYloZ6hmYqF",
"name": "AI Assistant",
"createdAt": "2026-06-03T05:57:06.949Z",
"updatedAt": "2026-06-03T05:57:06.949Z"
},
{
"id": "TjZzPXtJSbPYbLZJ",
"name": "Daily Briefing",
"createdAt": "2026-06-03T05:57:21.037Z",
"updatedAt": "2026-06-03T05:57:21.037Z"
}
],
"nodes": [
{
"id": "b511b0c7-b8d1-4a0d-9d76-9fbc7c9f6f00",
"name": "Sticky Note \u2014 Slack Trigger + Prep",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1312,
2272
],
"parameters": {
"color": 7,
"width": 520,
"height": 572,
"content": "## Slack Trigger and Input Cleanup\n\n### Nodes covered\n- When Slack Message Received\n- Prepare Slack Data\n\n### What this block does\n- Receives Slack event payloads.\n- Extracts clean `userMessage`, `channelId`, `threadTs`, and `userId`.\n- Removes `<@BOTID>` mentions so the AI reads only the user request.\n\n### Required config\n- Attach Slack app/OAuth credentials.\n- In your Slack app, subscribe to message events for the channels you want.\n- Test with real mention messages because formatting differs across Slack event types."
},
"typeVersion": 1
},
{
"id": "c42048ed-3169-41b4-a00c-2a2674f428cb",
"name": "Sticky Note \u2014 AI Agent Core",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
2288
],
"parameters": {
"color": 7,
"width": 600,
"height": 856,
"content": "## AI Agent Core\n\n### Nodes covered\n- AI Response Generator\n- Google Gemini Assistant\n- Persist Conversation Context\n\n### What this block does\n- Gemini is the chat model.\n- Memory stores recent context per Slack `userId`.\n- The agent decides which connected Google or Cal.com tool to call.\n\n### Best practice\n- Good for assistant-style Slack ops.\n- Weak point: memory is user-based, not channel-based, so cross-channel context can mix for the same user.\n- If you need safer context separation, use `userId + channelId` as the session key."
},
"typeVersion": 1
},
{
"id": "20096b46-0366-45e9-a518-884f57ca9f26",
"name": "Sticky Note \u2014 Workspace Tools",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
2624
],
"parameters": {
"color": 7,
"width": 1076,
"height": 918,
"content": "## Google Workspace and Cal.com Tools\n\n### Nodes covered\n- Search Gmail Messages / Send Gmail Message\n- Read Google Calendar Events / Create Google Calendar Event\n- Get Google Docs Document / Create Google Docs Document\n- Read Rows in Sheets / Append or Update Sheets\n- Get Google Contact Details\n- Search Google Drive Files\n- Fetch Cal.com Slots / Create Cal.com Booking\n\n### What works\n- Gives the AI agent read + write actions across mail, calendar, docs, sheets, contacts, drive, and bookings.\n- Uses `$fromAI(...)` fields so the agent can fill structured inputs dynamically.\n\n### Important setup\n- Every node needs the correct credential attached in n8n.\n- `Append or Update Sheets` expects valid JSON in `sheet_columns_json`; bad JSON will fail.\n- `Get Google Docs Document` currently has operation `get` but no visible document ID input; verify the node version/config in n8n before importing.\n- `Get Google Contact Details` also needs a resolvable contact input when the AI uses it; confirm the node exposes that field in your n8n version.\n- Cal.com nodes require header auth with a valid API token."
},
"typeVersion": 1
},
{
"id": "867055c7-6945-439e-b270-45c712f51d09",
"name": "Sticky Note \u2014 Slack Response Output",
"type": "n8n-nodes-base.stickyNote",
"position": [
-112,
2336
],
"parameters": {
"color": 7,
"width": 302,
"height": 518,
"content": "## Slack Response Output\n\n### Node covered\n- Post Response to Slack\n\n### What this block does\n- Sends the agent reply back to the originating Slack channel.\n\n### Improve it\n- You already capture `threadTs` but do not use it here.\n- Add thread posting if you want cleaner conversations instead of channel spam."
},
"typeVersion": 1
},
{
"id": "c9014eef-9f94-4f74-a0a3-f9b5ae65bb29",
"name": "Sticky Note \u2014 Daily Briefing Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2144,
4384
],
"parameters": {
"color": 7,
"width": 640,
"height": 642,
"content": "## Scheduled Daily Briefing\n\n### What works\n- Runs on a cron schedule at 9:00, Monday to Saturday.\n- Pulls today's calendar, unread important emails, upcoming Cal.com bookings, and Ahmedabad weather.\n- Uses AI to convert raw data into a prioritized Slack morning briefing.\n\n### Before production\n- Confirm the workflow timezone in n8n is Asia/Kolkata, otherwise cron timing can drift.\n- Replace placeholder Slack channel IDs in both posting nodes."
},
"typeVersion": 1
},
{
"id": "ea818f19-c165-4cd9-9f43-d37f02379760",
"name": "Sticky Note \u2014 Date + Data Fetchers",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1312,
4128
],
"parameters": {
"color": 7,
"width": 650,
"height": 1124,
"content": "## Date Prep and Source Fetching\n\n### Nodes covered\n- When Schedule Triggered\n- Prepare Date Variables\n- Fetch Today's Calendar\n- Fetch Unread Important Emails\n- Fetch Upcoming Cal.com Bookings\n- Fetch Ahmedabad Weather\n\n### What this block does\n- Builds today's start/end timestamps in Asia/Kolkata.\n- Pulls live source data from Calendar, Gmail, Cal.com, and OpenWeather.\n\n### Required config\n- Gmail credential must allow mail read access.\n- Cal.com header auth must be active.\n- Set `OPENWEATHER_API_KEY` in n8n environment variables."
},
"typeVersion": 1
},
{
"id": "d6762f66-00b5-4439-8c3e-1ba31db41f9d",
"name": "Sticky Note \u2014 Merge Layer",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
4208
],
"parameters": {
"color": 7,
"width": 684,
"height": 892,
"content": "## Merge Layer\n\n### Nodes covered\n- Merge Calendar and Emails\n- Combine Calendar and Cal.com\n- Combine with Weather Data\n\n### What this block does\n- Combines outputs from multiple sources so one item can move downstream.\n\n### Weak point\n- `combine` mode can be brittle if one upstream node returns zero items or a different item count.\n- This works only because later expressions read data directly from named nodes. If you want safer scaling, replace this pattern with a Code node or a single Set node that references source nodes directly."
},
"typeVersion": 1
},
{
"id": "7ee0dea0-2cd3-4b7b-a245-bea0e3ac1426",
"name": "Sticky Note \u2014 Summary Builder",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
4432
],
"parameters": {
"color": 7,
"width": 492,
"height": 584,
"content": "## Summary Compilation\n\n### Node covered\n- Compile Source Summaries\n\n### What this block does\n- Formats calendar meetings, unread emails, same-day Cal.com bookings, weather, and quick counts into Slack-ready text.\n\n### Watchouts\n- Uses long inline JavaScript expressions; these are hard to maintain.\n- `new Date().toDateString()` depends on runtime timezone behavior; safer is to compare dates after explicitly setting Asia/Kolkata logic.\n- If Gmail payload headers differ, sender/subject extraction can return blanks."
},
"typeVersion": 1
},
{
"id": "3943b279-2805-4b64-b6ac-7bd0f6b4e535",
"name": "Sticky Note \u2014 Briefing AI",
"type": "n8n-nodes-base.stickyNote",
"position": [
720,
4448
],
"parameters": {
"color": 7,
"width": 520,
"height": 732,
"content": "## Briefing AI Generator\n\n### Nodes covered\n- AI Summary Generator\n- Google Gemini Briefing\n\n### What this block does\n- Converts compiled raw summaries into a short, prioritized morning briefing.\n- Enforces a fixed Slack-friendly structure with priorities, actions, highlights, email focus, and one tip.\n\n### Best practice\n- Good use of a constrained output format.\n- Keep the max word count and format rules tight so the message stays usable in Slack."
},
"typeVersion": 1
},
{
"id": "39a9318f-8495-4984-8845-d3437194dc7b",
"name": "Sticky Note \u2014 Slack Briefing Output",
"type": "n8n-nodes-base.stickyNote",
"position": [
1312,
4320
],
"parameters": {
"color": 7,
"width": 520,
"height": 782,
"content": "## Slack Briefing Delivery\n\n### Nodes covered\n- Build Slack Message\n- Post Daily Briefing\n- Post Detailed Report\n\n### What this block does\n- Wraps the AI briefing in a greeting plus quick stats.\n- Sends one concise briefing and one more detailed follow-up report.\n\n### Required config\n- Replace `REPLACE_WITH_SLACK_CHANNEL_ID` in both Slack nodes.\n- Attach Slack OAuth2 credentials.\n- If you only want one daily message, disable `Post Detailed Report`."
},
"typeVersion": 1
},
{
"id": "804119e0-d7be-4c59-bffd-77f7e2e99aa0",
"name": "Sticky Note \u2014 Final Checklist",
"type": "n8n-nodes-base.stickyNote",
"position": [
1360,
2608
],
"parameters": {
"color": 7,
"width": 520,
"height": 560,
"content": "## Import and Launch Checklist\n\n### Must change before use\n- Attach credentials to Slack, Gemini, Gmail, Google Calendar, Google Docs, Google Sheets, Google Drive, Google Contacts, and Cal.com nodes.\n- Replace both `REPLACE_WITH_SLACK_CHANNEL_ID` values.\n- Set `OPENWEATHER_API_KEY` in environment variables.\n- Verify Slack Event Subscriptions are active and point to the n8n webhook.\n\n### Recommended fixes\n- Use `threadTs` in Slack replies.\n- Change memory key to `userId + channelId`.\n- Move long formatting logic from Set expressions into a Code node for maintainability.\n- Verify all tool node parameter fields exist in your installed n8n version before import.\n\n### Result\n- After these fixes, this becomes a solid template for a Slack-based Google Workspace assistant plus a daily executive briefing."
},
"typeVersion": 1
},
{
"id": "fd9399d5-a38c-49e7-ac98-831254f9a621",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2016,
2096
],
"parameters": {
"width": 480,
"height": 960,
"content": "## AI Assistance for google workspace\n\n### How it works\n\nThe workflow contains no nodes, so there is no executable automation or visible canvas structure to group. No trigger, processing, or output steps are currently defined.\n\n### Setup steps\n\n- Add at least one trigger node to define how the workflow starts.\n- Add processing and output nodes as needed, then connect them in the desired execution order.\n- Configure any required credentials on the nodes you add.\n\n### Customization\n\nBuild out the workflow by adding spatially clustered nodes for each major task, such as input handling, data processing, and final output.\n\n### What works\n- Watches Slack for new messages and strips the bot mention before processing.\n- Uses one AI agent with memory so each Slack user gets ongoing context by `userId`.\n- Can search/send Gmail, read/create Calendar events, read/create Docs, read/update Sheets, search Drive, check Contacts, and fetch/book Cal.com slots.\n- Sends the AI reply back to the same Slack channel.\n\n### How to use\n1. Connect Slack Trigger + Slack Send credentials.\n2. Connect Gemini model credentials.\n3. Connect Gmail, Google Calendar, Google Docs, Google Sheets, Google Drive, Google Contacts, and Cal.com credentials.\n4. In Slack app settings, enable Event Subscriptions and map the n8n webhook URL.\n5. Mention the assistant in Slack with requests like: `find unread emails`, `book meeting tomorrow 4pm`, `create doc for launch notes`.\n\n### Important setup\n- Set the Slack trigger `channelId` if you want the bot limited to one channel.\n- The current Slack response node posts to a channel, not a thread. If you want threaded replies, add `threadTs` to the Slack post node.\n- Keep the agent prompt strict so it asks only one short clarifying question when required."
},
"typeVersion": 1
},
{
"id": "b187b281-6166-46f4-bb3c-f90041882bf5",
"name": "When Slack Message Received1",
"type": "n8n-nodes-base.slackTrigger",
"notes": "Required: attach Slack OAuth2/app credentials and configure Slack Events subscriptions in your Slack app. If you want only one channel, set channelId to that channel in n8n.",
"position": [
-1184,
2688
],
"parameters": {
"options": {},
"trigger": "event",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 1
},
{
"id": "da72bd0b-0840-4d4c-888a-5076c64134d4",
"name": "AI Response Generator1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-688,
2688
],
"parameters": {
"text": "={{ $json.userMessage }}",
"options": {
"maxIterations": 8,
"systemMessage": "You are Ravi's Slack workspace assistant. Use tools for Gmail, Google Calendar, Google Docs, Google Sheets, Google Drive, Google Contacts, and Cal.com. Use Asia/Kolkata timezone by default. For read requests, retrieve data. For create/send/book/update requests, use the proper write tool. Ask one short clarifying question only if required. Keep replies short and Slack-friendly. Prefer existing IDs, titles, and names from the conversation. If a required document ID, sheet name, email, or booking detail is missing, ask one short clarifying question."
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "b84e1b0d-2eb6-41b6-ac1a-970e25d81df1",
"name": "Prepare Slack Data1",
"type": "n8n-nodes-base.set",
"position": [
-928,
2688
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "userMessage",
"type": "string",
"value": "={{ ($json.event.text || '').replace(/<@[A-Z0-9]+>/g, '').trim() }}"
},
{
"name": "channelId",
"type": "string",
"value": "={{ $json.event.channel }}"
},
{
"name": "threadTs",
"type": "string",
"value": "={{ $json.event.thread_ts || $json.event.ts }}"
},
{
"name": "userId",
"type": "string",
"value": "={{ $json.event.user }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "5aea060b-314e-4618-91ef-d4de3c25a0cb",
"name": "Google Gemini Assistant1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-688,
2864
],
"parameters": {
"options": {
"temperature": 0.2,
"maxOutputTokens": 2048
},
"modelName": "models/gemini-1.5-pro"
},
"typeVersion": 1
},
{
"id": "e48d2db2-60f7-4886-8c73-a965aec8d790",
"name": "Persist Conversation Context1",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
-592,
2976
],
"parameters": {
"sessionKey": "={{ $('Prepare Slack Data1').item.json.userId }}",
"sessionIdType": "customKey",
"contextWindowLength": 100
},
"typeVersion": 1.3
},
{
"id": "78fb17a7-563b-477f-8f03-5df683378753",
"name": "Search Gmail Messages1",
"type": "n8n-nodes-base.gmailTool",
"position": [
1184,
3168
],
"parameters": {
"operation": "getMany"
},
"typeVersion": 2.2
},
{
"id": "d8cd87a8-2796-44b3-bf95-9c3847c07e7c",
"name": "Send Gmail Message1",
"type": "n8n-nodes-base.gmailTool",
"position": [
1184,
3360
],
"parameters": {
"sendTo": "={{ $fromAI('email_to', 'Recipient email', 'string') }}",
"message": "={{ $fromAI('email_body', 'Email body', 'string') }}",
"options": {},
"subject": "={{ $fromAI('email_subject', 'Email subject', 'string') }}"
},
"typeVersion": 2.2
},
{
"id": "f9912234-48d4-4914-b311-6ce3efbf20a2",
"name": "Read Google Calendar Events1",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1008,
3168
],
"parameters": {
"options": {
"orderBy": "startTime"
},
"timeMax": "={{ $fromAI('calendar_to', 'End datetime in ISO 8601', 'string') }}",
"timeMin": "={{ $fromAI('calendar_from', 'Start datetime in ISO 8601', 'string') }}",
"calendar": {
"__rl": true,
"mode": "name",
"value": "primary"
},
"operation": "getAll"
},
"typeVersion": 1.3
},
{
"id": "be4c210d-1cd0-45c8-aa98-c029c0ca2f35",
"name": "Create Google Calendar Event1",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1008,
3360
],
"parameters": {
"end": "={{ $fromAI('event_end', 'Event end datetime in ISO 8601', 'string') }}",
"start": "={{ $fromAI('event_start', 'Event start datetime in ISO 8601', 'string') }}",
"calendar": {
"__rl": true,
"mode": "name",
"value": "primary"
},
"additionalFields": {
"summary": "={{ $fromAI('event_title', 'Event title', 'string') }}",
"location": "={{ $fromAI('event_location', 'Event location', 'string') }}",
"description": "={{ $fromAI('event_description', 'Event description', 'string') }}"
}
},
"typeVersion": 1.3
},
{
"id": "3c8dfad9-c6cf-4c51-9ccc-a58aa6d61468",
"name": "Get Google Docs Document1",
"type": "n8n-nodes-base.googleDocsTool",
"position": [
816,
3168
],
"parameters": {
"operation": "get"
},
"typeVersion": 2
},
{
"id": "d6510310-8b16-4902-96cd-43316891422b",
"name": "Create Google Docs Document1",
"type": "n8n-nodes-base.googleDocsTool",
"position": [
816,
3360
],
"parameters": {
"title": "={{ $fromAI('doc_title', 'Google Doc title', 'string') }}"
},
"typeVersion": 2
},
{
"id": "6770674e-84ca-4de6-871c-a1d96f9b0e88",
"name": "Read Rows in Sheets1",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
624,
3168
],
"parameters": {
"options": {},
"sheetName": "={{ $fromAI('sheet_read_name', 'Sheet name', 'string') }}",
"documentId": "={{ $fromAI('sheet_read_id', 'Google Sheet document ID', 'string') }}"
},
"typeVersion": 4.5
},
{
"id": "3f6393c8-7a13-4895-b291-856bb2b83c0c",
"name": "Append or Update Sheets1",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
624,
3360
],
"parameters": {
"columns": "{{ $fromAI('sheet_columns_json', 'JSON object of columns and values', 'string') }}",
"options": {},
"operation": "appendOrUpdate",
"sheetName": "={{ $fromAI('sheet_name', 'Sheet name', 'string') }}",
"documentId": "={{ $fromAI('sheet_id', 'Google Sheet document ID', 'string') }}"
},
"typeVersion": 4.5
},
{
"id": "6d2ade98-c45e-4361-be92-e3811b8eef66",
"name": "Get Google Contact Details1",
"type": "n8n-nodes-base.googleContactsTool",
"position": [
288,
3168
],
"parameters": {
"operation": "get"
},
"typeVersion": 1
},
{
"id": "4b9d6346-542b-4bcd-8e3f-63b435e48a51",
"name": "Fetch Cal.com Slots1",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
464,
3168
],
"parameters": {
"url": "=https://api.cal.com/v2/slots/available?eventTypeId={{ $fromAI('cal_event_type_id', 'Cal.com event type ID', 'string') }}&startTime={{ $fromAI('slot_start', 'Slot search start ISO datetime', 'string') }}&endTime={{ $fromAI('slot_end', 'Slot search end ISO datetime', 'string') }}&timeZone=Asia%2FKolkata",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"typeVersion": 4.4
},
{
"id": "316ab232-3e6b-4692-9d6c-6e8c40006c11",
"name": "Create Cal.com Booking1",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
464,
3360
],
"parameters": {
"url": "https://api.cal.com/v2/bookings",
"method": "POST",
"options": {},
"jsonBody": "={\"start\":\"{{$fromAI('booking_start','Booking start ISO datetime','string')}}\",\"eventTypeId\":{{$fromAI('booking_event_type_id','Cal.com event type ID','number')}},\"attendee\":{\"name\":\"{{$fromAI('attendee_name','Attendee name','string')}}\",\"email\":\"{{$fromAI('attendee_email','Attendee email','string')}}\",\"timeZone\":\"Asia/Kolkata\"},\"responses\":{\"name\":\"{{$fromAI('attendee_name','Attendee name','string')}}\",\"email\":\"{{$fromAI('attendee_email','Attendee email','string')}}\"}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"typeVersion": 4.4
},
{
"id": "79cfad82-de9f-408f-835f-dbc991616aac",
"name": "Post Response to Slack1",
"type": "n8n-nodes-base.slack",
"position": [
-48,
2688
],
"parameters": {
"text": "={{ $json.output }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Prepare Slack Data1').item.json.channelId }}"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.2
},
{
"id": "589aa0ec-95ba-443f-86e3-9d286da4ce05",
"name": "When Schedule Triggered1",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1968,
4784
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1-6"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "6754c97d-20be-4281-933b-3ba796e3e81a",
"name": "Prepare Date Variables1",
"type": "n8n-nodes-base.set",
"position": [
-1776,
4784
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "todayStart",
"type": "string",
"value": "={{ $now.setZone('Asia/Kolkata').startOf('day').toISO() }}"
},
{
"name": "todayEnd",
"type": "string",
"value": "={{ $now.setZone('Asia/Kolkata').endOf('day').toISO() }}"
},
{
"name": "todayLabel",
"type": "string",
"value": "={{ $now.setZone('Asia/Kolkata').toFormat('EEEE, MMMM d yyyy') }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cf473b4d-90ac-4982-99c2-71cc04de39ac",
"name": "Fetch Today's Calendar1",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-1008,
4576
],
"parameters": {
"options": {
"orderBy": "startTime"
},
"timeMax": "={{ $json.todayEnd }}",
"timeMin": "={{ $json.todayStart }}",
"calendar": {
"__rl": true,
"mode": "name",
"value": "primary"
},
"operation": "getAll"
},
"typeVersion": 1.3
},
{
"id": "78f01fe7-037a-42c2-98a5-a1cd31e7f2b9",
"name": "Fetch Unread Important Emails1",
"type": "n8n-nodes-base.gmail",
"position": [
-1008,
4736
],
"parameters": {
"limit": 15,
"filters": {
"q": "is:unread newer_than:1d -category:promotions -category:social"
},
"operation": "getAll"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "5c40aad0-d92b-49d5-9b69-699568ab3786",
"name": "Fetch Upcoming Cal.com Bookings1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1008,
4880
],
"parameters": {
"url": "https://api.cal.com/v2/bookings?status=upcoming&take=10",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "3adcc864-906b-421d-a283-fbd4bcd1a482",
"name": "Fetch Ahmedabad Weather1",
"type": "n8n-nodes-base.httpRequest",
"notes": "Required: set OPENWEATHER_API_KEY in your n8n environment variables.",
"position": [
-1008,
5040
],
"parameters": {
"url": "=https://api.openweathermap.org/data/2.5/weather?q=Ahmedabad,IN&appid={{$env.OPENWEATHER_API_KEY}}&units=metric",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "b0a2dad7-62b1-4fcd-876b-7299afcecf94",
"name": "Merge Calendar and Emails1",
"type": "n8n-nodes-base.merge",
"position": [
-496,
4640
],
"parameters": {
"mode": "combine",
"options": {}
},
"typeVersion": 3
},
{
"id": "24767f8c-e822-4e23-a5b6-c0eed7529b40",
"name": "Combine Calendar and Cal.com1",
"type": "n8n-nodes-base.merge",
"position": [
-272,
4704
],
"parameters": {
"mode": "combine",
"options": {}
},
"typeVersion": 3
},
{
"id": "ef59ea01-6c18-4048-8437-5d779266dd8d",
"name": "Combine with Weather Data1",
"type": "n8n-nodes-base.merge",
"position": [
-64,
4800
],
"parameters": {
"mode": "combine",
"options": {}
},
"typeVersion": 3
},
{
"id": "ebb00ab6-72e6-4465-9e14-53d8e9bcdad0",
"name": "Compile Source Summaries1",
"type": "n8n-nodes-base.set",
"position": [
336,
4816
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "calendarSummary",
"type": "string",
"value": "={{ $('Fetch Today\\'s Calendar1').all().map(item => { const ev = item.json; const start = ev.start?.dateTime ? new Date(ev.start.dateTime).toLocaleTimeString('en-IN',{hour:'2-digit',minute:'2-digit',timeZone:'Asia/Kolkata'}) : 'All Day'; const end = ev.end?.dateTime ? new Date(ev.end.dateTime).toLocaleTimeString('en-IN',{hour:'2-digit',minute:'2-digit',timeZone:'Asia/Kolkata'}) : ''; return `\u2022 *${ev.summary || 'Untitled'}* \u2014 ${start}${end ? ' to ' + end : ''}${ev.location ? ' \ud83d\udccd ' + ev.location : ''}`; }).join('\\n') || '_No meetings scheduled today_ \u2705' }}"
},
{
"name": "emailSummary",
"type": "string",
"value": "={{ $('Fetch Unread Important Emails1').all().slice(0,8).map(item => { const msg = item.json; const from = msg.payload?.headers?.find(h => h.name === 'From')?.value || 'Unknown'; const subject = msg.payload?.headers?.find(h => h.name === 'Subject')?.value || 'No Subject'; return `\u2022 *${subject}* \u2014 from ${from.replace(/<.*>/,'').trim()}`; }).join('\\n') || '_No new important emails_ \ud83d\udced' }}"
},
{
"name": "calcomSummary",
"type": "string",
"value": "={{ $('Fetch Upcoming Cal.com Bookings1').item.json.data?.bookings?.filter(b => new Date(b.startTime).toDateString() === new Date().toDateString()).map(b => `\u2022 *${b.title || b.eventType?.title || 'Booking'}* \u2014 ${new Date(b.startTime).toLocaleTimeString('en-IN',{hour:'2-digit',minute:'2-digit',timeZone:'Asia/Kolkata'})} with ${b.attendees?.[0]?.name || 'Guest'}`).join('\\n') || '_No Cal.com bookings today_' }}"
},
{
"name": "weatherSummary",
"type": "string",
"value": "={{ $('Fetch Ahmedabad Weather1').item.json.main ? $('Fetch Ahmedabad Weather1').item.json.weather[0].description.charAt(0).toUpperCase() + $('Fetch Ahmedabad Weather1').item.json.weather[0].description.slice(1) + ' \u2014 ' + Math.round($('Fetch Ahmedabad Weather1').item.json.main.temp) + '\u00b0C (feels like ' + Math.round($('Fetch Ahmedabad Weather1').item.json.main.feels_like) + '\u00b0C)' : 'Weather data unavailable' }}"
},
{
"name": "eventCount",
"type": "number",
"value": "={{ $('Fetch Today\\'s Calendar1').all().length }}"
},
{
"name": "emailCount",
"type": "number",
"value": "={{ $('Fetch Unread Important Emails1').all().length }}"
},
{
"name": "todayLabel",
"type": "string",
"value": "={{ $('Prepare Date Variables1').item.json.todayLabel }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9a8d570d-1cac-49b9-a200-437739050898",
"name": "AI Summary Generator1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
928,
4816
],
"parameters": {
"text": "=Generate today's morning briefing for {{ $json.todayLabel }}.\n\nCALENDAR EVENTS TODAY:\n{{ $json.calendarSummary }}\n\nUNREAD EMAILS ({{ $json.emailCount }} unread):\n{{ $json.emailSummary }}\n\nCAL.COM APPOINTMENTS:\n{{ $json.calcomSummary }}\n\nWEATHER: {{ $json.weatherSummary }}\n\nGenerate a smart, prioritized briefing with action items.",
"options": {
"maxIterations": 4,
"systemMessage": "You are Ravi's morning briefing assistant. Generate a concise, actionable daily Slack briefing. Format exactly like this:\n\n\ud83d\udd34/\ud83d\udfe1/\ud83d\udfe2 *Day Priority: [BUSY/MODERATE/LIGHT]*\n\n\ud83d\udccb *Top Actions for Today:*\n1. [action]\n2. [action]\n3. [action]\n\n\ud83d\udcc5 *Meeting Highlights:*\n[highlights]\n\n\ud83d\udce7 *Email Priority:*\n[who needs replies]\n\n\ud83d\udca1 *Focus Tip:*\n[one short useful tip]\n\nBe specific. Max 300 words."
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "07ddd05a-c3ff-48ab-b4d5-0fab2ca48376",
"name": "Build Slack Message1",
"type": "n8n-nodes-base.set",
"position": [
1344,
4816
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "slackMessage",
"type": "string",
"value": "=\ud83c\udf05 *Good Morning, Ravi!* | {{ $('Prepare Date Variables1').item.json.todayLabel }}\n\n{{ $json.output }}\n\n---\n\ud83d\udcca *Quick Stats* \u2192 \ud83d\udcc5 {{ $('Compile Source Summaries1').item.json.eventCount }} meetings \u00b7 \ud83d\udce7 {{ $('Compile Source Summaries1').item.json.emailCount }} unread emails\n\n_Reply with_ `@assistant help` _to take action_ \ud83d\udcac"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "212547c0-5bd8-40ec-98d2-027b1ca4aa11",
"name": "Post Daily Briefing1",
"type": "n8n-nodes-base.slack",
"notes": "Required: attach Slack OAuth2 credential and replace REPLACE_WITH_SLACK_CHANNEL_ID with your real Slack channel ID.",
"position": [
1680,
4704
],
"parameters": {
"text": "={{ $json.slackMessage }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_SLACK_CHANNEL_ID"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.2
},
{
"id": "19110eb6-b1c3-41cc-b00d-b4aed08d760c",
"name": "Post Detailed Report1",
"type": "n8n-nodes-base.slack",
"notes": "Required: attach Slack OAuth2 credential and replace REPLACE_WITH_SLACK_CHANNEL_ID with your real Slack channel ID.",
"position": [
1696,
4912
],
"parameters": {
"text": "=\ud83d\udccb *Full Event Details for Today:*\n\n*\ud83d\udcc5 Google Calendar:*\n{{ $('Compile Source Summaries1').item.json.calendarSummary }}\n\n*\ud83d\udcde Cal.com Appointments:*\n{{ $('Compile Source Summaries1').item.json.calcomSummary }}\n\n*\ud83d\udce7 Email Queue:*\n{{ $('Compile Source Summaries1').item.json.emailSummary }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_SLACK_CHANNEL_ID"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.2
},
{
"id": "e57b8006-71e8-4c2c-ac7a-80f15b92ba09",
"name": "Google Gemini Briefing1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
928,
5024
],
"parameters": {
"options": {
"temperature": 0.4,
"maxOutputTokens": 1024
},
"modelName": "models/gemini-1.5-pro"
},
"typeVersion": 1
},
{
"id": "a76a5333-febd-4ab9-ae13-86d214e238e6",
"name": "Search Google Drive Files1",
"type": "n8n-nodes-base.googleDriveTool",
"position": [
288,
3360
],
"parameters": {
"operation": "search"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "aec51c9d-a1ef-4f40-9f87-aded9a9cf627",
"nodeGroups": [],
"connections": {
"Prepare Slack Data1": {
"main": [
[
{
"node": "AI Response Generator1",
"type": "main",
"index": 0
}
]
]
},
"Send Gmail Message1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Build Slack Message1": {
"main": [
[
{
"node": "Post Daily Briefing1",
"type": "main",
"index": 0
},
{
"node": "Post Detailed Report1",
"type": "main",
"index": 0
}
]
]
},
"Fetch Cal.com Slots1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Read Rows in Sheets1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"AI Summary Generator1": {
"main": [
[
{
"node": "Build Slack Message1",
"type": "main",
"index": 0
}
]
]
},
"AI Response Generator1": {
"main": [
[
{
"node": "Post Response to Slack1",
"type": "main",
"index": 0
}
]
]
},
"Search Gmail Messages1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create Cal.com Booking1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Fetch Today's Calendar1": {
"main": [
[
{
"node": "Merge Calendar and Emails1",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Briefing1": {
"ai_languageModel": [
[
{
"node": "AI Summary Generator1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Prepare Date Variables1": {
"main": [
[
{
"node": "Fetch Today's Calendar1",
"type": "main",
"index": 0
},
{
"node": "Fetch Unread Important Emails1",
"type": "main",
"index": 0
},
{
"node": "Fetch Upcoming Cal.com Bookings1",
"type": "main",
"index": 0
},
{
"node": "Fetch Ahmedabad Weather1",
"type": "main",
"index": 0
}
]
]
},
"Append or Update Sheets1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Fetch Ahmedabad Weather1": {
"main": [
[
{
"node": "Combine with Weather Data1",
"type": "main",
"index": 1
}
]
]
},
"Google Gemini Assistant1": {
"ai_languageModel": [
[
{
"node": "AI Response Generator1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"When Schedule Triggered1": {
"main": [
[
{
"node": "Prepare Date Variables1",
"type": "main",
"index": 0
}
]
]
},
"Compile Source Summaries1": {
"main": [
[
{
"node": "AI Summary Generator1",
"type": "main",
"index": 0
}
]
]
},
"Get Google Docs Document1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Combine with Weather Data1": {
"main": [
[
{
"node": "Compile Source Summaries1",
"type": "main",
"index": 0
}
]
]
},
"Merge Calendar and Emails1": {
"main": [
[
{
"node": "Combine Calendar and Cal.com1",
"type": "main",
"index": 0
}
]
]
},
"Search Google Drive Files1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get Google Contact Details1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create Google Docs Document1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Read Google Calendar Events1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"When Slack Message Received1": {
"main": [
[
{
"node": "Prepare Slack Data1",
"type": "main",
"index": 0
}
]
]
},
"Combine Calendar and Cal.com1": {
"main": [
[
{
"node": "Combine with Weather Data1",
"type": "main",
"index": 0
}
]
]
},
"Create Google Calendar Event1": {
"ai_tool": [
[
{
"node": "AI Response Generator1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Persist Conversation Context1": {
"ai_memory": [
[
{
"node": "AI Response Generator1",
"type": "ai_memory",
"index": 0
}
]
]
},
"Fetch Unread Important Emails1": {
"main": [
[
{
"node": "Merge Calendar and Emails1",
"type": "main",
"index": 1
}
]
]
},
"Fetch Upcoming Cal.com Bookings1": {
"main": [
[
{
"node": "Combine Calendar and Cal.com1",
"type": "main",
"index": 1
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDriveOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow connects Slack with Google Workspace, Cal.com, OpenWeather, and Google Gemini to act as a Slack-based assistant for Gmail, Calendar, Docs, Sheets, Drive, and Contacts, and to post an automated morning briefing with today’s schedule, unread emails, upcoming…
Source: https://n8n.io/workflows/16088/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Telegram Trigger receives incoming messages (text, voice, photo, document). Switch routes by message type to appropriate processors: Text → forwarded as-is. Voice → downloaded and sent to Transcribe a
Transform your Telegram messenger into a powerful, multi-modal personal or team assistant. This n8n workflow creates an intelligent agent that can understand text, voice, images, and documents, and ta
Personal Assistant. Uses memoryBufferWindow, agent, agentTool, httpRequestTool. Event-driven trigger; 77 nodes.
Who is this for? Agencies, consultants, and service providers who conduct discovery calls and need to quickly turn conversations into professional proposals.
Jarvis is a powerful multi-agent productivity assistant built in n8n. It works directly from Telegram and can understand both text messages and voice notes.