# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: OpenAB Claude
spec:
    description: |
        Open Agent Broker — a lightweight Rust harness that bridges Discord and Slack to any ACP-compatible coding CLI (Claude Code, Codex, Gemini, Kiro) over stdio JSON-RPC.
        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: DISCORD_BOT_TOKEN
          type: STRING
          name: Discord Bot Token (optional)
          description: Optional. Token from https://discord.com/developers/applications. Leave empty if using Slack only.
        - key: OPENAB_AUTH_TOKEN
          type: STRING
          name: Auth Token (optional)
          description: 'Optional. Anthropic API key, Zeabur AI Hub token, or Claude OAuth token (from: claude setup-token). Leave empty to use credentials persisted under /home/node/.claude/ (e.g. via `claude auth login` run inside the container).'
        - key: OPENAB_ALLOWED_CHANNELS
          type: STRING
          name: Discord Channel IDs (optional)
          description: 'Optional. Comma-separated Discord channel IDs where the bot listens. Leave empty to allow all channels. Example: 123456789012345678,234567890123456789'
        - key: OPENAB_ALLOWED_USERS
          type: STRING
          name: Discord User IDs (optional)
          description: Optional. Comma-separated Discord user IDs allowed to interact with the bot. Leave empty to allow everyone in the allowed channels.
        - key: SLACK_BOT_TOKEN
          type: STRING
          name: Slack Bot Token (optional)
          description: Optional. Bot User OAuth Token (xoxb-...) from Slack App settings. Leave empty to disable Slack adapter.
        - key: SLACK_APP_TOKEN
          type: STRING
          name: Slack App Token (optional)
          description: Optional. App-Level Token (xapp-...) for Socket Mode. Required when Slack Bot Token is set.
        - key: OPENAB_ALLOW_BOT_MESSAGES
          type: STRING
          name: Allow Bot Messages (optional)
          description: Optional. Set to 'on' to allow messages from bots/webhooks to trigger the agent. Leave empty to disable (default).
        - key: OPENAB_TRUSTED_BOT_IDS
          type: STRING
          name: Trusted Bot IDs (optional)
          description: Optional. Comma-separated Discord bot IDs trusted to send messages to this bot. Leave empty to trust all bots (default). Only applies when Allow Bot Messages is set.
        - key: OPENAB_MAX_SESSIONS
          type: STRING
          name: Max Concurrent Sessions (optional)
          description: 'Optional. Maximum number of concurrent agent sessions (default: 10). Oldest idle session is evicted when the limit is reached.'
        - key: OPENAB_AGENT_COMMAND
          type: STRING
          name: Agent Command (optional)
          description: 'Optional. Override the agent CLI command (default: claude-agent-acp). Only change if you know what you''re doing.'
        - key: OPENAB_CONFIG_URL
          type: STRING
          name: Config URL (optional)
          description: Optional. URL to a remote config.toml (https://). When set, the local config file is ignored and this URL is used instead.
    tags:
        - AI
        - Developer Tools
        - Discord
        - Slack
    readme: |
        # OpenAB

        [OpenAB](https://github.com/openabdev/openab) is a lightweight, open-source Rust harness that bridges Discord to any [Agent Client Protocol](https://github.com/anthropics/agent-protocol)-compatible coding CLI over stdio JSON-RPC.

        This template deploys the Claude variant (`openab-claude`) which uses `claude-agent-acp` as the agent backend.

        ## Important Notes

        - **Image tag:** This template tracks the floating `beta` channel and auto-updates with each new OpenAB beta release. Switch to `stable` for production use. To pin a specific version, change the image tag in Zeabur Dashboard → Service → Settings. Available tags: [GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab).
        - **Persistent storage:** `/home/node` is mounted as a persistent volume. Plugins, settings, config, and credentials survive restarts.

        ## Setup

        ### 1. Get a Discord Bot Token

        1. Go to https://discord.com/developers/applications and click **New Application**
        2. Navigate to **Bot** tab → click **Reset Token** → copy the token
        3. On the same page, scroll down and enable **Message Content Intent** under Privileged Gateway Intents
        4. Go to **OAuth2 → URL Generator** → check scope `bot` → check permissions: Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Manage Messages
        5. Copy the generated URL and open it in your browser to invite the bot to your server

        ### 2. Choose an Auth Method (optional — leave token empty for in-container login)

        | Method | How to use |
        |--------|-----------|
        | **Anthropic API Key** | Go to [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → copy the `sk-ant-api...` key into `OPENAB_AUTH_TOKEN` |
        | **Zeabur AI Hub Token** | Go to [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → copy the token into `OPENAB_AUTH_TOKEN` |
        | **Claude OAuth Token** | Run `claude setup-token` in your terminal (requires Claude Pro/Max/Team/Enterprise subscription) → visit the URL it shows → authorize → paste the code back → copy the `sk-ant-oat...` token into `OPENAB_AUTH_TOKEN` |
        | **In-container login** | Leave `OPENAB_AUTH_TOKEN` empty. After deploy, go to Zeabur Dashboard → Service → **Exec** and run `runuser -u node -- claude auth login` (or `claude setup-token`). Credentials are written to `/home/node/.claude/` on the persistent volume and survive restarts. |

        > **Wiring tokens to the agent:** openab spawns the agent with `env_clear()`, so for methods 1–3 you must edit `/home/node/.config/openab/config.toml` after first boot and add an env allowlist (or explicit env map) under `[agent]`:
        >
        > ```toml
        > [agent]
        > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
        > ```
        >
        > Method 4 needs no edit — credentials are read from `~/.claude/.credentials.json`.

        ### 3. Get Discord Channel IDs

        1. Open Discord → go to **User Settings** (gear icon) → **Advanced** → enable **Developer Mode**
        2. Right-click the channel where you want the bot to respond → **Copy Channel ID**
        3. For multiple channels, separate IDs with commas: `123456789012345678,234567890123456789`

        ### 4. Deploy

        Fill in the variables and click deploy. The service connects to Discord and/or Slack automatically.

        ## Slack Setup (Optional)

        OpenAB supports Slack via Socket Mode — no public URL needed.

        1. Go to https://api.slack.com/apps → **Create New App** → **From scratch**
        2. **Socket Mode** → Enable → generate an App-Level Token with scope `connections:write` → copy the `xapp-...` token (`SLACK_APP_TOKEN`)
        3. **Event Subscriptions** → Enable Events → add bot events: `app_mention`, `message.channels`, `message.groups`
        4. **OAuth & Permissions** → Bot Token Scopes → add: `app_mentions:read`, `chat:write`, `channels:history`, `groups:history`, `channels:read`, `groups:read`, `reactions:write`, `files:read`, `users:read`
        5. **Install App** → Install to Workspace → copy the `xoxb-...` token (`SLACK_BOT_TOKEN`)
        6. In each Slack channel you want the bot in, run `/invite @YourAppName`

        Set `SLACK_BOT_TOKEN` and `SLACK_APP_TOKEN` in the template variables before deploying. Both Discord and Slack can run simultaneously.

        ## Add Messaging Platforms (Telegram / LINE / Feishu / Google Chat / MS Teams / WeCom)

        For Telegram, deploy the [OpenAB Telegram template](https://zeabur.com/templates/12LLKI) and switch its image tag to `beta-claude` with the matching `OPENAB_AGENT_COMMAND`. Other platforms are enabled by environment variables in unified mode (`LINE_CHANNEL_SECRET`, `FEISHU_APP_ID`, `GOOGLE_CHAT_ENABLED=true`, `TEAMS_APP_ID`, `WECOM_CORP_ID`) — see the [OpenAB docs](https://github.com/openabdev/openab/tree/main/docs). Webhook platforms need a public HTTPS domain on the service (port 8080); Feishu connects outbound via WebSocket and needs no domain.

        ## Usage

        - **@mention the bot** in an allowed channel or Slack channel to start a conversation
        - OpenAB creates a **thread** for multi-turn conversations — no @mention needed for follow-ups
        - Each thread maps to a persistent Claude session (24h TTL)

        ## Customization

        | File | Description |
        |------|-------------|
        | `/home/node/CLAUDE.md` | Agent instructions — Claude reads this on every session |
        | `/home/node/.config/openab/config.toml` | OpenAB config (sessions, reactions, STT, etc.) |
        | `/etc/claude-code/managed-settings.json` | Claude Code permission mode |

        `config.toml` is created from a built-in template on first boot. After that, edit the file directly — environment variables are only used for initial setup. To reset to defaults, delete the file and restart: `rm /home/node/.config/openab/config.toml`

        For config options, see the [OpenAB documentation](https://github.com/openabdev/openab).

        ## Disabling

        Leave `Discord Bot Token` empty. The service sleeps instead of crashing.

        ## Links

        - [OpenAB GitHub](https://github.com/openabdev/openab)
        - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
        - [Anthropic Console](https://console.anthropic.com/)
        - [Zeabur AI Hub](https://zeabur.com/ai-hub)
    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:beta-claude
                command:
                    - /bin/sh
                    - -c
                    - /opt/start-openab.sh
                runAsUserID: 1000
            volumes:
                - id: node-home
                  dir: /home/node
            env:
                DISCORD_BOT_TOKEN:
                    default: ${DISCORD_BOT_TOKEN}
                OPENAB_AGENT_COMMAND:
                    default: claude-agent-acp
                OPENAB_ALLOW_BOT_MESSAGES:
                    default: ""
                OPENAB_ALLOWED_CHANNELS:
                    default: ""
                OPENAB_ALLOWED_USERS:
                    default: ""
                OPENAB_AUTH_TOKEN:
                    default: ${OPENAB_AUTH_TOKEN}
                OPENAB_CONFIG_URL:
                    default: ""
                OPENAB_MAX_SESSIONS:
                    default: ""
                OPENAB_TRUSTED_BOT_IDS:
                    default: ""
                SLACK_APP_TOKEN:
                    default: ""
                SLACK_BOT_TOKEN:
                    default: ""
            configs:
                - path: /opt/start-openab.sh
                  template: |
                    #!/bin/sh
                    set -e

                    # Initialize shell config on first boot (volume is empty)
                    if [ ! -f /home/node/.bashrc ]; then
                      cp /etc/skel/.bashrc /etc/skel/.profile /etc/skel/.bash_logout /home/node/ 2>/dev/null || true
                    fi

                    # Fix ownership for persistent volume when startup runs as root
                    if [ "$(id -u)" = "0" ]; then
                      chown -R node:node /home/node
                      chmod 755 /home/node/.config 2>/dev/null || true
                    fi

                    if [ -z "$DISCORD_BOT_TOKEN" ] && [ -z "$SLACK_BOT_TOKEN" ] && [ -z "$GATEWAY_URL" ]; then
                      echo "openab: no adapter configured (set DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, or GATEWAY_URL) — sleeping"
                      exec sleep infinity
                    fi

                    # Detect auth token type and export appropriate env var.
                    # When OPENAB_AUTH_TOKEN is empty, no env vars are exported — claude-agent-acp
                    # falls back to credentials on the persistent volume (e.g. /home/node/.claude/
                    # written by `claude auth login` or `claude setup-token` run inside the container).
                    if [ -n "$OPENAB_AUTH_TOKEN" ]; then
                      case "$OPENAB_AUTH_TOKEN" in
                        sk-ant-oat*)
                          export CLAUDE_CODE_OAUTH_TOKEN="$OPENAB_AUTH_TOKEN"
                          ;;
                        sk-ant-*)
                          export ANTHROPIC_API_KEY="$OPENAB_AUTH_TOKEN"
                          ;;
                        *)
                          export ANTHROPIC_API_KEY="$OPENAB_AUTH_TOKEN"
                          export ANTHROPIC_BASE_URL="https://hnd1.aihub.zeabur.ai"
                          export CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
                          ;;
                      esac
                    fi

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

                    # Generate config.toml on first boot only
                    # To regenerate, delete the file and restart
                    if [ ! -f "$CONFIG_FILE" ]; then
                      cp /opt/config.toml.template "$CONFIG_FILE"

                      # Add [discord] section if token provided
                      if [ -n "$DISCORD_BOT_TOKEN" ]; then
                        printf '\n[discord]\nbot_token = "${DISCORD_BOT_TOKEN}"\n' >> "$CONFIG_FILE"
                        if [ -n "$OPENAB_ALLOW_BOT_MESSAGES" ]; then
                          printf 'allow_bot_messages = "%s"\n' "$OPENAB_ALLOW_BOT_MESSAGES" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_TRUSTED_BOT_IDS" ]; then
                          IFS=','; bots=""; for id in $OPENAB_TRUSTED_BOT_IDS; do
                            id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && bots="${bots}\"${id}\","; done; unset IFS
                          printf 'trusted_bot_ids = [%s]\n' "$(echo "$bots" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_ALLOWED_CHANNELS" ]; then
                          IFS=','; channels=""; for id in $OPENAB_ALLOWED_CHANNELS; do
                            id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && channels="${channels}\"${id}\","; done; unset IFS
                          printf 'allowed_channels = [%s]\n' "$(echo "$channels" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                        if [ -n "$OPENAB_ALLOWED_USERS" ]; then
                          IFS=','; users=""; for id in $OPENAB_ALLOWED_USERS; do
                            id=$(echo "$id" | tr -d ' '); [ -n "$id" ] && users="${users}\"${id}\","; done; unset IFS
                          printf 'allowed_users = [%s]\n' "$(echo "$users" | sed 's/,$//')" >> "$CONFIG_FILE"
                        fi
                      fi

                      # Add [slack] section if tokens provided
                      if [ -n "$SLACK_BOT_TOKEN" ] && [ -n "$SLACK_APP_TOKEN" ]; then
                        printf '\n[slack]\nbot_token = "${SLACK_BOT_TOKEN}"\napp_token = "${SLACK_APP_TOKEN}"\n' >> "$CONFIG_FILE"
                      fi

                      # Add [gateway] section if URL provided
                      if [ -n "$GATEWAY_URL" ]; then
                        printf '\n[gateway]\nurl = "%s"\nplatform = "%s"\nallow_all_channels = true\nallow_all_users = true\n' "$GATEWAY_URL" "${GATEWAY_PLATFORM:-telegram}" >> "$CONFIG_FILE"
                      fi

                      # Add [pool] section if max_sessions provided
                      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

                    # Inject streaming if GATEWAY_STREAMING is set
                    if [ "$GATEWAY_STREAMING" = "true" ] && grep -q "^\[gateway\]" "$CONFIG_FILE" && ! grep -q "^streaming" "$CONFIG_FILE"; then
                      sed -i '/^\[gateway\]/a streaming = true' "$CONFIG_FILE"
                      echo "openab: injected streaming = true"
                    fi

                    if [ "$(id -u)" = "0" ]; then
                      chown -R node:node "$CONFIG_DIR"
                      # Run openab as node user (claude-code 2.1+ blocks bypassPermissions as root)
                      exec runuser -u node --preserve-environment -- openab run --config "${OPENAB_CONFIG_URL:-$CONFIG_FILE}"
                    fi

                    exec openab run --config "${OPENAB_CONFIG_URL:-$CONFIG_FILE}"
                  permission: 493
                  envsubst: null
                - path: /opt/config.toml.template
                  template: |
                    [agent]
                  permission: null
                  envsubst: null
                - path: /etc/claude-code/managed-settings.json
                  template: |
                    {"permissions":{"defaultMode":"bypassPermissions"}}
                  permission: null
                  envsubst: null
localization:
    es-ES:
        description: |
            Open Agent Broker — un arnés ligero en Rust que conecta Discord y Slack con cualquier CLI de coding compatible con ACP (Claude Code, Codex, Gemini, Kiro) a través de stdio JSON-RPC.
            Fuente: https://github.com/openabdev/openab
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Token del Bot de Discord (opcional)
              description: Opcional. Token obtenido de https://discord.com/developers/applications. Dejar vacío si solo usa Slack.
            - key: OPENAB_AUTH_TOKEN
              type: STRING
              name: Token de Autenticación (opcional)
              description: 'Opcional. Clave API de Anthropic, token de Zeabur AI Hub o token OAuth de Claude (obtenido con: claude setup-token). Dejar vacío para usar las credenciales persistidas en /home/node/.claude/ (p. ej. ejecutando `claude auth login` dentro del contenedor).'
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: IDs de Canales de Discord (opcional)
              description: 'Opcional. IDs de canales de Discord donde el bot escucha, separados por comas. Dejar vacío para permitir todos los canales. Ejemplo: 123456789012345678,234567890123456789'
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: IDs de Usuarios de Discord (opcional)
              description: Opcional. IDs de usuarios de Discord permitidos para interactuar con el bot, separados por comas. Dejar vacío para permitir a todos en los canales permitidos.
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Token de Bot de Slack (opcional)
              description: Opcional. Bot User OAuth Token (xoxb-...) de la configuración de la Slack App. Dejar vacío para deshabilitar Slack.
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Token de App de Slack (opcional)
              description: Opcional. App-Level Token (xapp-...) para Socket Mode. Requerido cuando se configura el Slack Bot Token.
        readme: |
            # OpenAB

            [OpenAB](https://github.com/openabdev/openab) es un arnés ligero de código abierto en Rust que conecta Discord con cualquier CLI de coding compatible con [Agent Client Protocol](https://github.com/anthropics/agent-protocol) a través de stdio JSON-RPC.

            Esta plantilla despliega la variante Claude (`openab-claude`), que utiliza `claude-agent-acp` como backend de agente.

            ## Notas Importantes

            - **Etiqueta de imagen:** Esta plantilla rastrea la etiqueta flotante `beta` y se actualiza automáticamente con cada nueva versión beta de OpenAB. Para fijar una versión específica, cambie la etiqueta de imagen en Zeabur Dashboard → Servicio → Configuración. Etiquetas disponibles: [GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab).
            - **Almacenamiento persistente:** `/home/node` está montado como volumen persistente. Plugins, configuración y credenciales se conservan entre reinicios.

            ## Configuración

            ### 1. Obtener el Discord Bot Token

            1. Ir a https://discord.com/developers/applications y hacer clic en **New Application**
            2. Ir a la pestaña **Bot** → clic en **Reset Token** → copiar el token
            3. En la misma página, bajar y habilitar **Message Content Intent** en Privileged Gateway Intents
            4. Ir a **OAuth2 → URL Generator** → marcar scope `bot` → marcar permisos: Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Manage Messages
            5. Copiar la URL generada y abrirla en el navegador para invitar al Bot al servidor

            ### 2. Elegir método de autenticación (opcional — dejar vacío para login dentro del contenedor)

            | Método | Cómo usarlo |
            |--------|-------------|
            | **Anthropic API Key** | Ir a [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → pegar la clave `sk-ant-api...` en `OPENAB_AUTH_TOKEN` |
            | **Zeabur AI Hub Token** | Ir a [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → pegar el token en `OPENAB_AUTH_TOKEN` |
            | **Claude OAuth Token** | Ejecutar `claude setup-token` en la terminal (requiere suscripción Claude Pro/Max/Team/Enterprise) → abrir la URL mostrada → autorizar → pegar el código → pegar el token `sk-ant-oat...` en `OPENAB_AUTH_TOKEN` |
            | **Login dentro del contenedor** | Dejar `OPENAB_AUTH_TOKEN` vacío. Tras el despliegue, ir a Zeabur Dashboard → Servicio → **Exec** y ejecutar `runuser -u node -- claude auth login` (o `claude setup-token`). Las credenciales se guardan en `/home/node/.claude/` en el volumen persistente y se conservan tras reinicios. |

            > **Conectar tokens al agente:** openab lanza el agente con `env_clear()`, por lo que para los métodos 1–3 hay que editar `/home/node/.config/openab/config.toml` tras el primer arranque y añadir un allowlist de env (o un mapa env explícito) bajo `[agent]`:
            >
            > ```toml
            > [agent]
            > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
            > ```
            >
            > El método 4 no requiere edición — las credenciales se leen de `~/.claude/.credentials.json`.

            ### 3. Obtener IDs de canales de Discord

            1. Abrir Discord → **Ajustes de usuario** (icono de engranaje) → **Avanzado** → activar **Modo desarrollador**
            2. Clic derecho en el canal donde quieres que el Bot responda → **Copiar ID del canal**
            3. Para múltiples canales, separar con comas: `123456789012345678,234567890123456789`

            ### 4. Desplegar

            Completar las variables y hacer clic en desplegar. El servicio se conecta a Discord y/o Slack automáticamente.

            ## Configuración de Slack (Opcional)

            OpenAB soporta Slack mediante Socket Mode — no se necesita URL pública.

            1. Ir a https://api.slack.com/apps → **Create New App** → **From scratch**
            2. **Socket Mode** → Habilitar → generar App-Level Token con scope `connections:write` → copiar el token `xapp-...` (`SLACK_APP_TOKEN`)
            3. **Event Subscriptions** → Habilitar → añadir bot events: `app_mention`, `message.channels`, `message.groups`
            4. **OAuth & Permissions** → Bot Token Scopes → añadir: `app_mentions:read`, `chat:write`, `channels:history`, `groups:history`, `channels:read`, `groups:read`, `reactions:write`, `files:read`, `users:read`
            5. **Install App** → Instalar en el workspace → copiar el token `xoxb-...` (`SLACK_BOT_TOKEN`)
            6. En cada canal de Slack donde quieras usar el bot, ejecuta `/invite @YourAppName`

            Rellena `SLACK_BOT_TOKEN` y `SLACK_APP_TOKEN` antes de desplegar. Discord y Slack pueden funcionar simultáneamente.

            ## Añadir plataformas de mensajería (Telegram / LINE / Feishu / Google Chat / MS Teams / WeCom)

            Para Telegram, despliega la [plantilla OpenAB Telegram](https://zeabur.com/templates/12LLKI) y cambia su image tag a `beta-claude` con el `OPENAB_AGENT_COMMAND` correspondiente. Las demás plataformas se habilitan mediante variables de entorno en modo unified (`LINE_CHANNEL_SECRET`, `FEISHU_APP_ID`, `GOOGLE_CHAT_ENABLED=true`, `TEAMS_APP_ID`, `WECOM_CORP_ID`) — consulta la [documentación de OpenAB](https://github.com/openabdev/openab/tree/main/docs). Las plataformas webhook necesitan un dominio HTTPS público en el servicio (puerto 8080); Feishu se conecta por WebSocket saliente y no necesita dominio.

            ## Uso

            - **@mencionar al bot** en un canal de Discord o Slack permitido para iniciar una conversación
            - OpenAB crea un **thread** para conversaciones de múltiples turnos — no se necesita @mención en los mensajes siguientes
            - Cada thread corresponde a una sesión persistente de Claude (TTL de 24h por defecto)

            ## Integración con GitHub (Opcional)

            El agente puede usar `gh` (GitHub CLI) para revisar PRs, crear issues, comentar, fusionar, etc. Como el contenedor no tiene navegador, la autenticación usa device flow:

            1. Dile al bot en Discord: **"log in to GitHub"**
            2. El bot responderá con un código único y una URL (ej. `https://github.com/login/device`)
            3. Abre la URL en tu teléfono o computadora, ingresa el código y autoriza
            4. El bot confirma el inicio de sesión — `gh` está autenticado para esta sesión

            Ver [gh-auth-device-flow.md](https://github.com/openabdev/openab/blob/main/docs/gh-auth-device-flow.md) para detalles técnicos.

            ## Personalización

            | Archivo | Descripción |
            |---------|-------------|
            | `/home/node/CLAUDE.md` | Instrucciones del agente — Claude lo lee en cada sesión |
            | `/home/node/.config/openab/config.toml` | Configuración de OpenAB (sessions, reactions, STT, etc.) |
            | `/etc/claude-code/managed-settings.json` | Modo de permisos de Claude Code |

            `config.toml` se crea a partir de una plantilla integrada en el primer arranque. Después, edite el archivo directamente — las variables de entorno solo se usan para la configuración inicial. Para restablecer los valores predeterminados, elimine y reinicie: `rm /home/node/.config/openab/config.toml`

            Para opciones de configuración, consulte la [documentación de OpenAB](https://github.com/openabdev/openab).

            ## Desactivar

            Dejar `Discord Bot Token` vacío al desplegar. El servicio entrará en modo sleep sin fallar.

            ## Enlaces

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
            - [Anthropic Console](https://console.anthropic.com/)
            - [Zeabur AI Hub](https://zeabur.com/ai-hub)
    id-ID:
        description: |
            Open Agent Broker — harness Rust yang ringan untuk menjembatani Discord dan Slack ke CLI coding yang kompatibel dengan ACP (Claude Code, Codex, Gemini, Kiro) melalui stdio JSON-RPC.
            Sumber: https://github.com/openabdev/openab
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Token Bot Discord (opsional)
              description: Opsional. Token dari https://discord.com/developers/applications. Kosongkan jika hanya menggunakan Slack.
            - key: OPENAB_AUTH_TOKEN
              type: STRING
              name: Token Autentikasi (opsional)
              description: 'Opsional. Kunci API Anthropic, token Zeabur AI Hub, atau token OAuth Claude (dari: claude setup-token). Kosongkan untuk menggunakan kredensial yang dipertahankan di /home/node/.claude/ (mis. menjalankan `claude auth login` di dalam kontainer).'
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: ID Channel Discord (opsional)
              description: 'Opsional. ID channel Discord tempat bot mendengarkan, dipisahkan koma. Kosongkan untuk mengizinkan semua channel. Contoh: 123456789012345678,234567890123456789'
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: ID Pengguna Discord (opsional)
              description: Opsional. ID pengguna Discord yang diizinkan berinteraksi dengan bot, dipisahkan koma. Kosongkan untuk mengizinkan semua orang di channel yang diizinkan.
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Token Bot Slack (opsional)
              description: Opsional. Bot User OAuth Token (xoxb-...) dari pengaturan Slack App. Kosongkan untuk menonaktifkan Slack.
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Token App Slack (opsional)
              description: Opsional. App-Level Token (xapp-...) untuk Socket Mode. Diperlukan saat Slack Bot Token diatur.
        readme: |
            # OpenAB

            [OpenAB](https://github.com/openabdev/openab) adalah harness Rust yang ringan dan open-source yang menjembatani Discord ke CLI coding yang kompatibel dengan [Agent Client Protocol](https://github.com/anthropics/agent-protocol) melalui stdio JSON-RPC.

            Template ini men-deploy varian Claude (`openab-claude`) yang menggunakan `claude-agent-acp` sebagai backend agen.

            ## Catatan Penting

            - **Tag image:** Template ini mengikuti tag floating `beta` dan otomatis ikut rilis beta OpenAB terbaru. Untuk pin ke versi tertentu, ubah tag image di Zeabur Dashboard → Layanan → Pengaturan. Tag yang tersedia: [GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab).
            - **Penyimpanan persisten:** `/home/node` di-mount sebagai volume persisten. Plugin, pengaturan, config, dan kredensial dipertahankan antar restart.

            ## Pengaturan

            ### 1. Dapatkan Discord Bot Token

            1. Buka https://discord.com/developers/applications dan klik **New Application**
            2. Buka tab **Bot** → klik **Reset Token** → salin token
            3. Di halaman yang sama, scroll ke bawah dan aktifkan **Message Content Intent** di Privileged Gateway Intents
            4. Buka **OAuth2 → URL Generator** → centang scope `bot` → centang izin: Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Manage Messages
            5. Salin URL yang dihasilkan dan buka di browser untuk mengundang Bot ke server Anda

            ### 2. Pilih metode autentikasi (opsional — kosongkan untuk login di dalam kontainer)

            | Metode | Cara menggunakan |
            |--------|------------------|
            | **Anthropic API Key** | Buka [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → tempel kunci `sk-ant-api...` ke `OPENAB_AUTH_TOKEN` |
            | **Zeabur AI Hub Token** | Buka [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → tempel token ke `OPENAB_AUTH_TOKEN` |
            | **Claude OAuth Token** | Jalankan `claude setup-token` di terminal (memerlukan langganan Claude Pro/Max/Team/Enterprise) → buka URL yang ditampilkan → otorisasi → tempel kode → tempel token `sk-ant-oat...` yang dihasilkan ke `OPENAB_AUTH_TOKEN` |
            | **Login di dalam kontainer** | Biarkan `OPENAB_AUTH_TOKEN` kosong. Setelah deploy, buka Zeabur Dashboard → Layanan → **Exec** dan jalankan `runuser -u node -- claude auth login` (atau `claude setup-token`). Kredensial ditulis ke `/home/node/.claude/` pada volume persisten dan dipertahankan setelah restart. |

            > **Menyambungkan token ke agent:** openab menjalankan agent dengan `env_clear()`, jadi untuk metode 1–3 Anda perlu mengedit `/home/node/.config/openab/config.toml` setelah boot pertama dan menambahkan allowlist env (atau peta env eksplisit) di bawah `[agent]`:
            >
            > ```toml
            > [agent]
            > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
            > ```
            >
            > Metode 4 tidak perlu diedit — kredensial dibaca dari `~/.claude/.credentials.json`.

            ### 3. Dapatkan ID Channel Discord

            1. Buka Discord → **Pengaturan Pengguna** (ikon roda gigi) → **Lanjutan** → aktifkan **Mode Pengembang**
            2. Klik kanan channel tempat Anda ingin Bot merespons → **Salin ID Channel**
            3. Untuk beberapa channel, pisahkan dengan koma: `123456789012345678,234567890123456789`

            ### 4. Deploy

            Isi variabel dan klik deploy. Layanan akan terhubung ke Discord dan/atau Slack secara otomatis.

            ## Pengaturan Slack (Opsional)

            OpenAB mendukung Slack melalui Socket Mode — tidak perlu URL publik.

            1. Buka https://api.slack.com/apps → **Create New App** → **From scratch**
            2. **Socket Mode** → Aktifkan → buat App-Level Token dengan scope `connections:write` → salin token `xapp-...` (`SLACK_APP_TOKEN`)
            3. **Event Subscriptions** → Aktifkan → tambahkan bot events: `app_mention`, `message.channels`, `message.groups`
            4. **OAuth & Permissions** → Bot Token Scopes → tambahkan: `app_mentions:read`, `chat:write`, `channels:history`, `groups:history`, `channels:read`, `groups:read`, `reactions:write`, `files:read`, `users:read`
            5. **Install App** → Install ke workspace → salin token `xoxb-...` (`SLACK_BOT_TOKEN`)
            6. Di setiap channel Slack yang ingin menggunakan bot, jalankan `/invite @YourAppName`

            Isi `SLACK_BOT_TOKEN` dan `SLACK_APP_TOKEN` sebelum deploy. Discord dan Slack dapat berjalan bersamaan.

            ## Tambahkan Platform Pesan (Telegram / LINE / Feishu / Google Chat / MS Teams / WeCom)

            Untuk Telegram, deploy [template OpenAB Telegram](https://zeabur.com/templates/12LLKI) dan ganti image tag-nya ke `beta-claude` dengan `OPENAB_AGENT_COMMAND` yang sesuai. Platform lain diaktifkan lewat variabel lingkungan pada unified mode (`LINE_CHANNEL_SECRET`, `FEISHU_APP_ID`, `GOOGLE_CHAT_ENABLED=true`, `TEAMS_APP_ID`, `WECOM_CORP_ID`) — lihat [dokumentasi OpenAB](https://github.com/openabdev/openab/tree/main/docs). Platform webhook memerlukan domain HTTPS publik pada layanan (port 8080); Feishu terhubung keluar via WebSocket dan tidak butuh domain.

            ## Penggunaan

            - **@mention bot** di channel Discord atau Slack yang diizinkan untuk memulai percakapan
            - OpenAB membuat **thread** untuk percakapan multi-giliran — tidak perlu @mention untuk pesan selanjutnya
            - Setiap thread dipetakan ke sesi Claude yang persisten (TTL 24 jam secara default)

            ## Kustomisasi

            | File | Deskripsi |
            |------|-----------|
            | `/home/node/CLAUDE.md` | Instruksi agent — Claude membacanya di setiap sesi |
            | `/home/node/.config/openab/config.toml` | Konfigurasi OpenAB (sessions, reactions, STT, dll.) |
            | `/etc/claude-code/managed-settings.json` | Mode izin Claude Code |

            `config.toml` dibuat dari template bawaan saat boot pertama. Setelah itu, edit file secara langsung — variabel lingkungan hanya digunakan untuk pengaturan awal. Untuk mengembalikan ke default, hapus dan restart: `rm /home/node/.config/openab/config.toml`

            Untuk opsi konfigurasi, lihat [dokumentasi OpenAB](https://github.com/openabdev/openab).

            ## Menonaktifkan

            Kosongkan `Discord Bot Token` saat deploy. Layanan akan tidur tanpa crash.

            ## Tautan

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
            - [Anthropic Console](https://console.anthropic.com/)
            - [Zeabur AI Hub](https://zeabur.com/ai-hub)
    ja-JP:
        description: |
            Open Agent Broker — stdio JSON-RPC を通じて Discord と Slack を ACP 対応の coding CLI（Claude Code、Codex、Gemini、Kiro）にブリッジする軽量な Rust ハーネス。
            ソース：https://github.com/openabdev/openab
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord Bot トークン（オプション）
              description: オプション。https://discord.com/developers/applications から取得したトークン。Slack のみ使用する場合は空欄でも可。
            - key: OPENAB_AUTH_TOKEN
              type: STRING
              name: 認証トークン（オプション）
              description: オプション。Anthropic API キー、Zeabur AI Hub トークン、または Claude OAuth トークン（claude setup-token で取得）。空の場合、永続ボリュームの /home/node/.claude/ にある認証情報を使用します（例：コンテナ内で `claude auth login` を実行して書き込み）。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord チャンネル ID（オプション）
              description: オプション。Bot が監視する Discord チャンネル ID（カンマ区切り）。空の場合、全チャンネルで応答。例：123456789012345678,234567890123456789
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord ユーザー ID（オプション）
              description: オプション。Bot と対話できるユーザーの Discord ユーザー ID（カンマ区切り）。空の場合、許可チャンネルの全員が利用可能。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot トークン（オプション）
              description: オプション。Slack App 設定の Bot User OAuth Token（xoxb-...）。空の場合、Slack アダプターは無効。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App トークン（オプション）
              description: オプション。Socket Mode 用の App-Level Token（xapp-...）。Slack Bot Token を設定する場合は必須。
        readme: |
            # OpenAB

            [OpenAB](https://github.com/openabdev/openab) は、stdio JSON-RPC を通じて Discord を [Agent Client Protocol](https://github.com/anthropics/agent-protocol) 対応の coding CLI にブリッジする軽量なオープンソース Rust ハーネスです。

            このテンプレートは Claude バリアント（`openab-claude`）をデプロイし、`claude-agent-acp` をエージェントバックエンドとして使用します。

            ## 注意事項

            - **イメージタグ：** このテンプレートは floating `beta` タグを追跡し、OpenAB の新しい beta リリースが公開されると自動的に更新されます。特定のバージョンに pin するには、Zeabur Dashboard → サービス → 設定でイメージタグを変更してください。利用可能なタグ：[GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab)。
            - **永続ストレージ：** `/home/node` が永続ボリュームとしてマウントされます。プラグイン、設定、config、認証情報は再起動後も保持されます。

            ## セットアップ

            ### 1. Discord Bot Token の取得

            1. https://discord.com/developers/applications にアクセスし、**New Application** をクリック
            2. **Bot** タブ → **Reset Token** をクリック → token をコピー
            3. 同じページを下にスクロールし、Privileged Gateway Intents の **Message Content Intent** を有効化
            4. **OAuth2 → URL Generator** → scope `bot` にチェック → 権限にチェック：Send Messages、Send Messages in Threads、Create Public Threads、Read Message History、Add Reactions、Manage Messages
            5. 生成された URL をコピーし、ブラウザで開いて Bot をサーバーに招待

            ### 2. 認証方法を選択（オプション — 空のままにするとコンテナ内ログインが可能）

            | 方法 | 使用方法 |
            |------|---------|
            | **Anthropic API Key** | [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → `sk-ant-api...` キーを `OPENAB_AUTH_TOKEN` に貼り付け |
            | **Zeabur AI Hub Token** | [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → token を `OPENAB_AUTH_TOKEN` に貼り付け |
            | **Claude OAuth Token** | ターミナルで `claude setup-token` を実行（Claude Pro/Max/Team/Enterprise サブスクリプションが必要）→ 表示された URL を開く → 認証 → コードを貼り付け → 出力された `sk-ant-oat...` token を `OPENAB_AUTH_TOKEN` に貼り付け |
            | **コンテナ内ログイン** | `OPENAB_AUTH_TOKEN` を空のままに。デプロイ後、Zeabur Dashboard → サービス → **Exec** で `runuser -u node -- claude auth login`（または `claude setup-token`）を実行。認証情報は永続ボリュームの `/home/node/.claude/` に書き込まれ、再起動後も保持されます。 |

            > **トークンを agent に渡す：** openab は `env_clear()` で agent サブプロセスを分離するため、方法 1–3 では初回起動後に `/home/node/.config/openab/config.toml` を編集し、`[agent]` セクションに env allowlist（または明示的な env マップ）を追加する必要があります：
            >
            > ```toml
            > [agent]
            > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
            > ```
            >
            > 方法 4 は編集不要 — 認証情報は `~/.claude/.credentials.json` から直接読み込まれます。

            ### 3. Discord チャンネル ID の取得

            1. Discord を開く → **ユーザー設定**（歯車アイコン）→ **詳細設定** → **開発者モード** を有効化
            2. Bot に応答させたいチャンネルを右クリック → **チャンネル ID をコピー**
            3. 複数チャンネルはカンマで区切る：`123456789012345678,234567890123456789`

            ### 4. デプロイ

            変数を入力してデプロイをクリック。サービスは自動的に Discord および/または Slack に接続します。

            ## Slack セットアップ（オプション）

            OpenAB は Socket Mode 経由で Slack をサポートします — 公開 URL は不要です。

            1. https://api.slack.com/apps → **Create New App** → **From scratch**
            2. **Socket Mode** → 有効化 → scope `connections:write` で App-Level Token を生成 → `xapp-...` token をコピー（`SLACK_APP_TOKEN`）
            3. **Event Subscriptions** → 有効化 → bot events を追加：`app_mention`、`message.channels`、`message.groups`
            4. **OAuth & Permissions** → Bot Token Scopes → 追加：`app_mentions:read`、`chat:write`、`channels:history`、`groups:history`、`channels:read`、`groups:read`、`reactions:write`、`files:read`、`users:read`
            5. **Install App** → ワークスペースにインストール → `xoxb-...` token をコピー（`SLACK_BOT_TOKEN`）
            6. Bot を使用したい各 Slack チャンネルで `/invite @YourAppName` を実行

            デプロイ前に `SLACK_BOT_TOKEN` と `SLACK_APP_TOKEN` 変数を入力してください。Discord と Slack は同時に使用できます。

            ## メッセージプラットフォームを追加（Telegram / LINE / Feishu / Google Chat / MS Teams / WeCom）

            Telegram を使う場合は [OpenAB Telegram テンプレート](https://zeabur.com/templates/12LLKI) をデプロイし、image tag を `beta-claude` に変更して対応する `OPENAB_AGENT_COMMAND` を設定してください。その他のプラットフォームは unified mode で環境変数から直接有効化できます（`LINE_CHANNEL_SECRET`、`FEISHU_APP_ID`、`GOOGLE_CHAT_ENABLED=true`、`TEAMS_APP_ID`、`WECOM_CORP_ID`）。詳細は [OpenAB ドキュメント](https://github.com/openabdev/openab/tree/main/docs) を参照。Webhook 型プラットフォームはサービスに公開 HTTPS ドメイン（port 8080）が必要です。Feishu は WebSocket でアウトバウンド接続するためドメイン不要です。

            ## 使い方

            - 許可された Discord または Slack チャンネルで **Bot を @mention** して会話を開始
            - OpenAB は自動的に **thread** を作成してマルチターン会話を行います — 以降のメッセージでは @mention 不要
            - 各 thread は永続的な Claude session に対応（デフォルト 24 時間 TTL）

            ## カスタマイズ

            | ファイル | 説明 |
            |---------|------|
            | `/home/node/CLAUDE.md` | エージェント指示 — Claude が毎セッション自動的に読み込みます |
            | `/home/node/.config/openab/config.toml` | OpenAB 設定（sessions、reactions、STT など） |
            | `/etc/claude-code/managed-settings.json` | Claude Code 権限モード |

            `config.toml` は初回起動時に内蔵テンプレートから作成されます。以降の変更はファイルを直接編集してください。環境変数は初期設定時のみ使用されます。デフォルトに戻すにはファイルを削除して再起動：`rm /home/node/.config/openab/config.toml`

            設定オプションは [OpenAB ドキュメント](https://github.com/openabdev/openab) を参照。

            ## 無効化

            デプロイ時に `Discord Bot Token` を空にしてください。サービスはクラッシュせずスリープ状態になります。

            ## リンク

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
            - [Anthropic Console](https://console.anthropic.com/)
            - [Zeabur AI Hub](https://zeabur.com/ai-hub)
    zh-CN:
        description: |
            Open Agent Broker — 轻量的 Rust 程序，通过 stdio JSON-RPC 将 Discord 和 Slack 桥接到任何 ACP 兼容的 coding CLI（Claude Code、Codex、Gemini、Kiro）。
            来源：https://github.com/openabdev/openab
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord Bot Token（选填）
              description: 选填。从 https://discord.com/developers/applications 获取的 Token。仅使用 Slack 时可留空。
            - key: OPENAB_AUTH_TOKEN
              type: STRING
              name: 认证 Token（选填）
              description: 选填。Anthropic API 密钥、Zeabur AI Hub token 或 Claude OAuth token（通过 claude setup-token 获取）。留空时改用持久卷 /home/node/.claude/ 下的认证数据（例如进容器执行 `claude auth login` 写入）。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord 频道 ID（选填）
              description: 选填。Bot 监听的 Discord 频道 ID，以逗号分隔。留空则允许所有频道。示例：123456789012345678,234567890123456789
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord 用户 ID（选填）
              description: 选填。以逗号分隔的 Discord 用户 ID，限制可与 Bot 互动的用户。留空则允许频道中所有人。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot Token（选填）
              description: 选填。Slack App 设置中的 Bot User OAuth Token（xoxb-...）。留空则禁用 Slack。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App Token（选填）
              description: 选填。Socket Mode 用的 App-Level Token（xapp-...）。设置 Slack Bot Token 时必填。
        readme: |
            # OpenAB

            [OpenAB](https://github.com/openabdev/openab) 是一个轻量的开源 Rust 程序，通过 stdio JSON-RPC 将 Discord 桥接到任何支持 [Agent Client Protocol](https://github.com/anthropics/agent-protocol) 的 coding CLI。

            此模板部署的是 Claude 变体（`openab-claude`），使用 `claude-agent-acp` 作为 agent 后端。

            ## 注意事项

            - **镜像标签：** 此模板追踪 floating `beta` 标签，OpenAB 推出新 beta 版时自动更新。若要 pin 至特定版本，请在 Zeabur Dashboard → 服务 → 设置中更改镜像标签。可用标签：[GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab)。
            - **持久化存储：** `/home/node` 挂载为持久化磁盘。Plugins、设置、config 和认证数据会在重启后保留。

            ## 设置步骤

            ### 1. 获取 Discord Bot Token

            1. 前往 [Discord Developer Portal](https://discord.com/developers/applications)，点击 **New Application**
            2. 进入 **Bot** 页签 → 点击 **Reset Token** → 复制 token
            3. 同一页面往下滑，在 Privileged Gateway Intents 下启用 **Message Content Intent**
            4. 前往 **OAuth2 → URL Generator** → 勾选 scope `bot` → 勾选权限：Send Messages、Send Messages in Threads、Create Public Threads、Read Message History、Add Reactions、Manage Messages
            5. 复制生成的 URL，在浏览器中打开以邀请 Bot 到你的服务器

            ### 2. 选择认证方式（选填 — 留空可在容器内登录）

            | 方式 | 使用方法 |
            |------|---------|
            | **Anthropic API Key** | 前往 [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → 将 `sk-ant-api...` 密钥填入 `OPENAB_AUTH_TOKEN` |
            | **Zeabur AI Hub Token** | 前往 [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → 将 token 填入 `OPENAB_AUTH_TOKEN` |
            | **Claude OAuth Token** | 在终端运行 `claude setup-token`（需要 Claude Pro/Max/Team/Enterprise 订阅）→ 打开显示的 URL → 授权 → 粘贴验证码 → 将输出的 `sk-ant-oat...` token 填入 `OPENAB_AUTH_TOKEN` |
            | **容器内登录** | `OPENAB_AUTH_TOKEN` 留空。部署后到 Zeabur Dashboard → 服务 → **Exec** 运行 `runuser -u node -- claude auth login`（或 `claude setup-token`）。认证数据会写入持久卷的 `/home/node/.claude/`，重启后仍保留。 |

            > **将 token 传给 agent：** openab 会以 `env_clear()` 隔离 agent 子进程，因此方式 1–3 需在首次启动后编辑 `/home/node/.config/openab/config.toml`，在 `[agent]` 区块加入 env allowlist（或显式 env map）：
            >
            > ```toml
            > [agent]
            > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
            > ```
            >
            > 方式 4 无需修改 — 认证数据直接从 `~/.claude/.credentials.json` 读取。

            ### 3. 获取 Discord 频道 ID

            1. 打开 Discord → 前往 **用户设置**（齿轮图标）→ **高级** → 启用 **开发者模式**
            2. 右键点击你要 Bot 回应的频道 → **复制频道 ID**
            3. 多个频道用逗号分隔：`123456789012345678,234567890123456789`

            ### 4. 部署

            填入变量后点击部署即可。服务会自动连接到 Discord 和/或 Slack。

            ## Slack 设置（可选）

            OpenAB 支持通过 Socket Mode 连接 Slack，无需公开 URL。

            1. 前往 https://api.slack.com/apps → **Create New App** → **From scratch**
            2. **Socket Mode** → 启用 → 生成 App-Level Token，scope 选 `connections:write` → 复制 `xapp-...` token（`SLACK_APP_TOKEN`）
            3. **Event Subscriptions** → 启用 → 添加 bot events：`app_mention`、`message.channels`、`message.groups`
            4. **OAuth & Permissions** → Bot Token Scopes → 添加：`app_mentions:read`、`chat:write`、`channels:history`、`groups:history`、`channels:read`、`groups:read`、`reactions:write`、`files:read`、`users:read`
            5. **Install App** → 安装到工作区 → 复制 `xoxb-...` token（`SLACK_BOT_TOKEN`）
            6. 在每个要使用 Bot 的 Slack 频道执行 `/invite @YourAppName`

            部署前填入 `SLACK_BOT_TOKEN` 和 `SLACK_APP_TOKEN` 变量。Discord 和 Slack 可同时运行。

            ## 添加通讯平台（Telegram / LINE / 飞书 / Google Chat / MS Teams / WeCom）

            若要使用 Telegram，请部署 [OpenAB Telegram 模板](https://zeabur.com/templates/12LLKI)，并把 image tag 换成 `beta-claude`、设置对应的 `OPENAB_AGENT_COMMAND`。其他平台在 unified mode 下直接以环境变量启用（`LINE_CHANNEL_SECRET`、`FEISHU_APP_ID`、`GOOGLE_CHAT_ENABLED=true`、`TEAMS_APP_ID`、`WECOM_CORP_ID`），详见 [OpenAB 文档](https://github.com/openabdev/openab/tree/main/docs)。Webhook 类平台需要为服务绑定公开 HTTPS 域名（port 8080）；飞书走 WebSocket 对外连接，不需要域名。

            ## 使用方式

            - 在允许的 Discord 或 Slack 频道中 **@mention Bot** 即可开始对话
            - OpenAB 会自动创建 **thread** 进行多轮对话 — 后续消息不需要再 @mention
            - 每个 thread 对应一个持久的 Claude session（默认 24 小时 TTL）

            ## 自定义设置

            | 文件 | 说明 |
            |------|------|
            | `/home/node/CLAUDE.md` | Agent 指令 — Claude 每次 session 会自动读取 |
            | `/home/node/.config/openab/config.toml` | OpenAB 设置（sessions、reactions、STT 等） |
            | `/etc/claude-code/managed-settings.json` | Claude Code 权限模式 |

            `config.toml` 在首次启动时从内建模板创建。之后请直接编辑文件，环境变量仅用于初始设置。要恢复默认值请删除后重启：`rm /home/node/.config/openab/config.toml`

            设置选项请参阅 [OpenAB 文档](https://github.com/openabdev/openab)。

            ## 停用

            部署时将 `Discord Bot Token` 留空即可。服务会进入 sleep 状态，不会崩溃。

            ## 链接

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
            - [Anthropic Console](https://console.anthropic.com/)
            - [Zeabur AI Hub](https://zeabur.com/ai-hub)
    zh-TW:
        description: |
            Open Agent Broker — 輕量的 Rust 程式，透過 stdio JSON-RPC 將 Discord 和 Slack 橋接到任何 ACP 相容的 coding CLI（Claude Code、Codex、Gemini、Kiro）。
            來源：https://github.com/openabdev/openab
        variables:
            - key: DISCORD_BOT_TOKEN
              type: STRING
              name: Discord Bot Token（選填）
              description: 選填。從 https://discord.com/developers/applications 取得的 Token。僅使用 Slack 時可留空。
            - key: OPENAB_AUTH_TOKEN
              type: STRING
              name: 認證 Token（選填）
              description: 選填。Anthropic API 金鑰、Zeabur AI Hub token 或 Claude OAuth token（透過 claude setup-token 取得）。留空時改用持久卷 /home/node/.claude/ 下的認證資料（例如進容器執行 `claude auth login` 寫入）。
            - key: OPENAB_ALLOWED_CHANNELS
              type: STRING
              name: Discord 頻道 ID（選填）
              description: 選填。Bot 監聽的 Discord 頻道 ID，以逗號分隔。留空則允許所有頻道。範例：123456789012345678,234567890123456789
            - key: OPENAB_ALLOWED_USERS
              type: STRING
              name: Discord 用戶 ID（選填）
              description: 選填。以逗號分隔的 Discord 用戶 ID，限制可與 Bot 互動的用戶。留空則允許頻道中所有人。
            - key: SLACK_BOT_TOKEN
              type: STRING
              name: Slack Bot Token（選填）
              description: 選填。Slack App 設定中的 Bot User OAuth Token（xoxb-...）。留空則停用 Slack。
            - key: SLACK_APP_TOKEN
              type: STRING
              name: Slack App Token（選填）
              description: 選填。Socket Mode 用的 App-Level Token（xapp-...）。設定 Slack Bot Token 時必填。
        readme: |
            # OpenAB

            [OpenAB](https://github.com/openabdev/openab) 是一個輕量的開源 Rust 程式，透過 stdio JSON-RPC 將 Discord 橋接到任何支援 [Agent Client Protocol](https://github.com/anthropics/agent-protocol) 的 coding CLI。

            此模板部署的是 Claude 變體（`openab-claude`），使用 `claude-agent-acp` 作為 agent 後端。

            ## 注意事項

            - **映像標籤：** 此模板追蹤 floating `beta` 標籤，OpenAB 推出新 beta 版時自動更新。若要 pin 至特定版本，請在 Zeabur Dashboard → 服務 → 設定中更改映像標籤。可用標籤：[GitHub Packages](https://github.com/openabdev/openab/pkgs/container/openab)。
            - **持久化儲存：** `/home/node` 掛載為持久化磁碟。Plugins、設定、config 和認證資料會在重啟後保留。

            ## 設定步驟

            ### 1. 取得 Discord Bot Token

            1. 前往 [Discord Developer Portal](https://discord.com/developers/applications)，點擊 **New Application**
            2. 進入 **Bot** 頁籤 → 點擊 **Reset Token** → 複製 token
            3. 同一頁面往下滑，在 Privileged Gateway Intents 下啟用 **Message Content Intent**
            4. 前往 **OAuth2 → URL Generator** → 勾選 scope `bot` → 勾選權限：Send Messages、Send Messages in Threads、Create Public Threads、Read Message History、Add Reactions、Manage Messages
            5. 複製產生的 URL，在瀏覽器中開啟以邀請 Bot 到你的伺服器

            ### 2. 選擇認證方式（選填 — 留空則於容器內登入）

            | 方式 | 使用方法 |
            |------|---------|
            | **Anthropic API Key** | 前往 [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) → Create Key → 將 `sk-ant-api...` 金鑰填入 `OPENAB_AUTH_TOKEN` |
            | **Zeabur AI Hub Token** | 前往 [Zeabur AI Hub](https://zeabur.com/ai-hub) → API Keys → Create → 將 token 填入 `OPENAB_AUTH_TOKEN` |
            | **Claude OAuth Token** | 在終端執行 `claude setup-token`（需要 Claude Pro/Max/Team/Enterprise 訂閱）→ 開啟顯示的 URL → 授權 → 貼回驗證碼 → 將輸出的 `sk-ant-oat...` token 填入 `OPENAB_AUTH_TOKEN` |
            | **容器內登入** | `OPENAB_AUTH_TOKEN` 留空。部署後到 Zeabur Dashboard → 服務 → **Exec** 執行 `runuser -u node -- claude auth login`（或 `claude setup-token`）。認證資料會寫入持久卷的 `/home/node/.claude/`，重啟後仍保留。 |

            > **將 token 傳給 agent：** openab 會以 `env_clear()` 隔離 agent 子程序，因此方式 1–3 需在首次啟動後編輯 `/home/node/.config/openab/config.toml`，在 `[agent]` 區塊加入 env allowlist（或顯式 env map）：
            >
            > ```toml
            > [agent]
            > inherit_env = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"]
            > ```
            >
            > 方式 4 不需修改 — 認證資料直接從 `~/.claude/.credentials.json` 讀取。

            ### 3. 取得 Discord 頻道 ID

            1. 開啟 Discord → 前往 **使用者設定**（齒輪圖示）→ **進階** → 啟用 **開發者模式**
            2. 對你要 Bot 回應的頻道按右鍵 → **複製頻道 ID**
            3. 多個頻道用逗號分隔：`123456789012345678,234567890123456789`

            ### 4. 部署

            填入變數後點擊部署即可。服務會自動連線到 Discord 和/或 Slack。

            ## Slack 設定（選用）

            OpenAB 支援透過 Socket Mode 連接 Slack，不需要公開 URL。

            1. 前往 https://api.slack.com/apps → **Create New App** → **From scratch**
            2. **Socket Mode** → 啟用 → 產生 App-Level Token，scope 選 `connections:write` → 複製 `xapp-...` token（`SLACK_APP_TOKEN`）
            3. **Event Subscriptions** → 啟用 → 新增 bot events：`app_mention`、`message.channels`、`message.groups`
            4. **OAuth & Permissions** → Bot Token Scopes → 新增：`app_mentions:read`、`chat:write`、`channels:history`、`groups:history`、`channels:read`、`groups:read`、`reactions:write`、`files:read`、`users:read`
            5. **Install App** → 安裝到工作區 → 複製 `xoxb-...` token（`SLACK_BOT_TOKEN`）
            6. 在每個要使用 Bot 的 Slack 頻道執行 `/invite @YourAppName`

            部署前填入 `SLACK_BOT_TOKEN` 和 `SLACK_APP_TOKEN` 變數。Discord 和 Slack 可同時運作。

            ## 新增通訊平台（Telegram / LINE / Feishu / Google Chat / MS Teams / WeCom）

            若要使用 Telegram，請部署 [OpenAB Telegram 模板](https://zeabur.com/templates/12LLKI)，並把 image tag 換成 `beta-claude`、設定對應的 `OPENAB_AGENT_COMMAND`。其他平台在 unified mode 下直接以環境變數啟用（`LINE_CHANNEL_SECRET`、`FEISHU_APP_ID`、`GOOGLE_CHAT_ENABLED=true`、`TEAMS_APP_ID`、`WECOM_CORP_ID`），詳見 [OpenAB 文件](https://github.com/openabdev/openab/tree/main/docs)。Webhook 類平台需要為服務綁定公開 HTTPS 網域（port 8080）；Feishu 走 WebSocket 對外連線，不需網域。

            ## 使用方式

            - 在允許的 Discord 或 Slack 頻道中 **@mention Bot** 即可開始對話
            - OpenAB 會自動建立 **thread** 進行多輪對話 — 後續訊息不需要再 @mention
            - 每個 thread 對應一個持久的 Claude session（預設 24 小時 TTL）

            ## 自訂設定

            | 檔案 | 說明 |
            |------|------|
            | `/home/node/CLAUDE.md` | Agent 指令 — Claude 每次 session 會自動讀取 |
            | `/home/node/.config/openab/config.toml` | OpenAB 設定（sessions、reactions、STT 等） |
            | `/etc/claude-code/managed-settings.json` | Claude Code 權限模式 |

            `config.toml` 在首次啟動時從內建範本建立。之後請直接編輯檔案，環境變數僅用於初始設定。要恢復預設值請刪除後重啟：`rm /home/node/.config/openab/config.toml`

            設定選項請參閱 [OpenAB 文件](https://github.com/openabdev/openab)。

            ## 停用

            部署時將 `Discord Bot Token` 留空即可。服務會進入 sleep 狀態，不會崩潰。

            ## 連結

            - [OpenAB GitHub](https://github.com/openabdev/openab)
            - [Agent Client Protocol](https://github.com/anthropics/agent-protocol)
            - [Anthropic Console](https://console.anthropic.com/)
            - [Zeabur AI Hub](https://zeabur.com/ai-hub)
