Skip to content

Commit 2efa7e6

Browse files
committed
Guestbook crash fix, X removal, photo refresh
1 parent ae71681 commit 2efa7e6

17 files changed

Lines changed: 334 additions & 406 deletions

README.md

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ These are all lessons from this build. A PCB respin would fix most of them at th
104104
- Outdoor weather + air quality context (via Cloudflare Worker proxy to Open-Meteo): conditions with day/night-aware icons, feels-like, dewpoint, wind direction, pressure trend, AQI + PM2.5, atmospheric CO₂, UV index
105105
- Guestbook with two-level reply threading, tombstone deletes, moderation queue, inline AI translation, rate limiting
106106
- Snake at /snake (also embedded on the 404 / offline / timeout pages) with two leaderboards (today's top scores + all-time top ten, top scores cross over automatically), replay viewer for top entries, quarterly Hall of Fame archive of past all-time boards, 3-letter initials with content blocklist, server-side replay verification, idle demo mode
107-
- `/chronicle`: a daily auto-generated diary the chip writes about itself, plus weekly, monthly, and quarterly reflection entries that aggregate prior periods. Around 30 observation detectors fold sensor extremes, visitor counts, weather, calendar events (equinoxes / first-of-month / season transitions), sensor-retire events, owner-defined personal anchors (birthdays, framing day), and self-aware-chip moments (curator absence, tinkering noticed, long-uptime milestones) into one of several narrative templates per cadence. Daily entries seal at chip-local midnight; weekly on Mondays; monthly on the 1st; quarterly at quarter starts. Permalinks for every entry, RSS feed, owner-curated notes that thread to X as replies, public today-in-progress preview card on the index, year/month accordion archive with template-id filter chips (milestones / records / anomalies / busy / quiet / reflections), keyboard navigation (←/→) on detail views, and per-entry share button.
107+
- `/chronicle`: a daily auto-generated diary the chip writes about itself, plus weekly, monthly, and quarterly reflection entries that aggregate prior periods. Around 30 observation detectors fold sensor extremes, visitor counts, weather, calendar events (equinoxes / first-of-month / season transitions), sensor-retire events, owner-defined personal anchors (birthdays, framing day), and self-aware-chip moments (curator absence, tinkering noticed, long-uptime milestones) into one of several narrative templates per cadence. Daily entries seal at chip-local midnight; weekly on Mondays; monthly on the 1st; quarterly at quarter starts. Permalinks for every entry, RSS feed, owner-curated notes, public today-in-progress preview card on the index, year/month accordion archive with template-id filter chips (milestones / records / anomalies / busy / quiet / reflections), keyboard navigation (←/→) on detail views, and per-entry share button.
108108
- Dark mode, responsive, SRI-pinned CDN scripts, no tracking
109109

110110
**Firmware**
@@ -135,7 +135,6 @@ These are all lessons from this build. A PCB respin would fix most of them at th
135135
- Optional SMTP2GO integration for guestbook-pending alerts, dead-man's-switch (device silent >N hours), backup failures, and overdue-backup warnings
136136
- Optional daily off-site backups to Cloudflare R2 with GFS rotation (7 daily + 4 weekly + 12 monthly + yearly) and sha256 integrity manifests; Worker also writes a daily full Durable Object snapshot to `state/do-snapshot/YYYY-MM-DD.json` (30-day retention) so non-chronicle DO state (snake leaderboards + season archives + replays, caches) is recoverable independently if DO is ever wiped
137137
- Optional Shelly Gen 2+ smart plug integration for live power monitoring: live-wattage banner on homepage, power chart, energy column in CSV logs, per-period energy on `/history` cards, lifetime cost + CO₂ totals on homepage and `/about` (when grid rates are configured), admin observability panel + self-test entry
138-
- Optional X / Twitter auto-post: each sealed Chronicle entry crossposts once via the X API v2 (OAuth 1.0a HMAC-SHA1 signed in-Worker). Owner notes added later thread under as replies. Idempotent via `posted_to_x` and `note_x_tweet_id` flags so DO restarts and re-seals don't double-post. Silently skipped if any of the 4 secrets are unset
139138
- Security headers, no-cache list for dynamic endpoints
140139
- RSS feeds (`/changelog.rss`, `/guestbook.rss`, `/chronicle.rss`), `sitemap.xml`, `robots.txt`, `.well-known/security.txt`
141140

@@ -302,25 +301,6 @@ The binding is declared in `wrangler.toml`. If the binding isn't present, the Wo
302301

303302
For single-file fixes, download one object from R2 and drop it in via the admin file manager. No full restore needed.
304303

305-
### 8. X / Twitter auto-post (optional)
306-
307-
Each Chronicle entry crossposts once to X. Useful as a launch smoke test (the seeded launch entry tweets on first deploy) and for ongoing reach. All 4 secrets must be set or the post path silently no-ops, so the seal flow is never blocked by missing creds.
308-
309-
Create an X developer app with **read + write** permission, generate an access token, and:
310-
311-
```bash
312-
wrangler secret put X_API_KEY # consumer key
313-
wrangler secret put X_API_SECRET # consumer secret
314-
wrangler secret put X_ACCESS_TOKEN # access token
315-
wrangler secret put X_ACCESS_SECRET # access token secret
316-
```
317-
318-
Tweets carry a `Day N · {date}` header, the full entry body, and a permalink to `helloesp.com/chronicle/<date>`. The character budget defaults to 25,000 (X Premium's per-tweet ceiling) so weekly/monthly/quarterly reflections post in full; truncation at last-word-boundary still kicks in past that limit. Forks without Premium should drop the cap in `_chronicleFormatTweet` from 25000 to 280 (X's t.co counts URLs as 23 chars regardless of length, accounted for in the budget). Idempotency uses a `posted_to_x: true` flag stored on the entry itself, so DO eviction, isolate restarts, and same-day reseals can't double-post.
319-
320-
**Owner notes thread under as replies.** Adding a note via the admin panel posts a reply tweet to the original Chronicle tweet, so the X timeline mirrors the website's structure (chip's voice + curatorial annotation). First non-empty note posts; subsequent edits don't re-post (X API v2 has no free tweet-edit). Tracked via `note_x_tweet_id`. Same silent-skip rules apply if creds are missing or the original tweet failed.
321-
322-
OAuth 1.0a is signed in-Worker via `crypto.subtle.HMAC-SHA1`; no third-party libraries.
323-
324304
## Security
325305

326306
- `config.txt` is in `.gitignore`. Do not commit it. Treat `WORKER_SECRET` and `device_key` like passwords.

data/about.html

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
<meta property="og:image:alt" content="HelloESP: a website running on an ESP32">
1919
<meta property="og:type" content="website">
2020
<meta property="og:url" content="https://helloesp.com/about">
21-
<meta name="twitter:card" content="summary_large_image">
22-
<meta name="twitter:site" content="@HelloESP32">
23-
<meta name="twitter:title" content="About / HelloESP">
24-
<meta name="twitter:description" content="The story behind HelloESP: a public website running on a single ESP32 microcontroller, mounted on a wall in my house.">
25-
<meta name="twitter:image" content="https://helloesp.com/og-banner.jpg">
26-
<meta name="twitter:image:alt" content="HelloESP: a website running on an ESP32">
2721
<link rel="canonical" href="https://helloesp.com/about">
2822
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
2923
<link rel="icon" type="image/png" href="/favicon.png">
@@ -292,7 +286,7 @@ <h1>About</h1>
292286
</div>
293287

294288
<div class="prose" style="margin-top:32px;">
295-
<p>While you're here, the <a href="/guestbook">guestbook</a> is open if you'd like to leave a note. The <a href="/console">live feed</a> shows who else is visiting right now. The <a href="/history">archive</a> shows how the site has grown over time. The <a href="/">homepage</a> has the live sensor readings from the room the device is sitting in. The <a href="/chronicle">chronicle</a> is the chip's daily diary; new entries also post to <a href="https://x.com/HelloESP32" target="_blank" rel="noopener">@HelloESP32</a> on X.</p>
289+
<p>While you're here, the <a href="/guestbook">guestbook</a> is open if you'd like to leave a note. The <a href="/console">live feed</a> shows who else is visiting right now. The <a href="/history">archive</a> shows how the site has grown over time. The <a href="/">homepage</a> has the live sensor readings from the room the device is sitting in. The <a href="/chronicle">chronicle</a> is the chip's daily diary.</p>
296290
</div>
297291

298292
<div class="closing">

data/about.html.gz

-92 Bytes
Binary file not shown.

data/chronicle.html

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
<meta property="og:image:alt" content="HelloESP: a website running on an ESP32">
1919
<meta property="og:type" content="website">
2020
<meta property="og:url" content="https://helloesp.com/chronicle">
21-
<meta name="twitter:card" content="summary_large_image">
22-
<meta name="twitter:site" content="@HelloESP32">
23-
<meta name="twitter:title" content="The Chronicle / HelloESP">
24-
<meta name="twitter:description" content="A daily entry HelloESP writes about itself: visitors, sensor extremes, weather, and milestones, archived from launch onward.">
25-
<meta name="twitter:image" content="https://helloesp.com/og-banner.jpg">
26-
<meta name="twitter:image:alt" content="HelloESP: a website running on an ESP32">
2721
<link rel="canonical" href="https://helloesp.com/chronicle">
2822
<link rel="alternate" type="application/rss+xml" title="HelloESP Chronicle" href="/chronicle.rss">
2923
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
@@ -113,8 +107,7 @@
113107
line-height: 1.1;
114108
margin-bottom: 16px;
115109
}
116-
h1 .rss-link,
117-
h1 .x-link {
110+
h1 .rss-link {
118111
font-size: 0.4em;
119112
vertical-align: middle;
120113
margin-left: 8px;
@@ -123,7 +116,6 @@
123116
transition: color 0.15s;
124117
}
125118
h1 .rss-link:hover { color: #f26522; }
126-
h1 .x-link:hover { color: var(--ink); }
127119

128120
.desc {
129121
font-size: 13px;
@@ -726,9 +718,8 @@
726718
</ul>
727719
</nav>
728720

729-
<h1>The Chronicle<a class="rss-link" href="/chronicle.rss" aria-label="Subscribe to Chronicle via RSS" title="Subscribe via RSS"><i class="fa-solid fa-rss"></i></a><a class="x-link" href="https://x.com/HelloESP32" target="_blank" rel="noopener" aria-label="Follow Chronicle on X" title="Follow on X"><i class="fa-brands fa-x-twitter"></i></a></h1>
721+
<h1>The Chronicle<a class="rss-link" href="/chronicle.rss" aria-label="Subscribe to Chronicle via RSS" title="Subscribe via RSS"><i class="fa-solid fa-rss"></i></a></h1>
730722
<p class="desc">A daily entry the chip writes about itself. Auto-generated from sensor readings, visitor counts, and weather, archived from launch onward.</p>
731-
<p class="page-subhead">New entries also post to <a href="https://x.com/HelloESP32" target="_blank" rel="noopener">@HelloESP32</a> on X.</p>
732723

733724
<div class="page-jump">
734725
<label for="chronicle-jump">Jump to date:</label>

data/chronicle.html.gz

-144 Bytes
Binary file not shown.

data/console.html

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
<meta property="og:image:alt" content="HelloESP: a website running on an ESP32">
1919
<meta property="og:type" content="website">
2020
<meta property="og:url" content="https://helloesp.com/console">
21-
<meta name="twitter:card" content="summary_large_image">
22-
<meta name="twitter:site" content="@HelloESP32">
23-
<meta name="twitter:title" content="Console / HelloESP">
24-
<meta name="twitter:description" content="Live feed of recent public requests to HelloESP, with country flags, paths, and timestamps.">
25-
<meta name="twitter:image" content="https://helloesp.com/og-banner.jpg">
26-
<meta name="twitter:image:alt" content="HelloESP: a website running on an ESP32">
2721
<link rel="canonical" href="https://helloesp.com/console">
2822
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
2923
<link rel="icon" type="image/png" href="/favicon.png">

data/console.html.gz

-54 Bytes
Binary file not shown.

data/guestbook.html

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
<meta property="og:image:alt" content="HelloESP: a website running on an ESP32">
1919
<meta property="og:type" content="website">
2020
<meta property="og:url" content="https://helloesp.com/guestbook">
21-
<meta name="twitter:card" content="summary_large_image">
22-
<meta name="twitter:site" content="@HelloESP32">
23-
<meta name="twitter:title" content="Guestbook / HelloESP">
24-
<meta name="twitter:description" content="Sign the guestbook on a public website hosted by a single ESP32 microcontroller.">
25-
<meta name="twitter:image" content="https://helloesp.com/og-banner.jpg">
26-
<meta name="twitter:image:alt" content="HelloESP: a website running on an ESP32">
2721
<link rel="canonical" href="https://helloesp.com/guestbook">
2822
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
2923
<link rel="icon" type="image/png" href="/favicon.png">

data/guestbook.html.gz

-60 Bytes
Binary file not shown.

data/history.html

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
<meta property="og:image:alt" content="HelloESP: a website running on an ESP32">
1919
<meta property="og:type" content="website">
2020
<meta property="og:url" content="https://helloesp.com/history">
21-
<meta name="twitter:card" content="summary_large_image">
22-
<meta name="twitter:site" content="@HelloESP32">
23-
<meta name="twitter:title" content="History / HelloESP">
24-
<meta name="twitter:description" content="Weekly, monthly, and yearly stats archives from HelloESP: visitor charts, sensor extremes, and a Hall of Fame tracking the chip's lifetime records.">
25-
<meta name="twitter:image" content="https://helloesp.com/og-banner.jpg">
26-
<meta name="twitter:image:alt" content="HelloESP: a website running on an ESP32">
2721
<link rel="canonical" href="https://helloesp.com/history">
2822
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
2923
<link rel="icon" type="image/png" href="/favicon.png">

0 commit comments

Comments
 (0)