Hotel pre-arrival message on WhatsApp

Two days before check-in, guests get a WhatsApp welcome with their dates, room and a map link.

Easy Saves ~4 hours/month Restaurants & HotelsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Schedule — every day at 12:00
  1. Read the Bookings sheet.
  2. Keep confirmed guests arriving in 2 days.
  3. Send a WhatsApp template with check-in date, room type and your location.

Diagram

Every day 12:00Schedule TriggerGRead bookingsGoogle Sheets{ }Arriving in 2 daysCodeWSend arrival infoWhatsApp Business Cloud
Trigger App Code

Code

JavaScript used in the Code step — already included in the template below.

Arriving in 2 days · Code node
// Bookings sheet columns: guest | phone | check_in (YYYY-MM-DD) | nights | room_type | status
// Keeps confirmed guests arriving in exactly 2 days.
const inTwoDays = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);

return $input.all()
  .map((item) => item.json)
  .filter((b) => String(b.check_in).slice(0, 10) === inTwoDays && String(b.status).toLowerCase() === "confirmed" && b.phone)
  .map((b) => ({
    json: {
      phone: String(b.phone).replace(/[^0-9]/g, ""),
      guest: b.guest,
      check_in: b.check_in,
      nights: b.nights,
      room_type: b.room_type,
    },
  }));

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.

Workflow JSON
Show code (162 lines)
{
  "name": "Hotel pre-arrival message on WhatsApp (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Hotel pre-arrival message on WhatsApp\nTwo days before check-in, guests get a WhatsApp welcome with their dates, room and a map link.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "3757d265-b3e9-4413-a7d9-26f1a685deb4",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 12
            }
          ]
        }
      },
      "id": "3757d265-b3e9-4413-a7d9-26f1a685deb4",
      "name": "Every day 12:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Bookings",
          "mode": "name"
        },
        "options": {}
      },
      "id": "3757d265-b3e9-4413-a7d9-26f1a685deb4",
      "name": "Read bookings",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Bookings sheet columns: guest | phone | check_in (YYYY-MM-DD) | nights | room_type | status\n// Keeps confirmed guests arriving in exactly 2 days.\nconst inTwoDays = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);\n\nreturn $input.all()\n  .map((item) => item.json)\n  .filter((b) => String(b.check_in).slice(0, 10) === inTwoDays && String(b.status).toLowerCase() === \"confirmed\" && b.phone)\n  .map((b) => ({\n    json: {\n      phone: String(b.phone).replace(/[^0-9]/g, \"\"),\n      guest: b.guest,\n      check_in: b.check_in,\n      nights: b.nights,\n      room_type: b.room_type,\n    },\n  }));"
      },
      "id": "3757d265-b3e9-4413-a7d9-26f1a685deb4",
      "name": "Arriving in 2 days",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "operation": "sendTemplate",
        "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
        "recipientPhoneNumber": "={{ $json.phone }}",
        "template": "YOUR_PRE_ARRIVAL_TEMPLATE|ar",
        "components": {
          "component": [
            {
              "type": "body",
              "bodyParameters": {
                "parameter": [
                  {
                    "type": "text",
                    "text": "={{ $json.guest }}"
                  },
                  {
                    "type": "text",
                    "text": "={{ $json.check_in }}"
                  },
                  {
                    "type": "text",
                    "text": "={{ $json.room_type }}"
                  },
                  {
                    "type": "text",
                    "text": "YOUR_LOCATION_LINK"
                  }
                ]
              }
            }
          ]
        }
      },
      "id": "3757d265-b3e9-4413-a7d9-26f1a685deb4",
      "name": "Send arrival info",
      "type": "n8n-nodes-base.whatsApp",
      "typeVersion": 1,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "Every day 12:00": {
      "main": [
        [
          {
            "node": "Read bookings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read bookings": {
      "main": [
        [
          {
            "node": "Arriving in 2 days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Arriving in 2 days": {
      "main": [
        [
          {
            "node": "Send arrival info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Mention airport pickup in the template; it's the most common upsell.

Related flows