themountain_sync is a Val Town script that reads bolded passages from a Notion page and writes the current quote set into Val Town blob storage for the themountain app to display.
The source of truth is the Notion page:
- title:
the mountain is you reading - page ID:
34ac869b-2f04-80cf-a766-ed382650df33
The sync script is run manually from the Val Town editor after that page is edited.
On each run, the script:
- Fetches the Notion page block tree recursively.
- Extracts bold text runs from the block content.
- Normalizes and deduplicates the extracted quotes.
- Compares the extracted source quotes against the currently cached blob data.
- Rewrites blob storage so the stored quote list matches the current Notion source exactly.
- Writes sync metadata describing what happened.
The important design choice is that Notion is now authoritative.
This script does not keep an append-only archive anymore. If a quote disappears from the extracted Notion source, it is removed from blob storage on the next sync.
This val is a script, not an HTTP handler.
main()contains the sync logic.if (import.meta.main)callsmain()when you pressRunin Val Town.- The script emits structured JSON logs during the run.
Without the import.meta.main block, loading the file would not execute the sync.
Set these in the Val Town left sidebar:
NOTION_TOKENNOTION_PAGE_ID
Current page ID:
NOTION_PAGE_ID=34ac869b-2f04-80cf-a766-ed382650df33
NOTION_TOKEN must belong to the Notion integration that has access to that page.
If the page ID is correct but the integration is not shared onto the page, Notion returns:
404 object_not_found
In this setup, that usually means the page exists but the integration behind NOTION_TOKEN cannot read it.
To fix that:
- Open
the mountain is you readingin Notion. - Click
Share. - Add the integration used by
NOTION_TOKEN.
The script writes to these blob keys:
themountain_quotes_v1themountain_sync_meta_v1
themountain_quotes_v1
- stores the current synchronized quote list
- is what the
themountainapp reads on every request
themountain_sync_meta_v1
sourceHashsourceQuoteCountcachedQuoteCountlastSyncedAtlastChangedAtlastAddedCountnotionPageId
main.ts contains a SEEDED_QUOTES array.
That seeded list is only a bootstrap fallback for empty or unreadable blob storage. It is not the long-term source of truth. Once sync has written blob data, the live app should be driven by blob storage, not by the seed list.
Successful runs can currently return:
unchangedupdatedreconciled
unchanged
- the current Notion source hash matches the previous sync
- the cached blob quote list already matches the current extracted source
updated
- the Notion source hash changed
- blob storage was rewritten to the newly extracted source quotes
reconciled
- the current Notion source hash matches the previous sync hash
- but blob storage did not match the current extracted source
- blob storage was rewritten to bring it back in sync
This reconciled path matters because it repairs stale cached quote lists even when the source page itself has not changed.
The script emits structured logs that are useful when debugging:
sync.startsync.fetch.beginsync.fetch.completesync.fetch.samplesync.hash.computedsync.cache.loadedsync.diff.computedsync.cache.quotes_writtensync.cache.meta_writtensync.completesync.failed
The most useful debug event is sync.fetch.sample, which logs:
sourceQuoteCountfirstFiveQuoteslastFiveQuotes
That makes it easy to verify whether the extractor is seeing the beginning and end of the Notion page and whether a specific formatting edit is actually present in the API output.
The extractor walks the Notion block tree recursively and scans nested rich-text arrays inside each block payload.
This is important because Notion does not always expose useful text in a single top-level rich_text field for every block shape. Earlier versions of this script missed valid bold content because the traversal was too narrow.
Useful local commands:
deno check --allow-import main.ts vt status vt push vt pull vt tail
This repo is linked to the Val Town project through .vt/state.json.
themountain_sync writes the quote data.
themountain reads themountain_quotes_v1 and renders the quote app.
If the sync output is correct but the app still looks wrong, the next thing to check is whether blob storage was actually rewritten and whether the app is reading the same blob key.
When debugging this system, reason in this order:
- Is Notion returning the expected bold text?
- Is
themountain_syncextracting the expected quotes? - Did the sync write the updated quote list to
themountain_quotes_v1? - Is
themountainreading that same blob key and rendering the resulting list?
That order avoids mixing up extraction bugs, sync bugs, and app display bugs.