# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: OpenAB Feishu Bundle
spec:
    description: |
        All-in-one Feishu/Lark bot powered by OpenAB + Kiro. Deploys the OAB agent and the Feishu gateway together — fill in App ID and App Secret and you're done. WebSocket mode (outbound-only, no public endpoint needed).
        Source: https://github.com/openabdev/openab
    coverImage: https://cdn-console.zeabur.com/f/Xp0H6/openab-cover.webp
    icon: https://cdn-console.zeabur.com/f/0Ewi6/openab-icon.webp
    variables:
        - key: FEISHU_APP_ID
          type: STRING
          name: Feishu App ID
          description: App ID from Feishu Open Platform (https://open.feishu.cn) — starts with `cli_`. Required.
        - key: FEISHU_APP_SECRET
          type: STRING
          name: Feishu App Secret
          description: App Secret from Feishu Open Platform. Required.
        - key: KIRO_API_KEY
          type: STRING
          name: Kiro API Key (optional, Pro+)
          description: Optional. API key for Kiro Pro/Pro+/Power subscribers. Leave empty to authenticate via device flow after deployment (free tier).
    tags:
        - AI
        - Developer Tools
        - Feishu
    readme: |
        # OpenAB Feishu Bundle

        One-click [OpenAB](https://github.com/openabdev/openab) deployment for Feishu/Lark — bot agent + WebSocket gateway bundled together. Just fill in your Feishu App ID and App Secret.

        ```
        Feishu Open Platform ◀──Outbound WebSocket── ┌──────────────────┐ ◀──WebSocket── ┌────────────┐
                                                      │  openab-gateway  │                │   openab   │
                                                      │   (feishu only)  │                │  (Kiro CLI)│
                                                      └──────────────────┘                └────────────┘
                                                           no public ingress                  internal only
        ```

        ## What's deployed

        | Service | Purpose | Public |
        |---|---|---|
        | `openab` | OAB agent running Kiro CLI | No |
        | `openab-gateway` | Feishu event WebSocket → OAB WebSocket bridge | No |

        Both services are internal-only — the gateway connects **outbound** to Feishu Open Platform, no inbound webhook or public domain needed.

        ## Setup

        ### 1. Create a Feishu/Lark App

        1. Go to [Feishu Open Platform](https://open.feishu.cn) (China) or [Lark Developer](https://open.larksuite.com) (overseas)
        2. **Create Custom App** → note the **App ID** (`cli_xxx`) and **App Secret** → paste both into the variables above
        3. Left sidebar → **App Features** → **Bot** → toggle **Enable Bot** to ON
           > ⚠️ Easy to miss. Without this, the app cannot receive messages.
        4. Left sidebar → **Event Subscriptions** → **Connection mode** → select **WebSocket**
        5. **Add event** → `im.message.receive_v1`
        6. Left sidebar → **Permissions & Scopes** → add:
           - `im:message` — send and receive messages
           - `im:message.group_at_msg` — receive group @messages
           - `im:message.group_at_msg:readonly` — read group @mentions
           - `im:message.p2p_msg:readonly` — read DMs
           - `im:resource` — download images/files
           - `contact:user.base:readonly` — resolve display names
        7. **Create Version** → **Apply for publish** (or use in-test mode for development)

        ### 2. (Optional) Get a Kiro API Key

        If you have a paid Kiro subscription, go to [kiro.dev](https://kiro.dev) → Settings → API Keys → create a key and paste it into `KIRO_API_KEY`. Free tier users skip this and authenticate post-deploy in step 4.

        ### 3. Deploy

        Click deploy. No public domain is assigned — Feishu WebSocket is outbound-only.

        ### 4. Authenticate Kiro via Device Flow (free tier only)

        Skip if you set `KIRO_API_KEY` in step 2.

        After the `openab` service is running, open its terminal in Zeabur Dashboard and run:

        ```
        runuser -u agent -- kiro-cli login --use-device-flow
        ```

        Follow the URL and code to authorize in your browser.

        ### 5. Test

        Add the bot to a Feishu group (or DM it directly) and send a message. In groups, @mention the bot to trigger a response (default behavior). The gateway connects outbound to Feishu, receives the event, forwards it to OAB via internal WebSocket, and OAB replies through the gateway.

        Check `openab-gateway` logs for `feishu websocket connected` to confirm the outbound link is up.

        ## Customization

        - **`/home/agent/.config/openab/config.toml`** — OAB config (sessions, reactions, etc.). Created on first boot from a built-in template with the `[gateway]` block pre-wired. To regenerate, delete and restart.
        - **Lark (overseas) vs Feishu (China)** — defaults to Feishu (feishu.cn). If your app is registered on larksuite.com, open the `openab-gateway` service in Zeabur Dashboard → Variables → change `FEISHU_DOMAIN` from `feishu` to `lark` and restart.
        - **@mention requirement in groups** — default is `true` (bot only responds when @mentioned). To allow all messages in approved groups, add `FEISHU_REQUIRE_MENTION=false` to the `openab-gateway` service.
        - **Image tags** — bot tracks the floating `stable` channel (`ghcr.io/openabdev/openab:stable`) and auto-updates with each OpenAB stable release. Gateway is pinned at `ghcr.io/openabdev/openab-gateway:0.5.1` (no `:stable` tag yet). To pin or bump, change the tag in Zeabur Dashboard → Service → Settings. Available tags: [OpenAB](https://github.com/openabdev/openab/pkgs/container/openab) / [Gateway](https://github.com/openabdev/openab/pkgs/container/openab-gateway).

        ## Want a different agent backend?

        This bundle uses Kiro as the default agent. For Claude / Codex / Cursor / Gemini / OpenCode / Hermes / Grok, deploy the corresponding [bot template](https://zeabur.com/templates) separately together with the standalone [OpenAB Gateway](https://zeabur.com/templates/IMRONB).

        ## Want a different platform?

        See [OpenAB Gateway](https://zeabur.com/templates/IMRONB) for Telegram, LINE, Google Chat, MS Teams, WeCom. For an all-in-one Telegram bundle, see [OpenAB Telegram Bundle](https://zeabur.com/templates/RUBDBP).

        ## Links

        - [OpenAB GitHub](https://github.com/openabdev/openab)
        - [Feishu Chart README](https://github.com/openabdev/openab/blob/main/charts/openab-feishu/README.md)
        - [Standalone OpenAB Gateway Template](https://zeabur.com/templates/IMRONB)
    resourceRequirement:
        minConfig:
            cpu: 2
            ram: 4
        recommendedConfig:
            cpu: 4
            ram: 8
    services:
        - name: openab
          icon: https://cdn-console.zeabur.com/f/0Ewi6/openab-icon.webp
          template: PREBUILT_V2
          spec:
            id: openab
            source:
                image: ghcr.io/openabdev/openab:stable
                command:
                    - tini
                    - --
                    - /bin/sh
                    - -c
                    - /opt/start-openab.sh
                runAsUserID: 1000
            volumes:
                - id: agent-home
                  dir: /home/agent
            env:
                GATEWAY_PLATFORM:
                    default: feishu
                GATEWAY_URL:
                    default: ws://openab-gateway:8080/ws
                KIRO_API_KEY:
                    default: ${KIRO_API_KEY}
                OPENAB_MAX_SESSIONS:
                    default: ""
            configs:
                - path: /opt/start-openab.sh
                  template: |
                    #!/bin/sh
                    set -e

                    # Initialize shell dotfiles and fix ownership for persistent volume
                    if [ ! -f /home/agent/.bashrc ]; then
                      cp /etc/skel/.bashrc /home/agent/.bashrc 2>/dev/null || true
                      cp /etc/skel/.profile /home/agent/.profile 2>/dev/null || true
                      cp /etc/skel/.bash_logout /home/agent/.bash_logout 2>/dev/null || true
                    fi

                    if [ "$(id -u)" = "0" ]; then
                      chown -R agent:agent /home/agent
                      chmod 755 /home/agent/.config 2>/dev/null || true
                    fi

                    CONFIG_DIR=/home/agent/.config/openab
                    CONFIG_FILE=$CONFIG_DIR/config.toml
                    mkdir -p "$CONFIG_DIR"

                    if [ ! -f "$CONFIG_FILE" ]; then
                      cp /opt/config.toml.template "$CONFIG_FILE"

                      # [gateway] block — always set (this bundle is gateway-bound)
                      printf '\n[gateway]\nurl = "%s"\nplatform = "%s"\n' \
                        "${GATEWAY_URL:-ws://openab-gateway:8080/ws}" \
                        "${GATEWAY_PLATFORM:-feishu}" >> "$CONFIG_FILE"

                      if [ -n "$OPENAB_MAX_SESSIONS" ]; then
                        printf '\n[pool]\nmax_sessions = %s\n' "$OPENAB_MAX_SESSIONS" >> "$CONFIG_FILE"
                      fi

                      echo "openab: config.toml generated"
                    else
                      echo "openab: using existing config.toml (delete to regenerate)"
                    fi

                    if [ "$(id -u)" = "0" ]; then
                      chown -R agent:agent "$CONFIG_DIR"
                      exec runuser -u agent --preserve-environment -- openab run --config "$CONFIG_FILE"
                    fi

                    exec openab run --config "$CONFIG_FILE"
                  permission: 493
                  envsubst: null
                - path: /opt/config.toml.template
                  template: |
                    [agent]
                    command = "kiro-cli"
                    args = ["acp", "--trust-all-tools"]
                    working_dir = "/home/agent"
                  permission: null
                  envsubst: null
        - name: openab-gateway
          icon: https://cdn-console.zeabur.com/f/0Ewi6/openab-icon.webp
          template: PREBUILT_V2
          spec:
            id: openab-gateway
            source:
                image: ghcr.io/openabdev/openab-gateway:0.5.1
            ports:
                - id: web
                  port: 8080
                  type: HTTP
            env:
                FEISHU_APP_ID:
                    default: ${FEISHU_APP_ID}
                FEISHU_APP_SECRET:
                    default: ${FEISHU_APP_SECRET}
                FEISHU_CONNECTION_MODE:
                    default: websocket
                FEISHU_DOMAIN:
                    default: feishu
            healthCheck:
                type: TCP
                port: web
localization:
    zh-CN:
        description: |
            一键部署的飞书/Lark Bot，集成 OpenAB + Kiro。同时部署 OAB agent 与 Feishu gateway，只需填入 App ID 与 App Secret 即可使用。WebSocket 模式（纯对外连接，无需公开域名）。
            来源：https://github.com/openabdev/openab
        variables:
            - key: FEISHU_APP_ID
              type: STRING
              name: Feishu App ID
              description: 来自飞书开放平台（https://open.feishu.cn）的 App ID，格式为 `cli_xxx`。必填。
            - key: FEISHU_APP_SECRET
              type: STRING
              name: Feishu App Secret
              description: 来自飞书开放平台的 App Secret。必填。
            - key: KIRO_API_KEY
              type: STRING
              name: Kiro API Key（选填，Pro+ 方案）
              description: 选填。Kiro Pro/Pro+/Power 订阅者可填入 API Key，部署后无需手动登录。免费方案留空，部署后使用 device flow 认证。
        readme: |
            # OpenAB Feishu Bundle

            一键部署的 [OpenAB](https://github.com/openabdev/openab) 飞书/Lark bot — bot agent 与 WebSocket gateway 打包在一起，只需填入飞书 App ID 与 App Secret 即可使用。

            ## 部署内容

            | 服务 | 用途 | 公开 |
            |---|---|---|
            | `openab` | 运行 Kiro CLI 的 OAB agent | 否 |
            | `openab-gateway` | 飞书事件 WebSocket → OAB WebSocket 桥接 | 否 |

            两个服务都仅供内部使用——gateway 采**对外连接**（outbound）连到飞书开放平台，不需要 inbound webhook 或公开域名。

            ## 设置步骤

            ### 1. 创建飞书/Lark App

            1. 前往 [飞书开放平台](https://open.feishu.cn)（中国）或 [Lark Developer](https://open.larksuite.com)（海外）
            2. **创建企业自建应用** → 记下 **App ID**（`cli_xxx`）与 **App Secret** → 两者粘贴到上方变量
            3. 左侧菜单 → **应用功能** → **机器人** → 开启 **启用机器人**
               > ⚠️ 这步很容易遗漏。没开的话 App 无法收到消息。
            4. 左侧菜单 → **事件与回调** → **连接方式** → 选 **WebSocket**
            5. **新增事件** → `im.message.receive_v1`
            6. 左侧菜单 → **权限管理** → 新增：
               - `im:message` — 收发消息
               - `im:message.group_at_msg` — 接收群组 @mention 消息
               - `im:message.group_at_msg:readonly` — 读取群组 @mention
               - `im:message.p2p_msg:readonly` — 读取 DM
               - `im:resource` — 下载图片/文件
               - `contact:user.base:readonly` — 解析用户显示名称
            7. **创建版本** → **申请发布**（开发阶段可用测试模式）

            ### 2. （选填）获取 Kiro API Key

            如有付费 Kiro 订阅，前往 [kiro.dev](https://kiro.dev) → Settings → API Keys 创建 key，填入 `KIRO_API_KEY`。免费方案跳过此步骤，于步骤 4 部署后再认证。

            ### 3. 部署

            点击部署。不会分配公开域名——飞书 WebSocket 采对外连接。

            ### 4. 通过 Device Flow 认证 Kiro（仅免费方案）

            若步骤 2 已填入 `KIRO_API_KEY`，跳过此步骤。

            待 `openab` 服务启动后，在 Zeabur Dashboard 打开该服务的终端，运行：

            ```
            runuser -u agent -- kiro-cli login --use-device-flow
            ```

            按照屏幕显示的 URL 和 code 完成浏览器授权。

            ### 5. 测试

            把 bot 加入飞书群组（或直接 DM）并发送消息。群组中需 @mention bot 才会触发响应（默认行为）。Gateway 对外连接到飞书、收到事件后通过内部 WebSocket 转发给 OAB，OAB 处理后通过 Gateway 回复。

            于 `openab-gateway` 日志找 `feishu websocket connected` 确认对外连接已建立。

            ## 想换不同的 agent 后端？

            本 bundle 默认使用 Kiro。若想用 Claude / Codex / Cursor / Gemini / OpenCode / Hermes / Grok，请改部署对应的 [bot template](https://zeabur.com/templates) 搭配独立的 [OpenAB Gateway](https://zeabur.com/templates/IMRONB)。

            ## 想用其他通讯平台？

            请参考 [OpenAB Gateway](https://zeabur.com/templates/IMRONB)，支持 Telegram、LINE、Google Chat、MS Teams、WeCom。若需 Telegram 一键 bundle，请见 [OpenAB Telegram Bundle](https://zeabur.com/templates/RUBDBP)。

            ## 链接

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [飞书 Chart README](https://github.com/openabdev/openab/blob/main/charts/openab-feishu/README.md)
            - [独立 OpenAB Gateway 模板](https://zeabur.com/templates/IMRONB)
    zh-TW:
        description: |
            一鍵部署的飛書/Lark Bot，整合 OpenAB + Kiro。同時部署 OAB agent 與 Feishu gateway，只需填入 App ID 與 App Secret 即可使用。WebSocket 模式（純對外連線，無需公開網域）。
            來源：https://github.com/openabdev/openab
        variables:
            - key: FEISHU_APP_ID
              type: STRING
              name: Feishu App ID
              description: 來自飛書開放平台（https://open.feishu.cn）的 App ID，格式為 `cli_xxx`。必填。
            - key: FEISHU_APP_SECRET
              type: STRING
              name: Feishu App Secret
              description: 來自飛書開放平台的 App Secret。必填。
            - key: KIRO_API_KEY
              type: STRING
              name: Kiro API Key（選填，Pro+ 方案）
              description: 選填。Kiro Pro/Pro+/Power 訂閱者可填入 API Key，部署後無需手動登入。免費方案留空，部署後使用 device flow 認證。
        readme: |
            # OpenAB Feishu Bundle

            一鍵部署的 [OpenAB](https://github.com/openabdev/openab) 飛書/Lark bot — bot agent 與 WebSocket gateway 打包在一起，只需填入飛書 App ID 與 App Secret 即可使用。

            ```
            飛書開放平台 ◀──對外 WebSocket── ┌──────────────────┐ ◀──WebSocket── ┌────────────┐
                                              │  openab-gateway  │                │   openab   │
                                              │   （僅飛書）     │                │ （Kiro CLI）│
                                              └──────────────────┘                └────────────┘
                                                    無公開入口                        內部使用
            ```

            ## 部署內容

            | 服務 | 用途 | 公開 |
            |---|---|---|
            | `openab` | 執行 Kiro CLI 的 OAB agent | 否 |
            | `openab-gateway` | 飛書事件 WebSocket → OAB WebSocket 橋接 | 否 |

            兩個服務都僅供內部使用——gateway 採**對外連線**（outbound）連到飛書開放平台，不需要 inbound webhook 或公開網域。

            ## 設定步驟

            ### 1. 建立飛書/Lark App

            1. 前往 [飛書開放平台](https://open.feishu.cn)（中國）或 [Lark Developer](https://open.larksuite.com)（海外）
            2. **建立企業自建應用** → 記下 **App ID**（`cli_xxx`）與 **App Secret** → 兩者貼到上方變數
            3. 左側選單 → **應用功能** → **機器人** → 開啟 **啟用機器人**
               > ⚠️ 這步很容易漏掉。沒開的話 App 無法收到訊息。
            4. 左側選單 → **事件與回調** → **連線方式** → 選 **WebSocket**
            5. **新增事件** → `im.message.receive_v1`
            6. 左側選單 → **權限管理** → 新增：
               - `im:message` — 收發訊息
               - `im:message.group_at_msg` — 接收群組 @mention 訊息
               - `im:message.group_at_msg:readonly` — 讀取群組 @mention
               - `im:message.p2p_msg:readonly` — 讀取 DM
               - `im:resource` — 下載圖片/檔案
               - `contact:user.base:readonly` — 解析使用者顯示名稱
            7. **建立版本** → **申請發布**（開發階段可用測試模式）

            ### 2. （選填）取得 Kiro API Key

            如果你有付費的 Kiro 訂閱，前往 [kiro.dev](https://kiro.dev) → Settings → API Keys 建立 key，填入 `KIRO_API_KEY`。免費方案跳過此步驟，於步驟 4 部署後再認證。

            ### 3. 部署

            點擊部署。不會分配公開網域——飛書 WebSocket 採對外連線。

            ### 4. 透過 Device Flow 認證 Kiro（僅免費方案）

            若步驟 2 已填入 `KIRO_API_KEY`，跳過此步驟。

            待 `openab` 服務啟動後，於 Zeabur Dashboard 開啟該服務的終端機，執行：

            ```
            runuser -u agent -- kiro-cli login --use-device-flow
            ```

            依照畫面顯示的 URL 與 code 完成瀏覽器授權。

            ### 5. 測試

            把 bot 加入飛書群組（或直接 DM）並發送訊息。群組中需 @mention bot 才會觸發回應（預設行為）。Gateway 對外連線到飛書、收到事件後透過內部 WebSocket 轉發給 OAB，OAB 處理後透過 Gateway 回覆。

            於 `openab-gateway` 紀錄找 `feishu websocket connected` 確認對外連線已建立。

            ## 自訂設定

            - **`/home/agent/.config/openab/config.toml`** — OAB 設定（sessions、reactions 等）。首次啟動時從內建範本建立，`[gateway]` 區塊已預先設好。如需重建，刪除檔案後重啟服務。
            - **Lark（海外）vs 飛書（中國）** — 預設為飛書（feishu.cn）。若 App 註冊在 larksuite.com，請至 Zeabur Dashboard 開啟 `openab-gateway` 服務 → 環境變數 → 將 `FEISHU_DOMAIN` 從 `feishu` 改為 `lark` 並重啟。
            - **群組 @mention 行為** — 預設 `true`（bot 僅在被 @mention 時回應）。若要在已授權的群組中讓 bot 回應所有訊息，請於 `openab-gateway` 服務新增環境變數 `FEISHU_REQUIRE_MENTION=false`。
            - **映像標籤** — bot 追蹤 floating `stable` 標籤（`ghcr.io/openabdev/openab:stable`），OpenAB 推出新穩定版時自動更新。Gateway 目前 pin 在 `ghcr.io/openabdev/openab-gateway:0.5.1`（尚未發布 `:stable` 標籤）。若要 pin 至特定版本或手動升版，請至 Zeabur Dashboard → 服務 → 設定修改映像標籤。可用標籤：[OpenAB](https://github.com/openabdev/openab/pkgs/container/openab) / [Gateway](https://github.com/openabdev/openab/pkgs/container/openab-gateway)。

            ## 想換不同的 agent 後端？

            本 bundle 預設使用 Kiro。若想用 Claude / Codex / Cursor / Gemini / OpenCode / Hermes / Grok，請改部署對應的 [bot template](https://zeabur.com/templates) 搭配獨立的 [OpenAB Gateway](https://zeabur.com/templates/IMRONB)。

            ## 想用其他通訊平台？

            請參考 [OpenAB Gateway](https://zeabur.com/templates/IMRONB)，支援 Telegram、LINE、Google Chat、MS Teams、WeCom。若需 Telegram 一鍵 bundle，請見 [OpenAB Telegram Bundle](https://zeabur.com/templates/RUBDBP)。

            ## 連結

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [飛書 Chart README](https://github.com/openabdev/openab/blob/main/charts/openab-feishu/README.md)
            - [獨立 OpenAB Gateway 模板](https://zeabur.com/templates/IMRONB)
