{
  "id": "zzKoXD9ufZLJcl2L",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Telegram Event Countdown Bot",
  "tags": [],
  "nodes": [
    {
      "id": "e7c4998c-f586-4515-ad98-1ca8cbef921b",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1552,
        224
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ed9cfada-fdeb-47dc-89a2-8e929aa137d9",
      "name": "Events Database",
      "type": "n8n-nodes-base.code",
      "position": [
        -1168,
        224
      ],
      "parameters": {
        "jsCode": "// Define your events here\nconst events = [\n {\n name: \"Product Launch\",\n date: \"2025-12-25\",\n type: \"launch\",\n channel: \"slack\",\n webhookUrl: \"https://hooks.slack.com/services/YOUR/WEBHOOK/URL\"\n },\n {\n name: \"John's Birthday\",\n date: \"2025-11-15\",\n type: \"birthday\",\n channel: \"email\",\n emailRecipients: [\"user@example.com\"]\n },\n {\n name: \"Conference Date\",\n date: \"2025-12-01\",\n type: \"other\",\n channel: \"slack\",\n webhookUrl: \"https://hooks.slack.com/services/YOUR/WEBHOOK/URL\"\n }\n];\n\n// Calculate days remaining for each event\nconst today = new Date();\ntoday.setHours(0, 0, 0, 0);\n\nconst processedEvents = events.map(event => {\n const eventDate = new Date(event.date);\n eventDate.setHours(0, 0, 0, 0);\n \n const diffTime = eventDate - today;\n const daysRemaining = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n \n return {\n ...event,\n daysRemaining: daysRemaining,\n isPast: daysRemaining < 0,\n isToday: daysRemaining === 0,\n shouldNotify: daysRemaining >= 0 && (daysRemaining <= 7 || daysRemaining === 30 || daysRemaining === 14)\n };\n});\n\n// Filter only events that need notification\nconst eventsToNotify = processedEvents.filter(event => event.shouldNotify);\n\nreturn eventsToNotify.map(event => ({ json: event }));"
      },
      "typeVersion": 2
    },
    {
      "id": "5c4aca45-da92-42c3-aec2-57c057a3e655",
      "name": "Is Slack?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "slack-condition",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.channel }}",
              "rightValue": "slack"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "a6e0d25b-44eb-4df0-9280-699341e54fe0",
      "name": "Is Email?",
      "type": "n8n-nodes-base.if",
      "position": [
        -720,
        464
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "email-condition",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.channel }}",
              "rightValue": "email"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b867e405-ec2e-4f02-8c90-c07072c9f337",
      "name": "Format Slack Message",
      "type": "n8n-nodes-base.code",
      "position": [
        -288,
        160
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\n// Determine emoji based on event type\nlet emoji = 'Calendar';\nif (item.type === 'birthday') emoji = 'Birthday Cake';\nif (item.type === 'launch') emoji = 'Rocket';\n\n// Format message based on days remaining\nlet message = '';\nif (item.isToday) {\n message = `${emoji} *TODAY IS THE DAY!* ${emoji}\\n\\n*${item.name}* is happening today!`;\n} else if (item.daysRemaining === 1) {\n message = `${emoji} *TOMORROW!* ${emoji}\\n\\n*${item.name}* is happening tomorrow!`;\n} else {\n message = `${emoji} *Countdown Alert* ${emoji}\\n\\n*${item.name}* is coming up in *${item.daysRemaining} days*!\\n\\nDate: ${item.date}`;\n}\n\nreturn {\n json: {\n text: message,\n webhookUrl: item.webhookUrl\n }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "2333d43d-0eaf-4b3b-bf57-df729be490c3",
      "name": "Send to Slack",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        80,
        160
      ],
      "parameters": {
        "url": "={{ $json.webhookUrl }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={{ $json.text }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b67113b2-71f1-4afc-a7e1-f8d3b4907df6",
      "name": "Format Email",
      "type": "n8n-nodes-base.code",
      "position": [
        -304,
        496
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\n// Determine emoji and color based on event type and urgency\nlet emoji = 'Calendar';\nlet color = '#4CAF50';\nif (item.type === 'birthday') {\n emoji = 'Birthday Cake';\n color = '#FF6B6B';\n}\nif (item.type === 'launch') {\n emoji = 'Rocket';\n color = '#2196F3';\n}\n\nif (item.daysRemaining <= 3) color = '#FF5722';\n\n// Format email content\nlet subject = '';\nlet bodyText = '';\n\nif (item.isToday) {\n subject = `${emoji} TODAY: ${item.name}`;\n bodyText = `Today is the day for <strong>${item.name}</strong>!`;\n} else if (item.daysRemaining === 1) {\n subject = `${emoji} TOMORROW: ${item.name}`;\n bodyText = `<strong>${item.name}</strong> is happening tomorrow!`;\n} else {\n subject = `${emoji} ${item.daysRemaining} Days Until ${item.name}`;\n bodyText = `<strong>${item.name}</strong> is coming up in <strong>${item.daysRemaining} days</strong>!`;\n}\n\nconst htmlBody = `\n<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .header { background: ${color}; color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }\n .content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }\n .countdown { font-size: 48px; font-weight: bold; color: ${color}; text-align: center; margin: 20px 0; }\n .details { background: white; padding: 15px; border-left: 4px solid ${color}; margin: 20px 0; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>${emoji} Event Countdown</h1>\n </div>\n <div class=\"content\">\n <p>${bodyText}</p>\n <div class=\"countdown\">${item.daysRemaining > 0 ? item.daysRemaining : '0'}</div>\n <p style=\"text-align: center; color: #666;\">days remaining</p>\n <div class=\"details\">\n <p><strong>Event:</strong> ${item.name}</p>\n <p><strong>Date:</strong> ${item.date}</p>\n <p><strong>Type:</strong> ${item.type}</p>\n </div>\n </div>\n </div>\n</body>\n</html>\n`;\n\nreturn {\n json: {\n subject: subject,\n html: htmlBody,\n recipients: item.emailRecipients\n }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "9fd55f0c-700e-49d5-9939-65de3b6e5357",
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        0,
        480
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.subject }}",
        "toEmail": "={{ $json.recipients.join(',') }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "86775bb8-ebdf-4a04-94bd-0272e6aab7ab",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1360,
        816
      ],
      "parameters": {
        "path": "event-countdown",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "8846c32d-95d8-4364-b5a3-49dcbe1cb9e0",
      "name": "Process Webhook Event",
      "type": "n8n-nodes-base.code",
      "position": [
        -1024,
        816
      ],
      "parameters": {
        "jsCode": "// Process incoming webhook data\nconst incomingData = $input.first().json.body;\n\nconst response = {\n status: \"success\",\n message: \"Webhook received and processed\",\n timestamp: new Date().toISOString(),\n data: incomingData\n};\n\nreturn { json: response };"
      },
      "typeVersion": 2
    },
    {
      "id": "c4a5c30f-7d8f-4bff-bcc6-bb0944a97e55",
      "name": "Webhook Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -704,
        816
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "1323bb6e-d3bb-4a9a-8104-9f7b15a5fd9f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        96
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 272,
        "content": "Schedule Trigger\n\n Triggers the workflow automatically on a defined schedule (e.g., daily at 9 AM).\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5a332217-251c-4643-9f4a-e45ddd0ca694",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1232,
        64
      ],
      "parameters": {
        "height": 320,
        "content": "\n**Events Database \n\n Fetches upcoming events (like launches or birthdays) from a data source.** \n"
      },
      "typeVersion": 1
    },
    {
      "id": "78088c1c-2a07-49bb-8c83-22cbdf09bae2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        32
      ],
      "parameters": {
        "color": 4,
        "width": 288,
        "height": 256,
        "content": "\n**Is Slack?\n\n Checks if the event\u2019s notification channel is set to Slack.** to edit me. [Guide]"
      },
      "typeVersion": 1
    },
    {
      "id": "07c91f46-5bdb-4645-b78f-eed08f04f30a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        16
      ],
      "parameters": {
        "color": 3,
        "width": 288,
        "height": 288,
        "content": "## Format Slack Message \n** Formats event details into a Slack message layout.** "
      },
      "typeVersion": 1
    },
    {
      "id": "3e818512-d34b-4141-96aa-fe6a6e1c7227",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 6,
        "height": 304,
        "content": "## Send to Slack \u2013 \n**Sends the formatted message to the target Slack channel.** "
      },
      "typeVersion": 1
    },
    {
      "id": "45803040-d713-4a5e-bea1-1c2ec63158f8",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -784,
        320
      ],
      "parameters": {
        "color": 5,
        "height": 288,
        "content": "## Is Email? \n**\u2013 Checks if the event\u2019s notification channel is set to Email.** to edit me. "
      },
      "typeVersion": 1
    },
    {
      "id": "b63a7d56-dd0a-4bea-aadd-ff007771dbc1",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        400
      ],
      "parameters": {
        "height": 224,
        "content": "##Format Email\n**Formats event details into an email-friendly message.** "
      },
      "typeVersion": 1
    },
    {
      "id": "40015968-2490-4fdb-8b90-abcb12d03d35",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        384
      ],
      "parameters": {
        "color": 5,
        "height": 240,
        "content": "Send Email \u2013 Sends the formatted email to the recipient list."
      },
      "typeVersion": 1
    },
    {
      "id": "69d2e062-b579-44bf-bd45-ae92b8cc7c02",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1440,
        688
      ],
      "parameters": {
        "color": 6,
        "height": 272,
        "content": "## Webhook Trigger\n** \u2013 Starts the workflow when an external system sends a POST request.** "
      },
      "typeVersion": 1
    },
    {
      "id": "e112f333-ac81-4a1c-85d9-df61226582cb",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1104,
        672
      ],
      "parameters": {
        "color": 3,
        "height": 288,
        "content": "## Process Webhook Event \n**\u2013 Parses and validates the incoming webhook data.** to edit me."
      },
      "typeVersion": 1
    },
    {
      "id": "3de8ee76-3d19-4c0d-9c9d-b12bc721bc21",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        672
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 288,
        "content": "## Webhook Response \n**\u2013 Sends a confirmation or status response back to the webhook sender.**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "5f490f6c-45e6-4983-ac3c-6d30455f3f97",
  "connections": {
    "Is Email?": {
      "main": [
        [
          {
            "node": "Format Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Slack?": {
      "main": [
        [
          {
            "node": "Format Slack Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Email": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Events Database": {
      "main": [
        [
          {
            "node": "Is Slack?",
            "type": "main",
            "index": 0
          },
          {
            "node": "Is Email?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Process Webhook Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Events Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Slack Message": {
      "main": [
        [
          {
            "node": "Send to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Webhook Event": {
      "main": [
        [
          {
            "node": "Webhook Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}