Recipe · Product launch
Sign up and post
Opens a forum as this profile, and posts. If the profile is already signed in it keeps that account and goes straight to writing; if it is not, it signs up — with the handle you name, or one your model invents, and the profile's own password, or twenty random characters. It asks your model for a title and a body, submits the post, and files the account, the credential and the link in Launch posts. Every run ends with a row there, including the ones that fail: a dead page, a taken name or a rate-limited submit are recorded in the site's own words rather than raised as an error. Shipped pointed at Hacker News; the URLs are parameters and the form selectors are HN's.
What it does
A new account posting its own product link is the pattern forum moderation is tuned for — on Hacker News especially, where new accounts are rate-limited and a promotional first post is commonly flagged. Read what the model wrote before you let it submit, and expect the first one not to stick.
Keeps the account this profile is already signed into, or signs up as one — asks your model for a title and a body, submits the post, and files the account and the link.
It runs against one profile, through that profile's own proxy and with its own cookies — so the pages load the way that account's owner would see them. It navigates, so give it a profile whose session you are happy to have in use.
The 43 steps
The real tree, read out of the pack the launcher ships. Indentation is nesting: the steps under a loop run once per row, and the ones under a branch run only when the condition above them holds. Every {{…}} is a value filled in at run time — from the row being walked, from a setting on the run, or from the profile itself.
setVarStart the row under this profileSet account_namegotoOpen the submit pageGo to {{vars.submit_url}}on failure: continueevaluateRead the page: loaded, signed in, whoRun scripton failure: continueifOnly if nobody has named this account yetIf {{vars.page.needs_name}} equalsYes
aiPromptAsk the model for a nameAsk AI into ai_handleon failure: continueifOnly if the page is actually thereIf {{vars.page.route}} notEqualsYes
evaluateSettle on the account nameRun scripton failure: continueevaluateSettle on the passwordRun scripton failure: continueifOnly if it is not signed in yetIf {{vars.page.route}} equalsYes
gotoOpen the sign-up pageGo to {{vars.signup_url}}on failure: continueifOnly if this site shows a captchaIf iframe[src*="recaptcha"], iframe[src*="hcaptcha"], .h-captcha, .g-recap… selectorExistsYes
solveCaptchaSolve itSolve the captcha on the pageon failure: continueloopTry up to three namesLoop timesEach time
ifOnly while it has not signed upIf {{vars.signup.ok}} equalsYes
evaluateA different name, if this is a retryRun scripton failure: continuetypeType the account nameType into form:has(input[name="creating"]) input[name="acct"]on failure: continuetypeType the passwordType into form:has(input[name="creating"]) input[name="pw"]on failure: continueclickCreate the accountClick form:has(input[name="creating"]) input[type="submit"]on failure: continueevaluateDid it take?Run scripton failure: continuegotoBack to the form for another tryGo to {{vars.signup_url}}on failure: continueifOnly if the account now existsIf {{vars.signup.ok}} equalsYes
ifOnly if the site confirms by emailIf {{vars.confirm_email}} equalsYes
waitForEmailWait for the confirmationWait for mail matching verify|confirm|activateon failure: continueextractEmailLinkTake the link out of itTake a link from {{vars.mail}} into confirm_linkon failure: continuegotoOpen itGo to {{vars.confirm_link}}on failure: continueifReady, because it was already signed inIf {{vars.page.route}} equalsYes
setVarMark it readySet stageifReady, because the sign-up landedIf {{vars.signup.ok}} equalsYes
setVarMark it readySet stageifOnly with an account to post fromIf {{vars.stage}} equalsYes
aiPromptWrite the postAsk AI into poston failure: continueifOnly if the model actually wrote oneIf {{vars.post.title}} existsYes
gotoOpen the submit pageGo to {{vars.submit_url}}on failure: continuetypeTitleType into input[name="title"]on failure: continuetypeLinkType into input[name="url"]on failure: continuetypeBodyType into textarea[name="text"]on failure: continueclickSubmit itClick input[type="submit"]on failure: continueevaluateDid it go up?Run scripton failure: continueifOnly if something went upIf {{vars.submitted.ok}} equalsYes
gotoOpen this account's submissionsGo to https://news.ycombinator.com/submitted?id={{vars.account_name}}on failure: continueevaluateRead the post linkRun scripton failure: continueevaluateDecide what happenedRun scripton failure: continuesaveRowsFile what happenedSave to Launch postson failure: continueEach of those is one of the step types on the automation reference, with the same fields the editor shows and the same fields an agent is handed over the local API.
The tables it uses
These load with the recipe. A dataset is a typed table your workspace owns — the columns are named and typed up front so the steps can address them, and every one of them is yours to rename, extend or fill from a file afterwards.
Launch posts
writesOne row per post: the site, the account that made it, the link it went to and what became of it.
- handle
- Handle · text
- site
- Site · text
- password
- Password · text
- title
- Title · text
- body
- Body · longText
- post_url
- Post URL · url
- posted_at
- Posted at · datetime
- status
- Status · select · Posted | Flagged | Removed | Failed
- reason
- Reason · longText
Re-running updates the row it already wrote rather than adding a second one. That is what the match column in the save step is for, and it is the difference between a status check and a table that doubles in size every pass.
What it asks you for
Settings are filled in when the run starts, and every profile can hold its own values — which is how one workflow serves a whole folder of accounts.
- handle
- Account name · text
- signup_url
- Sign-up page · text
- submit_url
- Submit page · text
- link
- Link to post · text
- angle
- What it is · textarea
- confirm_email
- Does the site email a confirmation link? · select
Optional. If this profile is already signed in, that account wins whatever you put here. Otherwise this is the name it signs up with — and if you leave it empty, your model invents one that reads like a person and it is filed in Launch posts with its password.
The page carrying the create-account form. Only opened when the profile turns out not to be signed in already.
The page carrying the new-post form. Opened first, before anything is typed, because whether it serves that form is how the run knows it is signed in — and whether it loads at all is how the run knows the proxy has a route out.
The URL the post points at.
One phrase, in your own words, describing the thing. This is the only input the model gets about the product — a vague phrase here produces a vague post, and no amount of prompt does better than a specific one.
Hacker News does not. Set yes and the run waits for the mail in this profile's own mailbox, opens the link, and carries on.
Loading it
In the launcher, open Automations, choose Load a starter pack, and pick Product launch. Untick anything you do not want. The tables land first, then the workflows, then a project called Launch that links them together.
What arrives is an ordinary automation row. Open it in the editor, change a step, rename it, delete it — nothing in the app treats it as special afterwards, and loading the pack a second time makes a fresh copy rather than overwriting the one you edited. Tables are the opposite: an existing table of the same name is reused and keeps its rows.