Skip to content

Pre-arrival messages (T-14 / T-3 / T-1 / T-0)

Four phases keyed off the arrival date. Implemented in src/workflows/pre-arrival-messages.ts. All gated by the pre-arrival-messages feature flag (currently shadow_mode=0, live).

Each phase is exposed as a separate call (runPreArrivalSingle in BookingFlagWorkflow) so it can be interleaved with M4c (A-2), the arrival flag (A-1 evening), the Bill arrival email (A+0), and the still-dirty check (A+0 3pm) in true temporal order. The earlier bundled-loop design broke M4c and M4d.

The four phases

PhaseFires atWhatConditional?
T-14A −14d 15:00ZWelcome email + 3 form links + yellow flag “checkin info sent”Always (if booking has email)
T-3A −3d 15:00ZPre-check-in reminder + pink flag “Pre-check-in late”If not complete + ≥24h since last msg
T-1A −1d 15:00ZFinal pre-check-in reminderIf not complete + ≥24h since last msg
T-0A +0 14:00ZLock-box codes OR hard nudgeAlways (bypasses 24h gate)

A = arrival date. UTC. 15:00Z = 9am MT, 14:00Z = 8am MT.

BA calendar color progression

The flag color in BA’s calendar tracks pre-checkin status at a glance:

WhenColorText
T-14 sendsffffaa yellow”checkin info sent”
T-3 sends (still incomplete)ffaaff pink”Pre-check-in late”
Pre-checkin form bridgeffff56 bright yellow”Pre-check-in done”
A−1 eveningff56aa arrival pink(set by arrival phase)
Checkout-eveaaffd4 mint”check-out tomorrow”
Departureaaffff cyan(set by departure phase)

T-5 was retired — its dedicated flag-only phase was dropped; the visual progression is now folded into T-14 (yellow) and T-3 (pink-late).

What each one sends

T-14 welcome

Subject: Welcome to {Property}! Your stay info

Body: friendly welcome + 3 forms (pre-check-in, check-in, check-out) + booking summary (dates, guests) + early/late availability notes (computed via getPrevBooking and computeTurnoverDays) + link to property URL.

Also sets BA flag color ffffaa + text “checkin info sent” so the booking shows yellow in BA’s calendar.

T-3 / T-1 reminders

Subject: Please complete your pre-check-in for {Property}

Body: tighter nudge with the pre-checkin URL. T-1 says “tomorrow” instead of “3 days”.

Skipped if CA_PRE_CHECKIN_COMPL=Y on the booking.

T-3 also sets BA flag color ffaaff + text “Pre-check-in late” when it fires (i.e., when pre-checkin is still incomplete at A-3 days). This overrides the yellow flag from T-14.

T-0 morning-of-arrival

Two branches depending on CA_PRE_CHECKIN_COMPL:

If complete → renders property_config.arrival_message_body (per- unit content — see Property config) wrapped in a greeting + check-in form link + signature. Template supports {firstName} and {lockBoxCode} substitutions.

If incomplete → hard nudge: “We can’t release your lock box code until you complete the pre-check-in form. It takes 2 minutes.”

T-0 bypasses the 24h gate — most critical send of the sequence.

Channel routing

Per dispatchChannelFor:

  • Direct / VRBO / unknown → email only (via Mailgun)
  • Airbnb / Booking.com → both email (if real address) AND Beds24 thread message (routes to OTA chat)

24-hour gate

A new booking 3 days before arrival would otherwise blast all phases back-to-back. The gate (in pre-arrival-messages.ts):

if (lastSent && Date.now() - Date.parse(lastSent) < MIN_GAP_MS) {
return { skipped: true, reason: "within_24h_gate" };
}

last_pre_arrival_msg_at is updated after each send.

T-0 bypasses the gate — the morning-of arrival info is too important to skip.

Source

  • Code: src/workflows/pre-arrival-messages.ts
  • Tests: test/workflows/pre-arrival-messages.test.ts (22 cases)
  • Feature flag: feature_flags WHERE workflow_name='pre-arrival-messages'

BA AA mapping

BA AAOur phase
286616T-14 (was T-7 in BA; bumped)
288251Retired — visual flag folded into T-14 (yellow) + T-3 (pink-late)
286885T-3
286773T-1
287537, 287540, 290167 (CC/SS/TP lock-box)T-0
288261 (T-2 SMS)skipped — was a no-op in BA