/** * 人机验证页(极验 / geetest v3)。 * * ## 为什么要自带一张页面 * 以前 B站风控(-352)时发的是写死在代码里的一个第三方地址 * (`koishi-plugin-kkk-docs.vercel.app/geetest?...`)。那个站在国内经常连不上 —— * 于是「风控了」就变成「无解」:用户根本打不开验证页,只能干等。 * * 现在改由**插件自己**在 Koishi 的端口上挂一张 `/kkk/geetest`, * 唯一的外部依赖是极验自己的 CDN(`static.geetest.com`,国内可达)。 * 用户点开 → 过验证 → 页面给出 `validate=…&seccode=…` → 复制回群里, * 机器人拿去调 amagi 校验,流程接上。 * * ## 为什么不做「页面自动回传」 * 验证是在浏览器里完成的,而**等待结果的那次对话在机器人进程里**; * 要自动回传就得再做一套「浏览器 ↔ 正在等待的那次验证」的配对机制(token 关联、 * 用户中途离开群聊的状态清理……)。复制一行文本回群里是同一套流程最短的路, * 而且 QQ / OneBot / 私聊全通用。 */ /** 极验 v3 的官方脚本;这是本页唯一的外部依赖 */ const GEETEST_SDK = 'https://static.geetest.com/static/tools/gt.js' /* ------------------------------------------------------------------ * * 通用风控中转页(快手滑块这种「平台直接给了验证页地址」的情况) * ------------------------------------------------------------------ */ /** * 生成「平台给了验证页地址」时的中转页。 * * ## 为什么还要中转一层 * 平台给的地址(快手是 `captcha.zt.kuaishou.com/iframe/index.html?captchaSession=…`) * 本身在国内是通的,直接发出去用户也能点。中转页解决的是另外三件事: * 1. **链接走我们自己配的公网地址**(群里点开就是,不用复制一长串带票据的 URL); * 2. **说清楚要做什么**(哪个平台、过完验证回来干什么),光甩一个链接用户不知道; * 3. 将来想换成「自建验证页」(用 `jsSdkUrl`)时,入口不用变。 * * @param options.url 平台给的验证页地址(**必须过白名单**,见 `isAllowedCaptchaUrl`) * @param options.platform 平台名(显示用) * @param options.bizName 风控业务名(显示用,快手会给 `ANTICRAWL_DEFAULT` 这种) */ export function renderRiskPage (options: { url: string, platform?: string, bizName?: string }): string { const url = String(options?.url ?? '') const platform = String(options?.platform ?? '').trim() || '平台' const bizName = String(options?.bizName ?? '').trim() return ` 完成人机验证

${escapeHtml(platform)}这次要人机验证了

点下面的按钮过去,在打开的页面里完成验证,然后回到群里重新发一次链接就能解析。

${bizName ? '

风控类型:' + escapeHtml(bizName) + '

' : ''} 打开验证页

下面这片空白是正常的(很多验证页不允许被嵌进来)—— 用上面的按钮就行。

` } /** * `gt` / `challenge` 只可能是极验给的 id(字母数字和下划线、短横线)。 * * 这两个值要**拼进 HTML 里的 ` ` }