Your week ahead in one email
Every Sunday morning, get one email with the whole week's meetings, grouped by day.
How it works
Trigger: Schedule — Sundays at 7:00
- Get the next 7 days of events from Google Calendar.
- Group them by day with their times.
- Email the overview to yourself.
Diagram
Trigger App Code
Code
JavaScript used in the Code step — already included in the template below.
// Groups this week's calendar events by day into a short email.
const events = $input.all().map((item) => item.json).filter((e) => e.start);
const byDay = {};
for (const e of events) {
const start = new Date(e.start.dateTime || e.start.date);
const day = start.toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "short" });
const time = e.start.dateTime ? start.toTimeString().slice(0, 5) : "All day";
(byDay[day] ||= []).push(` ${time} ${e.summary || "(no title)"}`);
}
const body = Object.keys(byDay).length
? Object.entries(byDay).map(([day, items]) => `${day}\n${items.join("\n")}`).join("\n\n")
: "Nothing on your calendar this week.";
return [{ json: { count: events.length, body } }];Build it
Pick your tool — same automation, step by step.
Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.
Show code (140 lines)
{
"name": "Your week ahead in one email (Flowngn)",
"nodes": [
{
"parameters": {
"content": "## Your week ahead in one email\nEvery Sunday morning, get one email with the whole week's meetings, grouped by day.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
"height": 260,
"width": 340
},
"id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
"name": "Setup notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-60
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * 0"
}
]
}
},
"id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
"name": "Sundays 7:00",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "id"
},
"returnAll": true,
"timeMin": "={{ $today.toISO() }}",
"timeMax": "={{ $today.plus({ days: 7 }).toISO() }}",
"options": {
"singleEvents": true,
"orderBy": "startTime"
}
},
"id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
"name": "Get this week's events",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.3,
"position": [
300,
0
]
},
{
"parameters": {
"jsCode": "// Groups this week's calendar events by day into a short email.\nconst events = $input.all().map((item) => item.json).filter((e) => e.start);\nconst byDay = {};\n\nfor (const e of events) {\n const start = new Date(e.start.dateTime || e.start.date);\n const day = start.toLocaleDateString(\"en-GB\", { weekday: \"long\", day: \"numeric\", month: \"short\" });\n const time = e.start.dateTime ? start.toTimeString().slice(0, 5) : \"All day\";\n (byDay[day] ||= []).push(` ${time} ${e.summary || \"(no title)\"}`);\n}\n\nconst body = Object.keys(byDay).length\n ? Object.entries(byDay).map(([day, items]) => `${day}\\n${items.join(\"\\n\")}`).join(\"\\n\\n\")\n : \"Nothing on your calendar this week.\";\n\nreturn [{ json: { count: events.length, body } }];"
},
"id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
"name": "Group by day",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
600,
0
]
},
{
"parameters": {
"sendTo": "you@yourcompany.com",
"subject": "=🗓 Your week: {{ $json.count }} events",
"emailType": "text",
"message": "={{ $json.body }}",
"options": {
"appendAttribution": false
}
},
"id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
"name": "Email the week",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
900,
0
]
}
],
"connections": {
"Sundays 7:00": {
"main": [
[
{
"node": "Get this week's events",
"type": "main",
"index": 0
}
]
]
},
"Get this week's events": {
"main": [
[
{
"node": "Group by day",
"type": "main",
"index": 0
}
]
]
},
"Group by day": {
"main": [
[
{
"node": "Email the week",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}In Make, create a new scenario and add these modules in order:
- Schedule the scenario: Sundays 7:00
- Google Calendar › Search Events
- Tools › Set variable / Iterator + Array aggregator (same logic as the Code step)
- Gmail › Send an Email
- Every module run uses Make operations — the free plan includes a monthly quota.
- Make's built-in functions (map, sum, formatDate…) can replace most Code steps; for complex logic use a code module.
- Module and step names can differ slightly as Make and Zapier update their apps.
In Zapier, create a new Zap and add these steps in order:
- Schedule by Zapier — Sundays 7:00
- Google Calendar — Find Events
- Code by Zapier — Run JavaScript (paste the code from the Code section)
- Gmail — Send Email
- Zaps with more than two steps need a paid Zapier plan.
- Webhooks, Filters/Paths and Code by Zapier are premium features on some Zapier plans.
- Code by Zapier runs JavaScript: reuse the code shown above, reading inputs from inputData instead of $json.
- Module and step names can differ slightly as Make and Zapier update their apps.
Tips
- Change the cron to Monday if your week starts on Monday.
Related flows
ProductivityEasy
Your daily agenda on Telegram
Every morning, today's calendar events arrive as one neat Telegram message.
Google Calendar → Telegram2h/mo
ProductivityMedium
AI daily news digest
Every morning, AI summarises the latest articles from a news feed into one short email.
RSS → AI model → Gmail5h/mo
ProductivityMedium
Turn labelled emails into Notion tasks
Label an email "To-do" and it becomes a Notion task with a link back to the email.
Gmail → Notion3h/mo