BookingBot is an internal automation tool for the content team. It eliminates manual Revenue Proposal form-filling on the admin platform by driving a real headless Chromium browser — finding the right rerun row, clicking it, and filling every required field before submitting.
BookingBot uses a magic link login system. No passwords are stored. Only company email addresses are accepted. Links expire in 15 minutes and sessions last 7 days.
- Go to the login page — visit the internal tool URL and navigate to
/login - Enter your email — must be your company email address
- Check your inbox — click "Log In to BookingBot" (expires in 15 min)
- You're in — a signed session cookie is set, valid for 7 days
BookingBot runs a headless Chromium browser on the server. When you submit a booking, a background job drives the browser through four stages:
- Sale Lookup — navigates to the sale's edit page, finds the supplier link, then searches Revenue Opportunities across up to 8 pages for the matching sale row.
- Rerun Click — clicks the Rerun button on the matching RevOpp row and handles confirmation modals automatically.
- Form Fill — fills all required fields: date, buyer forecast, buyer, coordinator, facet tags, merchandising tenet, copy notes, MSRP checkbox + URL, price check notes, scheduling, and uploads the line sheet.
- Submit & Validate — submits the form and checks the result URL or banner for success. Ship-from address errors are handled automatically with an override attempt.
The web UI is the primary way to submit bookings. All fields are required unless noted. After clicking Book Rerun, the page polls for the job result every 3 seconds and displays the outcome automatically.
| Field | Type | Required | Description |
|---|---|---|---|
| Rerun Sale ID | number | Required | Numeric Sale ID from the admin platform. Example: 122478 |
| Date to Book | date | Required | Requested start date. Accepts YYYY-MM-DD or M.DD formats. Entered as MM/DD/YYYY in the admin form. |
| Buyer | select | Required | Team member who is the buyer. Maps to an internal user ID for the dropdown. |
| Coordinator | select | Required | Team member coordinating the rerun. Can be the same as Buyer. |
| Line Sheet | file | Required | Line sheet attachment (typically .xlsx). Max 10 MB. Attached to the proposal via the admin form's file input. |
| Debug Mode | checkbox | Optional | Enables failure-focused debug capture for this run. Requires server-side configuration to activate. |
The Buyer and Coordinator fields accept either a display name (e.g. alice) or an internal user ID. Names are case-insensitive. The dropdown is searched using the user's internal email address. The table below reflects the structure of the user mapping — specific names and IDs have been anonymized.
The line sheet is required for every booking, uploaded as multipart field lineSheet. It does not persist between bookings — you must attach a file each time.
Bookings run asynchronously. The UI polls GET /book-status?id={jobId} every 3 seconds until a terminal state is reached. Jobs are persisted to disk and expire after 24 hours.
| Field | Type | Required | Notes |
|---|---|---|---|
| saleId | string | Required | Numeric admin sale ID |
| dateToBook | string | Required | YYYY-MM-DD format |
| buyer | string | Required | Display name (e.g. "alice") or internal user ID |
| coordinator | string | Required | Display name or internal user ID |
| lineSheet | file | Required | Line sheet file attachment (max 10 MB) |
| buyerForecast | string | Optional | Default: "1000" |
| merchandisingTenet | string | Optional | Default: "Looks awesome" |
| debug | boolean | Optional | "true" to enable debug capture (requires server-side flag) |
Response — 202 Accepted
multipart/form-data. JSON body is not accepted. Passing a file path as a field is blocked for security.
Returns current job state. Poll every 3 seconds until finished or failed. Pass includeDebug=1 to include the full event log.
Returns a summary list of recent jobs sorted newest-first. Max limit: 100. Consumed by the Debug Monitor UI at /debug.
Visit /debug after a run to inspect the last 30 jobs. Click any row to view the full JSON payload including selector misses, missing fields, validation errors, and artifact paths.
Check "Enable debug capture for this run" in the booking form to activate detailed capture. Requires DEBUG_REMOTE_ENABLED=true on the server.
| Variable | Required | Description |
|---|---|---|
| AUTH_SECRET | Required | Secret key for signing session tokens. Must be a strong random value set at deploy time. |
| ADMIN_EMAIL | Required | Admin platform email for Playwright auto-login when the session expires. |
| ADMIN_PASSWORD | Required | Admin platform password for Playwright auto-login. |
| SES_FROM_EMAIL | Optional | From address used for magic link emails. |
| APP_URL | Optional | Public URL for magic link generation. Auto-detected from request headers if not set. |
| PORT | Optional | Server port. Default: 3457 |
| CORS_ALLOWED_ORIGINS | Optional | Comma-separated list of allowed CORS origins. |
| DEBUG_REMOTE_ENABLED | Optional | Set to "true" to allow debug capture from the UI. Default: false |
| DEBUG_RETENTION_HOURS | Optional | Hours to retain debug artifacts. Default: 24 |
| JOB_TTL_HOURS | Optional | Hours to keep jobs in memory. Default: 24 |
| MAX_UPLOAD_BYTES | Optional | Max line sheet size in bytes. Default: 10485760 (10 MB) |
| CHECKPOINT_SCREENSHOTS | Optional | Enable checkpoint screenshots during runs. Also configurable via walkthrough policy file. |
| APP_VERSION | Optional | Version string shown in the UI footer and /health endpoint. |
| WALKTHROUGH_CONFIG | Optional | Path to walkthrough policy JSON. Default: config/walkthrough.config.json |
User sessions are stored as HMAC-signed cookies. The browser's admin session is persisted in a local state file and reloaded on every new browser context to avoid re-authentication on each booking.
Controls which form fields BookingBot is allowed to touch and how to handle validation edge cases.
requiredFieldAllowlist is non-empty, BookingBot throws an error if it attempts to touch any field not on the list. This is a safety guard against unexpected form changes in the admin platform.
/debug for a DOM snapshot to see what was on the page./debug for screenshots and the field inventory.The admin platform sometimes rejects proposal submissions with a "ship from address not verified" error. BookingBot handles this automatically in two ways:
- Auto-override: BookingBot finds and checks the override checkbox on the form, then resubmits. If successful, the booking completes normally.
- Policy ignore: If
ignoreShipFromValidation: trueis set in the walkthrough config, ship-from-only errors are treated as success and the proposal URL is returned.
If both fail, error code SHIP_FROM_ADDRESS_UNVERIFIED is returned. Verify the supplier's ship-from address in the admin platform and retry.
For local development or integration testing, run mock-webhook.js to spin up a lightweight HTTP server that accepts the same POST /book contract without touching the real admin platform.
The mock returns a synthetic revOppId (e.g. MOCK-LX3K2A) and validates required fields, returning 400 if any are missing.
multipart/form-data for the line sheet upload. Adjust your test client accordingly.