AutomationFlowsSlack & Telegram › Aipa - Multi-business Calendar Management

Aipa - Multi-business Calendar Management

AIPA - Multi-Business Calendar Management. Uses telegram, supabase, telegramTrigger, googleCalendar. Webhook trigger; 20 nodes.

Webhook trigger★★★★☆ complexity20 nodesTelegramSupabaseTelegram TriggerGoogle Calendar
Slack & Telegram Trigger: Webhook Nodes: 20 Complexity: ★★★★☆ Added:

This workflow follows the Supabase → Telegram 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
{
  "name": "AIPA - Multi-Business Calendar Management",
  "nodes": [
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.message.text }}",
              "operation": "startsWith",
              "value2": "/calendar"
            }
          ]
        }
      },
      "id": "webhook-trigger",
      "name": "Calendar Command Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $json.message.chat.id }}",
        "text": "\ud83d\udcc5 **Multi-Business Calendar**\\n\\nWhat would you like to do?\\n\\n1\ufe0f\u20e3 Today's schedule\\n2\ufe0f\u20e3 This week's events\\n3\ufe0f\u20e3 Add new event\\n4\ufe0f\u20e3 Check conflicts\\n5\ufe0f\u20e3 View by business\\n6\ufe0f\u20e3 Upcoming deadlines\\n\\nReply with a number.",
        "additionalFields": {
          "parse_mode": "Markdown",
          "reply_markup": {
            "keyboard": [
              [
                "1 - Today",
                "2 - This Week"
              ],
              [
                "3 - Add Event",
                "4 - Conflicts"
              ],
              [
                "5 - By Business",
                "6 - Deadlines"
              ]
            ],
            "one_time_keyboard": true,
            "resize_keyboard": true
          }
        }
      },
      "id": "show-calendar-menu",
      "name": "Show Calendar Menu",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        450,
        300
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT * FROM calendar_events WHERE DATE(event_date) = CURRENT_DATE ORDER BY event_time ASC",
        "additionalFields": {}
      },
      "id": "get-today-events",
      "name": "Get Today's Events",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        650,
        200
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "// Format today's schedule\nconst events = items;\n\nif (events.length === 0) {\n  return [{\n    json: {\n      message: \"\ud83d\udced No events scheduled for today\"\n    }\n  }];\n}\n\nlet message = \"\ud83d\udcc5 **Today's Schedule**\\n\";\nmessage += new Date().toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' });\nmessage += \"\\n\\n\";\n\nfor (const event of events) {\n  const time = event.json.event_time ? event.json.event_time.substring(0, 5) : 'All day';\n  const business = event.json.business_context || 'Personal';\n  const businessEmoji = {\n    'woodys_creations': '\ud83c\udf81',\n    'dj_business': '\ud83c\udfb5',\n    'bmf_work': '\ud83d\udcbc',\n    'pub': '\ud83c\udf7a',\n    'personal': '\ud83d\udc64'\n  }[business] || '\ud83d\udccc';\n  \n  message += `${businessEmoji} **${time}** - ${business.replace('_', ' ').toUpperCase()}\\n`;\n  message += `   ${event.json.title}\\n`;\n  if (event.json.location) {\n    message += `   \ud83d\udccd ${event.json.location}\\n`;\n  }\n  if (event.json.notes) {\n    message += `   \ud83d\udcdd ${event.json.notes}\\n`;\n  }\n  message += `\\n`;\n}\n\nreturn [{\n  json: {\n    message: message,\n    event_count: events.length\n  }\n}];"
      },
      "id": "format-today-schedule",
      "name": "Format Today's Schedule",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        850,
        200
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Calendar Command Trigger\"].json.message.chat.id }}",
        "text": "={{ $json.message }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "send-today-schedule",
      "name": "Send Today's Schedule",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        1050,
        200
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT * FROM calendar_events WHERE event_date BETWEEN CURRENT_DATE AND DATE_ADD(CURRENT_DATE, INTERVAL 7 DAY) ORDER BY event_date, event_time ASC",
        "additionalFields": {}
      },
      "id": "get-week-events",
      "name": "Get This Week's Events",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        650,
        300
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "// Format week's events\nconst events = items;\n\nif (events.length === 0) {\n  return [{\n    json: {\n      message: \"\ud83d\udced No events scheduled this week\"\n    }\n  }];\n}\n\nlet message = \"\ud83d\udcc5 **This Week's Events**\\n\\n\";\n\n// Group by date\nconst eventsByDate = {};\n\nfor (const event of events) {\n  const date = event.json.event_date;\n  if (!eventsByDate[date]) {\n    eventsByDate[date] = [];\n  }\n  eventsByDate[date].push(event.json);\n}\n\n// Sort and format\nconst dates = Object.keys(eventsByDate).sort();\n\nfor (const date of dates) {\n  const dateObj = new Date(date);\n  const dateStr = dateObj.toLocaleDateString('en-GB', { weekday: 'short', day: 'numeric', month: 'short' });\n  const isToday = date === new Date().toISOString().split('T')[0];\n  \n  message += isToday ? `**${dateStr} (TODAY)**\\n` : `**${dateStr}**\\n`;\n  \n  for (const event of eventsByDate[date]) {\n    const time = event.event_time ? event.event_time.substring(0, 5) : 'All day';\n    const business = event.business_context || 'Personal';\n    const businessEmoji = {\n      'woodys_creations': '\ud83c\udf81',\n      'dj_business': '\ud83c\udfb5',\n      'bmf_work': '\ud83d\udcbc',\n      'pub': '\ud83c\udf7a',\n      'personal': '\ud83d\udc64'\n    }[business] || '\ud83d\udccc';\n    \n    message += `  ${time} ${businessEmoji} ${event.title}\\n`;\n  }\n  message += `\\n`;\n}\n\nmessage += `**Total: ${events.length} events**`;\n\nreturn [{\n  json: {\n    message: message,\n    event_count: events.length\n  }\n}];"
      },
      "id": "format-week-events",
      "name": "Format Week's Events",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        850,
        300
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Calendar Command Trigger\"].json.message.chat.id }}",
        "text": "={{ $json.message }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "send-week-events",
      "name": "Send Week's Events",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        1050,
        300
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Calendar Command Trigger\"].json.message.chat.id }}",
        "text": "\ud83d\udcdd **Add New Calendar Event**\\n\\nPlease provide:\\n\\n1. Title\\n2. Date (YYYY-MM-DD)\\n3. Time (HH:MM) or 'all-day'\\n4. Business (woodys/dj/bmf/pub/personal)\\n5. Location (optional)\\n6. Notes (optional)\\n\\nExample:\\nClient meeting\\n2025-12-15\\n14:00\\nwoodys\\nTheir office\\nDiscuss new product line",
        "additionalFields": {}
      },
      "id": "ask-event-details",
      "name": "Ask for Event Details",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        650,
        400
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "updates": [
          "message"
        ]
      },
      "id": "wait-for-event-details",
      "name": "Wait for Event Details",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1,
      "position": [
        850,
        400
      ]
    },
    {
      "parameters": {
        "functionCode": "// Parse event details\nconst input = items[0].json.message.text;\nconst lines = input.split('\\n').map(l => l.trim()).filter(l => l);\n\nif (lines.length < 4) {\n  return [{\n    json: {\n      error: true,\n      message: \"\u274c Missing required information (need at least title, date, time, business)\"\n    }\n  }];\n}\n\nconst title = lines[0];\nconst eventDate = lines[1];\nconst eventTime = lines[2].toLowerCase() === 'all-day' ? null : lines[2];\nconst business = lines[3].toLowerCase().replace(/\\s+/g, '_');\nconst location = lines[4] || null;\nconst notes = lines[5] || null;\n\nreturn [{\n  json: {\n    error: false,\n    title: title,\n    event_date: eventDate,\n    event_time: eventTime,\n    business_context: business,\n    location: location,\n    notes: notes,\n    created_at: new Date().toISOString()\n  }\n}];"
      },
      "id": "parse-event-details",
      "name": "Parse Event Details",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1050,
        400
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=SELECT * FROM calendar_events WHERE event_date = '{{ $json.event_date }}' AND event_time IS NOT NULL AND ABS(TIMESTAMPDIFF(MINUTE, event_time, '{{ $json.event_time }}')) < 60",
        "additionalFields": {}
      },
      "id": "check-conflicts",
      "name": "Check for Conflicts",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        1250,
        400
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $json.length }}",
              "operation": "equal",
              "value2": 0
            }
          ]
        }
      },
      "id": "check-if-clear",
      "name": "Check if Time Clear",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1450,
        400
      ]
    },
    {
      "parameters": {
        "operation": "insert",
        "table": "calendar_events",
        "columns": "title, event_date, event_time, business_context, location, notes, created_at",
        "additionalFields": {}
      },
      "id": "save-event",
      "name": "Save Event to Calendar",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        1650,
        350
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "event",
        "operation": "create",
        "calendar": "primary",
        "start": "={{ $node[\"Parse Event Details\"].json.event_date }}T{{ $node[\"Parse Event Details\"].json.event_time || '00:00' }}:00",
        "end": "={{ $node[\"Parse Event Details\"].json.event_date }}T{{ $node[\"Parse Event Details\"].json.event_time || '23:59' }}:00",
        "summary": "={{ $node[\"Parse Event Details\"].json.title }}",
        "options": {
          "description": "={{ $node[\"Parse Event Details\"].json.notes }}",
          "location": "={{ $node[\"Parse Event Details\"].json.location }}"
        }
      },
      "id": "add-to-google-calendar",
      "name": "Add to Google Calendar",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1,
      "position": [
        1850,
        350
      ],
      "credentials": {
        "googleCalendarOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Wait for Event Details\"].json.message.chat.id }}",
        "text": "=\u2705 **Event Added Successfully!**\\n\\n\ud83d\udcc5 {{ $node[\"Parse Event Details\"].json.event_date }}\\n\u23f0 {{ $node[\"Parse Event Details\"].json.event_time || 'All day' }}\\n\ud83d\udccc {{ $node[\"Parse Event Details\"].json.title }}\\n\ud83c\udfe2 {{ $node[\"Parse Event Details\"].json.business_context }}\\n\\n\u2713 Saved to database\\n\u2713 Added to Google Calendar",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "confirm-event-added",
      "name": "Confirm Event Added",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        2050,
        350
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Wait for Event Details\"].json.message.chat.id }}",
        "text": "=\u26a0\ufe0f **Time Conflict Detected!**\\n\\nThere's already an event scheduled around this time:\\n\\n{{ $node[\"Check for Conflicts\"].json[0].title }}\\n\u23f0 {{ $node[\"Check for Conflicts\"].json[0].event_time }}\\n\\nWould you like to:\\n1. Add anyway\\n2. Choose different time\\n3. Cancel",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "warn-conflict",
      "name": "Warn About Conflict",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        1650,
        450
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT * FROM calendar_events WHERE event_date >= CURRENT_DATE AND business_context IN ('dj_business', 'woodys_creations', 'bmf_work') ORDER BY event_date ASC LIMIT 20",
        "additionalFields": {}
      },
      "id": "get-upcoming-deadlines",
      "name": "Get Upcoming Deadlines",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        650,
        500
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "// Format upcoming deadlines\nconst events = items;\n\nif (events.length === 0) {\n  return [{\n    json: {\n      message: \"\ud83d\udced No upcoming deadlines\"\n    }\n  }];\n}\n\nlet message = \"\u23f0 **Upcoming Deadlines**\\n\\n\";\n\nfor (const event of events) {\n  const date = new Date(event.json.event_date);\n  const today = new Date();\n  today.setHours(0, 0, 0, 0);\n  const daysUntil = Math.ceil((date - today) / (1000 * 60 * 60 * 24));\n  \n  const dateStr = date.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' });\n  const business = event.json.business_context || 'Unknown';\n  const businessEmoji = {\n    'woodys_creations': '\ud83c\udf81',\n    'dj_business': '\ud83c\udfb5',\n    'bmf_work': '\ud83d\udcbc',\n    'pub': '\ud83c\udf7a'\n  }[business] || '\ud83d\udccc';\n  \n  // Urgency indicator\n  const urgency = daysUntil <= 1 ? '\ud83d\udd34' : daysUntil <= 3 ? '\ud83d\udfe1' : '\ud83d\udfe2';\n  \n  message += `${urgency} ${businessEmoji} **${event.json.title}**\\n`;\n  message += `   \ud83d\udcc5 ${dateStr} (${daysUntil} days)\\n`;\n  if (event.json.notes) {\n    message += `   \ud83d\udcdd ${event.json.notes}\\n`;\n  }\n  message += `\\n`;\n}\n\nreturn [{\n  json: {\n    message: message,\n    deadline_count: events.length\n  }\n}];"
      },
      "id": "format-deadlines",
      "name": "Format Deadlines",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        850,
        500
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $node[\"Calendar Command Trigger\"].json.message.chat.id }}",
        "text": "={{ $json.message }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "send-deadlines",
      "name": "Send Deadlines",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        1050,
        500
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Calendar Command Trigger": {
      "main": [
        [
          {
            "node": "Show Calendar Menu",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Show Calendar Menu": {
      "main": [
        [
          {
            "node": "Get Today's Events",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get This Week's Events",
            "type": "main",
            "index": 0
          },
          {
            "node": "Ask for Event Details",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Upcoming Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Today's Events": {
      "main": [
        [
          {
            "node": "Format Today's Schedule",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Today's Schedule": {
      "main": [
        [
          {
            "node": "Send Today's Schedule",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get This Week's Events": {
      "main": [
        [
          {
            "node": "Format Week's Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Week's Events": {
      "main": [
        [
          {
            "node": "Send Week's Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask for Event Details": {
      "main": [
        [
          {
            "node": "Wait for Event Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Event Details": {
      "main": [
        [
          {
            "node": "Parse Event Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Event Details": {
      "main": [
        [
          {
            "node": "Check for Conflicts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Conflicts": {
      "main": [
        [
          {
            "node": "Check if Time Clear",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if Time Clear": {
      "main": [
        [
          {
            "node": "Save Event to Calendar",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Warn About Conflict",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Event to Calendar": {
      "main": [
        [
          {
            "node": "Add to Google Calendar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to Google Calendar": {
      "main": [
        [
          {
            "node": "Confirm Event Added",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Upcoming Deadlines": {
      "main": [
        [
          {
            "node": "Format Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Deadlines": {
      "main": [
        [
          {
            "node": "Send Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [],
  "triggerCount": 0,
  "updatedAt": "2025-11-01T18:00:00.000Z",
  "versionId": "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.

Pro

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

About this workflow

AIPA - Multi-Business Calendar Management. Uses telegram, supabase, telegramTrigger, googleCalendar. Webhook trigger; 20 nodes.

Source: https://github.com/DirtyDerv/AIPA/blob/defb52161b0d387cd66b2a6d3bbb1e71b4afc6ae/n8n-workflows/06-calendar-management.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

AIPA - BMF Work Logging. Uses telegram, telegramTrigger, supabase, httpRequest. Webhook trigger; 19 nodes.

Telegram, Telegram Trigger, Supabase +1
Slack & Telegram

WF_UNIFIED_LEGAL_AUTOMATION. Uses googleSheets, httpRequest, telegram, telegramTrigger. Webhook trigger; 53 nodes.

Google Sheets, HTTP Request, Telegram +1
Slack & Telegram

02 - Proposal Generator. Uses telegramTrigger, supabase, httpRequest, telegram. Event-driven trigger; 37 nodes.

Telegram Trigger, Supabase, HTTP Request +1
Slack & Telegram

clients kept booking meetings during my prayer times. i'd either miss a prayer or scramble to reschedule. the problem wasn't the clients — it was that my calendar had no blocked windows for salah. i n

Telegram Trigger, HTTP Request, Google Calendar +3
Slack & Telegram

This workflow manages clinic appointments across Google Sheets and Google Calendar, using webhooks and Telegram to book and confirm visits, Gmail and Telegram to deliver prescriptions, scheduled Teleg

Google Calendar, Telegram, Google Sheets +4