ca_highlights
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
nostalgia‑drip daily tweets highlighting bangers from the community archive.
- runs every 15 min via val.town
- builds a queue of tweets once per utc‑day (00‑:)
- posts each item at the same hour & minute the original tweet dropped, give or take the 15 min tick
- uses supabase for archive lookup, sqlite (val.fs) for local state, and oauth 1.0a creds to hit
POST /2/tweets
layer | purpose |
---|---|
communityArchiveBot.ts | cron handler, queue builder, queue poster |
to_post_queue (sqlite) | rows waiting to go live — tweet_id , text , scheduled_at |
posted_tweets (sqlite) | permanent log of everything we already surfaced (plus daily dummy rows) |
enriched_tweets (supabase) | raw firehose of historical tweets (must include username , favorite_count , etc.) |
all_account (supabase) | whitelist of public accounts we'll resurface |
- every run (*/15 min):
cronValHandler()
executes. - queue build step (once/day):
- if nothing queued for today and no “dummy” row in
posted_tweets
, callselectHighlights()
. - result filtered & capped: 3‑12 tweets, ≤2 per user/year, likes ≥100.
- craft new tweet text (truncates to fit, adds credit + link).
- for each, calculate today’s
scheduled_at
matching originalHH:MM
(utc) and insert intoto_post_queue
. - if zero highlights, insert
dummy-YYYY-MM-DD
intoposted_tweets
to mark the attempt.
- if nothing queued for today and no “dummy” row in
- posting step:
- grab any queue rows with
scheduled_at ≤ now + 15 min
. postTweet()
signs the request with oauth1 and fires to x api v2.- on success, move row to
posted_tweets
.
- grab any queue rows with
- fork or create a val named
communityArchiveBot
. - add secrets (val → secrets pane):
NEXT_PUBLIC_SUPABASE_URL
SUPABASE_SERVICE_ROLE
X_API_KEY
,X_API_SECRET
(consumer key/secret)X_ACCESS_TOKEN
,X_ACCESS_TOKEN_SECRET
(user token/secret)- optional
X_USERNAME
(bot’s handle for nicer logs)
- set schedule to
*/15 * * * *
(val cron expression). - ship it.
note : oauth2 user‑bearer works too, but basic tier is happy with oauth1 and the four tokens are easier to yank from the dev portal.
create table enriched_tweets ( tweet_id text primary key, account_id text, username text, created_at timestamptz, full_text text, favorite_count int, reply_to_tweet_id text ); create table all_account ( account_id text primary key );
no writes are performed on supabase — it’s read‑only.
// peek at upcoming queue
await previewQueue();
// manual fire
await cronValHandler({ lastRunAt: undefined });
Cron