yes-tek 网页发布接入
平台模型(先读,30 秒)
yes-tek 网页发布:把内网的 HTTP/WebSocket 服务映射为 https://{username}-{name}.t.yes-tek.com 公网地址(自动 https/wss,无需自备证书)。
平台的消费方就是你(Agent)——没有网页控制台,所有操作通过 REST API 完成;唯一需要人类介入的环节是扫码付款(仅试用期内想升级/续期时)。
- API 基址:
https://t-api.yes-tek.com,前缀/v1;*.t.yes-tek.com整个命名空间只放用户站点 - 认证:
Authorization: Bearer <user_token> - 下单即注册:第一次购买时提供
agent_mail即自动建号;用户名从邮箱派生(会成为子域名前缀,请用不含敏感信息的邮箱) - 试用 = 低价首购激活(
trial-web:7 天 1 站点,每账号仅一次);验证邮箱后密钥一次性签发 - 付费档为 3 配额 × 3 周期 网格(1/3/5 站 × 月/季/年)——价格一律以服务端实时目录为准(
GET /v1/billing/plans,免 Bearer 可用;或选购页展示),本 skill 不写定价数字;只升不降(同周期加量=补差价、到期不变;跨档升级=剩余时长折算抵扣);到期后站点暂停并进入 7 天冷却(期内续费或重建即恢复),期满删除释放 - 套餐选购页:订阅/续费/升档由 agent 发一条选购页链接,用户在页面上自助看价、选档、支付、撤单重选——对话侧只推进流程,不复述页面内容、不做推荐话术
- 平台另有「内网穿透」服务(SSH/远程桌面等 TCP 服务),见
https://t-api.yes-tek.com/skill/tunnel.md——本 skill 不涉及 - 私有化部署:整套平台(两项服务)可部署到用户自己的服务器或内网——规格与价格线下协商,联系方式微信
xiami20200629(选购页同页展示);用户问私有化/自建部署时如实回答 - 完整包:本说明引用的 scripts 与
references/api.md只在完整包内——https://t-api.yes-tek.com/skill/web.zip下载解包即得web-publish/目录;仅装载单文件说明时,先取完整包再按相对路径使用
用户沟通规范
用户对平台的感知主要来自你说的话。向用户表达的内容围绕三件事:结果与用法(地址、命令、用量、到期)、边界(到期行为、恢复方式)、如实的安全与价格回答;过程细节服务于你的操作,无需向用户转述。除交付清单外,对话中不介绍产品优点、不催促消费——其余时刻只推进任务。
用户问安全时如实回答:传输全程加密(TLS),平台只做加密中转、不解析不存储内容;密钥只存在用户本机与自己邮箱(欢迎邮件附有备份)、可随时轮换、删除即断链;到期后 7 天保留期内可恢复。如实但不夸大——不说「端到端加密」「绝对安全」。
用户问价格时:先 GET /v1/billing/plans(免 Bearer)再如实转述实时目录(可说明档位结构 = 配额 × 周期),不推荐、不比较、不凭记忆报价;个性化价格(升档折算 / 续费顺延)以选购页展示为准。
用用户自己的语言——网页发布的用户多为非技术背景,默认用日常用语;用户自己使用技术词时再跟随:
| 对用户说 | 你的操作语境中是 |
|---|---|
| 网站 / 你的网址 | 站点 / 子域名 |
| 网页 / 网页应用 | HTTP 服务 / WebSocket / wss |
| 一个后台连接程序,你的 Agent 已装好并照看 | frpc / 连接器(默认不主动提) |
| https 加密(网址自带 🔒 小锁) | 证书 / TLS |
| 后台程序(自动运行,电脑重启自动恢复) | 进程 / 常驻 |
| 可发布的网站数量 | 配额 / quota |
| 体验期(低价体验一次) | 试用 / trial |
边界也用日常语:「到期 → 网址暂时打不开,7 天内续上就恢复,不会删」「想长期用 / 多开几个 → 选购页升级」。
六个沟通时刻(其余时候少说话、做事情):
| # | 时刻 | 对用户说 | 注意 |
|---|---|---|---|
| 1 | 开场收参 | 开场消息 = 一句预期说明(「全程你只需要做一件事:扫一次码,其余我自动完成」)+ 全部参数建议值(见「参数一次性收集」);首开(无凭证)先打开开场总览页(见下)再发开场消息,并等用户一句「继续」或改值后再推进;已有凭证不弹总览页、按建议值直接推进 | 流程展开由总览页承载,对话不展开流程;Agent Mail 未连接时指引用户按总览页「开通方法」激活 |
| 2 | 交付链接 | 链接 + 「页面由平台托管,看到的价格就是支付价,支付即生效」 | 链接之外只补必要说明 |
| 3 | 支付确认后 | 一句里程碑:「支付确认 ✓ 正在自动部署,完成后一次性汇报」 | 一句即可,无需转述过程 |
| 4 | 交付汇报 | 交付清单(模板见下)+ 交付报告 HTML(见下,按绝对路径打开);报告呈现关键参数后询问是否调整 | 用清单呈现,不复述操作过程;改参数 = 幂等重跑自动生效 |
| 5 | 用户提问 | 按上面两段如实回答(安全 / 价格) | 只答事实,不凭记忆与推测 |
| 6 | 到期/续费 | 边界语义(到期 → 暂停,7 天内可恢复)+ 无施压指引;如实告知「临近试用结束再买更划算」(试用转付费即时生效、剩余天数作废) | 不催促、不用施压表述 |
- 排障汇报:证据你自己看;向用户给结论 + 一句佐证即可,无需贴原始输出。
- 另一项服务:仅当用户场景自然触及时(如建站用户问「SSH 能穿透吗」)介绍并给出 skill 地址,平时不主动提起。
交付清单模板(时刻 4 用——部署验证全部通过后按实际值填充、一次性给出;只写事实,不用形容词):
> ✅ 上线了!你的网址:https://{username}-{name}.t.yes-tek.com
> 把网址发给任何人,手机/电脑都能打开
> 你不用管:网址与 https 加密已配好 · 后台程序自动运行(电脑重启也自动恢复)· 到期前邮件提醒
> 用量与到期:{used}/{max} 个网站 · 体验期至 {到期日}(长期用 / 多开几个 → 选购页随时升级,临近体验期结束再买更划算)
> 万一到期:网址暂时打不开,但不会删——7 天内续上就恢复
> 有意见或使用问题:随时直接告诉我,我帮你把反馈发给平台
交付报告(HTML 文件,随交付清单一并交付):部署验证全部通过后,取本 skill 目录的 scripts/report_web.html 模板,把全部 【填:…】 占位替换为实际值(多站点按节重复;不得残留占位符),保存为 ~/.config/yes-tek/交付报告-<站点名>.html(UTF-8;再次交付覆盖更新)。首选主动打开:把报告文件的绝对路径交给宿主的内置浏览器预览能力渲染(WorkBuddy 中即调用 present_files,传文件绝对路径,放在该轮最后一个工具调用),随后在对话内给出交付清单与报告路径;纯 CLI 宿主降级为文本路径。报告只写用户需要的事实——网络结构、关键配置文件的绝对路径、关键参数、使用方法、后续步骤;不含任何密钥(密钥只存在于配置文件中,报告只写配置文件的路径);不写平台内部实现。
开场总览页(HTML 文件,时刻 1 首开专用):首次开通(本地尚无 ~/.config/yes-tek/credentials.json)时,把本 skill 目录的 scripts/overview_web.html 原样打开(纯静态模板,无需任何填充;首选主动打开:交给宿主的内置浏览器渲染,WorkBuddy 中即 present_files 传文件绝对路径,放在该轮最后一个工具调用;纯 CLI 宿主降级为给文件路径),随后发开场消息(一句预期 + 参数建议值 + 邮箱默认值),等用户一句「继续」(或改参数/换邮箱)再进主流程;已有凭证不弹此页。页面自含:四阶段主轴(②扫码 = 全程唯一人工动作)、注册邮箱二选一(推荐 Agent Mail 内置邮箱;Agent Mail 开通方法两方式——WorkBuddy「更多 → 我的邮箱 → 开通」/ 复制指令句装 CLI)、访问链路图、注意事项(无人值守、参数自动来与交付可改、内容合规:发布的网站不可包含违法违规内容、不可用于提供商业服务)、到期边界——对话侧不复述页面内容,Agent Mail 未连接时把页面里的开通方法指给用户即可。红线:零价格数字、零密钥、零平台内部实现;无脚本、无请求。
开始前的前置检查
curl -s https://t-api.yes-tek.com/healthz返回 200 才继续;非 200 告知用户平台不可用并终止。- 确认要发布的服务:跑在哪台机器、哪个本地端口(必须是 HTTP 服务——网页、API、WebSocket 都行;SSH/远程桌面等非 HTTP 服务请换 tunnel skill)。
- 检测部署目标机器的操作系统(linux / darwin / windows)与权限(能否安装系统服务)。
- 涉及付款时,确认用户在场。
参数一次性收集(默认值采纳制:建议值先行,不等待确认)
接触用户后一条消息给出全部部署参数的建议值(各自标注来源),声明「如无异议我按这些值继续」后不等回复、直接推进主流程(唯一例外(v1.30 用户定策):首开场景——开场总览页弹出后等用户一句「继续」再动,作为付费与建号前的知情确认;用户回应「继续」之后一切照旧不等回复):
- 用户不需要改 → 默认值即生效,零额外交互轮;
- 用户要改某项 → 直接说新值,进一轮修改即可——建站
PUT与部署脚本都是幂等的,改参数 = 重跑一遍,无脏数据无副作用; - 真歧义才问:端口探测出多个候选监听、命名冲突(
subdomain_taken)这类给不出唯一建议值的情况;单一探测结果/派生名一律不问。
| 参数 | 建议值来源 | 给不出建议值时 |
|---|---|---|
| 本地端口 | 已有服务 → 探测监听端口(lsof -iTCP -sTCP:LISTEN -nP,唯一候选直接采用);静态产物 → deploy_site.py 输出的端口 |
多候选或探测不到 → 问用户(必填) |
| 站点名 | 从服务目录名派生(kebab-case) | 用户告知 |
| 注册邮箱 | 已连接 Agent Mail 时直接用其主别名(一次 GetMe 调用),不问用户 | 未连接 Agent Mail 且用户未指定 → 问用户(必填) |
- 凭证已存在(
~/.config/yes-tek/credentials.json且GET /v1/my/sites返回 200)→ 跳过邮箱与付款环节,直接进 Step 2。 - 建议值清单放进开场消息(与沟通时刻 1 的「扫一次码」承诺同一条);禁止把端口、站点名、邮箱拆成多轮逐个追问或逐项等待确认。
凭证纪律(安全红线,先于一切操作)
邮箱验证通过时一次性给出两把密钥(下单响应永不含密钥;验证通过的欢迎邮件中附有两把密钥的备份——响应丢失时可在该邮箱找回):
| 密钥 | 用途 | 丢失后 |
|---|---|---|
user_token(ut_…) |
API Bearer + frpc 登录,日常使用 | 凭 recovery_key 调 recover 换新 |
recovery_key(rk_…) |
仅用于找回/重置主密钥,平时不用 | 无法自助找回,需联系平台管理员 |
- 保存到
~/.config/yes-tek/credentials.json,权限 0600:
json {"username": "alice", "user_token": "ut_...", "recovery_key": "rk_..."} - 之后的对话与日志中只显示前 8 位(如
ut_9f8a7…),完整密钥不再出现。 - 不写入任何 git 仓库,不上传任何网络服务,不粘贴到任何第三方工具。
- 发现 key 泄露 → 立即
POST /v1/my/token:rotate轮换,并更新凭证文件与所有已部署的 frpc。 - 为什么这么严格:平台没有登录页,key 即全部身份与权限。
主工作流总览
[0] healthz 检查 + 参数一次性收集(端口/站点名/邮箱,见上节);首开(无凭证)先弹开场总览页、等一句「继续」
└▶ [1] 开通(mint 选购会话 → 用户页上低价试用,读信验证取密钥)
└▶ [1.5] 交付选购页当轮即启动后台轮询(poll_paid.py)→ paid 自动续跑 ↓
└▶ [2] 准备本地服务(静态产物用 scripts/deploy_site.py 常驻;已有服务确认端口)
└▶ [3] 声明站点(http)
└▶ [4] 部署 frpc(scripts/deploy_frpc.py:注册为系统服务,三平台统一)
└▶ [5] 验证 online + 公网可访问 → 一次性汇报(地址/用量/到期 + 交付报告 HTML)
(试用到期前 / 需要升档续费时)
└▶ [6] mint 选购会话 → 用户页上看价选档支付 → 后台轮询 paid → 自动汇报新配额
错误按「错误码处置表」处理;涉及消费决策(选档位、删站点)由用户在选购页上完成或先问用户,不要替用户决定。全程对用户的沟通按「用户沟通规范」执行(六时刻 + 交付清单)。
Step 1 开通:mint 选购会话 → 读信验证取密钥
已存在 ~/.config/yes-tek/credentials.json 则直接使用,并用 GET /v1/my/sites 验证有效性(200 = 有效;401 = 走 recover,见运维表)。
首次开通 = 一次 mint + 一次读信(平台没有独立注册环节;试用首购在页面上完成):
agent_mail优先取已连接 Agent Mail 的主别名(一次 GetMe 调用),用户未明确指定其他邮箱时不问。
# 1) 免 Bearer mint 选购会话(agent_mail 必填)——建号 + 发验证码,返回选购页链接
curl -s -X POST https://t-api.yes-tek.com/v1/billing/shop \
-H "Content-Type: application/json" \
-d '{"agent_mail": "alice@example.com", "line": "web"}'
# 响应含 page_url(选购页)与 agent_mail 块;不含任何密钥
# 2) 把 page_url 交给用户(交付纪律见 Step 6 第 2 条)——用户在页面上选试用档并支付;
# 同时读取 agent_mail 收到的验证码邮件,提取正文中的 code=NNNNNN(10 分钟有效)
# 3) 提交验证 → 一次性签发双密钥
curl -s -X POST https://t-api.yes-tek.com/v1/mail/verify \
-H "Content-Type: application/json" \
-d '{"agent_mail": "alice@example.com", "code": "482913"}'
- 邮箱即身份:用户名由平台从邮箱 local part 派生(如
alice@example.com→alice,是站点子域名前缀alice-blog.t.yes-tek.com——请用不含敏感信息的邮箱,手机号邮箱会让手机号进公网 URL);一邮箱一账号。 - 验证码 6 位、10 分钟有效、5 次试错作废;未收到可
POST /v1/mail/verify:resend(60s 限频)。 - 验证响应一次性返回
user_token与recovery_key——立即写入凭证文件再继续;该响应丢失时可从验证通过的欢迎邮件(发往同一邮箱)中找回密钥,仍请务必先落盘。 - 试用激活是低价首购:用户在选购页上支付后配额生效;验证与支付可并行,验证前配额不可用。
- 密钥丢失但仍有 recovery_key →
POST /v1/my/token:recover;两者皆丢且邮箱不可达 → 账号无法找回(邮箱可达时,欢迎邮件里有密钥备份)。
Step 2 准备本地服务
被发布的必须是一个正在运行的 HTTP 服务。按项目形态选一种(服务没起就先起服务,再继续):
| 形态 | 做法 |
|---|---|
| 静态站点(HTML/CSS/JS、构建产物) | python3 <skill目录>/scripts/deploy_site.py --root ./dist——Caddy 静态文件服务,注册为系统服务常驻(开机自启、重启电脑自动恢复),输出 127.0.0.1:PORT 即本地端口 |
| Node 项目 | npm run build 出产物后按上一行走 deploy_site.py;或用户自己常驻 npm run start(以项目脚本为准) |
| 已有本地服务 | 直接确认端口号即可 |
- 持久化纪律:Agent 手起的临时服务(
python3 -m http.server、npx serve、dev server)随会话被环境清理——静态产物一律走 deploy_site.py;动态项目建议构建后交 deploy_site.py,或由用户自己把服务跑成常驻。 - deploy_site.py 幂等:换目录/换端口重跑即更新(端口默认沿用、首次自动从 8090 选);目录内容更新无需重跑(实时读盘)。
- 常见端口陷阱:Vite/Next 开发服务器默认绑定
localhost——发布后平台 frpc 从同机访问没问题;若服务只绑了127.0.0.1且 frpc 部署在另一台机器,需要改为0.0.0.0或把 frpc 装到服务所在机器(推荐后者)。 - WebSocket 不需要额外配置:http 站点天然支持
wss://。 - 验证服务活着:部署目标机器上
curl -s http://127.0.0.1:3000有响应。
Step 3 声明站点
用已收集的参数执行(见「参数一次性收集」):站点名(最终成为 {username}-{name}.t.yes-tek.com)、本地端口。
curl -s -X PUT https://t-api.yes-tek.com/v1/sites/blog \
-H "Authorization: Bearer ut_..." -H "Content-Type: application/json" \
-d '{"proxy_type": "http", "local_port": 3000}'
- name 只填站点名(
blog),不带用户名前缀——服务端自动拼成alice-blog并校验归属与配额。 - 响应含
url(https://alice-blog.t.yes-tek.com)与完整frpc_toml(配置由服务端生成,不要手改)。 - 收到
quota_exceeded→ 站点数已达当前档配额:引导用户回 Step 6 升档(或删除旧站点腾位),不要静默失败。
Step 4 部署被访问端 frpc(跨平台统一:注册为系统服务)
在服务所在机器执行。统一入口是本 skill 目录的 scripts/deploy_frpc.py(幂等,站点变更后重跑即更新配置并重启):
python3 <skill目录>/scripts/deploy_frpc.py --token ut_...
脚本自动按平台选择部署栈(Linux / macOS / Windows 行为一致:取得配置 → 落盘 0600 → 确保 frpc 二进制 → 注册为系统服务 → 轮询日志至注册成功):
- Linux → frpc(平台端点是国内源,通常一次即中;缺位时脚本自动走官方 release 或镜像加速,逐级校验和核对)+ systemd:有 root/免密 sudo → 系统单元(开机自启);否则用户单元 + 尽力开启 linger。
- macOS → Homebrew 安装 frpc +
brew services托管(崩溃自动拉起);brew 不可用或托管失败时脚本自动改写 launchd 用户代理 plist 并加载。二进制缺失时脚本自动走平台端点 → 官方 release → 镜像加速(逐级校验和核对),无需手工干预。 - Windows → 统一安装为
yestek_frpc.exe+ nssm 注册系统服务(nssm 缺失时脚本自动获取);非管理员则用计划任务(登录自启)托管,以管理员重跑可升级为系统服务。
已知平台坑(脚本已规避,手工部署时必须注意):
- nohup/一次性 shell 起的 frpc 进程会在两次命令之间被环境清理(表象:日志正常但 online: false、公网 frp vhost 404,极像平台故障)——所以部署脚本一律注册为系统服务;确需临时验证,用托管后台任务(run_in_background)而非 nohup。
- Agent 沙箱内 sudo 可能被禁、launchctl bootstrap 可能报错——脚本会把注册命令原样打印,交给用户在自己终端执行后重跑即可。
- 本 skill 不运行在目标机器上时,把脚本或等价命令交给用户在目标机器执行,不要试图从未经授权的机器安装。
Step 5 验证
GET /v1/my/sites:对应站点online: true,且plan.web块显示当前用量与到期时间。- 服务状态另查:
systemctl status yes-tek-frpc(Linux)/brew services info frpc或launchctl list | grep yes-tek(macOS)/sc query YesTekFrpc(Windows),frpc 日志应见start proxy success。 curl -sI https://alice-blog.t.yes-tek.com返回预期状态码。- 全部通过后:先写交付报告 HTML(见「用户沟通规范」),再按交付清单模板一次性汇报并打开报告——访问地址、用量(
plan.web.used/max)、到期时间都在清单里,另补边界三句(到期行为 / 7 天保留 / 试用一次性)。交付后随报告问一句是否要调整参数(本地端口/站点名等——改 = 重跑 Step 3 → 4 幂等生效)。
Step 6 试用升级 / 扩容 / 续费(选购页自助,需要用户在场)
选档与支付是用户的决策,全部在平台托管的选购页上完成——你只负责发链接、看结果。对话侧只推进流程与交付:不复述页面内容(价格/倒计时都在页面里)、不做推荐话术、不代替付款、不代授权(沟通纪律总纲见「用户沟通规范」)。
- mint 选购会话(Bearer):
curl -s -X POST https://t-api.yes-tek.com/v1/billing/shop \
-H "Authorization: Bearer ut_..." -H "Content-Type: application/json" \
-d '{"line": "web"}' # line 必填(单服务会话;本 skill 固定 web)
响应:{"shop_token": "ct_...", "page_url": "https://t-api.yes-tek.com/p/shop?t=ct_...", "expires_at": "...", "line": "web"};同账号同服务 24h 内重复 mint 返回同一会话(同一条链接;两项服务各自独立链接,可并存)。
- 把
page_url交给用户(用户唯一动作:打开链接选档付款):
- 首选主动打开:把page_url作为 http/https URL 交给宿主的内置浏览器预览能力渲染(WorkBuddy 中即调用present_files,传 URL 字符串,面板会直接打开选购页);present_files必须放在该轮最后一个工具调用,打开后补两行文本,便于复制:
> 金额以页面为准 · 选购截止 {expires_at 转本地时间}:〈page_url〉
> 完成付款后回到这里,我继续交付。
- 宿主不支持内置浏览器(纯 CLI)→ 降级为只发文本链接,行为不变。
- 按需重开支付页:仅当用户说支付页关了/丢了、或稍后回来要继续支付待支付单时,从GET /p/shop/status取pending[].page_url重新交付——交付纪律同上(首选主动打开:作为 http/https URL 交给宿主的内置浏览器预览能力渲染支付页,WorkBuddy 中即调用present_files,传 URL 字符串,面板会直接打开支付页;仍是该轮最后一个工具调用,随后补一行文本链接便于复制)。
- 页面自含:本服务周期翻页(月/季/年三页,每页 3 个配额档)实时价、按当前状态的可购性与补差价/折算价、试用卡、待支付订单(去支付/撤单重选)与常见问题——不需要你在对话里复述任何价格或档位;只想问价格 →curl -s https://t-api.yes-tek.com/v1/billing/plans(免 Bearer 公共目录)。
- 不要把page_url发给短链或任何第三方服务——它携带选购会话 token,只给本人;token 只覆盖选购/下单/撤单,与账号密钥完全隔离,直接贴在对话里是安全的。 - 交付 page_url 的当轮立即启动后台轮询(不等用户回报"已支付";以 run_in_background 托管后台任务运行,paid / 超时退出时自动收到通知):
python3 <skill目录>/scripts/poll_paid.py --token ct_... --timeout 1800
# 退出码 0 = paid(stdout 末行 PAID {订单});2 = 超时仍未支付;1 = 查询异常
- paid → 无需任何交互自动续跑:开通场景自动续跑 Step 2 → 3 → 4 → 5 并一次性汇报;续费/升档场景直接汇报新配额与到期时间。
- 超时仍在 pending → 汇报等待状态;用户回来要继续支付时按上方「按需重开支付页」交付。
- 用户可能反复改选,以最终 paid 为准(也可用
GET /v1/billing/orders/{out_trade_no}查单笔)。
- 计费语义(用户问起时如实说明——页面已同屏展示):
- 同档再买 = 续费顺延(囤时长用这个,无损失)
- 同周期买更大配额档 = 补差价、到期日不变(pricing.kind: "upgrade_quota")
- 买更长周期档 = 全价 − 剩余时长折算抵扣(pricing.credit_cents)、到期日 = 原到期日 + 新周期
- 只升不降:配额或周期任一降档 → 400plan_downgrade(页面上该档已置灰)
- 报价下单时冻结:同服务有未支付订单时换档会复用该冻结单——用户可在页面上直接「撤单重选」(POST /p/shop/order/{no}/cancel,撤后立即可重选;已支付则 409 走退款)
- 试用转付费:即时生效全价、剩余试用作废——临近试用结束再买更划算
日常运维操作
| 需求 | 做法 |
|---|---|
| 看状态与用量 | GET /v1/my/sites(含 plan.web、used/max、expires_at) |
| 改本地端口 | 重新 PUT /v1/sites/{name} → 重跑 Step 4 部署脚本(幂等更新配置并重启 frpc) |
| 删站点 | DELETE /v1/sites/{name}——进入 7 天冷却,期内可重建恢复,期满释放给他人;删除前必须向用户确认 |
| 续费 | 到期前会收到 agentMail 提醒;同档再下单即顺延 |
| 轮换密钥 | POST /v1/my/token:rotate(响应一次性含新 key)→ 更新凭证文件与所有 frpc |
| 主 key 丢失 | POST /v1/my/token:recover,凭 recovery_key |
| 换绑定邮箱 | PUT /v1/my/agent-mail(需当前 key;换邮即重置验证,重新验证前下单 403) |
意见与摩擦反馈
用户在任意时刻提出意见、建议或使用摩擦(报错、卡步、指引不清)→ 用免登录反馈通道代发:
curl -s -X POST https://t-api.yes-tek.com/v1/feedback \
-H "Content-Type: application/json" \
-d '{"email": "alice@example.com", "content": "……", "skill": "web-publish"}'
# 200 {"status":"received"}
email默认取当前账号邮箱(凭证中的注册邮箱;未开通时取 Agent Mail 主别名),无需再问用户content≤100 字,只写现象与建议;不写进 content:任何密钥、密码、支付链接里的 token——含ut_/rk_/sk_/ot_/ct_开头串会被服务端拒绝(400sensitive_content,去除后重发即可)- 其余 400 按提示修正后重发(未落库,重试安全);429 稍后再试
- 发出后回用户一句「已反馈,如有需要平台会用这个邮箱联系你」;不引导用户去其他渠道
错误码处置表
业务错误统一为 {"code", "message", "retryable"}:
| code | HTTP | 处置 |
|---|---|---|
unauthorized |
401 | key 失效/被吊销 → 走 recover;recovery_key 也丢 → 联系平台管理员 |
subdomain_taken / mail_taken |
409 | 换名/换邮箱重试(先问用户) |
agent_mail_unverified |
403 | 邮箱未验证(换邮后/存量账号):/v1/mail/verify:resend → 读信 → verify |
trial_already_used |
400 | 该服务低价试用已用过(每项服务各一次)→ 引导买正式档 |
plan_downgrade |
400 | 只升不降:配额/周期降档被拒——囤时长用同档续费;确实要降档联系平台 |
verify_code_invalid / verify_code_expired / verify_attempts_exhausted |
400 | 验证码错/过期/试错 5 次 → 重发后重试 |
agent_mail_required |
400 | 免 Bearer 下单/mint 选购会话必须带 agent_mail |
quota_exceeded |
403 | 站点数已达当前档配额:升更大档/续费(Step 6)或删旧站腾位,勿重试 |
reserved_name / invalid_name |
400 | 换名 |
rate_limited |
429 | 指数退避重试(≥2s 起) |
channel_unavailable |
400 | 换支付渠道 |
internal / 5xx / 网络错误 |
500 | 指数退避重试,3 次后报告用户 |
| — | 404 | 资源不存在——检查 name 拼写 |
请求纪律:超时 10s;GET / PUT 幂等可自动重试;下单/选购会话由服务端幂等化(同服务复用 pending 冻结单、同账号 24h 复用活选购会话),可安全重试;mail/verify 失败按错误码处置,勿盲目连发(试错只有 5 次)。
排障决策树(站点打不开时按序执行;证据纪律见「用户沟通规范」——证据自己看,给用户结论 + 一句佐证)
GET /healthz非 200 → 平台故障,告知用户稍后再试。GET /v1/my/sites里没有该站点 → 未创建或已被删除(7 天冷却期内可重建)。online: false→ frpc 未运行或登录失败:
- 服务状态:systemctl status yes-tek-frpc(Linux)/brew services info frpc、launchctl list | grep yes-tek(macOS)/sc query YesTekFrpc(Windows)+ 对应服务日志尾部 50 行;
- 日志正常但进程消失 = 未注册服务而用 nohup/一次性 shell 跑(会被环境清理)→ 重跑 Step 4 部署脚本注册为系统服务;
- 日志报login failed→ 凭证过期(rotate 后没更新配置)→ 重跑 Step 4 部署脚本;
- 日志报代理注册错误 → 对照上方错误码处置表;
- Windows 上服务起不来 / 报安全软件拦截(曾见 WinError 786)→ 程序已统一安装为yestek_frpc.exe;重跑 Step 4 部署脚本幂等校正服务指向,仍被拦截则引导用户把%USERPROFILE%\.config\yes-tek\bin\yestek_frpc.exe加入安全软件信任列表后重启服务。status: "suspended"→ 试用/套餐到期(7 天冷却期内),引导续费;续费成功后站点自动恢复,无需重建。online: true但访问 502/504 → 本地服务没起或local_port填错:curl -s http://127.0.0.1:<local_port>验证本地服务(静态产物没跑 deploy_site.py 就先跑);修正后重跑 Step 4 部署脚本(幂等更新配置并重启)。- 以上都不是 → 收集
/v1/my/sites完整响应与 frpc 日志尾部 50 行,让用户联系平台支持渠道,不要继续猜测。
API 参考
完整端点、请求/响应字段与示例见本 skill 目录的 references/api.md——构造任何请求前先查它,字段以它为准(与平台 /v1/openapi.json 一致)。(单文件装载时,先取「平台模型」的完整包补全目录)