Рецепт · Запуск продукта

Sign up and post

Открывает форум под этим профилем и публикует пост. Если профиль уже авторизован, аккаунт сохраняется и дело сразу переходит к тексту; если нет — регистрируется новый, с тем ником, который вы назвали, или придуманным вашей моделью, и с собственным паролем профиля или двадцатью случайными символами. Заголовок и текст запрашиваются у вашей модели, пост отправляется, а аккаунт, учётные данные и ссылка попадают в Launch posts. Строкой там заканчивается каждый прогон, включая неудачные: мёртвая страница, занятый ник или отклонённая по частоте отправка записываются словами самого сайта, а не поднимаются как ошибка. В поставке нацелен на Hacker News: адреса — это параметры, а селекторы формы принадлежат HN.

Содержание

Что он делает

Новый аккаунт, публикующий ссылку на собственный продукт, — ровно тот случай, под который настроена модерация форумов, и особенно на Hacker News, где новые аккаунты ограничены по частоте, а рекламный первый пост чаще всего отправляют в флаг. Прочитайте написанное моделью, прежде чем дать отправить, и не рассчитывайте, что первый пост удержится.

Сохраняет аккаунт, под которым профиль уже вошёл, либо регистрирует новый; просит вашу модель придумать заголовок и текст, отправляет пост и записывает аккаунт и ссылку.

Он выполняется на одном профиле, через его собственный прокси и с его собственными cookie, — поэтому страницы загружаются такими, какими их увидел бы владелец этого аккаунта. Он ходит по страницам, так что дайте ему профиль, сессию которого не жалко задействовать.

One profileIts own proxy and cookiesThe Launch posts table6 settings on the run

Шагов: 43

Настоящее дерево, прочитанное из набора, который поставляется с лаунчером. Отступ — это вложенность: шаги внутри цикла выполняются по разу на строку, а шаги внутри ветви — только когда выполнено условие над ними. Каждое {{…}} — это значение, подставляемое во время выполнения: из строки, по которой идёт обход, из настройки прогона или из самого профиля.

setVarStart the row under this profileSet account_name
gotoOpen the submit pageGo to {{vars.submit_url}}при сбое: continue
evaluateRead the page: loaded, signed in, whoRun scriptпри сбое: continue
ifOnly if nobody has named this account yetIf {{vars.page.needs_name}} equals

Yes

aiPromptAsk the model for a nameAsk AI into ai_handleпри сбое: continue
ifOnly if the page is actually thereIf {{vars.page.route}} notEquals

Yes

evaluateSettle on the account nameRun scriptпри сбое: continue
evaluateSettle on the passwordRun scriptпри сбое: continue
ifOnly if it is not signed in yetIf {{vars.page.route}} equals

Yes

gotoOpen the sign-up pageGo to {{vars.signup_url}}при сбое: continue
ifOnly if this site shows a captchaIf iframe[src*="recaptcha"], iframe[src*="hcaptcha"], .h-captcha, .g-recap… selectorExists

Yes

solveCaptchaSolve itSolve the captcha on the pageпри сбое: continue
loopTry up to three namesLoop times

Each time

ifOnly while it has not signed upIf {{vars.signup.ok}} equals

Yes

evaluateA different name, if this is a retryRun scriptпри сбое: continue
typeType the account nameType into form:has(input[name="creating"]) input[name="acct"]при сбое: continue
typeType the passwordType into form:has(input[name="creating"]) input[name="pw"]при сбое: continue
clickCreate the accountClick form:has(input[name="creating"]) input[type="submit"]при сбое: continue
evaluateDid it take?Run scriptпри сбое: continue
gotoBack to the form for another tryGo to {{vars.signup_url}}при сбое: continue
ifOnly if the account now existsIf {{vars.signup.ok}} equals

Yes

ifOnly if the site confirms by emailIf {{vars.confirm_email}} equals

Yes

waitForEmailWait for the confirmationWait for mail matching verify|confirm|activateпри сбое: continue
extractEmailLinkTake the link out of itTake a link from {{vars.mail}} into confirm_linkпри сбое: continue
gotoOpen itGo to {{vars.confirm_link}}при сбое: continue
ifReady, because it was already signed inIf {{vars.page.route}} equals

Yes

setVarMark it readySet stage
ifReady, because the sign-up landedIf {{vars.signup.ok}} equals

Yes

setVarMark it readySet stage
ifOnly with an account to post fromIf {{vars.stage}} equals

Yes

aiPromptWrite the postAsk AI into postпри сбое: continue
ifOnly if the model actually wrote oneIf {{vars.post.title}} exists

Yes

gotoOpen the submit pageGo to {{vars.submit_url}}при сбое: continue
typeTitleType into input[name="title"]при сбое: continue
typeLinkType into input[name="url"]при сбое: continue
typeBodyType into textarea[name="text"]при сбое: continue
clickSubmit itClick input[type="submit"]при сбое: continue
evaluateDid it go up?Run scriptпри сбое: continue
ifOnly if something went upIf {{vars.submitted.ok}} equals

Yes

gotoOpen this account's submissionsGo to https://news.ycombinator.com/submitted?id={{vars.account_name}}при сбое: continue
evaluateRead the post linkRun scriptпри сбое: continue
evaluateDecide what happenedRun scriptпри сбое: continue
saveRowsFile what happenedSave to Launch postsпри сбое: continue

Каждый из них — один из типов шагов из справочника по автоматизациям, с теми же полями, которые показывает редактор, и теми же полями, которые получает агент через локальный API.

Какие таблицы использует

Они загружаются вместе с рецептом. Датасет — это типизированная таблица, которой владеет ваше рабочее пространство: колонки названы и типизированы заранее, чтобы шаги могли к ним обращаться, и любую из них потом можно переименовать, дополнить или заполнить из файла.

Launch posts

пишет

One 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

Повторный запуск обновляет ту строку, которую уже записал, а не добавляет вторую. Именно для этого в шаге сохранения нужна колонка сопоставления, и именно в этом разница между проверкой статуса и таблицей, которая удваивается на каждом проходе.

О чём он спрашивает

Настройки заполняются при старте прогона, и у каждого профиля могут быть свои значения — так один сценарий обслуживает целую папку аккаунтов.

handle
Account name · text

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.

signup_url
Sign-up page · text

The page carrying the create-account form. Only opened when the profile turns out not to be signed in already.

submit_url
Submit page · text

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.

link
Link to post · text

The URL the post points at.

angle
What it is · textarea

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.

confirm_email
Does the site email a confirmation link? · select

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.

Как загрузить

В лаунчере откройте Automations, выберите Load a starter pack и укажите Запуск продукта. Снимите галочки с того, что вам не нужно. Сначала приходят таблицы, потом сценарии, потом проект с названием Launch, который связывает их вместе.

К вам приходит обычная строка автоматизации. Откройте её в редакторе, поменяйте шаг, переименуйте, удалите — дальше приложение не считает её чем-то особенным, а повторная загрузка набора делает свежую копию, а не перезаписывает отредактированную вами. С таблицами наоборот: существующая таблица с тем же именем переиспользуется и сохраняет свои строки.