Notifications & Integrations

dsh-feishu-bridge-ailoushu

ailoushu666/dsh-feishu-bridge · ★ 2

ailoushu666

飞书机器人 ↔ DeepSeek Harness 桥接插件:通过飞书 WebSocket 长连接收发消息,把飞书会话映射到 Harness Agent,并把 Agent 的回复与执行过程回传到飞书。

License
MIT
Added
2026-10-30
Maintenance
active
Install kind
github
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T09:38:24.418Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add 'github:ailoushu666/dsh-feishu-bridge#7c9bd50bded5fd19c9e1ad73902c1d1468b916df'

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. dsh-feishu-bridge
  2. Quick install
  3. Features
  4. Supported commands
  5. Requirements
  6. Quick start (deploy into DSH)
  7. Step 1: Prepare Feishu
  8. Step 2: Install the plugin into the web profile
  9. Step 3: Store the secret and enable
  10. Step 4: Start
  11. Step 5: Verify
  12. Config & credential locations
  13. Configuration options
  14. Feishu permissions
  15. Project structure
  16. Security
  17. Known limitations (MVP)
  18. Troubleshooting
  19. Uninstall
  20. Docs
  21. License

dsh-feishu-bridge banner

dsh-feishu-bridge

A bridge plugin that connects a Feishu (Lark) bot to DeepSeek Harness (DSH): Feishu / Lark ↔ DeepSeek Harness.

Message a bot in Feishu, and the message becomes one task for a DSH Agent; the Agent's final answer and progress hints (e.g. which tools it called) are sent back to Feishu — control DSH agents directly from Feishu.

  • No public endpoint needed: WebSocket long connection, runs locally
  • Session context preserved: one DSH Session per Feishu chat / thread
  • Visible execution: tool-call progress forwarded to Feishu in real time
  • Control from Feishu: /reset, /workspace, /mode, /model, /effort, /stop, and more

Quick install

# Install from GitHub (recommended)
npx @deepseek-ai/dsh plugin --profile web add git+https://github.com/ailoushu666/dsh-feishu-bridge.git

# Or install from a local checkout (development)
npx @deepseek-ai/dsh plugin --profile web add "<this project directory>"

For the full steps see Quick start (deploy into DSH); Feishu console setup: docs/feishu-setup.md.

中文:README.md


Features

  • Uses Feishu's official @larksuiteoapi/node-sdk over a WebSocket long connection — no public IP / domain / port forwarding required.
  • Reuses the same DSH Session per Feishu chat (or thread), so context is preserved; each thread is independent.
  • Replies are linked to the triggering message; replies inside a thread stay in that thread.
  • By default only handles direct messages and group messages that @mention the bot.
  • Visible progress: tool calls show as 🔧 调用工具 <name>, and intermediate replies between tool calls are forwarded too (💬), all sent through a throttled queue so Feishu rate limits never drop them; the final answer is replied to the original message separately.
  • Instant acknowledgement (“processing / queued”) for every message; turns exceeding turnTimeoutMs are auto-cancelled with a notice.
  • Autonomous DSH turns are pushed back to Feishu: when DSH wakes the Agent on its own (goal rounds / scheduled tasks / background jobs) and produces a result, Feishu receives it — no longer limited to one reply per message.
  • Interactive questions in Feishu: when the Agent needs your confirmation or choice (ask_user_question), the question and its options arrive as a ❓ list — reply with a number (e.g. 1), an option label, or free text to answer, and the Agent continues; invalid replies (several numbers for a single choice, out-of-range numbers) are re-prompted instead of polluting the Agent.
  • A set of Feishu control commands: switch project folder, switch working mode, switch model & reasoning effort, stop a task, record feedback, manage a long-running goal, enter plan mode, and more.

Supported commands

Send them directly in Feishu (@mention the bot in groups, plain in DMs). Case-insensitive.

Command Argument Purpose Interrupts the conversation?
/reset — Start a new conversation (the old one stays in the DSH sidebar). Aliases: /new, /clear, 重置, 新会话, 清空会话, 重置会话 Yes
/compact — Compact context (summarize older history to save tokens). Aliases: /压缩, 压缩上下文, 压缩会话 No
/workspace <absolute path> Switch the project folder (path must already exist) Yes
/mode (= /permission) <read|write|full> Switch working mode: read-only / workspace-write / full access (a permission preset bundling sandbox + approval policy) No (this session only)
/model <model name> Switch model (unknown names are rejected) No (next turn)
/effort <off|high|max> Set reasoning effort (only effort levels the model supports) No (next turn)
/stop — Immediately cancel the running task. Aliases: /cancel, /halt —
/feedback <feedback text> Record feedback about this session No
/goal [objective|clear|edit <objective>|pause|resume] Set / view / manage a long-running goal No
/plan [off|description] Enter / leave plan mode (plan before acting) No
/export — Export the session log (web-only feature; the Feishu text channel cannot deliver files, so it points you to the web UI) —
/session [number|full id] List non-archived sessions (with titles) without an argument; switch to a specific session with one Yes (switches session)
/help — List all commands —

/workspace, /mode, /model, /effort without an argument show the current value or available options. For /mode, the short names read / write / full map to read-only / workspace-write / danger-full-access; full names are also accepted.


Requirements

  • Node.js ^22.19.0 or >= 24 (same as Harness).
  • A working DeepSeek Harness (dsh web).
  • A Feishu self-built app with: bot capability enabled, the im.message.receive_v1 event subscribed over long connection, and the required permissions granted.

See docs/feishu-setup.md for the full Feishu console steps.


Quick start (deploy into DSH)

Step 1: Prepare Feishu

Follow docs/feishu-setup.md: create the self-built app → enable the bot capability → grant permissions → subscribe im.message.receive_v1 over long connection → publish and install the app. Note down the App ID and App Secret.

Step 2: Install the plugin into the web profile

npx @deepseek-ai/dsh plugin --profile web add "<this project directory>"

The plugin creates a disabled by default feishu-bridge instance in the bundle layer.

Step 3: Store the secret and enable

The App ID (not secret) and the App Secret (secret) are stored separately:

  1. Put the App Secret into DSH's credential file ~/.dsh/.credentials.yaml (Windows: C:\Users\<you>\.dsh\.credentials.yaml), with a key matching appSecretEnv (default FEISHU_APP_SECRET):

    FEISHU_APP_SECRET: <your App Secret>
    
  2. Edit the profile patch ~/.dsh/profiles/web/cordis.patch.yml (Windows: C:\Users\<you>\.dsh\profiles\web\cordis.patch.yml) and override the same id to enable it:

    - id: feishu-bridge
      disabled: false
      config:
        appId: cli_xxxxxxxxxxxxxxxx        # App ID (not secret)
        appSecretEnv: FEISHU_APP_SECRET    # reference name; value lives in ~/.dsh/.credentials.yaml
        domain: feishu                     # feishu (China) or lark (international)
        requireMention: true               # group messages must @mention the bot
        dmMode: open                       # DMs: open / allowlist / disabled
    

Do not insert a second instance with the same id — that raises duplicate loader entry id: feishu-bridge.

Step 4: Start

npx @deepseek-ai/dsh web

This line means the Feishu long connection is up:

feishu-bridge: WebSocket connected

Step 5: Verify

  • DM the bot; it replies with the final answer, and keeps context on follow-ups.
  • In a group: @bot your question.
  • Send /help for the full command list.

Config & credential locations

What File
Enable instance + plugin config ~/.dsh/profiles/web/cordis.patch.yml (Windows: C:\Users\<you>\.dsh\profiles\web\cordis.patch.yml)
App Secret (credential) ~/.dsh/.credentials.yaml (Windows: C:\Users\<you>\.dsh\.credentials.yaml)

Configuration options

Option Required Default Description
appId Yes — Feishu App ID (not secret; plaintext)
appSecretEnv Yes FEISHU_APP_SECRET Credential reference name; the value lives in ~/.dsh/.credentials.yaml
domain No feishu feishu (China) / lark (international)
requireMention No true Require @mention in groups
dmMode No open DM policy: open / allowlist / disabled
groupAllowlist No [] Group chat_id allowlist; empty = unrestricted
dmAllowlist No [] Allowed user open_ids when dmMode: allowlist
botOpenId No — Bot open_id for exact @mention detection; absent falls back to "mentions not empty"
provider / model No Harness default Model for the Feishu channel
reasoningEffort No model default Reasoning effort for the Feishu channel (e.g. off/high/max)
workspace No first Workspace Agent working directory
agentPreset No default Preset Preset for the Agent (tools / system prompt)
streamProgress No true Forward tool-call progress to Feishu
maxProgressMessages No 0 (unlimited) Max progress messages per turn (tool calls + intermediate replies); 0 = forward everything
processingNotice No true Send an instant “processing / queued” acknowledgement for normal messages
turnTimeoutMs No 900000 (15 min) Max duration of one turn in ms; auto-cancel with a notice on timeout
resetCommand No /reset The reset command
compactCommand No /compact The compact command
requireAdminForGroupReset No true Require group owner/admin for /reset (needs im:chat:readonly; set false to allow members)
errorMessage No built-in Chinese text Unified reply on error (max 500 chars)

Full example:

- id: feishu-bridge
  disabled: false
  config:
    appId: cli_xxxxxxxxxxxxxxxx
    appSecretEnv: FEISHU_APP_SECRET
    domain: feishu
    requireMention: true
    dmMode: open
    # optional:
    provider: deepseek-official
    model: deepseek-v4-flash
    reasoningEffort: high
    workspace: C:\Project\my-repo
    agentPreset: coding
    streamProgress: true
    maxProgressMessages: 10

Feishu permissions

The default setup (DM + group @mention + reply) needs these permissions; see docs/feishu-setup.md for details:

Permission Purpose Required
im:message.p2p_msg:readonly Receive DM messages Yes
im:message.group_at_msg:readonly Receive group messages that @mention the bot Yes
im:message:send_as_bot Send messages (reply) as the app Yes
im:chat:readonly Read group info (owner/admin check) Only when group /reset requires admin

Event subscription: use the long connection receive mode and subscribe im.message.receive_v1.


Project structure

dsh-feishu-bridge/
├── package.json          # package metadata + dsh.bundle declaration
├── cordis.patch.yml      # bundle patch: disabled-by-default instance
├── lib/
│   ├── index.js          # plugin entry (name/inject/Config/apply + command dispatch)
│   ├── config.js         # config schema + validation
│   ├── feishu.js         # Feishu long connection + send/reply
│   └── bridge.js         # session mapping + agent driving + channel state + command execution
├── docs/
│   ├── technical.md      # technical documentation
│   └── feishu-setup.md   # Feishu developer console guide
└── .env.example          # explains credential location (no .env needed in practice)

Security

  • The App Secret lives only in DSH's credential file ~/.dsh/.credentials.yaml; the plugin never records it or writes it into the project.
  • Internal errors reply with a unified errorMessage only — stack traces and sensitive info never reach Feishu users.
  • Session IDs are derived via SHA-256 and never embed the raw chat_id / thread_id.
  • Do not run multiple long-connection consumers for the same Feishu app (e.g. both this bridge and OpenClaw's Feishu channel). Feishu distributes events randomly among the connections, so messages get "stolen" and the bot becomes flaky or silent.

Known limitations (MVP)

  • Text messages only; images, rich text (post), files and cards are unsupported.
  • Replies are sent all-at-once (not streamed); progress covers "tool call started + intermediate replies", not tool results.
  • Progress messages, intermediate replies, autonomous-turn results and ❓ questions are all sent to the chat root — including for thread conversations (Feishu API limitation: only reply can stay inside a thread).
  • No persistent chatId → sessionId mapping: after a DSH restart, existing Feishu chats get a new Session (the old one stays on disk but is no longer reused).
  • Runtime switches of model / reasoning effort / project folder are in-memory and reset to config defaults after a DSH restart.
  • /export (ZIP download) is a DSH web-only feature; the Feishu text channel cannot deliver files.
  • Only one long-connection instance per Feishu app.

Troubleshooting

Symptom Check
Auth failure on startup App ID / Secret belong to the same app; FEISHU_APP_SECRET is in ~/.dsh/.credentials.yaml
Connected but no messages app published & installed; bot in the group; im.message.receive_v1 subscribed; long-connection mode; permissions approved; group @mention
Receives but can't reply im:message:send_as_bot granted; check Feishu API errors in the terminal
Connection keeps reconnecting Feishu HTTPS/WebSocket reachable; not running multiple long-connection consumers
Config change has no effect stop and restart Harness (instances are created at profile startup)
Group /reset says "owner/admin only" grant im:chat:readonly, or set requireAdminForGroupReset: false
Intermittent "no response" on consecutive messages usually DeepSeek API rate/concurrency limits (TPM/RPM); retry later, or use /effort off to reduce reasoning cost

Uninstall

npx @deepseek-ai/dsh plugin --profile web remove dsh-feishu-bridge

Then remove the leftover feishu-bridge config from ~/.dsh/profiles/web/cordis.patch.yml.


Docs

License

MIT