# dsh-plugin-acfun 给 **DeepSeek Harness** 用的 **AcFun(A站)** 插件:搜索视频、读取视频详情、 评论、弹幕、日/周排行榜、播放地址和**动态(moment)**;可在 **“设置 → AcFun”里扫码登录**;开启写操作后可用自己的账号点赞、投蕉、收藏、 关注、评论(含动态)。 ## 工具 | 工具 | 类型 | 作用 | | --- | --- | --- | | `acfun_search` | 读 | 关键词搜索视频;`sort: "views"` 按播放量(A 站只返回固定第一页 30 条)。 | | `acfun_video` | 读 | 单个视频完整信息:UP 主、分区、标签、播放/点赞/收藏/投蕉/评论/弹幕数、发布时间、封面。 | | `acfun_comments` | 读 | 视频评论(按楼层序)的一页。 | | `acfun_danmaku` | 读 | 视频弹幕一批,按视频内时间排序,支持 `cursor` 翻页。 | | `acfun_rank` | 读 | 日榜 / 周榜,`channelId: 0` 为全站。 | | `acfun_playurl` | 读 | m3u8 清晰度列表(1080P+ / 1080P / 720P / 540P / 360P)。 | | `acfun_moment` | 读 | 按 id 读取一条动态:正文、话题、图片、作者、计数、官方分享链接。 | | `acfun_moment_comments` | 读 | 动态评论区一页(动态使用独立的评论枚举)。 | | `acfun_topic` | 读 | 社区圈话题页(尽力解析,最多 15 条)——目前唯一可公开发现动态 id 的入口。 | | `acfun_interact` | 写 | 视频:`like`、`unlike`、`banana`、`favorite`、`unfavorite`、`follow`、`unfollow`;动态:`moment_like`、`moment_unlike`、`moment_banana`。 | | `acfun_post_comment` | 写 | 给视频(`acId`)或动态(`momentId`)发表评论或回复。 | | `acfun_account` | 读 | 登录状态、凭据来源、写操作是否开启、下一步操作提示。 | 插件还附带面向模型的技能文件 `skills/plugin-tool-acfun/SKILL.md`,说明调用顺序、 写操作安全规则和动态相关限制。 ## 安装 把工作区目录作为 bundle 安装: ``` plugin_manager action=install_bundle target=C:\path\to\dsh-acfun ``` 插件会插入两行:`acfun`(工具、面板接口、扫码登录)与 `acfun-skill-filesystem`(把本包的 `skills/` 暴露给 Agent)。本地目录是链接 安装,修改插件代码后需要重启 Harness 才能加载新的模块实例。 卸载:`plugin_manager action=remove_bundle target=dsh-plugin-acfun`。 ## 扫码登录与 Web UI 面板 插件自带 Client 半(`client.js`),在 **设置 → AcFun** 增加一页:显示登录状态、 凭据来源、写操作是否开启,渲染二维码并轮询直到手机确认。 流程全部在 Host 侧(`lib/qr-flow.js`): 1. `GET https://scan.acfun.cn/rest/pc-direct/qr/start?type=WEB_LOGIN` 返回 base64 PNG 以及 `qrLoginToken`、`qrLoginSignature`、`expireTime`(120 秒)。 2. `scanResult` 是 A 站保持的一次长轮询,直到手机扫码或二维码过期;扫码成功时 返回**轮换后的新签名**。 3. 用新签名调用 `acceptResult`,A 站通过 `Set-Cookie` 下发会话;插件捕获 Cookie, 经 Host 凭据服务持久化为 `acfun-session` 记录,并把 provider 切到该会话。 面板通过同源 `/acfun-panel/*` JSON 接口访问 Host,跨源请求会被拒绝。扫码确认这 一步插件无法自行验证,只有真实手机扫码才会走到确认分支。 **需要重启一次:** 如果某个包在 Host 已经扫描过之后才新增 Client 半,则需要重启 一次 Harness,再刷新页面,**设置 → AcFun** 才会出现(Boot 图是在启动时按当时的 Loader 条目组合的)。可用 `GET /acfun-panel/state` 的 `client.path`(必须非空)或 `GET /acfun-panel/diagnose` 判断,细节与证据见 [`docs/client-panel.md`](docs/client-panel.md)。 ## 配置 配置位于 `cordis.patch.yml` 的 `acfun` 行,所有键都可省略。 | 键 | 默认值 | 含义 | | --- | --- | --- | | `cookie` | `''` | 完整的 AcFun `Cookie` 请求头。推荐用环境变量,避免密钥写进 patch。 | | `cookieEnv` | `ACFUN_COOKIE` | `cookie` 为空时读取的环境变量名。 | | `allowWriteActions` | `false` | `acfun_interact` / `acfun_post_comment` 的总开关。 | | `requestTimeoutMs` | `30000` | 单次 HTTP 请求超时。 | | `timeoutMs` | `45000` | 单次工具调用的协作式预算(写操作至少 60 秒)。 | 面板扫码得到的 Cookie 以凭据记录保存,优先于 `cookie`/`ACFUN_COOKIE`;在面板退出 登录后回退到配置值。 ### 不用面板时手动获取 Cookie 1. 在桌面浏览器登录 。 2. 打开开发者工具 → Network,刷新任意 acfun.cn 页面,复制文档请求的完整 `Cookie` 请求头(包含 `auth_key`、`acPasstoken`、`_did` 等)。 3. 粘贴到 `cookie` 或 `ACFUN_COOKIE`。 这串 Cookie 等同于账号密码,插件不会写进日志。 ## 安全设计 - 读取类工具不会修改任何内容,也不需要 Cookie。 - 写操作必须同时具备 `allowWriteActions: true` 与登录状态;只满足其一时返回 `WRITE_DISABLED` / `LOGIN_REQUIRED`,不会发出写请求。 - 写工具声明为非并发安全,Harness 不会并行执行两个账号操作。 - AcFun 返回人机验证要求(`result` 400001–410999)时报告 `CAPTCHA_REQUIRED`, 绝不尝试绕过。 ## 验证情况 2026-10-27 对 acfun.cn 实测(匿名): - 九个读取工具(`acfun_search` 含 `sort: "views"`、`acfun_video`、 `acfun_comments`、`acfun_danmaku`、`acfun_rank`、`acfun_playurl`、 `acfun_moment`、`acfun_moment_comments`、`acfun_topic`)返回真实数据并通过 输出 schema 校验与渲染(`node scripts/live-check.mjs`)。 - 扫码登录的二维码下发、等待与中止路径已实测(真实 ticket + PNG;未扫码时保持长 轮询到 120 秒过期,然后报告 expired)。 - 十二个工具通过模拟 Cordis 上下文注册,面板接口在本地 HTTP 服务器上验证 (含跨源拒绝、登出),写操作守卫正确失败关闭 (`node scripts/self-check.mjs`)。 - 写接口路由存在,匿名调用返回 `{"result":-401}`;但**未**验证登录后的成功路径 (包括扫码最后一步和动态写操作),因为本次没有可用账号。首次使用时请以 A 站 页面上的实际结果为准,不要在结果不明时重复调用。 ## 已知限制 - A 站的 pc-direct 搜索接口忽略 `page`/`pageSize`,永远只返回第一页 30 条;只有 `sort` 有效。 - 不支持番剧(bangumi)与文章页面——`acfun_video` 会返回 `UNSUPPORTED_RESOURCE`。 - **没有公开的“广场”列表接口。** 约 560 条路径探测后,各站点都没有公开的 广场/推荐动态列表;动态 id 只能通过 `acfun_topic`(SSR 页面,最多 15 条,无分页) 或分享链接获得,动态列表类接口都需要登录。 - 发布、删除、转发、投票动态只能在 App 内完成(需要签名 token),Web 插件做不了。 - 动态的点赞/投蕉/评论契约来自站点自身代码,只验证到 `401` 未登录,属于实验性 功能。 - 弹幕翻页依赖 A 站不透明的 `pcursor`,通过 `cursor`/`nextCursor` 透传。 - 播放地址是带签名的临时 m3u8,过期需重新调用;下载/合并流媒体不在范围内。 - 插件只调用 acfun.cn 的公开 Web 接口,属于非官方实现,A 站改版后可能失效。 ## 开发 ``` node scripts/self-check.mjs # 离线:导出、工具 schema、扫码状态机、面板 HTTP node scripts/live-check.mjs # 在线:真实读取、二维码下发、schema 校验与渲染 ``` 无构建步骤、无运行时依赖。`lib/` 与 `client.js` 都是只依赖 Node/浏览器内置能力的 纯 JS。插件故意不导出 `Config` schema:工作区链接安装的 bundle 无法解析 `@deepseek-ai/*` 包,所以由 `lib/config.js` 校验配置并带告警地回退默认值。 接口笔记:`docs/acfun-api.md`(视频/评论/弹幕/排行)、`docs/acfun-login.md` (扫码登录)、`docs/acfun-moment.md`(广场/动态调研与结论)。 ## 许可证 MIT,见 `LICENSE`。