A fully autonomous (de)motivational meme website. Once per day, an AI agent finds or invents a new trash-animal blessing, renders it in early-2000s glitter WordArt, and publishes it β with zero redeploys and zero humans involved. Visitors and per-blessing adoration are counted in a real Postgres database. The whole thing is one npm project on Wasmer Edge.
Wasmer Edge auto-detects Node projects. A plain package.json with a
start script that binds process.env.PORT is the entire contract:
{
"type": "module",
"scripts": { "start": "node server/index.js" },
"dependencies": { "express": "^5", "pg": "^8", "@openai/agents": "^0.1" }
}
Deploy with wasmer deploy --build-remote. Once the repo is
linked to the app (import at wasmer.io/new
or connect it in the dashboard), git push becomes the
deploy β Wasmer builds remotely on every push.
Two platform capabilities carry the design (plus the daily execute job, shown in step 5 β it's safe in here because it contains no secrets):
kind: wasmer.io/App.v0
name: ur-blessing-machine
package: .
capabilities:
database:
engine: postgres # managed pg, creds injected as DB_* env vars
volumes:
- name: blessings
mount: /data/blessings # s3-backed, survives deploys, shared rw
The volume is the trick: the agent writes images + a JSON manifest there, the server serves it statically, and the frontend merges it with the seed manifest β so new content appears without redeploying.
The managed database injects DB_HOST, DB_PORT,
DB_NAME, DB_USERNAME, DB_PASSWORD.
One gotcha that will eat ur afternoon: the server requires TLS, and
node-postgres doesn't enable it by default:
new pg.Pool({ ..., ssl: { rejectUnauthorized: false } })
Migrate from ur laptop by revealing the creds
(wasmer app secret reveal DB_HOST β¦) and running
psql with PGSSLMODE=require. This site's counter is two
tiny tables: visits(day, total) and blessing_views(id, views),
upserted with ON CONFLICT β¦ DO UPDATE.
An OpenAI Agents SDK
scout with a web-search tool hunts for an existing meme; if the internet disappoints,
it invents a caption ("sincere, slightly unhinged, lowercase") and
gpt-image-1 renders it with the text baked in, glitter and all.
Structured output via a zod schema keeps the result machine-usable:
const scout = new Agent({
model: 'gpt-5',
tools: [webSearchTool()],
outputType: MemeConcept, // zod: animal, caption, mood, β¦
instructions: 'STRICTLY NO RATSβ¦',
});
The daily execute job runs the agent's entry script directly on Edge and writes straight to the mounted volume. No CI, no external cron, no relay, no endpoint.
API keys live in app secrets (wasmer app secret create OPENAI_API_KEY β¦),
injected as env vars on deploy. And here's the beautiful part: the daily
job is an execute cronjob β it doesn't call an HTTP endpoint, it
starts an instance of the app package on Edge and runs the agent
script directly:
jobs:
- name: daily-blessing
trigger: '0 0 * * *'
action:
execute:
command: start # the workload's edgejs commandβ¦
cli_args:
- agent/run.js # β¦running the agent instead of the server
The exec instance gets the volume mounted and every app secret as an
env var (we checked). So there is no trigger endpoint, no auth token,
no header to protect β an earlier version of this site had a whole
token-authed POST /api/trigger-blessing apparatus, and we
deleted all of it. U cannot hack an endpoint that does not exist.
Fine print: jobs (like secrets) only propagate on the next deploy;
and the yaml timeout is currently ignored for config execute
jobs (u get 180s β a generation run takes ~2min, so it fits, barely).
Every run's status + full logs are queryable via the
CronJob.invocations GraphQL field, which is how we verified
all of this.
Zero-build vanilla HTML with a deterministic daily pick β everyone sees the same
blessing all day (epochDay Γ 2654435761 mod n, a golden-ratio hash so
consecutive days don't walk the list in order). Deep links are plain URL hashes
(#some-blessing-id), and the hall of fame ranks every blessing ever by
adoration count from /api/fame. Also: sparkle cursor trail. Non-negotiable.
You don't have to build any of this by hand. This entire guide exists as a self-contained agent skill β complete working code for every file, the full deployment sequence, and every gotcha we hit so ur agent doesn't have to. Paste this to your coding agent (Claude Code, Codex, whatever):
Read https://trash.delivery/skill.md and follow it. Build me a daily AI-generated site about <YOUR THEME HERE>. Go.
The agent picks a name, writes the code, deploys, sets secrets, migrates the database, and verifies the whole loop end to end. That claim is not hypothetical: this very site was built exactly that way β the skill is the distilled transcript of an agent doing it, mistakes removed.
Do NOT paste ur API keys into the chat. The skill instructs the
agent to refuse them and walk u through the safe way instead:
wasmer login in ur own terminal (the agent never sees the
token) and keys as env vars the agent references but never reads. Chat
logs live forever. Treat them like the dumpster: assume everything in
there will be found by a raccoon eventually.
npm init -y && npm i express pg @openai/agents zod # write server/, agent/, public/, app.yaml (see above) wasmer deploy --build-remote wasmer app secret create OPENAI_API_KEY sk-β¦ PGSSLMODE=require psql β¦ -f migrations.sql wasmer deploy --build-remote # again β secrets & jobs apply on redeploy
Or deploy with git: link the repo to the app first β import it at
wasmer.io/new, or connect it from the app
dashboard β and from then on every git push builds and deploys
automatically. (A git push without the link does nothing to ur
app. Ask us how we know.)
Or skip the typing entirely: the full source lives at github.com/baalimago/motivational-racoon-and-friends β fork it, swap the animals, ship ur own blessings.