Snow forecast notification service. Get Slack alerts when snow is in the forecast for your saved locations.
Snow forecast data comes from the NOAA HRRR (High-Resolution Rapid Refresh) model, made accessible as analysis-ready cloud-optimized data by dynamical.org and served via the Earthmover EDR API.
┌─────────────────┐
│ KV Store │
│ (locations) │
└────────┬────────┘
│
▼
┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Arraylake │─webhook─▶│ Worker │─────────▶│ Earthmover │
│ (HRRR data) │ │ │◀─────────│ EDR API │
└─────────────┘ └────────┬────────┘ └─────────────────┘
│
┌──────────────────────────┤
│ │ snow forecasted?
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Slack commands │ │ Slack alerts │
│ /snowbot add │ │ │
│ /snowbot list │ │ │
└─────────────────┘ └─────────────────┘
- Add locations via Slack:
/snowbot add "Lake Tahoe" 39.0968 -120.0324 - When HRRR forecast data updates, Arraylake sends a webhook to the worker
- Worker queries Earthmover EDR for snow forecast at each location
- If snow is forecasted, a Slack notification is sent
/snowbot add "Name" lat lon- Add a location/snowbot list- List all locations/snowbot remove "Name"- Remove a location/snowbot help- Show help
🚨☃️🚨☃️🚨☃️🚨☃️🚨
🌨️ *SNOW ALERT!* 🌨️
❄️ *Tahoe City*
🕒 Sun 1/19 2pm-8pm, Mon 1/20 6am-12pm
❄️ *Mammoth Lakes*
🕒 Sun 1/19 4pm-11pm
🚨☃️🚨☃️🚨☃️🚨☃️🚨
npm install
npm run devnpm run deployThis app uses cloudflare for all infrastructure. Create a cloudflare account and install the wrangler CLI.
Create a KV namespace to store location data:
# Create the KV namespace
npx wrangler kv namespace create SNOW_LOCATIONS
# Note the ID from the output, then update wrangler.json:
# "kv_namespaces": [
# { "binding": "SNOW_LOCATIONS", "id": "<your-namespace-id>" }
# ]For local development, create a preview namespace:
npx wrangler kv namespace create SNOW_LOCATIONS --preview- Go to api.slack.com/apps and click Create New App
- Choose From scratch, name it "Snowbot", and select your workspace
- Navigate to OAuth & Permissions in the sidebar
- Under Scopes > Bot Token Scopes, add:
chat:write- Send messagescommands- Handle slash commands
- Navigate to Slash Commands in the sidebar
- Click Create New Command:
- Command:
/snowbot - Request URL:
https://your-worker.workers.dev/api/slack/commands - Short Description: Manage snow alert locations
- Usage Hint:
[add|list|remove|help]
- Command:
- Navigate to Install App in the sidebar
- Click Install to Workspace and authorize
- Copy the Bot User OAuth Token (starts with
xoxb-)
- Navigate to Basic Information in the sidebar
- Under App Credentials, copy the Signing Secret
- In Slack, right-click the channel for snow alerts
- Click View channel details
- Copy the Channel ID at the bottom of the modal
Set these secrets via wrangler secret put <SECRET_NAME>:
wrangler secret put SLACK_BOT_TOKEN # Bot token (xoxb-...)
wrangler secret put SLACK_DEFAULT_CHANNEL # Channel ID for alerts
wrangler secret put SLACK_SIGNING_SECRET # Signing secret from app credentials
wrangler secret put FLUX_TOKEN # Earthmover EDR API token
wrangler secret put WEBHOOK_SECRET # Secret for webhook verification| Secret | Description |
|---|---|
SLACK_BOT_TOKEN |
Bot token for posting messages |
SLACK_DEFAULT_CHANNEL |
Channel ID for snow alerts |
SLACK_SIGNING_SECRET |
For verifying slash commands |
FLUX_TOKEN |
Earthmover EDR API token |
WEBHOOK_SECRET |
Shared secret for verifying incoming webhooks |
When configuring the upstream webhook (e.g., Arraylake), include the X-Secret-Token header with the value of your WEBHOOK_SECRET:
POST /api/on-forecast-update
X-Secret-Token: <your-webhook-secret>