AutomationFlowsData & Sheets › Cron 24h Appointment Reminder

Cron 24h Appointment Reminder

cron-24h-appointment-reminder. Uses postgres. Scheduled trigger; 8 nodes.

Cron / scheduled trigger★★★★☆ complexity8 nodesPostgres
Data & Sheets Trigger: Cron / scheduled Nodes: 8 Complexity: ★★★★☆ Added:

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": "cron-24h-appointment-reminder",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9,
              "triggerAtMinute": 0
            }
          ]
        }
      },
      "id": "cron-24h",
      "name": "Cron: Daily 9:00 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        100,
        300
      ],
      "notes": "Runs every day at 9:00 AM to find appointments happening tomorrow"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT a.id, a.customer_id, a.service_type, a.start_time, a.end_time, a.duration_minutes, a.notes, a.price_quoted, a.status, c.name AS customer_name, c.phone AS customer_phone, c.email AS customer_email FROM appointments a JOIN customers c ON a.customer_id = c.id WHERE a.start_time >= NOW() + INTERVAL '23 hours' AND a.start_time <= NOW() + INTERVAL '25 hours' AND a.status = 'confirmed'",
        "options": {}
      },
      "id": "query-tomorrow-appts",
      "name": "Supabase: Get Tomorrow's Appointments",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        320,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.length }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "if-has-appointments",
      "name": "IF: Has Appointments?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        540,
        300
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "split-batches",
      "name": "Split Into Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        760,
        260
      ],
      "notes": "Process each appointment one at a time to avoid rate limiting on Twilio/email"
    },
    {
      "parameters": {
        "jsCode": "// Build notification payload for sub-notification-engine\nconst appt = $input.first().json;\nreturn [{\n  json: {\n    customer_phone: appt.customer_phone,\n    customer_email: appt.customer_email,\n    customer_name: appt.customer_name,\n    notification_type: 'reminder_24h',\n    appointment_details: {\n      id: appt.id,\n      service_type: appt.service_type,\n      start_time: appt.start_time,\n      end_time: appt.end_time,\n      duration_minutes: appt.duration_minutes,\n      notes: appt.notes,\n      price_quoted: appt.price_quoted\n    }\n  }\n}];"
      },
      "id": "build-24h-payload",
      "name": "Code: Build 24hr Payload",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        980,
        260
      ]
    },
    {
      "parameters": {
        "workflowId": "={{ $vars.SUB_NOTIFICATION_ENGINE_ID }}"
      },
      "id": "exec-notification-24h",
      "name": "Execute: sub-notification-engine (24hr)",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1,
      "position": [
        1200,
        260
      ]
    },
    {
      "parameters": {
        "jsCode": "// Log the batch completion\nconst item = $input.first().json;\nreturn [{ json: { status: '24h_reminder_sent', customer: item.customer_name, timestamp: new Date().toISOString() } }];"
      },
      "id": "log-24h",
      "name": "Code: Log 24hr Sent",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1420,
        260
      ]
    },
    {
      "parameters": {
        "options": {},
        "operation": "insert",
        "schema": "public",
        "table": "analytics_events",
        "columns": "event_type,customer_id,channel,metadata",
        "values": "={{ JSON.stringify({ event_type: 'reminder_24h_sent', customer_id: $json.customer_id, channel: 'automated', metadata: { appointment_id: $json.id } }) }}"
      },
      "id": "log-analytics-24h",
      "name": "Supabase: Log Analytics Event",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        540,
        440
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "notes": "Track reminder delivery for analytics dashboard"
    }
  ],
  "connections": {
    "Cron: Daily 9:00 AM": {
      "main": [
        [
          {
            "node": "Supabase: Get Tomorrow's Appointments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase: Get Tomorrow's Appointments": {
      "main": [
        [
          {
            "node": "IF: Has Appointments?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Has Appointments?": {
      "main": [
        [
          {
            "node": "Split Into Batches",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Split Into Batches": {
      "main": [
        [
          {
            "node": "Code: Build 24hr Payload",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Code: Build 24hr Payload": {
      "main": [
        [
          {
            "node": "Execute: sub-notification-engine (24hr)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute: sub-notification-engine (24hr)": {
      "main": [
        [
          {
            "node": "Code: Log 24hr Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Log 24hr Sent": {
      "main": [
        [
          {
            "node": "Split Into Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "errorWorkflow": "sub-error-handler"
  },
  "tags": [
    {
      "name": "sweethandbraids"
    },
    {
      "name": "cron"
    },
    {
      "name": "reminders"
    }
  ]
}

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

cron-24h-appointment-reminder. Uses postgres. Scheduled trigger; 8 nodes.

Source: https://github.com/rdmahpcengineer-gpu/sweethandbraidsMainProject/blob/9c327e7b2190848ae227fe277b0662173be78f38/n8n/cron-24h-reminder.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.

Item Lists, Postgres, Email Send +1
Data & Sheets

공유회_알림톡_크론. Uses postgres, httpRequest, n8n-nodes-solapi. Scheduled trigger; 39 nodes.

Postgres, HTTP Request, N8N Nodes Solapi
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request