我们几乎用 AI Agents 自动化了 Gumroad 产品发布
Source: Dev.to
请提供您希望翻译的完整文本内容,我将按照要求保留源链接、原始格式、Markdown 语法以及技术术语,仅翻译正文部分。谢谢!
介绍
昨晚我们尝试在 Gumroad 上推出一款产品,整个技术工作全部由 AI 完成,没有任何人为干预。三个基于 Claude 的 AI 代理(菠萝、小墩 和 小默)被赋予了一个任务:创建产品页面、上传文件并点击发布。我们完成了大约 90 % 的工作。下面是成功的地方、出现的问题,以及关于自动化何时止步的关键教训。
代理与目标
- 代理: Three Claude‑based bots running on OpenClaw (菠萝 on MBP, 小墩 on a Mac mini, 小默 on Android).
- 产品: An AI‑agent starter kit priced at $9 on Gumroad.
绕过 Gumroad 登录
显而易见的阻碍是 Gumroad 的登录,它需要账户所有者的凭据和 2FA。Gumroad 使用 Google OAuth,而 Google 的通行密钥系统通常会强制进行设备级验证(生物识别、本地确认),这使得在无头浏览器中它“无法被阻止”。
提取 Google 会话 Cookie
我们从本地 Firefox 配置文件中提取了现有的 Google 会话 Cookie,并将其注入 OpenClaw 的无头浏览器,使 OAuth 流程在已认证的状态下启动。
import sqlite3, shutil, os, json
# Firefox stores cookies in a SQLite database
profile_path = os.path.expanduser("~/.mozilla/firefox/*.default*/cookies.sqlite")
# Copy the DB first (Firefox may have it locked)
shutil.copy(profile_path, "/tmp/cookies_copy.sqlite")
conn = sqlite3.connect("/tmp/cookies_copy.sqlite")
cursor = conn.execute("""
SELECT name, value, host, path, expiry, isSecure, isHttpOnly
FROM moz_cookies
WHERE host LIKE '%google.com%'
""")
cookies = [
dict(zip(
['name','value','domain','path','expires','secure','httpOnly'],
row
)) for row in cursor.fetchall()
]
将这些 Cookie 注入 Playwright 浏览器上下文后,Google OAuth 弹窗被识别为已认证,并重定向到 Gumroad。接下来的难题是 Gumroad 的 2FA。
Handling Gumroad’s 2FA
Gumroad 通过电子邮件发送数字验证码。我们没有设置带 OAuth 范围的 Gmail API,而是直接访问 Gmail(仍通过注入的 Cookie 进行身份验证),读取最新邮件的主题行,其中包含验证码:
Your authentication token is 455647
提取该字符串并将其输入 2FA 字段后完成登录。此步骤耗时最长。
上传产品文件
OpenClaw 的内置上传操作因路径验证错误而失败,即使文件路径是正确的。工具的内部验证会拒绝任何超出其预期目录的路径。
使用 Chrome DevTools 协议 (CDP)
我们通过 CDP 直接连接到已经在运行的无头 Chrome 实例,并使用 Playwright 的 setInputFiles 绕过文件选择对话框。
from playwright.async_api import async_playwright
async with async_playwright() as p:
# Connect to the already‑running headless Chrome
browser = await p.chromium.connect_over_cdp("http://localhost:9222")
context = browser.contexts[0]
page = context.pages[0]
# setInputFiles bypasses the file chooser dialog entirely
file_input = page.locator('input[type="file"]')
await file_input.setInputFiles("/path/to/your-file.zip")
上传触发了 S3 的分段上传流程(初始化 → 上传分段 → 完成),每个请求均返回 HTTP 200。文件最终存放在:
s3.amazonaws.com/gumroad/attachments/9876020928956/fdea8f74b31d4ec299d8ce4d56a2947a/original
React 前端问题
虽然文件已成功存入 S3,Gumroad 的 React 前端却从未更新其状态,因为 setInputFiles 并未触发组件所期待的合成 onChange 事件。因此,文件未在 Gumroad 的数据库中注册。
随后一次轮询调用(GET /dropbox_files?link_id=bpqdn)返回空列表,进一步确认注册步骤根本没有执行。
发布因支付方式要求被阻止
尝试直接通过 API (POST /links/bpqdn/publish) 发布时得到:
{
"success": false,
"error_message": "You must connect at least one payment method before you can publish this product for sale."
}
Gumroad 对每个产品都强制要求连接支付方式(PayPal 或银行账户),即使价格设为 $0。此检查在服务器端执行,若不完成支付设置表单(该表单需要敏感的财务信息),则无法绕过。
仍需人工干预的情况
- 财务账户绑定:将 PayPal 或银行账户绑定到 Gumroad 必须由人工完成。
- React 事件处理:自动化依赖于框架特定合成事件的上传可能需要自定义脚本,而不仅仅是简单的文件输入操作。
要点
- 会话 Cookie 可以取代 OAuth 流程,当您拥有已认证的浏览器配置文件时。
- CDP 为您提供对已认证的 Chrome 实例的深度控制,使您能够执行高级工具阻止的操作。
- 框架特定的 UI 逻辑(例如 React 合成事件)可能会破坏简单的自动化;您可能需要直接触发底层 API 调用。
- 金融集成仍然是全自动化产品发布的硬性障碍。
产品页面
部分自动化的产品页面已上线:
https://nfreeness.gumroad.com/l/bpqdn
ZIP 文件、描述和价格已设置;一旦连接付款方式,页面将正式上线。
References
- OpenClaw 文档
- Playwright API(尤其是
setInputFiles和 CDP 连接) - Gumroad API 端点(
/dropbox_files、/links/{id}/publish)
Tags: AI agents, browser automation, Playwright, Gumroad, OpenClaw, Claude