{
 "name": "FREE \u00b7 Daily Birthday Reminders",
 "nodes": [
  {
   "parameters": {
    "rule": {
     "interval": [
      {
       "triggerAtHour": 8
      }
     ]
    }
   },
   "id": "f673fa4f-f11a-47db-b245-277d124b0557",
   "name": "Every morning, 8am",
   "type": "n8n-nodes-base.scheduleTrigger",
   "typeVersion": 1.2,
   "position": [
    -360,
    0
   ]
  },
  {
   "parameters": {
    "fields": [
     "emailAddresses",
     "birthdays",
     "names"
    ],
    "options": {},
    "operation": "getAll",
    "returnAll": true
   },
   "id": "927b96a8-5969-40e0-909b-c0fff92deabc",
   "name": "Read Google Contacts",
   "type": "n8n-nodes-base.googleContacts",
   "typeVersion": 1,
   "position": [
    -140,
    0
   ]
  },
  {
   "parameters": {
    "jsCode": "// Find the contacts whose birthday is TODAY.\n// Handles this year's date, and people born on 29 Feb.\nconst today = new Date();\nconst mm = today.getMonth() + 1;\nconst dd = today.getDate();\n\nconst out = [];\nfor (const item of $input.all()) {\n  const j = item.json;\n  const b = j.birthdays;\n  if (!b) continue;\n\n  // Google Contacts returns birthday as { date: { year, month, day } } or similar\n  const d = b.date || b;\n  const bm = Number(d.month);\n  const bd = Number(d.day);\n  if (!bm || !bd) continue;\n\n  // 29 Feb birthday in a non-leap year -> celebrate on 28 Feb\n  const isLeap = (today.getFullYear() % 4 === 0 && today.getFullYear() % 100 !== 0)\n                 || today.getFullYear() % 400 === 0;\n  const treatAsToday = (bm === mm && bd === dd) ||\n                       (bm === 2 && bd === 29 && mm === 2 && dd === 28 && !isLeap);\n  if (!treatAsToday) continue;\n\n  const names = j.names?.[0] || {};\n  const emails = j.emailAddresses || [];\n  out.push({ json: {\n    name:  names.displayName || names.givenName || 'A contact',\n    email: emails[0]?.value || '',\n    birthday: `${bm}/${bd}`\n  }});\n}\nreturn out;"
   },
   "id": "fb8548bf-281b-46b9-a797-53cd48baf2af",
   "name": "Whose birthday is today?",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    80,
    0
   ]
  },
  {
   "parameters": {
    "conditions": {
     "options": {
      "version": 2,
      "caseSensitive": true,
      "typeValidation": "loose"
     },
     "combinator": "and",
     "conditions": [
      {
       "id": "6be24c2c-8aaa-4ab8-8786-125d1efd2190",
       "operator": {
        "type": "array",
        "operation": "notEmpty",
        "singleValue": true
       },
       "leftValue": "={{ $input.all() }}",
       "rightValue": ""
      }
     ]
    },
    "options": {}
   },
   "id": "1dbd1afb-a46f-4b8b-be15-8a5a62f00240",
   "name": "Anyone today?",
   "type": "n8n-nodes-base.if",
   "typeVersion": 2,
   "position": [
    300,
    0
   ]
  },
  {
   "parameters": {
    "sendTo": "CHANGE_ME@yourdomain.com",
    "subject": "=\ud83c\udf82 Birthday today: {{ $json.name }}",
    "message": "=Today is {{ $json.name }}'s birthday ({{ $json.birthday }}).\\n\\n{{ $json.email ? 'Email them: ' + $json.email : 'No email on file.' }}\\n\\n- sent by your Maui Tech Hub birthday reminder",
    "options": {}
   },
   "id": "407cc905-5aaf-4c45-bdf5-9f1072ba3fc0",
   "name": "Email me the reminder",
   "type": "n8n-nodes-base.gmail",
   "typeVersion": 2.1,
   "position": [
    520,
    -100
   ]
  },
  {
   "parameters": {},
   "id": "8e76c0c1-5c65-40fc-8273-edccc50e72c1",
   "name": "Nobody today",
   "type": "n8n-nodes-base.noOp",
   "typeVersion": 1,
   "position": [
    520,
    120
   ]
  },
  {
   "parameters": {
    "content": "## FREE \u00b7 Daily Birthday Reminders\n**by Maui Tech Hub** \u2014 free to use, modify and resell. No attribution required.\n\nEvery morning at 8am this reads your Google Contacts, works out whose\nbirthday it is today, and emails you one reminder. That is it. It never\nforgets a birthday again.\n\nThe version of this that floats around the internet is **broken** \u2014 it\ncompares against a field nothing ever sets, so it silently never fires.\nThis one actually computes today's date, and handles 29 February births\nin non-leap years.\n\n**Set it up in 3 steps**\n1. Connect your Google Contacts credential.\n2. Connect your Gmail credential.\n3. In **Email me the reminder**, replace `CHANGE_ME@yourdomain.com`\n   with the address you want the reminder sent to.\n\nQuestions? mauitechhub.com",
    "height": 470,
    "width": 1050,
    "color": 4
   },
   "id": "9caf2699-7e55-435b-a1f0-1759485307d9",
   "name": "About this workflow",
   "type": "n8n-nodes-base.stickyNote",
   "typeVersion": 1,
   "position": [
    -620,
    -620
   ]
  }
 ],
 "connections": {
  "Every morning, 8am": {
   "main": [
    [
     {
      "node": "Read Google Contacts",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Read Google Contacts": {
   "main": [
    [
     {
      "node": "Whose birthday is today?",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Whose birthday is today?": {
   "main": [
    [
     {
      "node": "Anyone today?",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Anyone today?": {
   "main": [
    [
     {
      "node": "Email me the reminder",
      "type": "main",
      "index": 0
     }
    ],
    [
     {
      "node": "Nobody today",
      "type": "main",
      "index": 0
     }
    ]
   ]
  }
 },
 "settings": {
  "executionOrder": "v1"
 },
 "active": false
}