Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ BUB_DISCORD_ALLOW_CHANNELS='["123456789012345678"]'
uv run bub message
```

Feishu (WebSocket):

```bash
BUB_FEISHU_ENABLED=true
BUB_FEISHU_APP_ID=cli_xxx
BUB_FEISHU_APP_SECRET=xxx
BUB_FEISHU_ALLOW_FROM='["ou_xxx","user@example.com"]'
BUB_FEISHU_ALLOW_CHATS='["oc_xxx"]'
uv run bub message
```

## Development

```bash
Expand Down
4 changes: 3 additions & 1 deletion docs/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Use channels when you want either local interactive operation or remote operatio
- `cli` (local): interactive terminal channel used by `uv run bub chat`.
- [Telegram](telegram.md): direct messages and group chats.
- [Discord](discord.md): servers, channels, and threads.
- [Feishu](feishu.md): WebSocket event subscription for 1:1 and group chats.

## Run Entry

Expand All @@ -24,11 +25,12 @@ If the process exits immediately, check that at least one channel is enabled in
- CLI session key: `cli` or `cli:<name>` (from `--session-id`).
- Telegram session key: `telegram:<chat_id>`
- Discord session key: `discord:<channel_id>`
- Feishu session key: `feishu:<chat_id>` (group) or `feishu:<open_id>` (1:1)

This keeps message history isolated per conversation endpoint.

## Runtime Semantics

- `uv run bub chat` runs `CliChannel` via `ChannelManager`, sharing the same channel pipeline as Telegram/Discord.
- `uv run bub chat` runs `CliChannel` via `ChannelManager`, sharing the same channel pipeline as Telegram/Discord/Feishu.
- CLI sets `debounce_enabled = False`, so each input is processed immediately.
- Message channels keep debounce enabled to batch short bursts before model execution.
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ uv run bub chat \
Other run modes:

- `uv run bub run "summarize current repo status"`: one-shot message and exit.
- `uv run bub message`: run enabled message channels (Telegram/Discord).
- `uv run bub message`: run enabled message channels (Telegram/Discord/Feishu).
- `uv run bub idle`: run scheduler only (no interactive CLI).

## How Input Is Interpreted
Expand Down
14 changes: 12 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Choose one mode based on your operation target:

1. Interactive local operator:
`uv run bub chat`
2. Channel service (Telegram/Discord):
2. Channel service (Telegram/Discord/Feishu):
`uv run bub message`
3. Scheduler-only autonomous mode:
`uv run bub idle`
Expand Down Expand Up @@ -63,6 +63,16 @@ BUB_DISCORD_ALLOW_FROM='["123456789012345678","your_discord_name"]'
BUB_DISCORD_ALLOW_CHANNELS='["123456789012345678"]'
```

Feishu (WebSocket):

```bash
BUB_FEISHU_ENABLED=true
BUB_FEISHU_APP_ID=cli_xxx
BUB_FEISHU_APP_SECRET=xxx
BUB_FEISHU_ALLOW_FROM='["ou_xxx","user@example.com"]'
BUB_FEISHU_ALLOW_CHATS='["oc_xxx"]'
```

Start channel service:

```bash
Expand Down Expand Up @@ -100,7 +110,7 @@ Health checklist:
2. Model key is loaded:
`rg -n "BUB_MODEL|OPENROUTER_API_KEY|LLM_API_KEY" .env`
3. Channel flags are correct:
`rg -n "BUB_TELEGRAM_ENABLED|BUB_DISCORD_ENABLED" .env`
`rg -n "BUB_TELEGRAM_ENABLED|BUB_DISCORD_ENABLED|BUB_FEISHU_ENABLED" .env`
4. Logs show channel startup:
`uv run bub message` and confirm `channel.manager.start` output.

Expand Down
41 changes: 41 additions & 0 deletions docs/feishu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Feishu Integration

Feishu allows Bub to run as a remote collaboration endpoint through a WebSocket event stream.

## Configure

```bash
BUB_FEISHU_ENABLED=true
BUB_FEISHU_APP_ID=cli_xxx
BUB_FEISHU_APP_SECRET=xxx
BUB_FEISHU_ALLOW_FROM='["ou_xxx","user@example.com"]'
BUB_FEISHU_ALLOW_CHATS='["oc_xxx"]'
```

Notes:

- If `BUB_FEISHU_ALLOW_FROM` is empty, all senders are accepted.
- If `BUB_FEISHU_ALLOW_CHATS` is empty, all chats are accepted.
- In production, use strict allowlists.

## Run

```bash
uv run bub message
```

## Run Behavior

- Uses WebSocket subscription for inbound Feishu events.
- Group chats map to `feishu:<chat_id>` session key.
- 1:1 chats map to `feishu:<open_id>` session key.
- Inbound messages enter the same `AgentLoop` used by CLI/Telegram/Discord.
- `,` command boundary is unchanged (`,help` / `,git status` / natural language).

## Security and Operations

1. Keep `BUB_FEISHU_APP_SECRET` only in `.env` or a secret manager.
2. Restrict both `BUB_FEISHU_ALLOW_FROM` and `BUB_FEISHU_ALLOW_CHATS`.
3. Use a dedicated Feishu app for Bub; avoid sharing app credentials across services.
4. Validate reconnect behavior in logs after network interruptions.
5. If `uv run bub message` exits quickly, verify at least one channel is enabled.
15 changes: 15 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ LLM_API_KEY=sk-...
# BUB_DISCORD_COMMAND_PREFIX=!
# BUB_DISCORD_PROXY=http://127.0.0.1:7890

# ---------------------------------------------------------------------------
# Feishu channel (optional)
# ---------------------------------------------------------------------------
# BUB_FEISHU_ENABLED=true
# BUB_FEISHU_APP_ID=cli_xxxxxxxxxxxxx
# BUB_FEISHU_APP_SECRET=xxxxxxxxxxxxxxxx
# Optional security fields for event subscription:
# BUB_FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxx
# BUB_FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxx
# JSON array recommended:
# BUB_FEISHU_ALLOW_FROM='["ou_xxxxxxxxxxxxx","user@example.com"]'
# BUB_FEISHU_ALLOW_CHATS='["oc_xxxxxxxxxxxxx"]'
# Optional API domain override:
# BUB_FEISHU_DOMAIN=open.feishu.cn

# ---------------------------------------------------------------------------
# Example minimal OpenRouter setup
# ---------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ nav:
- CLI (Local): cli.md
- Telegram: telegram.md
- Discord: discord.md
- Feishu: feishu.md

plugins:
- search
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Documentation = "https://bub.build"
bub = "bub.cli:app"

[dependency-groups]
feishu = [
"lark-oapi>=1.4.20",
]
dev = [
"pytest>=7.2.0",
"tox-uv>=1.11.3",
Expand Down
3 changes: 3 additions & 0 deletions src/bub/channels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from bub.channels.base import BaseChannel
from bub.channels.cli import CliChannel
from bub.channels.discord import DiscordChannel, DiscordConfig
from bub.channels.feishu import FeishuChannel, FeishuConfig
from bub.channels.manager import ChannelManager
from bub.channels.telegram import TelegramChannel, TelegramConfig

Expand All @@ -12,6 +13,8 @@
"CliChannel",
"DiscordChannel",
"DiscordConfig",
"FeishuChannel",
"FeishuConfig",
"TelegramChannel",
"TelegramConfig",
]
Loading