Task 3

n8n Automation Design

A 72-hour re-engagement workflow for patients who sign up but do not complete a booking.

Live n8n workflow Workflow: Task 3 - 72h Booking Re-engagement Workflow ID: task3Veriheal72h Production webhook: https://test.muhibnadeem.com/n8n/webhook/veriheal-patient-signed-up URL: https://test.muhibnadeem.com/n8n/ Email: [email protected] Password: TqbEhAtJRfR0obTAjEG1qSOB

Workflow Shape

This design uses n8n for orchestration and keeps the booking decision at evaluation time after the 72-hour wait, so a patient who books at hour 71 is excluded from re-engagement.

1. Signup webhook Store patient ID, signup timestamp, state, product interest, and ESP contact key.
2. Wait 72 hours The imported n8n workflow uses a Wait node before checking booking status.
3. Booking check Query booking API or database by patient ID and signup window.
4. ESP sequence Add unbooked patients to the re-engagement journey.
5. Logging Write outcome, retries, and alerts for operational visibility.

Trigger

Use a webhook for patient_signed_up. The imported n8n workflow accepts the signup payload, strips it down to non-PHI routing fields, waits 72 hours, then performs the final booking decision.

  • Required fields: patient_id, signup_id, signup_at, state, product_type, esp_contact_id.
  • Recommended privacy posture: do not pass medical conditions or diagnosis notes to n8n unless there is a signed BAA and a strict retention policy.

72-Hour Waiting Logic

The workflow uses an n8n Wait node for 72 hours after signup, then checks booking status at evaluation time.

  • This is straightforward for the assessment build and makes the canvas easy to inspect.
  • For high production volume, I would move to a cron-based due evaluator to avoid thousands of long-lived wait executions.
  • A booking at hour 71 is caught because status is checked after the 72-hour window closes.

Conditional Branch

At evaluation time, query the booking service by patient ID and signup ID.

GET /internal/bookings/status
  ?patient_id={{$json.patient_id}}
  &signup_id={{$json.signup_id}}
  • If status is completed or scheduled, mark the candidate as resolved and do not email.
  • If status is none, continue to ESP enrollment.

ESP Integration

The imported workflow uses a code node to build the exact ESP enrollment payload. In production, replace that node with the enterprise ESP HTTP/API node using the same minimum fields.

{
  "contact_id": "esp_12345",
  "sequence_key": "mmj_booking_reengagement_72h",
  "attributes": {
    "state": "FL",
    "product_type": "initial_certification",
    "signup_id": "su_789"
  }
}

Error Handling

  • Webhook malformed: reject with 400, log payload hash and reason, do not retry bad data.
  • Booking API down: retry with exponential backoff, then park candidate for a later evaluation run.
  • ESP API down: retry 3 times, then send alert and leave reengagement_sent_at blank.
  • Duplicate signup webhook: enforce idempotency on signup_id.
  • Missing patient record: log as data integrity error and notify marketing ops.

Observability

  • Daily heartbeat message with counts: candidates due, booked, enrolled, failed.
  • Error workflow sends Slack or email alerts when failures exceed a threshold.
  • Persist each evaluated candidate with status and timestamps for auditability.
  • Edge case handled: patient books after the ESP call but before first email. The ESP journey should re-check booking status before send or honor a suppression webhook.
Open question: confirm whether the ESP contact identifier is available at signup time, or whether n8n must create or look up the ESP contact before enrolling the patient in the sequence.