npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openduo/channel-feishu

v0.2.11

Published

Feishu / Lark channel adapter for [duoduo](https://www.npmjs.com/package/@openduo/duoduo).

Readme

@openduo/channel-feishu

Feishu / Lark channel adapter for duoduo.

Connects duoduo to Feishu via the Feishu Open Platform WebSocket long-poll API. Requires no public URL — the gateway initiates the connection outbound.

The Feishu messaging layer in this package was written by duoduo itself, referencing openclaw as prior art (with respect). The implementation was designed from scratch to fit duoduo's channel protocol — session routing, media bridging, delivery cursors, and gateway command handling are native to this runtime.

How It Works

The Feishu gateway is an independent process that sits between the Feishu Open Platform and the duoduo daemon. It translates Feishu events into the duoduo standard protocol and vice versa.

Inbound: Feishu messages arrive via WebSocket event subscription. The gateway handles deduplication, access policy, media download, @mention normalization, and dispatch to the daemon.

Outbound: The gateway maintains a pull subscription per active chat. When the daemon produces output, the gateway renders it (plain text or interactive card), handles file upload, and sends it back to Feishu.

Media bridging: Images, files, audio, and video are downloaded from Feishu and uploaded to the daemon's file store before ingress. On egress, daemon-produced files are downloaded and re-uploaded to Feishu.

Typing indicators: Feishu has no native typing API. The gateway uses emoji reactions as staged presence signals (received → thinking → working → typing), cleaned up after each response.

Access control: Configurable DM policy (open, allowlist) and group policy (open, allowlist, disabled). Groups can require a bot @mention before the message is forwarded to the daemon.

Commands: Gateway control commands (/status, /cancel, /cd, /clear, /stats) are handled directly without routing through the agent session.

Requirements

  • Node.js 20+
  • A running duoduo daemon (@openduo/duoduo)
  • A Feishu app with WebSocket long-poll enabled

Installation

Via duoduo CLI (recommended)

duoduo channel install @openduo/channel-feishu

Manual

npm install -g @openduo/channel-feishu

Feishu App Setup

In the Feishu Developer Console:

  1. Create an app (or use an existing one).
  2. Enable WebSocket long-poll under Events & Callbacks → Connection mode.
  3. Subscribe to the im.message.receive_v1 event.
  4. Grant the following permissions:

| Permission | Purpose | | ---------------------------------- | --------------------------------------- | | im:message | Send and receive messages | | im:message.p2p_msg:readonly | Receive direct messages | | im:message.group_at_msg:readonly | Receive @bot messages in groups | | im:message:send_as_bot | Send messages as bot | | im:resource | Upload and download media | | contact:user.base:readonly | Resolve sender display names (optional) |

Configuration

All configuration is via environment variables:

| Variable | Default | Description | | ------------------------ | ------------------------ | ------------------------------------------------ | | FEISHU_APP_ID | — | Required. Feishu app ID | | FEISHU_APP_SECRET | — | Required. Feishu app secret | | FEISHU_DOMAIN | feishu | feishu, lark, or custom domain URL | | ALADUO_DAEMON_URL | http://127.0.0.1:20233 | duoduo daemon address | | FEISHU_DM_POLICY | open | DM access: open or allowlist | | FEISHU_GROUP_POLICY | allowlist | Group access: open, allowlist, or disabled | | FEISHU_REQUIRE_MENTION | true | Require @bot mention in groups | | FEISHU_ALLOW_FROM | — | Comma-separated open_id allowlist | | FEISHU_ALLOW_GROUPS | — | Comma-separated chat_id allowlist | | FEISHU_RENDER_MODE | auto | Output rendering: auto, raw, or card | | FEISHU_BOT_OPEN_ID | — | Bot's own open_id (for mention detection) | | FEISHU_LOG_LEVEL | info | Log level |

For FEISHU_GROUP_POLICY=allowlist, FEISHU_ALLOW_FROM and FEISHU_ALLOW_GROUPS are peer entity allowlists:

  • A listed open_id may talk to the bot in any group.
  • A listed chat_id allows any member of that group to talk to the bot.
  • If neither list matches, the group message is denied.

Render modes:

  • auto — plain text by default; switches to interactive card when output contains code blocks or tables.
  • raw — always plain text.
  • card — always interactive card.

Usage

Via duoduo CLI

# Start (managed by duoduo)
duoduo channel feishu start

# Check status
duoduo channel feishu status

# View logs
duoduo channel feishu logs

# Stop
duoduo channel feishu stop

In host mode, duoduo channel feishu start auto-loads ~/.config/duoduo/.env before launching the managed channel process. Put FEISHU_APP_ID, FEISHU_APP_SECRET, and optional ALADUO_DAEMON_URL there if you want daemon and channel startup to behave consistently.

Standalone

FEISHU_APP_ID=cli_xxx \
FEISHU_APP_SECRET=xxx \
ALADUO_DAEMON_URL=http://127.0.0.1:20233 \
duoduo-feishu

When you launch duoduo-feishu directly in host mode, the process logs a warning that ~/.config/duoduo/.env is not auto-loaded. That warning is intentional: direct standalone launch expects you to export the environment yourself.

License

MIT