Monitors SpaceflightNow's launch schedule and sends email alerts when new launches are announced or existing launch dates/times change for tracked sites.
| Site | Patterns matched |
|---|---|
| ๐ด Florida (Cape Canaveral / KSC) | cape canaveral, kennedy space center, slc-40, lc-39a, lc-39b, slc-41, slc-36, florida |
| ๐ค Starbase (Boca Chica, TX) | starbase, boca chica, orbital launch mount, olm |
| ๐ Vandenberg (SFB, CA) | vandenberg, slc-4e, slc-2, slc-3e |
| File | Type | Purpose |
|---|---|---|
monitor.ts | Interval (every 6 hours) | Main monitor โ fetches schedule, diffs against stored state, sends alert emails |
testEmail.ts | HTTP endpoint | Manual trigger โ sends a snapshot email of all current launches without modifying state |
monitor.tsruns on a 6-hour interval via Val Town.- It fetches and strips SpaceflightNow's HTML to plain text.
- The structured parser extracts launch blocks (date header โ vehicle/mission โ launch time โ launch site โ description).
- Each launch is assigned a stable ID:
{siteId}-{vehicle}-{mission}(slugified). - The current launch list is diffed against the state stored in a Val Town blob (
rocketLaunchMonitorStateV3). - Alerts are sent for:
- New launches not previously in state
- Updated launches where the date or time has changed
- State is saved back to the blob after every run.
- Confidence levels:
CONFIRMED(specific date + time),NET(date known, time TBD or "no earlier than"),TBD(only quarter/year known) - Launches with past
sortDateare filtered out of each run's results (they remain in stored state) - The blob accumulates all launches ever seen โ past launches are never removed
If you need to force a full re-alert of all current launches (e.g., after fixing a parser bug):
import { blob } from "https://esm.town/v/std/blob";
await blob.delete("rocketLaunchMonitorStateV3");
Run this as a one-off script in Val Town. The next monitor run will treat every launch as new and send a full alert email.
SpaceflightNow uses paired <h5> elements for the date header and vehicle/mission line. The original stripHtml added \n for </p>, </div>, </li> but not </h5>. If the raw HTML had no whitespace between the closing and opening </h5><h5> tags, the date and vehicle/mission would be concatenated onto one line:
NET April 1 Space Launch System โข Artemis 2
The parser would then:
- Set
rawDate = "NET April 1 Space Launch System โข Artemis 2"(full line) - Read the next line ("Launch time: 6:24 p.m. EDT") as the vehicle name
- Store the launch under a bogus ID like
florida-launch-time-624-pm-edt
Result: Artemis II was never alerted correctly. The "new" alert that fired on first detection had a garbled vehicle name.
Fix applied: Added </h[1-6]> to the \n-producing list. Also added a defensive fallback: after matching the date portion with dateHeaderRe, any remaining text on the same line is parsed as vehicle/mission instead of reading the next line.
When "Updated: March 03" appears on one line (as SpaceflightNow renders it), the inner scan loop's handler did:
j++; // advance past "Updated: March 03"
while (empty) j++;
j++; // intended to skip a separate date line โ incorrectly consumed the NEXT launch's date header
break;
This caused the launch entry immediately after any updated launch to be silently dropped.
Fix applied: The extra j++ now only fires when Updated: is on its own line (/^updated:\s*$/i). When the date is inline, a single j++ suffices.
testEmail.ts checked both launchSite and description for site pattern matching, but monitor.ts only checked launchSite. Launches where the site name appeared in the description but not the launch site field would be detected by the test email but silently dropped by the monitor.
Fix applied: monitor.ts now passes launchSite + " " + description to siteIdForText, consistent with testEmail.ts.
After HTML stripping, each launch block looks like:
NET April 1
Space Launch System โข Artemis 2
Launch time: 6:24 p.m. EDT (2224 UTC)
Launch site: Launch Complex 39B, Kennedy Space Center
[Description paragraph...]
Updated: March 03
Key structural notes:
- Date header and vehicle/mission are in separate
<h5>elements Updated:appears on a single line (inline with the date, e.g. "Updated: March 03")(UTC time)in launch time is stripped by the cleanerNETprefix means "No Earlier Than" โ the date is the floor, not exact