Most "prompt of the day" bots are a random line of text in a Slack channel. Nobody reads them, because a prompt with no output next to it is just a sentence. I wanted the opposite: one prompt a day, with the clip that prompt actually produced , and no credentials to set up. It turned into a small n8n workflow and a much more interesting question — what does a prompt that actually works look like, statistically? The workflow Six nodes, no API key, no account: Schedule trigger — once a day. HTTP Request — fetch the site's public sitemap.xml . Code — filter it down to prompt detail pages, pick one by day % total . HTTP Request — fetch that page as text. HTML — extract h1 , the pre blocks, and the JSON-LD script tags. Code — pull the example video out of the VideoObject schema, assemble a Slack-flavoured message. HTTP Request — POST to a Slack or Discord webhook. The source is a public library of Seedance 2 video prompts — 150 of them, each with the clip it generated. Three things that made it work Rotate, don't randomize. Math.floor(Date.now() / 86400000) % urls.length gives you one prompt per day that is stable across re-runs. Math.random() gives you duplicates within a week and a different result every time you debug. const urls = [... xml . matchAll ( / ([^ < ] + ) < / loc>/g )] . map (( m ) => m [ 1 ]. trim ()) . filter (( u ) => u . includes ( ' /prompt/ ' )) . filter (( u ) => ! u . includes ( ' /prompt/category/ ' )); const dayIndex = Math . floor ( Date . now () / 86400000 ); const url = urls [ dayIndex % urls . length ]; Read the schema, not the layout. Every prompt page ships a VideoObject in JSON-LD with name , description and contentUrl . That is a stable contract; the rendered markup is not. Scraping the schema means a CSS refactor on their side does not silently break my workflow. for ( const raw of item . structuredData || []) { const parsed = JSON . parse ( raw ); const blocks = Array . isArray ( parsed ) ? parsed : [ parsed ]; const found = blocks . find (( b ) => b [ ' @type ' ] === ' VideoObject ' ); if ( found ) { video = found ; break ; } } Count your selectors before you trust index 0. Each page has two
blocks: the Japanese original and the English version. cssSelector: "pre" with returnArray: false silently gives you the first one — so my first run posted Japanese into an English channel and looked completely fine. Set returnArray: true and choose explicitly. The part I didn't expect: the prompts are short Since I had all 150 in a list, I counted them. Median prompt length is 152 characters . Longest is 215. That is roughly one sentence each for style, place, subject and motion. Every "advanced prompting guide" I have read implies the opposite — that control comes from length. In this corpus, it doesn't exist. Long prompts tend to contain contradicting instructions, and the model drops one of them, non-deterministically. Element frequency across the 150: Element Appears in Camera / lens / framing 69 / 150 (46%) Duration stated in seconds 63 / 150 (42%) Lighting 55 / 150 (37%) Cut structure 22 / 150 (15%) Audio (ambience, SFX, dialogue, ASMR) 22 / 150 (15%) Resolution (4K / 8K) 14 / 150 (9%) Slow motion 4 / 150 (3%) Two readings I'd stand behind: Camera direction is not mandatory. 54% of these prompts never mention a camera. It earns its characters when distance changes the meaning of the shot — macro for texture, wide for scale — and otherwise it is filler. Audio is the cheapest differentiator. Only 15% specify it, and it is most of the gap between "an AI clip" and "a finished shot". A third of the corpus (34/150) splits the prompt by time range rather than describing one continuous action: [00:00-00:05] intro, camera enters from behind the subject
[00:05-00:10] turn, light source switches
[00:10-00:15] wide, full scene That form clusters hard: sci-fi (9), cinematic (7), people (5) — and it is almost absent from scenery (2) and food (0). It shows up exactly where order carries meaning . For a single continuous shot, stating total duration is enough. And 32 of 150 need a reference image rather than text alone. The tell is simple: the moment a prompt points at a specific person or a specific frame instead of a kind of thing, text can no longer specify it. That is the line between text-to-video and image-to-video . Setup Create an Incoming Webhook in Slack, or a Webhook in a Discord channel. Paste it into the last node. Discord only: append /slack to the webhook URL — it then accepts the same { "text": ... } payload. Activate. That's the whole thing. Everything it reads is public, so there is no credential step and nothing to rotate. The prompts themselves are written against Seedance 2.5 ; if you have not run one before, the walkthrough is shorter than this post. I wrote the full breakdown of all 150 — element frequency, duration patterns, the reference-image split by category — as a standalone reference (Japanese). There is also a Japanese write-up of the implementation on Qiita if that is your reading language. If you build something similar against another corpus, the transferable part is not the scraping — it is checking whether the thing you are scraping publishes structured data first. It usually does, and it is usually more stable than the HTML around it.
