📤 dsh-bili-publisher
DSH(DeepSeek Harness)B站动态发布插件。把「扫码登录 → 发纯文本/图文动态 → 删动态 → 验证」固化为 agent 工具 + HTTP API:执行零 token 消耗、输出确定性 JSON(相比每次让 AI 手敲 curl 拼 B站 接口)。
✨ 为什么需要它?
| 痛点 |
本插件做法 |
| 每次发布都要 AI 现场拼 B站 私有接口、猜参数 |
接口封装固化为 bili_publish 工具,一次测试永久复用 |
| 登录态无处存放,每会话重新扫码 |
扫码成功后 cookie 持久化到本地文件(~180 天),跨会话复用 |
| B站 接口频繁废弃(旧 type=1、旧 create/rm 均已失效) |
全部按 2026-08 实测接口实现,报错信息可读 |
| 图文动态要先传图再发、还要填图片尺寸 |
自动上传 + 零依赖解析图片真实尺寸,一次调用完成 |
🏗️ 架构
┌────────────────────────── agent 会话 ──────────────────────────┐
│ bili_status / bili_publish / bili_delete(defineTool 工具) │
└──────────────────────────────┬─────────────────────────────────┘
▼
┌──────────────────── dsh-bili-publisher 插件 ───────────────────┐
│ lib/index.js apply 入口(工具注册 + HTTP 路由 /api/bili/*) │
│ │ │
│ ▼ │
│ lib/core.js B站 API 纯函数封装(无 ctx 依赖,可独立单测) │
│ ├─ passport 扫码登录(qr → poll,Set-Cookie → 持久化) │
│ ├─ 发纯文本 dynamic_svr/create(type=4) │
│ ├─ 发图文 upload_bfs 传图 → create/dyn(scene=2) │
│ ├─ 删动态 dynamic_svr/rm_dynamic │
│ └─ 验证 t.bilibili.com/<id> HTTP 200 │
└──────────────────────────────┬─────────────────────────────────┘
▼
┌───── B站 API(api.bilibili.com)─────┐
│ curl / fetch 直连,无代理无中间层 │
└──────────────────────────────────────┘
🎛️ 工具(agent 会话内直接调用)
| 工具 |
参数 |
说明 |
bili_status |
— |
查登录态:是否登录 / uname / uid / 过期时间,未登录返回 loggedIn:false |
bili_publish |
{text, images?} |
发动态。无图片→纯文本;有图片(≤9,绝对路径)→自动上传+图文。⚠️ 发布前必须把完整文案与配图清单发给用户确认(约定见 bilibili-promo) |
bili_delete |
{dynamicId} |
删动态。发布错误内容时:发新版 → 删旧版,保持账号动态干净 |
🔑 扫码登录
# 1. 生成二维码
curl -X POST http://127.0.0.1:3083/api/bili/login/qr # → {url, qrcodeKey}
# 用 url 生成二维码 PNG 给用户扫(qrcode 库 / python-qrcode)
# 2. 轮询扫码结果(每 3s,最长 ~180s)
curl -X POST http://127.0.0.1:3083/api/bili/login/poll -d '{"qrcodeKey":"<key>"}'
# code=0 登录成功,cookie 持久化到 biliDataDir/bili-session.json(~180 天)
# 未扫码/已扫码未确认返回 202 + waiting:true,继续轮询即可
- 登录态只存本地(SESSDATA/bili_jct),不长期持有可
POST /api/bili/logout 清除;cookie 泄露风险见 bilibili-dynamic-publish skill
- 登录态异常(缺 csrf / 过期)时插件会明确提示「请重新扫码登录」,而不是抛 B站 原始报错
🔌 HTTP API
前缀:/api/bili,全部 JSON 响应。status 用 GET,其余用 POST。
| 方法 |
路径 |
请求体 |
说明 |
| GET |
/api/bili/status |
— |
登录态 + 插件配置(biliDataDir) |
| POST |
/api/bili/login/qr |
— |
生成二维码 → {url, qrcodeKey} |
| POST |
/api/bili/login/poll |
{qrcodeKey} |
轮询扫码;成功存 session;未扫返回 202+waiting |
| POST |
/api/bili/publish |
{text, images?[]} |
发动态;图片为本地绝对路径数组(≤9) |
| POST |
/api/bili/delete |
{dynamicId} |
删动态 |
| POST |
/api/bili/verify |
{dynamicId} |
验证动态可见(HTTP 200=可见) |
| POST |
/api/bili/logout |
— |
清除本地登录态 |
响应示例
// status(已登录)
{ "ok": true, "plugin": "dsh-bili-publisher", "biliDataDir": "...", "loggedIn": true,
"uname": "某用户", "uid": "123456", "expired": false, "hasSessdata": true, "hasCsrf": true }
// publish 成功(图文)
{ "ok": true, "kind": "draw", "dynamicId": "7654321", "images": [{ "file": "/tmp/a.png", "imageUrl": "..." }] }
// publish 失败(错误统一为 { ok:false, error:{ code, message, step?, biliCode? } })
{ "ok": false, "error": { "code": "BILI", "message": "未登录:请先扫码登录(POST /api/bili/login/qr + poll)" } }
📦 安装
# 注册三要素(cordis.patch.yml 或等价位置):
- insert:
- id: bili-publisher
name: dsh-bili-publisher
config:
workspaceRoot: '/vol1/@appshare/DeepSeekHarness/workspace'
biliDataDir: '/vol1/@appshare/DeepSeekHarness/workspace/.dsh-plugin-data/bili-publisher'
# 重启 DSH
⚙️ 配置
| 字段 |
默认 |
说明 |
enabled |
true |
设为 false 禁用插件 |
workspaceRoot |
process.cwd() |
工作区根 |
biliDataDir |
<workspace>/.dsh-plugin-data/bili-publisher |
登录态存储目录(bili-session.json) |
🧪 开发与测试
node --check lib/core.js && node --check lib/index.js # 语法
node test-core.mjs # 核心逻辑 22 项:session 管理 / 参数校验 / 图片尺寸解析 + 真实接口
node test-apply.mjs # apply mock 6 项:路由 + 工具注册
- 测试零外部依赖,图片尺寸解析用构造的最小合法文件头验证(PNG/GIF/JPEG/WebP 四格式),不依赖网络
- 真机验证:测试实例 3083 加载,
status / login/qr / verify 全通(真实网络);完整发布链路需真实扫码
⚠️ 已知边界
- 发布前确认:插件只做「管道」,文案生成与发布前确认留给 LLM/用户(bilibili-promo 约定),
bili_publish 工具描述中已内置该约束
- 图片尺寸:
imageDimensions() 零依赖解析 PNG/GIF/JPEG/WebP 真实宽高,无法识别的格式回退 960×540 兜底(B站 可能不显示图)
- 验证局限:
verify 基于页面 HTTP 200,B站 对个别异常状态也可能返回 200,仅作快速确认
- 接口漂移:B站 接口随时可能风控/废弃,报错时参考 bilibili-dynamic-publish skill 接口速查,并跑
test-core.mjs 回归
- 多图中断:图文上传中途某张失败时,之前已上传的图片会留在 B站 图床(不影响功能,占用极小的存储配额)
- 登录态有效期:
~180 天 为 SESSDATA 常规有效期估算,B站 风控可能提前失效,届时重新扫码即可
No comments yet. Be the first to write one.