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 →
{
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 7
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
304,
240
],
"id": "1fa0d5b5-9671-4de1-bdce-6d1c333c0ba7",
"name": "Schedule Trigger"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
304,
48
],
"id": "095ec94d-5fec-407a-be92-754f1ad9212f",
"name": "Manual Trigger"
},
{
"parameters": {
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "YOUR_GOOGLE_CALENDAR_EMAIL",
"mode": "list",
"cachedResultName": "YOUR_GOOGLE_CALENDAR_EMAIL"
},
"options": {
"timeMin": "={{ $now.beginningOf('day').toISO() }}",
"timeMax": "={{ $now.plus(1, 'day').beginningOf('day').toISO() }}"
}
},
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1,
"position": [
528,
144
],
"alwaysOutputData": true,
"id": "f24ae974-20be-48a1-8b7d-ca9752eca1d5",
"name": "Get Today's Events"
},
{
"parameters": {
"jsCode": "// Calendar events from upstream\nconst events = $('Get Today\\'s Events').all();\nconst lines = [];\n\nfor (const item of events) {\n const ev = item.json;\n // Skip empty items (alwaysOutputData sends one empty item when no events)\n if (!ev.summary && !ev.start) continue;\n\n const start = ev.start?.dateTime || ev.start?.date || '';\n const end = ev.end?.dateTime || ev.end?.date || '';\n\n // Format times (HH:MM)\n let timeRange = '';\n if (start.includes('T')) {\n const s = new Date(start);\n const e = new Date(end);\n const fmt = (d) => d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', hour12: false });\n timeRange = `${fmt(s)}-${fmt(e)}`;\n } else {\n timeRange = 'All day';\n }\n\n lines.push(`${timeRange} ${ev.summary || '(no title)'}`);\n}\n\nconst calendarBlock = lines.length > 0\n ? lines.join('\\n')\n : 'No events today';\n\n// Price section from price-checker\nconst priceSection = $input.first().json.priceSection || '';\n\nconst message = `\\u2600\\uFE0F Good morning! Your day:\\n${calendarBlock}${priceSection}`;\n\nreturn [{ json: { message } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1184,
144
],
"id": "7dd737b0-7c4c-4c14-955f-01356f83d2b9",
"name": "Format Message"
},
{
"parameters": {
"chatId": "YOUR_CHAT_ID_1",
"text": "={{ $json.message }}",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "\ud83d\udcca Expenses",
"additionalFields": {
"callback_data": "briefing:expenses"
}
},
{
"text": "\ud83d\udcda Learning Notes",
"additionalFields": {
"callback_data": "briefing:learning"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\ud83d\udecd\ufe0f Deal Finder",
"additionalFields": {
"callback_data": "briefing:deals"
}
},
{
"text": "\u2753 Help",
"additionalFields": {
"callback_data": "briefing:help"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false,
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1392,
144
],
"id": "7cb8f9c2-7b6b-4f4d-b45b-1c6d6ce204c2",
"name": "Send to Telegram"
},
{
"parameters": {
"content": "## Daily Briefing\n\nSends calendar summary + price tracker report every morning at 7 AM.\n\n**Flow:** Schedule/Manual \u2192 Calendar \u2192 Price Check \u2192 Format \u2192 Telegram\n\nManual Trigger wired for testing.",
"height": 180,
"width": 320
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
0,
0
],
"id": "01bbbab4-8ffa-4ad0-a8e9-39f81e28df33",
"name": "Sticky Note - Overview"
},
{
"parameters": {
"content": "## Button Callbacks\n\ud83d\udcca briefing:expenses \u00b7 \ud83d\udcda briefing:learning \u00b7 \ud83d\udecd\ufe0f briefing:deals \u00b7 \u2753 briefing:help\nRouted by menu-handler.json in [10_steward](YOUR_GITHUB_REPO_URL/tree/main/projects/n8n/10_steward)",
"height": 140,
"width": 400
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
688,
320
],
"id": "53a66f4c-94ec-41bb-b20a-d5bbd5143e1c",
"name": "Sticky - Mode B"
},
{
"parameters": {
"content": "## Standalone Briefing\nCalendar + price tracker with inline action buttons.\nCallbacks handled by menu-handler.json in project 10.",
"height": 100,
"width": 320
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
304,
320
],
"id": "087f3373-9453-4ecd-bdff-059d16cad7e9",
"name": "Sticky - Mode A"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "YOUR_PRICE_CHECKER_WORKFLOW_ID",
"mode": "list",
"cachedResultUrl": "/workflow/YOUR_PRICE_CHECKER_WORKFLOW_ID",
"cachedResultName": "price-checker"
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
960,
-40
],
"id": "db100001-0001-0001-0001-000000000002",
"name": "Check Prices"
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Get Today's Events",
"type": "main",
"index": 0
}
]
]
},
"Manual Trigger": {
"main": [
[
{
"node": "Get Today's Events",
"type": "main",
"index": 0
}
]
]
},
"Get Today's Events": {
"main": [
[
{
"node": "Check Prices",
"type": "main",
"index": 0
}
]
]
},
"Check Prices": {
"main": [
[
{
"node": "Format Message",
"type": "main",
"index": 0
}
]
]
},
"Format Message": {
"main": [
[
{
"node": "Send to Telegram",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Daily-Briefing. Uses googleCalendar, telegram. Scheduled trigger; 9 nodes.
Source: https://github.com/runfish5/micro-services/blob/main/projects/n8n/05_daily-briefing/workflows/daily-briefing.json — 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.
This n8n template demonstrates how to automatically fetch upcoming movie releases from TMDB and let users add selected movies to their Google Calendar directly from Telegram. On a daily schedule, the
20 - Daily Backup (22:00). Uses googleDrive, googleCalendar, telegram. Scheduled trigger; 13 nodes.
This workflow automatically sends you a daily message on Telegram summarizing all your meetings and events for the day, straight from your Google Calendar.
Automatically Send Daily Meeting List to Telegram. Uses googleCalendar, scheduleTrigger, telegram, stickyNote. Scheduled trigger; 8 nodes.
This workflow automatically sends you a list of your daily meetings every morning via a Telegram bot.