{
  "name": "06 · Shift Roster Reminders — one WhatsApp per staff member",
  "nodes": [
    {
      "parameters": {
        "content": "# 06 · Shift Roster Reminders\n\n**The problem:** no-shows and late arrivals. The manager spends the morning on the phone instead of the floor.\n\n**What this does:** every evening it reads tomorrow's roster and WhatsApps each staff member their own shift — time, section, shift buddy. One message each, nobody gets the whole sheet.\n\n**Setup:** `Roster` sheet: Date, StaffName, Phone, StartTime, EndTime, Section, Off\n\n**Note:** Ahmed off Mondays · Kezang off Tuesdays — handles split shifts.\n\nBuilt by **Maui Tech Hub** · mauitechhub.com/workflows",
        "height": 440,
        "width": 400,
        "color": 7
      },
      "id": "a119731d-35e4-4d6f-9cae-20287c7cda45",
      "name": "NOTE",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 20 * * *"
            }
          ]
        }
      },
      "id": "7c04aa39-0d39-4f9d-a73f-392ca7f5a5df",
      "name": "Evening 8pm",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        100
      ]
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "YOUR_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Roster",
          "mode": "name"
        },
        "options": {}
      },
      "id": "4d2180bb-e8b5-47a0-89b4-b46e1131f280",
      "name": "Read Roster",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 1,
      "position": [
        240,
        100
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// One row per person, only tomorrow, skip days off, handle split shifts.\nconst t = new Date(); t.setDate(t.getDate()+1);\nconst tomorrow = t.toISOString().slice(0,10);\nconst DAYNAME = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];\nconst rows = $input.all().map(i=>i.json)\n  .filter(r => String(r.Date ?? r.date ?? '').startsWith(tomorrow));\nconst off = (r) => {\n  const f = String(r.Off ?? r.off ?? '').trim().toLowerCase();\n  return ['yes','y','true','1','off'].includes(f);\n};\nconst out = [];\nfor (const r of rows) {\n  if (off(r)) continue;\n  const name = r.StaffName ?? r.Name ?? r.name ?? '';\n  if (!name) continue;\n  const phone = String(r.Phone ?? r.phone ?? '').replace(/[^0-9]/g,'');\n  if (!phone) continue;\n  let m = `*Shift tomorrow — ${DAYNAME[t.getDay()]}*\\n\\n`;\n  m += `Hi ${name},\\n`;\n  m += `🕐 *${r.StartTime} – ${r.EndTime}*\\n`;\n  if (r.Section) m += `📍 ${r.Section}\\n`;\n  if (r.Buddy)   m += `👥 With ${r.Buddy}\\n`;\n  if (String(r.Split ?? '').toLowerCase()==='yes')\n    m += `\\n_Split shift — break in between._\\n`;\n  m += `\\nPlease confirm with ✅ or tell us now if you can't make it.`;\n  out.push({ json: { phone, name, message: m, start: r.StartTime,\n    end: r.EndTime, section: r.Section ?? '' } });\n}\nreturn out;"
      },
      "id": "d8e846a4-d5e6-4ae7-8b64-ac4b7b3cfca4",
      "name": "Tomorrow's Shifts",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        100
      ]
    },
    {
      "parameters": {
        "operation": "send",
        "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
        "recipientPhoneNumber": "={{ $json.phone }}",
        "textBody": "={{ $json.message }}",
        "additionalFields": {}
      },
      "id": "bdc11eba-321c-474f-81bd-8a4ff3022e8b",
      "name": "WhatsApp Each Staff",
      "type": "n8n-nodes-base.whatsApp",
      "typeVersion": 1,
      "position": [
        760,
        100
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "ReminderLog",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {}
        },
        "options": {}
      },
      "id": "526a1392-8246-46f1-9e06-c4e8c669e71b",
      "name": "Log Sends",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 1,
      "position": [
        1020,
        100
      ]
    }
  ],
  "connections": {
    "Evening 8pm": {
      "main": [
        [
          {
            "node": "Read Roster",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Roster": {
      "main": [
        [
          {
            "node": "Tomorrow's Shifts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tomorrow's Shifts": {
      "main": [
        [
          {
            "node": "WhatsApp Each Staff",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp Each Staff": {
      "main": [
        [
          {
            "node": "Log Sends",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "instanceId": "mauitechhub-retail-ops"
  }
}