# feishu-bot-bootstrap
**Repository Path**: hackerwjz/feishu-bot-bootstrap
## Basic Information
- **Project Name**: feishu-bot-bootstrap
- **Description**: https://github.com/Hoper-J/feishu-bot-bootstrap
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-13
- **Last Updated**: 2026-05-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
---
`feishu-bot-bootstrap` automates the manual flow on the Feishu Open Platform: **create app → enable bot capability → import permissions → configure event + callback subscriptions → publish a version → extract credentials**. Scan once to log in, and receive a working `App ID` / `App Secret` for your downstream AI consumer.
## One-command setup
```bash
npx feishu-bot-bootstrap --headless --app-name "MyBot"
```
Scan the QR → CLI walks through every step → 30–60 seconds later the terminal prints `App ID` / `App Secret`, and the result is written to `~/.feishu-bot-bootstrap/runs//result.json`.

### OpenClaw
If the downstream is OpenClaw, add `--write-openclaw` to have the CLI also write the Feishu channel into the local `openclaw.json`:
```bash
npx feishu-bot-bootstrap --headless --write-openclaw --app-name "MyBot" --preset open-group
```
The CLI auto-detects the OpenClaw config path (as long as the `openclaw` command is available). For flag details, see [OpenClaw integration](#openclaw-integration).
---
## Usage flow
Using headless mode (`--headless`) as the example. After launch, the terminal prints the QR:
```
[feishu-bot-bootstrap] Waiting for Feishu console to be ready
[feishu-bot-bootstrap] Please scan the QR code below with the Feishu mobile app:
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▄▄▄ █▄▄███▄▄█ ▀█▄█ ▄ ▄█ ▄▄▄▄▄ █
█ █ █ █ ▀█ ▄▄▄█▀▀▀ ▀███▄█ █ █ █
█ █▄▄▄█ █▄ ▄▄▀▄ ▄ █▀ ▀▄███ █▄▄▄█ █
...
```
Open the Feishu app → Messages → the `+` in the top-right → Scan, point at the terminal, then confirm on your phone. Everything else runs automatically:
```
[feishu-bot-bootstrap] Create or open app
[feishu-bot-bootstrap] Enable bot capability
[feishu-bot-bootstrap] Configure permissions
[feishu-bot-bootstrap] Permissions: open permission page
[feishu-bot-bootstrap] Permissions: open batch import/export dialog
[feishu-bot-bootstrap] Permissions: switch to import tab
[feishu-bot-bootstrap] Permissions: paste permission JSON
[feishu-bot-bootstrap] Permissions: confirm imported permissions
[feishu-bot-bootstrap] Permissions: submit application
[feishu-bot-bootstrap] Extract credentials
[feishu-bot-bootstrap] Configure event subscriptions
[feishu-bot-bootstrap] Start temporary Feishu long-connection client
[feishu-bot-bootstrap] Events: open add event dialog
[feishu-bot-bootstrap] Events: select Messaging / Receive message
...
[feishu-bot-bootstrap] Configure callback subscriptions
[feishu-bot-bootstrap] Validate credentials
[feishu-bot-bootstrap] App ID: cli_xxxxxxxxxxxxxxxx
[feishu-bot-bootstrap] App Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[feishu-bot-bootstrap] Result written to /Users/you/.feishu-bot-bootstrap/runs//result.json
```
Copy the `App ID` / `App Secret` from stdout into your downstream config, or hand them to your AI to fill in. If the downstream is OpenClaw, add `--write-openclaw` and the CLI will write them for you (see [OpenClaw integration](#openclaw-integration)).
## Output
Main fields in `result.json`:
```json
{
"status": "succeeded",
"app": { "name": "MyBot", "description": "MyBot description" },
"credentials": {
"appId": "cli_xxxxxxxxxxxxxxxx",
"appSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"subscriptions": {
"eventDeliveryMode": "long-connection",
"callbackDeliveryMode": "long-connection",
"events": [
/* receive message / message reaction / ... */
],
"callbacks": [
/* card interaction callback / ... */
]
},
"publish": { "enabled": true, "version": "0.0.1" },
"validation": { "ok": true, "code": 0, "expire": 7185 }
}
```
Default path is `~/.feishu-bot-bootstrap/runs//result.json`; change it with `--output-dir`.
> [!note]
> The `App Secret` appears in stdout, `result.json`, and the `--events-jsonl` event stream.
## Common scenarios
### Watch the browser (local debugging)
```bash
npx feishu-bot-bootstrap --app-name "MyBot"
```
Dropping `--headless` opens a Chrome window (requires a graphical environment) and walks through the full bootstrap flow visibly. The QR appears in the browser — scan it from your phone.
### Credentials only, skip publishing
```bash
npx feishu-bot-bootstrap --headless --app-name "MyBot" --no-publish
```
The app stays in pre-release state.
### Script / pipeline consumption
```bash
npx feishu-bot-bootstrap --headless --app-name "MyBot" --json
```
In `--json` mode stdout emits only the result JSON, progress logs stay quiet, and errors go to stderr with a non-zero exit code. Pull a field straight out of a pipe:
```bash
APP_SECRET=$(npx feishu-bot-bootstrap --headless --app-name "MyBot" --json | jq -r '.credentials.appSecret')
```
### Write into OpenClaw config
```bash
npx feishu-bot-bootstrap --headless --app-name "MyBot" --write-openclaw
```
If the `openclaw` CLI is present, the tool auto-detects the OpenClaw config path and drops the Feishu channel into `openclaw.json`. See [OpenClaw integration](#openclaw-integration).
## Flags quick reference
Full list via `npx feishu-bot-bootstrap --help`. The commonly used ones:
| Flag | Description |
| --------------------------------------------- | ------------------------------------------------------------------------ |
| `--app-name ` | Feishu app name (default `OpenClaw`) |
| `--app-description ` | App description (default `OpenClaw`) |
| `--output-dir ` | Target directory for `result.json` and artifacts |
| `--events-jsonl ` | NDJSON progress-event output path |
| `--headless` | Headless mode; the login QR is printed to the terminal |
| `--no-publish` | Skip the publish step |
| `--json` | Print only the result JSON on stdout; progress logs stay silent |
| `--keep-browser-open` | Keep the browser open after completion for manual inspection |
| `--enable-sensitive-group-message-permission` | Request the Feishu sensitive permission for non-@ group messages |
| `--lang zh\|en` | Switch CLI language (default zh) |
| `--print-spec` | Don't run; print the resolved run configuration |
| `--save-spec ` | Save the resolved configuration to a spec file for reuse |
| `--spec ` | Load configuration from a spec file |
| `--user-data-dir ` | Browser profile path (default `~/.feishu-bot-bootstrap/browser-profile`) |
| `--browser-path ` | Path to a Chromium-family browser executable |
## OpenClaw integration
With `--write-openclaw`, after bootstrap succeeds the CLI writes the Feishu channel into OpenClaw's `openclaw.json`. Related flags all start with `--openclaw-`.
### Channel-behavior presets
The Feishu channel has four key behavior fields (`dmPolicy` / `groupPolicy` / `requireMention` / `streaming`). Three common combinations are preset:
| preset | `dmPolicy` | `groupPolicy` | `requireMention` | `streaming` |
| ------------- | ---------- | ------------- | ---------------- | ----------- |
| `mention-bot` | `pairing` | `open` | `true` | `true` |
| `dm-first` | `pairing` | `disabled` | `true` | `true` |
| `open-group` | `pairing` | `open` | `false` | `true` |
- `mention-bot` — groups open, only replies to @-mentions (**default**)
- `dm-first` — group chat disabled, DMs only
- `open-group` — groups open, replies to every message
Passing `--write-openclaw` without an explicit `--preset` uses `mention-bot`.
### Override individual fields
Instead of (or on top of) a preset, write fields directly:
- `--openclaw-dm-policy {pairing|allowlist|open}`
- `--openclaw-group-policy {allowlist|open|disabled}`
- `--openclaw-allow-from a@example.com,b@example.com` (takes effect when `dmPolicy=allowlist`)
- `--openclaw-group-allow-from chat-id-a,chat-id-b` (takes effect when `groupPolicy=allowlist`)
- `--openclaw-require-mention {true|false}`
- `--openclaw-streaming {true|false}`
- `--openclaw-reply-in-thread {enabled|disabled}`
Explicit flags override the preset's same-named fields.
### Backup and restore
Each write first backs up the existing `openclaw.json` to `openclaw.json.bak-`.
To roll back a bad write:
```bash
npx feishu-bot-bootstrap --restore-openclaw-backup
```
By default this restores the latest backup.
### Non-@ group messages
"Have the bot reply to any message in a group" requires turning on two layers:
- **Feishu side**: by default, non-@ group messages aren't delivered to the bot. Request the sensitive permission `im:message.group_msg` (via `--enable-sensitive-group-message-permission`).
- **OpenClaw side**: `requireMention=false`, provided by `--preset open-group`.
**Passing `--preset open-group` auto-enables the Feishu-side sensitive permission**:
```bash
npx feishu-bot-bootstrap --write-openclaw --preset open-group
```
Equivalent to:
```bash
npx feishu-bot-bootstrap --write-openclaw --preset open-group --enable-sensitive-group-message-permission
```
If you only want the Feishu side (receive every group message but still reply only to @-mentions, e.g. for logging / analytics), pass `--enable-sensitive-group-message-permission` together with the default preset.
### Feishu setup
After bootstrap, two manual steps remain on the Feishu side:
1. Pairing (required)
Open Feishu → search for the published app (or use `Ctrl+K` / `Command+K`):

In the DM, send any text. OpenClaw replies with a line `openclaw pairing approve feishu ...`. Copy that last line:

Run it in your local terminal:

Pairing complete — you can now chat with 🦞:

> [!note]
>
> Pairing is **required**. Until paired, no message sent to the bot from Feishu will get a response:
>
> 
>
> If your Feishu organization has not completed enterprise legal-entity verification or stamped letter-of-authorization verification, the bot cannot be shared externally — external chats / external groups won't work; the other party must first be invited into your organization:
>
> 
2. Add to a group (optional)
Group → top-right `...` → Settings → Group bots:

Click Add:

Pick the published app:

Confirm Add:

`@` the bot in the group to chat:

If you used `--preset open-group --write-openclaw`, both the Feishu side and the OpenClaw side are configured to receive and respond to non-@ messages. To toggle `@`-required off later, run:
```bash
openclaw config set channels.feishu.requireMention false --strict-json
openclaw gateway restart
```
## FAQ
**Q: I already have an app with the same name — will it be reused?**
A: By default **no** — a new one is created.
**Q: Running this repeatedly leaves a pile of apps in the Feishu console?**
A: Yes. Each run creates a new app, nothing is cleaned up. Please manually delete the test apps in the developer console to avoid zombie apps accumulating in your tenant.
**Q: Can I point it at my installed Chrome instead of the managed Chromium?**
A: `--browser-path /path/to/chrome`, or let the CLI auto-detect your system Chrome/Edge.
**Q: Only Chromium-family browsers are supported?**
A: Yes. Safari / Firefox are not supported.
## Local development
```bash
pnpm install
pnpm test # unit tests
pnpm typecheck # type check
pnpm check # lint + format
pnpm cli --help # run the CLI from inside the repo
```