Skip to content
Merged
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
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

![OpenAB banner](images/banner.jpg)

A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, and any [Agent Client Protocol](https://github.com/anthropics/agent-protocol)-compatible coding CLI (Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI, etc.) over stdio JSON-RPC — delivering the next-generation development experience. **Telegram, LINE**, and other webhook-based platforms are supported via the standalone [Custom Gateway](gateway/).
A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, and any [Agent Client Protocol](https://github.com/anthropics/agent-protocol)-compatible coding CLI (Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI, etc.) over stdio JSON-RPC — delivering the next-generation development experience. **Telegram, LINE, Feishu/Lark**, and other webhook-based platforms are supported via the standalone [Custom Gateway](gateway/).

🪼 **Join our community!** Come say hi on Discord — we'd love to have you: **[🪼 OpenAB — Official](https://discord.gg/DmbhfDZjQS)** 🎉

Expand All @@ -21,8 +21,10 @@ A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**,
├──────────────┤ ▼ ▼
│ LINE │◄──webhook──┌──────────────────┐
│ User │ │ Custom Gateway │
└──────────────┘ │ (standalone) │
└──────────────────┘
├──────────────┤ │ (standalone) │
│ Feishu/Lark │◄───WS──────│ │
│ User │ └──────────────────┘
└──────────────┘
```

## Demo
Expand Down Expand Up @@ -87,6 +89,13 @@ See [docs/line.md](docs/line.md) for the full setup guide. Requires the standalo

</details>

<details>
<summary><strong>Feishu/Lark</strong> (via Custom Gateway)</summary>

See [docs/feishu.md](docs/feishu.md) for the full setup guide. Requires the standalone [Custom Gateway](gateway/) service. Supports WebSocket long-connection (default, no public URL needed) and HTTP webhook fallback.

</details>

### 2. Install with Helm (Kiro CLI — default)

```bash
Expand Down
14 changes: 13 additions & 1 deletion charts/openab/templates/gateway-secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
{{- $gwCfg := omit $cfg "nameOverride" }}
{{- $d := dict "ctx" $ "agent" (printf "%s-gateway" $name) "cfg" $gwCfg }}
{{- $hasTeams := and (($cfg.gateway).teams).appId (($cfg.gateway).teams).appSecret }}
{{- if $hasTeams }}
{{- $hasFeishu := and (($cfg.gateway).feishu).appId (($cfg.gateway).feishu).appSecret }}
{{- if or $hasTeams $hasFeishu }}
---
apiVersion: v1
kind: Secret
Expand All @@ -15,7 +16,18 @@ metadata:
"helm.sh/resource-policy": keep
type: Opaque
data:
{{- if $hasTeams }}
teams-app-secret: {{ ($cfg.gateway).teams.appSecret | b64enc | quote }}
{{- end }}
{{- if $hasFeishu }}
feishu-app-secret: {{ ($cfg.gateway).feishu.appSecret | b64enc | quote }}
{{- if ($cfg.gateway).feishu.verificationToken }}
feishu-verification-token: {{ ($cfg.gateway).feishu.verificationToken | b64enc | quote }}
{{- end }}
{{- if ($cfg.gateway).feishu.encryptKey }}
feishu-encrypt-key: {{ ($cfg.gateway).feishu.encryptKey | b64enc | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
48 changes: 48 additions & 0 deletions charts/openab/templates/gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,54 @@ spec:
value: {{ ($cfg.gateway).teams.webhookPath | quote }}
{{- end }}
{{- end }}
{{- $hasFeishu := and (($cfg.gateway).feishu).appId (($cfg.gateway).feishu).appSecret }}
{{- if $hasFeishu }}
- name: FEISHU_APP_ID
value: {{ ($cfg.gateway).feishu.appId | quote }}
- name: FEISHU_APP_SECRET
valueFrom:
secretKeyRef:
name: {{ include "openab.agentFullname" $d }}
key: feishu-app-secret
{{- if ($cfg.gateway).feishu.domain }}
- name: FEISHU_DOMAIN
value: {{ ($cfg.gateway).feishu.domain | quote }}
{{- end }}
{{- if ($cfg.gateway).feishu.connectionMode }}
- name: FEISHU_CONNECTION_MODE
value: {{ ($cfg.gateway).feishu.connectionMode | quote }}
{{- end }}
{{- if ($cfg.gateway).feishu.webhookPath }}
- name: FEISHU_WEBHOOK_PATH
value: {{ ($cfg.gateway).feishu.webhookPath | quote }}
{{- end }}
{{- if ($cfg.gateway).feishu.verificationToken }}
- name: FEISHU_VERIFICATION_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "openab.agentFullname" $d }}
key: feishu-verification-token
{{- end }}
{{- if ($cfg.gateway).feishu.encryptKey }}
- name: FEISHU_ENCRYPT_KEY
valueFrom:
secretKeyRef:
name: {{ include "openab.agentFullname" $d }}
key: feishu-encrypt-key
{{- end }}
{{- if ($cfg.gateway).feishu.allowedGroups }}
- name: FEISHU_ALLOWED_GROUPS
value: {{ ($cfg.gateway).feishu.allowedGroups | join "," | quote }}
{{- end }}
{{- if ($cfg.gateway).feishu.allowedUsers }}
- name: FEISHU_ALLOWED_USERS
value: {{ ($cfg.gateway).feishu.allowedUsers | join "," | quote }}
{{- end }}
{{- if not (($cfg.gateway).feishu).requireMention }}
- name: FEISHU_REQUIRE_MENTION
value: "false"
{{- end }}
{{- end }}
- name: RUST_LOG
value: {{ ($cfg.gateway).rustLog | default "info" | quote }}
livenessProbe:
Expand Down
13 changes: 13 additions & 0 deletions charts/openab/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ agents:
openidMetadata: "" # Override for sovereign clouds → TEAMS_OPENID_METADATA
allowedTenants: [] # List of tenant IDs → TEAMS_ALLOWED_TENANTS
webhookPath: "" # Gateway default: /webhook/teams → TEAMS_WEBHOOK_PATH
# Feishu/Lark adapter config (gateway-side env vars)
# See docs/feishu.md for full setup guide
feishu:
appId: "" # Feishu App ID → FEISHU_APP_ID
appSecret: "" # Feishu App Secret → FEISHU_APP_SECRET (use --set-literal or external secret mgmt)
domain: "feishu" # "feishu" (China) or "lark" (international) → FEISHU_DOMAIN
connectionMode: "websocket" # "websocket" (default, recommended) or "webhook" → FEISHU_CONNECTION_MODE
webhookPath: "" # Gateway default: /webhook/feishu → FEISHU_WEBHOOK_PATH
verificationToken: "" # Webhook verification token → FEISHU_VERIFICATION_TOKEN
encryptKey: "" # Webhook encrypt key → FEISHU_ENCRYPT_KEY
allowedGroups: [] # List of chat_id → FEISHU_ALLOWED_GROUPS
allowedUsers: [] # List of open_id → FEISHU_ALLOWED_USERS
requireMention: true # Require @mention in groups → FEISHU_REQUIRE_MENTION
# Scheduled messages — config-driven cron (ADR: basic-cronjob)
# Each entry sends a message to the agent at the specified schedule.
# Example:
Expand Down
4 changes: 2 additions & 2 deletions docs/config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ Slack adapter using Socket Mode. Requires both a Bot User OAuth Token and an App

## `[gateway]`

Custom Gateway adapter for platforms like Telegram and LINE. Connects to the gateway via WebSocket.
Custom Gateway adapter for platforms like Telegram, LINE, and Feishu/Lark. Connects to the gateway via WebSocket.

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `url` | string | *required* | WebSocket URL of the gateway (e.g. `ws://openab-gateway:8080/ws`). |
| `platform` | string | `"telegram"` | Platform name for session key namespacing (e.g. `"telegram"`, `"line"`). |
| `platform` | string | `"telegram"` | Platform name for session key namespacing (e.g. `"telegram"`, `"line"`, `"feishu"`). |
| `token` | string | — | Shared token for WebSocket authentication (optional but recommended). |
| `bot_username` | string | — | Bot username for @mention gating in groups. |
| `allow_all_channels` | bool \| omit | auto-detect | `true` = all channels; `false` = only `allowed_channels`. Omitted = inferred from list (non-empty → false, empty → true). |
Expand Down
108 changes: 108 additions & 0 deletions docs/feishu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Feishu / Lark

Connect OpenAB to Feishu (China) or Lark (international) so users can chat with an AI agent in DMs or group chats.

## Prerequisites

1. Create a Feishu/Lark app at [open.feishu.cn](https://open.feishu.cn/) or [open.larksuite.com](https://open.larksuite.com/).
2. Enable the **Bot** capability.
3. In **Event Subscriptions**, select **Long Connection** (WebSocket) mode.
4. Add the `im.message.receive_v1` event.
5. Grant the following permission scopes:
- `im:message` — receive messages
- `im:message:send_as_bot` — send messages as bot
- `contact:user.base:readonly` — resolve sender display names (recommended; without it, senders show as `ou_xxx`)
6. Copy the **App ID** and **App Secret** from **Credentials & Basic Info**.

## Quick Start (Helm)

```yaml
agents:
kiro:
gateway:
enabled: true
url: "ws://openab-kiro-gateway:8080/ws"
platform: "feishu"
botUsername: "ou_YOUR_BOT_OPEN_ID" # bot's open_id for @mention gating
feishu:
appId: "cli_xxx"
appSecret: "secret_xxx"
domain: "feishu" # "feishu" or "lark"
connectionMode: "websocket" # recommended
```

```bash
helm upgrade --install openab charts/openab \
--set-literal agents.kiro.gateway.feishu.appSecret="your-secret"
```

## Connection Modes

### WebSocket (default, recommended)

The gateway connects outbound to Feishu — no public URL, TLS, or Ingress required.

Set `connectionMode: "websocket"` (default).

### Webhook (fallback)

Use when outbound WebSocket is blocked by your network.

```yaml
feishu:
connectionMode: "webhook"
webhookPath: "/webhook/feishu"
verificationToken: "your-token"
encryptKey: "your-key"
```

Then configure the webhook URL in Feishu Open Platform → Event Subscriptions → Request URL:
```
https://your-gateway-host/webhook/feishu
```

## Configuration Reference

| Helm Value | Env Var | Default | Description |
|---|---|---|---|
| `feishu.appId` | `FEISHU_APP_ID` | — | App ID (required) |
| `feishu.appSecret` | `FEISHU_APP_SECRET` | — | App Secret (required, stored in K8s Secret) |
| `feishu.domain` | `FEISHU_DOMAIN` | `feishu` | `feishu` (China) or `lark` (international) |
| `feishu.connectionMode` | `FEISHU_CONNECTION_MODE` | `websocket` | `websocket` or `webhook` |
| `feishu.webhookPath` | `FEISHU_WEBHOOK_PATH` | `/webhook/feishu` | Webhook endpoint path |
| `feishu.verificationToken` | `FEISHU_VERIFICATION_TOKEN` | — | Webhook verification token (stored in K8s Secret) |
| `feishu.encryptKey` | `FEISHU_ENCRYPT_KEY` | — | Webhook encrypt key (stored in K8s Secret) |
| `feishu.allowedGroups` | `FEISHU_ALLOWED_GROUPS` | — | Comma-separated chat_id allowlist |
| `feishu.allowedUsers` | `FEISHU_ALLOWED_USERS` | — | Comma-separated open_id allowlist |
| `feishu.requireMention` | `FEISHU_REQUIRE_MENTION` | `true` | Require @mention in groups |
| — | `FEISHU_DEDUPE_TTL_SECS` | `300` | Event deduplication cache TTL (seconds) |
| — | `FEISHU_MESSAGE_LIMIT` | `4000` | Max message length before auto-splitting (bytes) |
| `gateway.botUsername` | — | — | Set to bot's `open_id` for @mention gating |

## @mention Gating

In group chats, the bot only responds when @mentioned (default). To find your bot's `open_id`:

1. Start the gateway — it logs the bot identity on startup:
```
feishu bot identity resolved bot_open_id=ou_xxx
```
2. Set `gateway.botUsername` to this value.

To disable mention gating: `feishu.requireMention: false`.

## Security Notes

- `appSecret`, `verificationToken`, and `encryptKey` are stored in a Kubernetes Secret, not in ConfigMap.
- In webhook mode, always set both `verificationToken` and `encryptKey` for production.
- The gateway enforces a 1 MB body size limit and per-IP rate limiting (120 req/60s) on the webhook endpoint.

## Troubleshooting

| Problem | Fix |
|---|---|
| Bot doesn't respond | Check `FEISHU_APP_ID`/`FEISHU_APP_SECRET` are correct. Check gateway logs for token errors. |
| Bot doesn't respond in groups | Ensure bot is @mentioned, or set `requireMention: false`. Check `botUsername` matches bot's `open_id`. |
| WebSocket keeps reconnecting | Check event subscription is set to **Long Connection** mode. Check app is published and approved. |
| Webhook verification fails | Ensure `verificationToken` and `encryptKey` match Feishu app config. |
| Messages from Lark (international) | Set `domain: "lark"` to use `open.larksuite.com` API endpoints. |
Loading
Loading