Рецепт · Запуск продукта
Sign up and post
Открывает форум под этим профилем и публикует пост. Если профиль уже авторизован, аккаунт сохраняется и дело сразу переходит к тексту; если нет — регистрируется новый, с тем ником, который вы назвали, или придуманным вашей моделью, и с собственным паролем профиля или двадцатью случайными символами. Заголовок и текст запрашиваются у вашей модели, пост отправляется, а аккаунт, учётные данные и ссылка попадают в Launch posts. Строкой там заканчивается каждый прогон, включая неудачные: мёртвая страница, занятый ник или отклонённая по частоте отправка записываются словами самого сайта, а не поднимаются как ошибка. В поставке нацелен на Hacker News: адреса — это параметры, а селекторы формы принадлежат HN.
Что он делает
Новый аккаунт, публикующий ссылку на собственный продукт, — ровно тот случай, под который настроена модерация форумов, и особенно на Hacker News, где новые аккаунты ограничены по частоте, а рекламный первый пост чаще всего отправляют в флаг. Прочитайте написанное моделью, прежде чем дать отправить, и не рассчитывайте, что первый пост удержится.
Сохраняет аккаунт, под которым профиль уже вошёл, либо регистрирует новый; просит вашу модель придумать заголовок и текст, отправляет пост и записывает аккаунт и ссылку.
Он выполняется на одном профиле, через его собственный прокси и с его собственными cookie, — поэтому страницы загружаются такими, какими их увидел бы владелец этого аккаунта. Он ходит по страницам, так что дайте ему профиль, сессию которого не жалко задействовать.
Шагов: 43
Настоящее дерево, прочитанное из набора, который поставляется с лаунчером. Отступ — это вложенность: шаги внутри цикла выполняются по разу на строку, а шаги внутри ветви — только когда выполнено условие над ними. Каждое {{…}} — это значение, подставляемое во время выполнения: из строки, по которой идёт обход, из настройки прогона или из самого профиля.
setVarStart the row under this profileSet account_namegotoOpen the submit pageGo to {{vars.submit_url}}при сбое: continueevaluateRead the page: loaded, signed in, whoRun scriptпри сбое: continueifOnly if nobody has named this account yetIf {{vars.page.needs_name}} equalsYes
aiPromptAsk the model for a nameAsk AI into ai_handleпри сбое: continueifOnly if the page is actually thereIf {{vars.page.route}} notEqualsYes
evaluateSettle on the account nameRun scriptпри сбое: continueevaluateSettle on the passwordRun scriptпри сбое: continueifOnly if it is not signed in yetIf {{vars.page.route}} equalsYes
gotoOpen the sign-up pageGo to {{vars.signup_url}}при сбое: continueifOnly if this site shows a captchaIf iframe[src*="recaptcha"], iframe[src*="hcaptcha"], .h-captcha, .g-recap… selectorExistsYes
solveCaptchaSolve itSolve the captcha on the pageпри сбое: 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 scriptпри сбое: continuetypeType the account nameType into form:has(input[name="creating"]) input[name="acct"]при сбое: continuetypeType the passwordType into form:has(input[name="creating"]) input[name="pw"]при сбое: continueclickCreate the accountClick form:has(input[name="creating"]) input[type="submit"]при сбое: continueevaluateDid it take?Run scriptпри сбое: continuegotoBack to the form for another tryGo to {{vars.signup_url}}при сбое: 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|activateпри сбое: continueextractEmailLinkTake the link out of itTake a link from {{vars.mail}} into confirm_linkпри сбое: continuegotoOpen itGo to {{vars.confirm_link}}при сбое: 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 postпри сбое: continueifOnly if the model actually wrote oneIf {{vars.post.title}} existsYes
gotoOpen the submit pageGo to {{vars.submit_url}}при сбое: continuetypeTitleType into input[name="title"]при сбое: continuetypeLinkType into input[name="url"]при сбое: continuetypeBodyType into textarea[name="text"]при сбое: continueclickSubmit itClick input[type="submit"]при сбое: continueevaluateDid it go up?Run scriptпри сбое: continueifOnly if something went upIf {{vars.submitted.ok}} equalsYes
gotoOpen this account's submissionsGo to https://news.ycombinator.com/submitted?id={{vars.account_name}}при сбое: continueevaluateRead the post linkRun scriptпри сбое: continueevaluateDecide what happenedRun scriptпри сбое: continuesaveRowsFile 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
- 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.
Как загрузить
В лаунчере откройте Automations, выберите Load a starter pack и укажите Запуск продукта. Снимите галочки с того, что вам не нужно. Сначала приходят таблицы, потом сценарии, потом проект с названием Launch, который связывает их вместе.
К вам приходит обычная строка автоматизации. Откройте её в редакторе, поменяйте шаг, переименуйте, удалите — дальше приложение не считает её чем-то особенным, а повторная загрузка набора делает свежую копию, а не перезаписывает отредактированную вами. С таблицами наоборот: существующая таблица с тем же именем переиспользуется и сохраняет свои строки.