🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

飞书双向桥接 yangwuan55/dsh-feishu-integration

DeepSeek Harness
yangwuan5569 天前有提交已提供中文文档扫描:含敏感能力

把会话总结发到飞书,回复即可路由回原会话

27.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add yangwuan55/dsh-feishu-integration
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · platform
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 69 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 35 处,展示前 35 条)
  • 写入本地文件
    lib/index.js:117
    mkdirSync(dirname(bridgeDebugPath), { recursive: true })
  • 写入本地文件
    lib/index.js:118
    appendFileSync(bridgeDebugPath, `[${new Date().toISOString()}] ${args.join(' ')}\n`)
  • 读取本地文件
    bin/fsum-admin.mjs:45
    return JSON.parse(readFileSync(configPath(), 'utf8'))
  • 写入本地文件
    bin/fsum-admin.mjs:54
    writeFileSync(tmp, JSON.stringify(config, null, 2))
  • 写入本地文件
    bin/fsum-admin.mjs:55
    renameSync(tmp, p)
  • 发起网络请求
    bin/fsum-admin.mjs:60
    const res = await fetch(new URL('/api/' + method, baseUrl), {
  • 读取本地文件
    bin/fsum-admin.mjs:78
    for (const line of readFileSync(credPath(), 'utf8').split('\n')) {
  • 读取本地文件
    bin/fsum-admin.mjs:89
    lines = readFileSync(credPath(), 'utf8').split('\n')
  • 写入本地文件
    bin/fsum-admin.mjs:106
    writeFileSync(tmp, lines.join('\n'), { mode: 0o600 })
  • 写入本地文件
    bin/fsum-admin.mjs:107
    renameSync(tmp, credPath())
  • 读取本地文件
    bin/fsum-admin.mjs:113
    const lines = readFileSync(credPath(), 'utf8').split('\n')
  • 写入本地文件
    bin/fsum-admin.mjs:121
    writeFileSync(tmp, lines.join('\n'), { mode: 0o600 })
  • 写入本地文件
    bin/fsum-admin.mjs:122
    renameSync(tmp, credPath())
  • 读取本地文件
    lib/host/bot-store.js:13
    const parsed = JSON.parse(readFileSync(join(feishuDir, 'config.json'), 'utf8'))
  • 写入本地文件
    lib/host/bot-store.js:26
    mkdirSync(join(feishuDir, '..'), { recursive: true })
  • 读取本地文件
    lib/host/bot-store.js:28
    const cur = (() => { try { return JSON.parse(readFileSync(p, 'utf8')) } catch { return {} } })()
  • 写入本地文件
    lib/host/bot-store.js:30
    writeFileSync(tmp, JSON.stringify({ ...cur, version: cur.version ?? 2, bots }, null, 2))
  • 写入本地文件
    lib/host/bot-store.js:31
    renameSync(tmp, p)
  • 读取本地文件
    lib/host/bot-store.js:46
    const parsed = JSON.parse(readFileSync(statePathFor(bot), 'utf8'))
  • 写入本地文件
    lib/host/bot-store.js:58
    mkdirSync(join(p, '..'), { recursive: true })
  • 写入本地文件
    lib/host/bot-store.js:60
    writeFileSync(tmp, JSON.stringify(state, null, 2))
  • 写入本地文件
    lib/host/bot-store.js:61
    renameSync(tmp, p)
  • 读取本地文件
    lib/host/reply-map-store.js:15
    cache = JSON.parse(readFileSync(replyMapPath, 'utf8'))
  • 写入本地文件
    lib/host/reply-map-store.js:25
    mkdirSync(join(replyMapPath, '..'), { recursive: true })
  • 写入本地文件
    lib/host/reply-map-store.js:27
    writeFileSync(tmp, JSON.stringify(cache, null, 2))
  • 写入本地文件
    lib/host/reply-map-store.js:28
    renameSync(tmp, replyMapPath)
  • 发起网络请求
    lib/host/feishu-api.js:22
    const res = await fetch(FEISHU_OPEN_BASE + '/auth/v3/tenant_access_token/internal', {
  • 发起网络请求
    lib/host/feishu-api.js:39
    const res = await fetch(FEISHU_OPEN_BASE + path, {
  • 写入本地文件
    lib/host/summary-service.js:35
    mkdirSync(dirname(deadLetterPath), { recursive: true })
  • 写入本地文件
    lib/host/summary-service.js:36
    appendFileSync(deadLetterPath, JSON.stringify(entry) + '\n')
  • 发起网络请求
    lib/host/connection-rpc.js:159
    const tokenRes = await fetch(base + '/open-apis/auth/v3/tenant_access_token/internal', {
  • 发起网络请求
    lib/host/connection-rpc.js:165
    const botRes = await fetch(base + '/open-apis/bot/v3/info/', { headers: { authorization: 'Bearer ' + tokenBody.tenant_access_token } })
  • 删除本地文件递归
    lib/host/connection-rpc.js:292
    try { rmSync(join(deps.dshHome, 'integrations', 'dsh-feishu', 'bots', botId), { recursive: true, force: true }) } catch { }
  • 发起网络请求
    lib/host/session-gateway.js:24
    const response = await fetch(new URL('/api/' + method, origin), {
  • 发起网络请求
    lib/host/mux-client.js:101
    const res = await fetch(new URL('/api/respond', origin), {
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 发送会话摘要到飞书
  • 回复路由回原会话
  • 扫码绑定配置

飞书/Lark 与 DeepSeek Harness 双向打通:摘要、回复路由、绑定界面、扫码配置。

README

由 DeepSeek 最新模型翻译生成
dsh-feishu-integration 中文优先 / Chinese first 将飞书与 DeepSeek Harness 双向连接: - DSH 会话完成后,把总结发送到飞书; - 在飞书中回复某条总结,自动路由回产生该总结的 DSH 会话; - 支持 p2p 和群聊的固定会话延续; - 在 DSH 设置页查看绑定状态、扫码绑定、重连、断开和解绑; - 提供二维码 provisioning 和 fsum-admin CLI 管理入口; - 支持飞书 Feishu 域和国际版 Lark 域。 安全默认值 公开安装包默认使用 takeoverInbound: false。这样安装时不会自动和已有的飞书长连接插件竞争事件流。 只有在同一个 DSH profile 中禁用其他飞书长连接插件后,才应启用入站接管: - id: xmanrui-dsh-feishu disabled: true - id: dsh-feishu-integration config: takeoverInbound: true 飞书长连接使用集群式事件分发;同一个应用同时运行多个长连接客户端可能导致事件随机分流。
展开完整文档(README 剩余 1 节)
dsh-feishu-integration

中文优先 / Chinese first

将飞书与 DeepSeek Harness 双向连接:

- DSH 会话完成后,把总结发送到飞书;
- 在飞书中回复某条总结,自动路由回产生该总结的 DSH 会话;
- 支持 p2p 和群聊的固定会话延续;
- 在 DSH 设置页查看绑定状态、扫码绑定、重连、断开和解绑;
- 提供二维码 provisioning 和 fsum-admin CLI 管理入口;
- 支持飞书 Feishu 域和国际版 Lark 域。

安全默认值

公开安装包默认使用 takeoverInbound: false。这样安装时不会自动和已有的飞书长连接插件竞争事件流。

只有在同一个 DSH profile 中禁用其他飞书长连接插件后,才应启用入站接管:

- id: xmanrui-dsh-feishu
disabled: true

- id: dsh-feishu-integration
config:
takeoverInbound: true

飞书长连接使用集群式事件分发;同一个应用同时运行多个长连接客户端可能导致事件随机分流。

安装

在目标 DSH profile 中安装 GitHub 仓库:

dsh plugin --profile web add github:yangwuan55/dsh-feishu-integration

其他 profile 例如:

dsh plugin --profile headless add github:yangwuan55/dsh-feishu-integration

安装完成后重启对应的 DSH profile。插件自带 dsh.bundle.patch,会自动进入 profile;默认不会开启入站长连接。

安装后可在:

设置 → 插件 → 飞书

查看当前绑定状态并扫码绑定。绑定状态和二维码由 DSH 设置页提供,不要求先使用 CLI。

启用入站回复路由

如果需要“回复飞书总结 → 路由回对应 DSH 会话”,先确认旧飞书长连接插件已禁用,再在 profile patch 中覆盖配置:

- id: xmanrui-dsh-feishu
disabled: true

- id: dsh-feishu-integration
config:
takeoverInbound: true
replyTimeoutMs: 600000

配置文件通常是:

$DSH_HOME/profiles/web/cordis.patch.yml

也可以使用全局 patch:

$DSH_HOME/cordis.patch.yml

修改 patch 后可热重载配置;插件代码或依赖变化需要重启 DSH Web。

CLI 管理

设置页是推荐入口。CLI 仍然保留,方便自动化和无 UI 环境:

fsum-admin list
fsum-admin bind
fsum-admin bind --app-id cli_xxx --app-secret xxx --owner ou_xxx
fsum-admin verify --app-id cli_xxx
fsum-admin set-owner --app-id cli_xxx --open-id ou_xxx
fsum-admin unbind --app-id cli_xxx

二维码绑定使用飞书 SDK 的设备授权流程。凭据优先通过 DSH loopback credentials RPC 写入;在 DSH Web 未运行时才回退到本地 credential 文件。

数据与兼容性

插件保留旧 @xmanrui/dsh-feishu 的本地数据布局,以便迁移时延续已有绑定和固定会话:

$DSH_HOME/integrations/dsh-feishu/config.json
$DSH_HOME/integrations/dsh-feishu/reply-map.json
$DSH_HOME/integrations/dsh-feishu/bots//state.json

敏感的 app_secret 使用 DSH credential store,不写入公开配置文件。

路由行为

1. DSH 完成一次会话回合;
2. 插件向飞书发送文本总结;
3. 插件记录 message_id → sessionId 映射;
4. 用户在飞书中回复该总结;
5. 插件根据 parent_id/root_id 查找映射;
6. 命中后先立即在原飞书线程回复“已转发到哪个空间、哪个 DSH 会话”,其中包含 workspace 路径、会话标题和 session ID;
7. 再以 queue 模式把文本注入对应 DSH session;
8. 最终回答回帖到原飞书线程。

即时回执的 message_id 也会写入同一个 sessionId 映射,因此用户继续回复这条确认消息时,仍会回到同一个 DSH 会话。

发送重试:总结直发内置有界重试——最多 10 次尝试,指数退避(1s 起、30s 封顶、±20% 抖动);重试等待期间用 DNS 探测 open.feishu.cn 做可达性门控,断网时顺延等待(不消耗尝试次数),总截止 10 分钟。每次逻辑发送携带飞书消息幂等 uuid,「已送达但响应丢失」不会重复投递。重试全部放弃时写入死信 ~/.dsh/integrations/dsh-feishu/pending-summaries.jsonl 供排查(不自动补发)。

等待回答超时(默认 600s)时插件保持静默:不追发「处理失败」回帖、不追加错误表情——转发回执本身已被视为送达确认,超时仅记录在 host 日志中。其他真实错误仍会回帖提示。

由飞书回复触发的 DSH 回合带有 fsum- RPC 标记,不会再次生成总结,从而避免回环。

会话提问转接(answerFromFeishu)

DSH 会话执行中调用 ask_user_question 暂停等待用户回答时,回合不会结束,飞书侧原本收不到任何通知。takeoverInbound=true 且 answerFromFeishu=true(默认)时,提问桥打通双向链路:

1. 插件经本机 WebSocket(/api/events.mux 下行流)收到 question/requested;
2. 问题与选项格式化后发到该会话最近使用过的飞书线程(无历史线程则落到总结目的地);多问题批次逐题串行:先发第 1 题,回答后自动发下一题,全部答完一次性提交;
3. 用户在飞书回帖:数字选选项(multiSelect 可「1、3」组合)、选项原文精确匹配、其余文本作为自定义回答;回复「取消」放弃整批(等价网页端取消);
4. 插件组装结构化作答 POST /api/respond,成功后在原帖回「✅ 已把全部回答提交给会话」(含逐题回显),会话继续执行;
5. 网页端抢先作答时插件收到 accepted:false,静默补一条说明;问题被取消同理。

断线自动重连(1s→30s 退避),重放帧按 rpcId 去重不会重复发帖。该通道为纯下行 WebSocket + HTTP 上行,不占用也不影响飞书长连接数量约束。

验证

dsh web --dump-config
node --check lib/index.js
node --check lib/client.js

检查启动后的 Web 页面 window.__DSH_BOOT__.entries 是否包含 dsh-feishu-integration。如果设置页没有「飞书」,优先检查:

1. package.json 是否保留 exports["./package.json"];
2. 旧飞书插件是否被禁用;
3. DSH profile 是否已经重启;
4. dsh web --dump-config 是否包含新插件 entry。

目录结构

lib/index.js 组装根:config 解析 + 模块装配(无业务细节) lib/host/ host 侧领域模块:bot 存储 / reply-map / 飞书 API / 总结推送 / session 网关 / 单 bot 入站运行时 / 设置页 RPC lib/shared/ 纯函数与常量(findReplyMapping 等测试缝) client-src/ 浏览器设置页源码(api / styles / index) lib/client.js 由 client-src 构建生成的浏览器 bundle(勿手改) scripts/ build-client.mjs:esbuild 打包出 ModuleLoader 包装产物 test/ node:test 回归(路由映射 / 回执文案 / 入站顺序)

约束:一个 bot 只允许一个飞书长连接(集群模式多 client 会随机分流事件); parent_id/root_id → reply-map → DSH session 的路由语义与 fsum- 防回环前缀不可变。

开发

git clone https://github.com/yangwuan55/dsh-feishu-integration.git
cd dsh-feishu-integration
pnpm install
pnpm build # client-src/ → lib/client.js(改前端源码后必须重建)
pnpm test # node:test 全量回归
node --check lib/index.js

改 host 侧逻辑直接编辑 lib/host/*.js,无需构建;改设置页 UI 编辑 client-src/,然后 pnpm build 重新生成 lib/client.js。发布包只含 lib/、bin/ 与文档。

dsh-feishu-integration 双向连接飞书/Lark 与 DeepSeek Harness:

- 将已完成的 DSH 回合总结发送到飞书;
- 将针对某条总结的回复路由回产生它的 DSH 会话;
- 为未匹配的消息保留固定的 p2p/群组会话;
- 提供一个 DSH 设置标签页,包含绑定状态、扫码绑定、重连、断开连接和删除操作;
- 支持扫码配置和 fsum-admin CLI;
- 同时支持飞书和 Lark 域名。

当入站消息被路由到已映射的 DSH 会话时,插件会立即在同一飞书线程中回复工作区路径、会话标题和会话 ID。该确认消息被映射到同一会话,因此后续回复会在同一对话中继续。

如果超时前未收到回答(默认 600 秒),插件在飞书中保持静默——不发送失败消息,也不添加错误表情回应。路由确认消息已经充当了送达回执;超时仅在 host 侧记录日志。真正的错误仍会收到失败回复。

会话问题中继(answerFromFeishu)

当 DSH 会话在 ask_user_question 处暂停时,该回合永远不会结束,因此飞书以前什么也听不到。启用 takeoverInbound: true 和 answerFromFeishu: true(默认)后,问题桥接会闭合这一环路:
1. 插件通过本地 WebSocket 下行链路(/api/events.mux)接收 question/requested 帧;
2. 问题和选项会被发送到该会话最近的飞书话题串(若不存在则发送到摘要目标);多问题批次按顺序分轮进行——先发送问题 1,每次回答后发送下一个问题,全部回答完毕后一次性提交;
3. 话题回复的解析方式为:选项编号(multiSelect 允许多个,如“1、3”)、精确的选项标签,或作为自定义答案的自由文本;回复“取消”会取消整个批次(等同于在 Web UI 中取消);
4. 插件通过 POST /api/respond 提交结构化答案,并在话题串内以逐题回顾的形式进行确认;如果 Web UI 先完成了回答(accepted:false),则改为发布一条简短说明;
5. 重连时会重放待处理的帧——按 rpcId 去重可防止重复发布。

开发

宿主侧模块位于 lib/host/ 和 lib/shared/(纯 ESM,无需构建步骤)。设置界面源码位于 client-src/,通过 esbuild 打包进 lib/client.js——编辑后请运行 pnpm build。pnpm test 会运行回归测试套件(路由映射、确认文案、使用模拟 Lark SDK 的入站排序)。

安全默认值

该包默认 takeoverInbound: false。只有在禁用同一配置文件中所有其他飞书长连接插件后,才能启用入站接管:

- id: xmanrui-dsh-feishu
disabled: true

- id: dsh-feishu-integration
config:
takeoverInbound: true

飞书长连接使用集群化事件投递。为同一应用运行多个客户端可能会导致事件不可预测地分流。

安装

dsh plugin --profile web add github:yangwuan55/dsh-feishu-integration

该包附带一个 dsh.bundle.patch,因此会自动挂载到配置文件中。安装后重启 DSH,然后打开:

Settings → Plugins → Feishu

设置界面是查看绑定状态和扫描二维码的首选方式。

CLI

fsum-admin list
fsum-admin bind
fsum-admin verify --app-id cli_xxx
fsum-admin unbind --app-id cli_xxx

兼容性

该插件有意将旧版本地数据路径保留在 $DSH_HOME/integrations/dsh-feishu/ 下,以便在迁移期间复用现有的绑定、回复映射和固定会话状态。

官方发现

DeepSeek Harness 目前建议发布一个公开的 GitHub 仓库,并添加 dsh-plugin 话题以便被发现。本仓库遵循该约定。

许可证

MIT。参见 LICENSE。
预览分享卡片长什么样 ↓yangwuan55/dsh-feishu-integration
分享 · DeepSeek Harness Hub
yangwuan55/dsh-feishu-integration

把会话总结发到飞书,回复即可路由回原会话

这是你的仓库?认领条目

回到顶部