diff --git a/README.md b/README.md index e76855a6..0a5d4bc7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ On first run, botserver automatically: - Installs required components (PostgreSQL, S3 storage, Cache, LLM) - Sets up database with migrations - Downloads AI models -- Starts HTTP server at `http://127.0.0.1:8080` +- Starts HTTP server at `http://127.0.0.1:9000` ### Run the Desktop App diff --git a/src/01-introduction/README.md b/src/01-introduction/README.md index 5ccd9f76..f85c8d19 100644 --- a/src/01-introduction/README.md +++ b/src/01-introduction/README.md @@ -35,7 +35,7 @@ By the end of this chapter, you will: ./botserver ``` -Open `http://localhost:8080`. Start chatting. That's it. +Open `http://localhost:9000`. Start chatting. That's it. Everything installs automatically on first run—PostgreSQL, storage, cache, and your first bot. @@ -55,7 +55,7 @@ Everything installs automatically on first run—PostgreSQL, storage, cache, and

Just three steps:

1️⃣ Download botserver

2️⃣ Run ./botserver

-

3️⃣ Open your browser to localhost:8080

+

3️⃣ Open your browser to localhost:9000

The bootstrap process handles everything else automatically!

09:00
diff --git a/src/01-introduction/first-conversation.md b/src/01-introduction/first-conversation.md index 31c03874..56c53217 100644 --- a/src/01-introduction/first-conversation.md +++ b/src/01-introduction/first-conversation.md @@ -4,7 +4,7 @@ After botserver starts, you can immediately start chatting with your bot. No pro ## Just Start Talking -Open your browser to `http://localhost:8080` and start chatting: +Open your browser to `http://localhost:9000` and start chatting: ``` You: Hi! diff --git a/src/01-introduction/installation.md b/src/01-introduction/installation.md index 45442779..a66bab88 100644 --- a/src/01-introduction/installation.md +++ b/src/01-introduction/installation.md @@ -120,7 +120,7 @@ psql $DATABASE_URL -c "SELECT version();" curl http://localhost:8081/v1/models # Open UI -open http://localhost:8080 +open http://localhost:9000 ``` ## Bot Deployment diff --git a/src/01-introduction/local-domains.md b/src/01-introduction/local-domains.md index c354da33..54126119 100644 --- a/src/01-introduction/local-domains.md +++ b/src/01-introduction/local-domains.md @@ -10,7 +10,7 @@ botserver certificates include `127.0.0.1` as a Subject Alternative Name (SAN), | Component | Description | IP:Port | |-----------|-------------|---------| -| api | Main botserver API | `127.0.0.1:8443` (HTTPS) / `127.0.0.1:8080` (HTTP) | +| api | Main botserver API | `127.0.0.1:8443` (HTTPS) / `127.0.0.1:9000` (HTTP) | | tables | PostgreSQL database | `127.0.0.1:5432` | | drive | Object storage (S3-compatible) | `127.0.0.1:9000` | | cache | Redis cache | `127.0.0.1:6379` | diff --git a/src/01-introduction/overview.md b/src/01-introduction/overview.md index b3fd35cf..1b874a8d 100644 --- a/src/01-introduction/overview.md +++ b/src/01-introduction/overview.md @@ -105,7 +105,7 @@ Installation begins by downloading and running the botserver binary. The bootstr Bot deployment uses object storage buckets. Each bot receives its own bucket for file storage. Bots are deployed to the drive rather than the work folder, which is reserved for internal operations as documented in the gbapp chapter. -After startup, access the UI interface at `http://localhost:8080` to interact with your bots and monitor their operation. +After startup, access the UI interface at `http://localhost:9000` to interact with your bots and monitor their operation. ## Use Cases diff --git a/src/01-introduction/quick-start.md b/src/01-introduction/quick-start.md index 2874eca3..159e7753 100644 --- a/src/01-introduction/quick-start.md +++ b/src/01-introduction/quick-start.md @@ -28,13 +28,13 @@ Installing Cache... Creating bots from templates... default.gbai deployed announcements.gbai deployed -botserver ready at http://localhost:8080 +botserver ready at http://localhost:9000 ``` ### 3. Open Browser ``` -http://localhost:8080 +http://localhost:9000 ``` Start chatting with your bot! diff --git a/src/01-introduction/sessions.md b/src/01-introduction/sessions.md index 08f5476f..d5efb5f2 100644 --- a/src/01-introduction/sessions.md +++ b/src/01-introduction/sessions.md @@ -14,7 +14,7 @@ A session is a persistent conversation container that tracks everything about an ### UI Interface -When a user opens `http://localhost:8080`, the browser receives a session token in the form of a UUID. This token is stored in localStorage for persistence across page loads. The session itself is created in PostgreSQL for durability and cached for fast access during active conversations. +When a user opens `http://localhost:9000`, the browser receives a session token in the form of a UUID. This token is stored in localStorage for persistence across page loads. The session itself is created in PostgreSQL for durability and cached for fast access during active conversations. ### API Access @@ -22,12 +22,12 @@ Programmatic access to sessions uses the REST API. A POST request to `/api/sessi ```bash # Get new session -curl -X POST http://localhost:8080/api/session +curl -X POST http://localhost:9000/api/session # Returns: {"session_id": "uuid-here", "token": "secret-token"} # Use session curl -H "Authorization: Bearer secret-token" \ - http://localhost:8080/api/chat + http://localhost:9000/api/chat ``` ### Anonymous vs Authenticated diff --git a/src/02-templates/gbai.md b/src/02-templates/gbai.md index d692e56e..403de837 100644 --- a/src/02-templates/gbai.md +++ b/src/02-templates/gbai.md @@ -158,7 +158,7 @@ greeting,Welcome to support! ```bash cp -r my-bot.gbai/ templates/ ./botserver restart -# Visit http://localhost:8080/my-bot +# Visit http://localhost:9000/my-bot ``` ### Production Server diff --git a/src/02-templates/template-embedded.md b/src/02-templates/template-embedded.md index 05415da1..2babcb71 100644 --- a/src/02-templates/template-embedded.md +++ b/src/02-templates/template-embedded.md @@ -674,7 +674,7 @@ idleTimeout = 60 ' Return to welcome screen after inactivity lastActivity = NOW ' Initialize display -' (Runs in browser kiosk mode at http://localhost:8088/embedded/) +' (Runs in browser kiosk mode at http://localhost:9000/embedded/) TALK welcomeMessage diff --git a/src/02-templates/templates.md b/src/02-templates/templates.md index 4b0c01ad..7b9b7557 100644 --- a/src/02-templates/templates.md +++ b/src/02-templates/templates.md @@ -122,7 +122,7 @@ Select based on your needs: ```bash # Templates are auto-deployed during bootstrap -# Access at: http://localhost:8080/template-name +# Access at: http://localhost:9000/template-name ``` ### 3. Customize Configuration diff --git a/src/04-gbui/README.md b/src/04-gbui/README.md index 88ee8ffe..61ff9135 100644 --- a/src/04-gbui/README.md +++ b/src/04-gbui/README.md @@ -19,10 +19,10 @@ General Bots UI system built with HTMX and server-side rendering. ## Quick Access ``` -http://localhost:8080 → Main interface -http://localhost:8080/chat → Chat app -http://localhost:8080/drive → File manager -http://localhost:8080/console → Terminal mode +http://localhost:9000 → Main interface +http://localhost:9000/chat → Chat app +http://localhost:9000/drive → File manager +http://localhost:9000/console → Terminal mode ``` ## Suite Applications diff --git a/src/04-gbui/apps/chat.md b/src/04-gbui/apps/chat.md index ae80f69a..ca164281 100644 --- a/src/04-gbui/apps/chat.md +++ b/src/04-gbui/apps/chat.md @@ -96,7 +96,7 @@ Bot responses support full Markdown rendering: ### WebSocket Connection ``` -ws://your-server:8080/ws +ws://your-server:9000/ws ``` **Message Types:** diff --git a/src/04-gbui/apps/suite.md b/src/04-gbui/apps/suite.md index 26dffc82..4231fce5 100644 --- a/src/04-gbui/apps/suite.md +++ b/src/04-gbui/apps/suite.md @@ -102,7 +102,7 @@ Default template for browser access: ```bash ./botserver -# Browse to http://localhost:8080 +# Browse to http://localhost:9000 # Loads Suite interface ``` diff --git a/src/04-gbui/console-mode.md b/src/04-gbui/console-mode.md index 5ae3e9ff..e565119b 100644 --- a/src/04-gbui/console-mode.md +++ b/src/04-gbui/console-mode.md @@ -90,7 +90,7 @@ Console mode supports any terminal with basic text output capabilities. UTF-8 su ## Tips -Console mode operates in read-only fashion and does not accept bot commands. For interactive bot testing, use the web interface available at http://localhost:8080. The display refreshes automatically every few seconds to show current status. Output is buffered for performance to avoid slowing down the server during high activity periods. +Console mode operates in read-only fashion and does not accept bot commands. For interactive bot testing, use the web interface available at http://localhost:9000. The display refreshes automatically every few seconds to show current status. Output is buffered for performance to avoid slowing down the server during high activity periods. ## Troubleshooting diff --git a/src/04-gbui/dev-chat.md b/src/04-gbui/dev-chat.md index 1bcfa585..ca012627 100644 --- a/src/04-gbui/dev-chat.md +++ b/src/04-gbui/dev-chat.md @@ -130,7 +130,7 @@ This means: The widget connects via WebSocket for real-time updates: ``` -ws://localhost:8080/ws/dev +ws://localhost:9000/ws/dev ``` When connected: diff --git a/src/04-gbui/how-to/create-first-bot.md b/src/04-gbui/how-to/create-first-bot.md index 1009f9d6..25901dac 100644 --- a/src/04-gbui/how-to/create-first-bot.md +++ b/src/04-gbui/how-to/create-first-bot.md @@ -63,7 +63,7 @@ Launch your preferred web browser by clicking its icon. ┌─────────────────────────────────────────────────────────────────────────┐ │ 🌐 Browser [─][□][×]│ ├─────────────────────────────────────────────────────────────────────────┤ -│ ← → ↻ │ https://your-company.bot:8080 │ ☆ │ │ +│ ← → ↻ │ https://your-company.bot:9000 │ ☆ │ │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Loading... │ @@ -76,7 +76,7 @@ Launch your preferred web browser by clicking its icon. Type your General Bots address in the address bar and press **Enter**. 💡 **Tip**: Your URL will look something like: -- `http://localhost:8080` (development) +- `http://localhost:9000` (development) - `https://bots.yourcompany.com` (production) - `https://app.pragmatismo.cloud` (cloud hosted) diff --git a/src/04-gbui/monitoring.md b/src/04-gbui/monitoring.md index 3aa3eeb3..03194b85 100644 --- a/src/04-gbui/monitoring.md +++ b/src/04-gbui/monitoring.md @@ -21,7 +21,7 @@ The dashboard displays botserver at the center orchestrating all interactions, w The monitoring dashboard is the **default homepage** when accessing Suite: ```/dev/null/monitoring-url.txt#L1 -http://localhost:8080/monitoring +http://localhost:9000/monitoring ``` Or from within Suite: diff --git a/src/04-gbui/single-gbui.md b/src/04-gbui/single-gbui.md index e487967a..9b2a635a 100644 --- a/src/04-gbui/single-gbui.md +++ b/src/04-gbui/single-gbui.md @@ -71,7 +71,7 @@ Automatic dark mode activates based on system preference: Connection handling is simplified for reliability: ```javascript -const ws = new WebSocket('ws://localhost:8080/ws'); +const ws = new WebSocket('ws://localhost:9000/ws'); ws.onmessage = (event) => { const data = JSON.parse(event.data); @@ -98,7 +98,7 @@ function sendMessage() { The single.gbui template is perfect for embedding in existing websites: ```html - diff --git a/src/04-gbui/suite-manual.md b/src/04-gbui/suite-manual.md index 66507808..70d1d682 100644 --- a/src/04-gbui/suite-manual.md +++ b/src/04-gbui/suite-manual.md @@ -23,7 +23,7 @@ General Bots Suite is your all-in-one workspace that combines communication, pro ### Opening the Suite 1. **Open your web browser** (Chrome, Firefox, Safari, or Edge) -2. **Go to your General Bots address** (example: `http://your-company.bot:8080`) +2. **Go to your General Bots address** (example: `http://your-company.bot:9000`) 3. **The Suite loads automatically** - you'll see the workspace in seconds ### Your First Look diff --git a/src/04-gbui/ui-structure.md b/src/04-gbui/ui-structure.md index 32e3f4fb..535be788 100644 --- a/src/04-gbui/ui-structure.md +++ b/src/04-gbui/ui-structure.md @@ -59,7 +59,7 @@ The Suite interface provides multi-application integration with seamless navigat The Suite interface is best suited for enterprise deployments requiring full functionality, power users working with multiple services simultaneously, desktop application distribution via Tauri builds, and multi-service integrations where context switching between modules matters. -You can access the Suite interface via web at `http://localhost:8080/suite` or as a native desktop application using the `botui` Tauri app (see [BotUI Desktop](../botui/README.md)). +You can access the Suite interface via web at `http://localhost:9000/suite` or as a native desktop application using the `botui` Tauri app (see [BotUI Desktop](../botui/README.md)). ## Minimal Interface @@ -69,7 +69,7 @@ This lightweight interface provides core chat and basic interactions only, fast The Minimal interface excels for mobile web access, embedded chatbots in external websites, low-bandwidth environments, quick access terminals and kiosks, and scenarios where simplicity matters more than features. -Access the Minimal interface at the root URL `http://localhost:8080` where it is served by default, explicitly at `http://localhost:8080/minimal`, or embedded via iframe or WebView in your own applications. +Access the Minimal interface at the root URL `http://localhost:9000` where it is served by default, explicitly at `http://localhost:9000/minimal`, or embedded via iframe or WebView in your own applications. ## Configuration @@ -211,11 +211,11 @@ ls -la ui/suite/ ls -la ui/minimal/ # Test interfaces -curl http://localhost:8080/ -curl http://localhost:8080/suite/ +curl http://localhost:9000/ +curl http://localhost:9000/suite/ # Check static file serving -curl http://localhost:8080/js/htmx-app.js +curl http://localhost:9000/js/htmx-app.js ``` ## Customization diff --git a/src/06-gbdialog/keyword-save.md b/src/06-gbdialog/keyword-save.md index 4ac81dce..09d2994a 100644 --- a/src/06-gbdialog/keyword-save.md +++ b/src/06-gbdialog/keyword-save.md @@ -4,18 +4,38 @@ Saves data to a database table using upsert (insert or update) semantics. ## Syntax +### Form 1: Save with object (classic) + ```basic SAVE "table", id, data ``` +### Form 2: Save with variables (direct) + +```basic +SAVE "table", id, field1, field2, field3, ... +``` + +The variable names are used as column names automatically. + ## Parameters +### Form 1 (with object) + | Parameter | Type | Description | |-----------|------|-------------| | table | String | The name of the database table | | id | String/Number | The unique identifier for the record | | data | Object | A map/object containing field names and values | +### Form 2 (with variables) + +| Parameter | Type | Description | +|-----------|------|-------------| +| table | String | The name of the database table | +| id | String/Number | The unique identifier for the record | +| field1, field2, ... | Any | Variable references (names become column names) | + ## Description `SAVE` performs an upsert operation: @@ -24,9 +44,55 @@ SAVE "table", id, data The `id` parameter maps to the `id` column in the table. +### Form 1 vs Form 2 + +**Form 1** (with object) is useful when you need custom column names or complex data structures: + +```basic +data = #{ + "customer_name": "João Silva", + "email": "joao@example.com" +} +SAVE "customers", "CUST-001", data +``` + +**Form 2** (with variables) is simpler - variable names become column names: + +```basic +customerName = "João Silva" +email = "joao@example.com" +phone = "+5511999887766" +SAVE "customers", "CUST-001", customerName, email, phone +' Creates columns: customerName, email, phone +``` + +This eliminates the need for WITH blocks when variable names match your desired column names. + +### Perfect for TOOL Functions + +**This is especially useful for TOOL functions** where variables are automatically filled by user input and can be saved directly without needing WITH blocks: + +```basic +' TOOL function parameters - automatically filled by LLM +PARAM nome AS STRING LIKE "João Silva" DESCRIPTION "Nome completo" +PARAM email AS EMAIL LIKE "joao@example.com" DESCRIPTION "Email" +PARAM telefone AS STRING LIKE "(21) 98888-8888" DESCRIPTION "Telefone" + +' Generate unique ID +customerId = "CUST-" + FORMAT(NOW(), "yyyyMMddHHmmss") + +' Save directly - variable names become column names automatically! +' No need for WITH block - just pass the variables directly +SAVE "customers", customerId, nome, email, telefone + +RETURN customerId +``` + +In TOOL functions, the parameters (variables like `nome`, `email`, `telefone`) are automatically extracted from user input by the LLM. The direct SAVE syntax allows you to persist these variables immediately without manual object construction. + ## Examples -### Basic Save with Object +### Basic Save with Object (Form 1) ```basic ' Create data object using Rhai map syntax @@ -40,32 +106,73 @@ data = #{ SAVE "customers", "CUST-001", data ``` -### Save Order Data +### Save with Variables - No WITH Block Needed (Form 2) + +```basic +' Variable names become column names automatically +casamentoId = "CAS-20250117-1234" +protocolo = "CAS123456" +nomeNoivo = "Carlos Eduardo" +nomeNoiva = "Juliana Cristina" +telefoneNoivo = "(21) 98888-8888" +telefoneNoiva = "(21) 97777-7777" +emailNoivo = "carlos@example.com" +emailNoiva = "juliana@example.com" +tipoCasamento = "RELIGIOSO_COM_EFEITO_CIVIL" +dataPreferencial = "2026-12-15" +horarioPreferencial = "16:00" + +' Save directly without WITH block +SAVE "casamentos", casamentoId, protocolo, nomeNoivo, nomeNoiva, telefoneNoivo, telefoneNoiva, emailNoivo, emailNoiva, tipoCasamento, dataPreferencial, horarioPreferencial +``` + +### Save Order Data (Direct Syntax - No Object) ```basic order_id = "ORD-" + FORMAT(NOW(), "YYYYMMDDHHmmss") +customer_id = "CUST-001" +customer_name = "João Silva" +total = 150.50 +status = "pending" -order_data = #{ - "customer_id": customer_id, - "customer_name": customer_name, - "total": total, - "status": "pending", - "created_at": NOW() -} - -SAVE "orders", order_id, order_data +' Save directly - variable names become columns +SAVE "orders", order_id, customer_id, customer_name, total, status TALK "Order " + order_id + " saved successfully!" ``` +### Save Event Registration + +```basic +' Event registration form data +eventId = "EVT-" + FORMAT(NOW(), "YYYYMMDDHHmmss") +nome = "Maria Santos" +email = "maria@example.com" +telefone = "(11) 91234-5678" +dataEvento = "2025-03-15" +quantidadePessoas = 3 +observacoes = "Precisa de cadeira de rodas" + +' Direct save - no WITH block needed +SAVE "eventos", eventId, nome, email, telefone, dataEvento, quantidadePessoas, observacoes + +TALK "Inscrição confirmada! ID: " + eventId +``` + ### Update Existing Record ```basic ' If order exists, this updates it; otherwise creates it +order_id = "ORD-20250117-0001" +status = "shipped" +shipped_at = NOW() +tracking_number = "TRACK123456" + +' Use object for updates to specific columns update_data = #{ - "status": "shipped", - "shipped_at": NOW(), - "tracking_number": tracking + "status": status, + "shipped_at": shipped_at, + "tracking_number": tracking_number } SAVE "orders", order_id, update_data @@ -79,15 +186,10 @@ WEBHOOK "new-customer" customer_id = "CUST-" + FORMAT(NOW(), "YYYYMMDDHHmmss") phone = body.phone name = body.name +source = "webhook" -customer_data = #{ - "name": name, - "phone": phone, - "source": "webhook", - "created_at": NOW() -} - -SAVE "customers", customer_id, customer_data +' Direct save with variables +SAVE "customers", customer_id, phone, name, source ' Notify via WhatsApp TALK TO "whatsapp:" + phone, "Welcome " + name + "! Your account has been created." @@ -121,12 +223,11 @@ WEBHOOK "create-order" ' Save order order_id = body.order_id -order_data = #{ - "customer_id": body.customer_id, - "total": body.total, - "status": "pending" -} -SAVE "orders", order_id, order_data +customer_id = body.customer_id +total = body.total +status = "pending" + +SAVE "orders", order_id, customer_id, total, status ' Save each line item FOR EACH item IN body.items @@ -146,6 +247,27 @@ TALK TO "whatsapp:" + body.customer_phone, "Order #" + order_id + " confirmed!" result_status = "ok" ``` +### Comparison: WITH Block vs Direct Syntax + +**Old way (WITH block):** +```basic +WITH casamento + id = casamentoId + protocolo = protocolo + noivo = nomeNoivo + noiva = nomeNoiva +END WITH +SAVE "casamentos", casamento +``` + +**New way (direct):** +```basic +' Variable names become column names automatically +SAVE "casamentos", casamentoId, protocolo, nomeNoivo, nomeNoiva +``` + +The direct syntax is cleaner and avoids the intermediate object creation. Use it when your variable names match your desired column names. + ## Return Value Returns an object with: diff --git a/src/06-gbdialog/keyword-send-mail.md b/src/06-gbdialog/keyword-send-mail.md index 3b3c3765..87943067 100644 --- a/src/06-gbdialog/keyword-send-mail.md +++ b/src/06-gbdialog/keyword-send-mail.md @@ -4,11 +4,27 @@ Send email messages. ## Syntax +### Single Line + ```basic SEND MAIL to, subject, body SEND MAIL to, subject, body USING "account@example.com" ``` +### Multi-Line Block with Variable Substitution + +```basic +BEGIN MAIL recipient +Subject: Email subject here + +Dear ${customerName}, + +Your order ${orderId} is ready. + +Thank you! +END MAIL +``` + ## Parameters | Parameter | Type | Description | @@ -17,6 +33,7 @@ SEND MAIL to, subject, body USING "account@example.com" | `subject` | String | Email subject line | | `body` | String | Email body (plain text or HTML) | | `account` | String | (Optional) Connected account to send through | +| `${variable}` | Expression | Variable substitution within MAIL blocks | ## Description @@ -25,6 +42,190 @@ The `SEND MAIL` keyword sends emails using either: 1. **Default SMTP** - Configuration from `config.csv` 2. **Connected Account** - Send through Gmail, Outlook, etc. configured in Sources app +## BEGIN MAIL / END MAIL Blocks + +The `BEGIN MAIL / END MAIL` block syntax allows you to write elegant multi-line emails with automatic variable substitution using `${variable}` syntax. + +### Syntax + +```basic +BEGIN MAIL recipient +Subject: Email subject ${variable} + +Dear ${customerName}, + +Your order ${orderId} has been shipped. + +Tracking: ${trackingNumber} + +Best regards, +The Team +END MAIL +``` + +### How It Works + +1. **First line after `BEGIN MAIL`**: Should contain the email recipient +2. **Line starting with `Subject:`**: Email subject line (supports `${variable}`) +3. **Blank line after subject**: Separates subject from body +4. **Body lines**: Email content with automatic `${variable}` substitution +5. **Each line** is converted to string concatenation with proper newline handling + +**Input:** +```basic +nome = "João" +pedido = "12345" + +BEGIN MAIL "cliente@example.com" +Subject: Confirmação do Pedido ${pedido} + +Olá ${nome}, + +Seu pedido foi confirmado! + +Atenciosamente, +Equipe de Vendas +END MAIL +``` + +**Converted to:** +```basic +SEND MAIL "cliente@example.com", "Confirmação do Pedido 12345", "Olá " + nome + ",\n\nSeu pedido foi confirmado!\n\nAtenciosamente,\nEquipe de Vendas" +``` + +### Variable Substitution Rules + +- `${variableName}` - Replaced with the variable value +- `${FUNCTION(args)}` - Function calls are evaluated and substituted +- Plain text without `${}` is treated as a string literal +- Special characters like `$` (not followed by `{`) are preserved +- Newlines are preserved as `\n` in the final email body + +### Examples + +#### Simple Email + +```basic +email = "customer@example.com" +nome = "Maria" + +BEGIN MAIL email +Subject: Bem-vindo ao nosso serviço! + +Olá ${nome}, + +Obrigado por se cadastrar! + +Atenciosamente, +Equipe +END MAIL +``` + +#### With Function Calls + +```basic +BEGIN MAIL "cliente@empresa.com" +Subject: Pedido ${pedidoId} - Confirmação + +Prezado ${nomeCliente}, + +Confirmamos seu pedido #${pedidoId} no valor de ${FORMAT(total, "currency")}. + +Entrega prevista para: ${FORMAT(dataEntrega, "dd/MM/yyyy")} + +Atenciosamente, +Departamento de Vendas +END MAIL +``` + +#### HTML Email + +```basic +BEGIN MAIL "cliente@exemplo.com" +Subject: Seu pedido foi enviado! + +

Confirmação de Pedido

+ +

Olá ${nome},

+

Seu pedido ${pedidoId} foi enviado com sucesso!

+ +

Valor: ${FORMAT(valor, "currency")}

+ +

Atenciosamente,
Loja Virtual

+END MAIL +``` + +### Real-World Example: Wedding Confirmation + +```basic +PARAM nomeNoivo AS STRING LIKE "Carlos" DESCRIPTION "Nome do noivo" +PARAM nomeNoiva AS STRING LIKE "Ana" DESCRIPTION "Nome da noiva" +PARAM emailNoivo AS EMAIL LIKE "noivo@example.com" DESCRIPTION "Email do noivo" +PARAM emailNoiva AS EMAIL LIKE "noiva@example.com" DESCRIPTION "Email da noiva" +PARAM protocolo AS STRING LIKE "CAS123456" DESCRIPTION "Protocolo" + +casamentoId = "CAS-" + FORMAT(NOW(), "yyyyMMddHHmmss") +tipoTexto = "Religioso Simples" + +BEGIN MAIL emailNoivo +Subject: Confirmação de Casamento - Protocolo ${protocolo} + +Queridos ${nomeNoivo} e ${nomeNoiva}, + +Parabéns pelo compromisso de amor que estão assumindo! Recebemos a solicitação de casamento no Santuário Cristo Redentor. + +DADOS DA SOLICITAÇÃO: +Protocolo: ${protocolo} +ID: ${casamentoId} +Noivo: ${nomeNoivo} +Noiva: ${nomeNoiva} +Tipo: ${tipoTexto} + +Nossa equipe verificará a disponibilidade e enviará todas as instruções necessárias em breve. + +Que Deus abençoe a união de vocês! + +Atenciosamente, +Secretaria do Santuário Cristo Redentor +Tel: (21) 4101-0770 | WhatsApp: (21) 99566-5883 +END MAIL +``` + +### Multiple Recipients + +Send the same email to multiple people: + +```basic +BEGIN MAIL "team1@company.com" +Subject: Meeting Reminder + +Team meeting tomorrow at 3 PM. +END MAIL + +BEGIN MAIL "team2@company.com" +Subject: Meeting Reminder + +Team meeting tomorrow at 3 PM. +END MAIL +``` + +Or use comma-separated recipients: + +```basic +recipients = "john@company.com, jane@company.com, bob@company.com" +SEND MAIL recipients, "Meeting Update", "Meeting rescheduled to 4 PM" +``` + +### Advantages + +1. **Cleaner Syntax** - No more repetitive string concatenation for email body +2. **Easier to Read** - Multi-line emails are natural to write and maintain +3. **Template-Like** - Write emails like templates with `${variable}` placeholders +4. **Automatic Newlines** - Blank lines in the block become `\n` in the email +5. **Perfect for TOOL Functions** - Variables are automatically filled by user input + +## Examples + ## Configuration Default SMTP in `config.csv`: diff --git a/src/06-gbdialog/keyword-talk.md b/src/06-gbdialog/keyword-talk.md index 9d166ec8..a90aea8a 100644 --- a/src/06-gbdialog/keyword-talk.md +++ b/src/06-gbdialog/keyword-talk.md @@ -4,18 +4,31 @@ Sends a message to the current conversation or to a specific recipient on any su ## Syntax +### Single Message + ```basic TALK message TALK TO recipient, message ``` +### Multi-Line Block with Variable Substitution + +```basic +BEGIN TALK +Line 1 with ${variable} +Line 2 with ${anotherVariable} +Plain text line +END TALK +``` + ## Parameters | Parameter | Type | Description | |-----------|------|-------------| | message | String | The message to send | | recipient | String | Channel and address in format `channel:address` | +| ${variable} | Expression | Variable substitution within TALK blocks | ## Description @@ -23,6 +36,151 @@ TALK TO recipient, message - **TALK message** - Sends to the current conversation (web chat, WhatsApp, etc.) - **TALK TO recipient, message** - Sends to a specific recipient on any channel +- **BEGIN TALK / END TALK** - Multi-line block with automatic variable substitution + +## BEGIN TALK / END TALK Blocks + +The `BEGIN TALK / END TALK` block syntax allows you to write multiple messages with automatic variable substitution using `${variable}` syntax. + +### Syntax + +```basic +BEGIN TALK +Hello ${name}! +Your order ${orderId} is confirmed. +Total: ${FORMAT(total, "currency")} +Thank you for your purchase! +END TALK +``` + +Each line within the block becomes a separate `TALK` statement. The `${variable}` syntax is automatically converted to string concatenation. + +### How It Works + +**Input:** +```basic +nomeNoivo = "Carlos" +protocolo = "CAS123456" + +BEGIN TALK +Solicitacao de Casamento enviada com sucesso! +PROTOCOLO: ${protocolo} +Noivo: ${nomeNoivo} +END TALK +``` + +**Converted to:** +```basic +TALK "Solicitacao de Casamento enviada com sucesso!" +TALK "PROTOCOLO: " + protocolo +TALK "Noivo: " + nomeNoivo +``` + +### Variable Substitution Rules + +- `${variableName}` - Replaced with the variable value using string concatenation +- `${FUNCTION(args)}` - Function calls are evaluated and substituted +- Plain text without `${}` is treated as a string literal +- Special characters like `$` (not followed by `{`) are preserved as-is + +### Examples + +#### Simple Substitution + +```basic +nome = "João" +idade = 30 + +BEGIN TALK +Olá ${nome}! +Você tem ${idade} anos. +END TALK +``` + +**Equivalent to:** +```basic +TALK "Olá " + nome + "!" +TALK "Você tem " + idade + " anos." +``` + +#### With Function Calls + +```basic +total = 299.90 +numero = 42 + +BEGIN TALK +Seu pedido: ${numero} +Total: ${FORMAT(total, "currency")} +Obrigado pela preferência! +END TALK +``` + +#### Mixed Content + +```basic +nome = "Maria" +codigo = "PROMO2024" +desconto = 20 + +BEGIN TALK +🎉 Oferta Especial para ${nome}! + +Use o código: ${codigo} +Desconto de ${desconto}% + +Aproveite! +END TALK +``` + +### Real-World Example: Wedding Confirmation + +```basic +PARAM nomeNoivo AS STRING LIKE "Carlos" DESCRIPTION "Nome do noivo" +PARAM nomeNoiva AS STRING LIKE "Ana" DESCRIPTION "Nome da noiva" +PARAM protocolo AS STRING LIKE "CAS123456" DESCRIPTION "Protocolo" +PARAM dataCasamento AS DATE LIKE "2026-12-15" DESCRIPTION "Data do casamento" + +casamentoId = "CAS-" + FORMAT(NOW(), "yyyyMMddHHmmss") +dataDisplay = FORMAT(dataCasamento, "dd/MM/yyyy") + +BEGIN TALK +✅ Solicitação de Casamento enviada com sucesso! + +Protocolo: ${protocolo} +ID: ${casamentoId} +Noivo: ${nomeNoivo} +Noiva: ${nomeNoiva} +Data: ${dataDisplay} + +Status: Aguardando verificação de disponibilidade +Contato: (21) 4101-0770 +END TALK +``` + +This is much cleaner than writing individual TALK statements with manual concatenation: + +**Old way:** +```basic +TALK "Solicitacao de Casamento enviada com sucesso!" +TALK "Protocolo: " + protocolo +TALK "ID: " + casamentoId +TALK "Noivo: " + nomeNoivo +TALK "Noiva: " + nomeNoiva +TALK "Data: " + dataDisplay +TALK "Status: Aguardando verificacao de disponibilidade" +TALK "Contato: (21) 4101-0770" +``` + +### Advantages + +1. **Cleaner Syntax** - No more repetitive `TALK` statements and `+` concatenations +2. **Easier to Read** - Multi-line messages are more natural to write +3. **Less Error-Prone** - Automatic substitution reduces typos in variable names +4. **Template-Like** - Write messages like templates with `${variable}` placeholders +5. **Perfect for TOOL Functions** - Variables are automatically filled by user input + +## TALK - Current Conversation ## TALK - Current Conversation diff --git a/src/06-gbdialog/universal-messaging.md b/src/06-gbdialog/universal-messaging.md index 4de768f0..837754d2 100644 --- a/src/06-gbdialog/universal-messaging.md +++ b/src/06-gbdialog/universal-messaging.md @@ -21,7 +21,7 @@ This script works identically whether the user is: ## Supported Channels ### Web (Default) -The primary channel. Users access via browser at `http://localhost:8080`. +The primary channel. Users access via browser at `http://localhost:9000`. ### WhatsApp Business Requires WhatsApp Business API configuration. Messages are automatically formatted for WhatsApp's constraints. diff --git a/src/07-gbapp/infrastructure.md b/src/07-gbapp/infrastructure.md index aed03e1a..5120348d 100644 --- a/src/07-gbapp/infrastructure.md +++ b/src/07-gbapp/infrastructure.md @@ -292,7 +292,7 @@ bot.example.com { # WebSocket (sticky sessions) handle /ws* { - reverse_proxy botserver-1:8080 botserver-2:8080 { + reverse_proxy botserver-1:9000 botserver-2:9000 { lb_policy cookie health_uri /api/health health_interval 10s @@ -301,7 +301,7 @@ bot.example.com { # API (round robin) handle /api/* { - reverse_proxy botserver-1:8080 botserver-2:8080 { + reverse_proxy botserver-1:9000 botserver-2:9000 { lb_policy round_robin fail_duration 30s } @@ -400,7 +400,7 @@ VAULT_ADDR=https://localhost:8200 VAULT_TOKEN=hvs.your-token-here # Directory for user auth (Zitadel) -DIRECTORY_URL=https://localhost:8080 +DIRECTORY_URL=https://localhost:9000 DIRECTORY_CLIENT_ID=your-client-id DIRECTORY_CLIENT_SECRET=your-client-secret diff --git a/src/07-gbapp/scaling.md b/src/07-gbapp/scaling.md index 56749227..b1204581 100644 --- a/src/07-gbapp/scaling.md +++ b/src/07-gbapp/scaling.md @@ -87,7 +87,7 @@ scale-rule-queue-action,up for i in {2..5}; do lxc launch images:debian/12 botserver-$i lxc config device add botserver-$i port-$((8080+i)) proxy \ - listen=tcp:0.0.0.0:$((8080+i)) connect=tcp:127.0.0.1:8080 + listen=tcp:0.0.0.0:$((8080+i)) connect=tcp:127.0.0.1:9000 done ``` @@ -207,7 +207,7 @@ update_load_balancer() { upstreams="" for container in $(lxc list -c n --format csv | grep "^botserver-"); do ip=$(lxc list $container -c 4 --format csv | cut -d' ' -f1) - upstreams="$upstreams\n to $ip:8080" + upstreams="$upstreams\n to $ip:9000" done # Update Caddy config @@ -268,12 +268,12 @@ bot.example.com { # Health check endpoint (no load balancing) handle /api/health { - reverse_proxy localhost:8080 + reverse_proxy localhost:9000 } # WebSocket connections (sticky sessions) handle /ws* { - reverse_proxy botserver-1:8080 botserver-2:8080 botserver-3:8080 { + reverse_proxy botserver-1:9000 botserver-2:9000 botserver-3:9000 { lb_policy cookie lb_try_duration 5s health_uri /api/health @@ -284,7 +284,7 @@ bot.example.com { # API requests (round robin) handle /api/* { - reverse_proxy botserver-1:8080 botserver-2:8080 botserver-3:8080 { + reverse_proxy botserver-1:9000 botserver-2:9000 botserver-3:9000 { lb_policy round_robin lb_try_duration 5s health_uri /api/health @@ -295,7 +295,7 @@ bot.example.com { # Static files (any instance) handle { - reverse_proxy botserver-1:8080 botserver-2:8080 botserver-3:8080 { + reverse_proxy botserver-1:9000 botserver-2:9000 botserver-3:9000 { lb_policy first } } @@ -353,7 +353,7 @@ bot.example.com { window 1m } } - reverse_proxy botserver:8080 + reverse_proxy botserver:9000 } } ``` diff --git a/src/08-config/secrets-management.md b/src/08-config/secrets-management.md index e0e0c69c..21fcb28e 100644 --- a/src/08-config/secrets-management.md +++ b/src/08-config/secrets-management.md @@ -162,7 +162,7 @@ Use the Vault CLI or API: ```bash # Directory (Zitadel) - includes URL, no longer in .env vault kv put gbo/directory \ - url=https://localhost:8080 \ + url=https://localhost:9000 \ project_id=your-project-id \ client_id=your-client-id \ client_secret=your-client-secret @@ -506,7 +506,7 @@ If you're currently using environment variables: ```bash # .env - TOO MANY SECRETS! DATABASE_URL=postgres://user:password@localhost/db -DIRECTORY_URL=https://localhost:8080 +DIRECTORY_URL=https://localhost:9000 DIRECTORY_CLIENT_ID=your-client-id DIRECTORY_CLIENT_SECRET=your-client-secret REDIS_PASSWORD=redis-secret @@ -528,7 +528,7 @@ VAULT_TOKEN=hvs.xxxxx ```bash # EVERYTHING in Vault vault kv put gbo/directory \ - url=https://localhost:8080 \ + url=https://localhost:9000 \ project_id=12345 \ client_id=xxx \ client_secret=xxx @@ -579,7 +579,7 @@ fi # Store everything in Vault vault kv put gbo/directory \ - url="${DIRECTORY_URL:-https://localhost:8080}" \ + url="${DIRECTORY_URL:-https://localhost:9000}" \ project_id="${DIRECTORY_PROJECT_ID:-}" \ client_id="${ZITADEL_CLIENT_ID:-}" \ client_secret="${ZITADEL_CLIENT_SECRET:-}" diff --git a/src/10-rest/admin-api.md b/src/10-rest/admin-api.md index b4fafd29..0565ed10 100644 --- a/src/10-rest/admin-api.md +++ b/src/10-rest/admin-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/admin +http://localhost:9000/api/v1/admin ``` ## Authentication diff --git a/src/10-rest/ai-api.md b/src/10-rest/ai-api.md index 1c2b9284..d4b32747 100644 --- a/src/10-rest/ai-api.md +++ b/src/10-rest/ai-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/ai +http://localhost:9000/api/v1/ai ``` ## Authentication diff --git a/src/10-rest/analytics-api.md b/src/10-rest/analytics-api.md index 57c7f99a..f433fe4e 100644 --- a/src/10-rest/analytics-api.md +++ b/src/10-rest/analytics-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/analytics +http://localhost:9000/api/v1/analytics ``` ## Authentication diff --git a/src/10-rest/backup-api.md b/src/10-rest/backup-api.md index a396eef6..590c5112 100644 --- a/src/10-rest/backup-api.md +++ b/src/10-rest/backup-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/backup +http://localhost:9000/api/v1/backup ``` ## Authentication diff --git a/src/10-rest/compliance-api.md b/src/10-rest/compliance-api.md index 74619bd2..71856ea5 100644 --- a/src/10-rest/compliance-api.md +++ b/src/10-rest/compliance-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/compliance +http://localhost:9000/api/v1/compliance ``` ## Authentication diff --git a/src/10-rest/document-processing.md b/src/10-rest/document-processing.md index 4556da3c..f584a5f1 100644 --- a/src/10-rest/document-processing.md +++ b/src/10-rest/document-processing.md @@ -14,7 +14,7 @@ The Document Processing API enables: ## Base URL ``` -http://localhost:8080/api/v1/documents +http://localhost:9000/api/v1/documents ``` ## Authentication @@ -47,7 +47,7 @@ curl -X POST \ -H "Authorization: Bearer token123" \ -F "file=@document.pdf" \ -F 'process_options={"extract_text":true,"extract_metadata":true}' \ - http://localhost:8080/api/v1/documents/upload + http://localhost:9000/api/v1/documents/upload ``` **Response:** @@ -532,7 +532,7 @@ import requests # Upload and process document with open('document.pdf', 'rb') as f: response = requests.post( - 'http://localhost:8080/api/v1/documents/upload', + 'http://localhost:9000/api/v1/documents/upload', headers={'Authorization': 'Bearer token123'}, files={'file': f}, data={'process_options': '{"extract_text": true}'} @@ -542,7 +542,7 @@ document_id = response.json()['document_id'] # Get extracted text text_response = requests.get( - f'http://localhost:8080/api/v1/documents/{document_id}/text', + f'http://localhost:9000/api/v1/documents/{document_id}/text', headers={'Authorization': 'Bearer token123'} ) diff --git a/src/10-rest/examples.md b/src/10-rest/examples.md index ba18563e..5009737b 100644 --- a/src/10-rest/examples.md +++ b/src/10-rest/examples.md @@ -22,7 +22,7 @@ async function authenticate() { **cURL:** ```bash # Session validation -curl -X GET http://localhost:8080/auth/validate \ +curl -X GET http://localhost:9000/auth/validate \ -H "Authorization: Bearer YOUR_SESSION_TOKEN" ``` @@ -55,7 +55,7 @@ async function createGroup() { import requests def create_group(): - url = "http://localhost:8080/api/groups/create" + url = "http://localhost:9000/api/groups/create" headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json" @@ -96,7 +96,7 @@ async function addMember(groupId, userId) { **cURL:** ```bash -curl -X GET http://localhost:8080/api/admin/system/status \ +curl -X GET http://localhost:9000/api/admin/system/status \ -H "Authorization: Bearer ADMIN_TOKEN" ``` @@ -113,7 +113,7 @@ import ( func getSystemStatus(token string) { client := &http.Client{} req, _ := http.NewRequest("GET", - "http://localhost:8080/api/admin/system/status", nil) + "http://localhost:9000/api/admin/system/status", nil) req.Header.Add("Authorization", "Bearer " + token) resp, err := client.Do(req) @@ -164,7 +164,7 @@ class BotChat { } connect() { - this.ws = new WebSocket('ws://localhost:8080/ws'); + this.ws = new WebSocket('ws://localhost:9000/ws'); this.ws.onopen = () => { console.log('Connected to bot'); @@ -370,7 +370,7 @@ function handleConversationCompleted(conversationData) { 1. Import the API collection (when available) 2. Set environment variables for: - - `base_url`: http://localhost:8080 + - `base_url`: http://localhost:9000 - `token`: Your session token 3. Run requests individually or as collection diff --git a/src/10-rest/group-membership.md b/src/10-rest/group-membership.md index 550e277d..78b4f62b 100644 --- a/src/10-rest/group-membership.md +++ b/src/10-rest/group-membership.md @@ -15,7 +15,7 @@ The Group Membership API enables: ## Base URL ``` -http://localhost:8080/api/v1/groups +http://localhost:9000/api/v1/groups ``` ## Authentication diff --git a/src/10-rest/ml-api.md b/src/10-rest/ml-api.md index 1fb644b4..90b9306c 100644 --- a/src/10-rest/ml-api.md +++ b/src/10-rest/ml-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/ml +http://localhost:9000/api/v1/ml ``` ## Authentication diff --git a/src/10-rest/monitoring-api.md b/src/10-rest/monitoring-api.md index 04ff4c30..4d9d28e6 100644 --- a/src/10-rest/monitoring-api.md +++ b/src/10-rest/monitoring-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/monitoring +http://localhost:9000/api/v1/monitoring ``` ## Authentication diff --git a/src/10-rest/notifications-api.md b/src/10-rest/notifications-api.md index bba35c32..b90de63d 100644 --- a/src/10-rest/notifications-api.md +++ b/src/10-rest/notifications-api.md @@ -14,7 +14,7 @@ The Notifications API enables: ## Base URL ``` -http://localhost:8080/api/v1/notifications +http://localhost:9000/api/v1/notifications ``` ## Authentication @@ -446,7 +446,7 @@ curl -X POST \ "title": "Hello", "message": "This is a test notification" }' \ - http://localhost:8080/api/v1/notifications/send + http://localhost:9000/api/v1/notifications/send ``` ### Schedule Broadcast @@ -463,7 +463,7 @@ curl -X POST \ }, "schedule": "2024-01-20T02:00:00Z" }' \ - http://localhost:8080/api/v1/notifications/broadcast + http://localhost:9000/api/v1/notifications/broadcast ``` ## Best Practices diff --git a/src/10-rest/reports-api.md b/src/10-rest/reports-api.md index b1605bbb..0d3749f5 100644 --- a/src/10-rest/reports-api.md +++ b/src/10-rest/reports-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/reports +http://localhost:9000/api/v1/reports ``` ## Authentication diff --git a/src/10-rest/security-api.md b/src/10-rest/security-api.md index b4a07b4d..b6afaaf1 100644 --- a/src/10-rest/security-api.md +++ b/src/10-rest/security-api.md @@ -9,7 +9,7 @@ This API is on the development roadmap. The endpoints documented below represent ## Base URL ``` -http://localhost:8080/api/v1/security +http://localhost:9000/api/v1/security ``` ## Authentication diff --git a/src/10-rest/storage-api.md b/src/10-rest/storage-api.md index 0a7635c7..5910a531 100644 --- a/src/10-rest/storage-api.md +++ b/src/10-rest/storage-api.md @@ -14,7 +14,7 @@ The Storage API allows you to: ## Base URL ``` -http://localhost:8080/api/v1/storage +http://localhost:9000/api/v1/storage ``` ## Authentication @@ -268,7 +268,7 @@ curl -X PUT \ -H "Authorization: Bearer token123" \ -H "Content-Type: application/pdf" \ --data-binary @document.pdf \ - http://localhost:8080/api/v1/storage/buckets/mybot.gbai/objects/docs/manual.pdf + http://localhost:9000/api/v1/storage/buckets/mybot.gbai/objects/docs/manual.pdf ``` ### Download File @@ -276,7 +276,7 @@ curl -X PUT \ ```bash curl -X GET \ -H "Authorization: Bearer token123" \ - http://localhost:8080/api/v1/storage/buckets/mybot.gbai/objects/docs/manual.pdf \ + http://localhost:9000/api/v1/storage/buckets/mybot.gbai/objects/docs/manual.pdf \ -o downloaded.pdf ``` @@ -285,7 +285,7 @@ curl -X GET \ ```bash curl -X GET \ -H "Authorization: Bearer token123" \ - "http://localhost:8080/api/v1/storage/buckets/mybot.gbai/objects?prefix=docs/" + "http://localhost:9000/api/v1/storage/buckets/mybot.gbai/objects?prefix=docs/" ``` ## Storage Organization diff --git a/src/10-rest/tasks-api.md b/src/10-rest/tasks-api.md index 9c0a3653..1c3a57ce 100644 --- a/src/10-rest/tasks-api.md +++ b/src/10-rest/tasks-api.md @@ -15,7 +15,7 @@ The Tasks API enables: ## Base URL ``` -http://localhost:8080/api/v1/tasks +http://localhost:9000/api/v1/tasks ``` ## Authentication diff --git a/src/10-rest/user-security.md b/src/10-rest/user-security.md index 2ce8aaa9..c69cfb6b 100644 --- a/src/10-rest/user-security.md +++ b/src/10-rest/user-security.md @@ -15,7 +15,7 @@ The User Security API enables: ## Base URL ``` -http://localhost:8080/api/v1/security +http://localhost:9000/api/v1/security ``` ## Authentication diff --git a/src/10-rest/users-api.md b/src/10-rest/users-api.md index 723008eb..2cb9e102 100644 --- a/src/10-rest/users-api.md +++ b/src/10-rest/users-api.md @@ -359,7 +359,7 @@ Register new user (if self-registration enabled). For full user management, access Zitadel admin console: -1. **Access Console**: `http://localhost:8080` (or your Zitadel URL) +1. **Access Console**: `http://localhost:9000` (or your Zitadel URL) 2. **Create Users**: Organization → Users → Add 3. **Manage Roles**: Users → Select User → Authorizations 4. **Reset Passwords**: Users → Select User → Actions → Reset Password diff --git a/src/11-features/platform-comparison.md b/src/11-features/platform-comparison.md index ebc30ede..8afa8505 100644 --- a/src/11-features/platform-comparison.md +++ b/src/11-features/platform-comparison.md @@ -159,7 +159,7 @@ Run General Bots on your own infrastructure with single binary deployment, conta ./botserver ``` -Access at `http://localhost:8080` and start building. +Access at `http://localhost:9000` and start building. ## Summary diff --git a/src/12-auth/compliance-requirements.md b/src/12-auth/compliance-requirements.md index 6fa3da28..37fd0dfe 100644 --- a/src/12-auth/compliance-requirements.md +++ b/src/12-auth/compliance-requirements.md @@ -85,7 +85,7 @@ app.example.com { | ⚠️ | Password Rotation | Directory | HIPAA | Configure 90-day rotation policy | | 📝 | Access Reviews | Directory | All | Quarterly manual review of user permissions | -**Configuration**: Directory Admin Console (`http://localhost:8080`) +**Configuration**: Directory Admin Console (`http://localhost:9000`) **Key Settings**: - Password min length: 12 characters @@ -206,7 +206,7 @@ directory = "oidc" [directory."oidc"] type = "oidc" -issuer = "http://localhost:8080" +issuer = "http://localhost:9000" ``` **DNS Records**: diff --git a/src/12-auth/security-checklist.md b/src/12-auth/security-checklist.md index 9770a2a6..6b6e6653 100644 --- a/src/12-auth/security-checklist.md +++ b/src/12-auth/security-checklist.md @@ -180,7 +180,7 @@ cargo test --all RUSTFLAGS="-Z sanitizer=address" cargo +nightly test # Verify rate limiting -curl -X POST http://localhost:8080/api/test \ +curl -X POST http://localhost:9000/api/test \ -H "Content-Type: application/json" \ --data '{}' \ --parallel --parallel-max 1000 diff --git a/src/13-community/documentation.md b/src/13-community/documentation.md index 0a8b83fd..4c891469 100644 --- a/src/13-community/documentation.md +++ b/src/13-community/documentation.md @@ -123,7 +123,7 @@ Document WebSocket protocols with connection details, message formats for both d ### Connection ``` -ws://localhost:8080/ws +ws://localhost:9000/ws ``` ### Message Format diff --git a/src/13-community/ide-extensions.md b/src/13-community/ide-extensions.md index dd57c1e3..ad4d810b 100644 --- a/src/13-community/ide-extensions.md +++ b/src/13-community/ide-extensions.md @@ -67,7 +67,7 @@ return { 'botserver/nvim-botserver', config = function() require('botserver').setup({ - server_url = 'http://localhost:8080', + server_url = 'http://localhost:9000', default_bot = 'edu' }) end diff --git a/src/13-community/setup.md b/src/13-community/setup.md index 7d391a26..230b01b6 100644 --- a/src/13-community/setup.md +++ b/src/13-community/setup.md @@ -313,7 +313,7 @@ cargo test --all-features 3. **Port Already in Use** - Change SERVER_PORT in .env - - Kill existing process: `lsof -i :8080` + - Kill existing process: `lsof -i :9000` 4. **Compilation Errors** - Update Rust: `rustup update` diff --git a/src/13-hardware-devices/buying-guide.md b/src/13-hardware-devices/buying-guide.md index 2b7b286a..0187509e 100644 --- a/src/13-hardware-devices/buying-guide.md +++ b/src/13-hardware-devices/buying-guide.md @@ -229,7 +229,7 @@ cd botserver Open in your browser: ``` -http://mybot.local:8088 +http://mybot.local:9000 ``` ## Common Beginner Mistakes diff --git a/src/13-hardware-devices/local-llm.md b/src/13-hardware-devices/local-llm.md index 02b47cc0..440c0c46 100644 --- a/src/13-hardware-devices/local-llm.md +++ b/src/13-hardware-devices/local-llm.md @@ -83,7 +83,7 @@ wget https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/ --threads 4 # Verify -curl http://localhost:8080/v1/models +curl http://localhost:9000/v1/models ``` ### Systemd Service @@ -127,7 +127,7 @@ sudo systemctl start llama-server ```env # Use local llama.cpp LLM_PROVIDER=llamacpp -LLM_API_URL=http://127.0.0.1:8080 +LLM_API_URL=http://127.0.0.1:9000 LLM_MODEL=tinyllama # Memory limits @@ -263,7 +263,7 @@ llama.cpp exposes an OpenAI-compatible API: ### Chat Completion ```bash -curl http://localhost:8080/v1/chat/completions \ +curl http://localhost:9000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "tinyllama", @@ -277,7 +277,7 @@ curl http://localhost:8080/v1/chat/completions \ ### Streaming ```bash -curl http://localhost:8080/v1/chat/completions \ +curl http://localhost:9000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "tinyllama", @@ -289,8 +289,8 @@ curl http://localhost:8080/v1/chat/completions \ ### Health Check ```bash -curl http://localhost:8080/health -curl http://localhost:8080/v1/models +curl http://localhost:9000/health +curl http://localhost:9000/v1/models ``` ## Monitoring diff --git a/src/13-hardware-devices/mobile.md b/src/13-hardware-devices/mobile.md index 488d8402..eecb8fec 100644 --- a/src/13-hardware-devices/mobile.md +++ b/src/13-hardware-devices/mobile.md @@ -231,7 +231,7 @@ BotDevice can work offline with local LLM: 1. Install botserver on the device (see [Local LLM](./local-llm.md)) 2. Configure to use localhost: ```javascript - window.BOTSERVER_URL = "http://127.0.0.1:8088"; + window.BOTSERVER_URL = "http://127.0.0.1:9000"; ``` 3. Run llama.cpp with small model (TinyLlama on 4GB+ devices) diff --git a/src/13-hardware-devices/quick-start.md b/src/13-hardware-devices/quick-start.md index 76a641bc..3354d769 100644 --- a/src/13-hardware-devices/quick-start.md +++ b/src/13-hardware-devices/quick-start.md @@ -22,9 +22,9 @@ cd botserver ``` That's it! After ~10-15 minutes: -- botserver runs on port 8088 -- llama.cpp runs on port 8080 with TinyLlama -- Embedded UI available at `http://your-device:8088/embedded/` +- botserver runs on port 9000 +- llama.cpp runs on port 8081 with TinyLlama +- Embedded UI available at `http://your-device:9000/embedded/` ## Step-by-Step Guide @@ -87,17 +87,17 @@ ssh pi@raspberrypi.local 'sudo systemctl status botserver' ssh pi@raspberrypi.local 'sudo systemctl status llama-server' # Test botserver -curl http://raspberrypi.local:8088/health +curl http://raspberrypi.local:9000/health # Test llama.cpp -curl http://raspberrypi.local:8080/v1/models +curl http://raspberrypi.local:9000/v1/models ``` ### Step 5: Access the Interface Open in your browser: ``` -http://raspberrypi.local:8088/embedded/ +http://raspberrypi.local:9000/embedded/ ``` Or set up kiosk mode (auto-starts on boot): @@ -142,11 +142,11 @@ Key settings: ```env # Server HOST=0.0.0.0 -PORT=8088 +PORT=9000 # Local LLM LLM_PROVIDER=llamacpp -LLM_API_URL=http://127.0.0.1:8080 +LLM_API_URL=http://127.0.0.1:8081 LLM_MODEL=tinyllama # Memory limits for small devices diff --git a/src/18-appendix-external-services/hosting-dns.md b/src/18-appendix-external-services/hosting-dns.md index 735874b1..f64b26d6 100644 --- a/src/18-appendix-external-services/hosting-dns.md +++ b/src/18-appendix-external-services/hosting-dns.md @@ -100,7 +100,7 @@ lxc config set botserver limits.memory 4GB lxc config set botserver limits.cpu 2 # Forward ports -lxc config device add botserver http proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:8080 +lxc config device add botserver http proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:9000 lxc config device add botserver https proxy listen=tcp:0.0.0.0:443 connect=tcp:127.0.0.1:8443 # Set environment for Vault @@ -118,7 +118,7 @@ services: botserver: image: generalbots/botserver:latest ports: - - "8080:8080" + - "8080:9000" environment: - VAULT_ADDR=http://vault:8200 volumes: diff --git a/src/19-maintenance/cli-reference.md b/src/19-maintenance/cli-reference.md index 852f0f9e..11760e16 100644 --- a/src/19-maintenance/cli-reference.md +++ b/src/19-maintenance/cli-reference.md @@ -404,6 +404,7 @@ botserver rotate-secret | `email` | SMTP password | | `directory` | Zitadel client secret | | `encryption` | Master encryption key (⚠️ dangerous) | +| `jwt` | JWT signing secret (⚠️ invalidates refresh tokens) | **Examples:** @@ -496,6 +497,73 @@ botserver version --all --- +## Security Considerations + +### Current Limitations + +⚠️ **Manual Service Updates Required** +After rotating credentials, you MUST manually update each service: + +- **Database (tables):** Run the provided SQL command to update PostgreSQL user password +- **Drive (MinIO):** Run the provided `mc admin` commands to update S3 credentials +- **Cache (Redis):** Run the provided `redis-cli` command to update password +- **Directory (Zitadel):** Update client secret via admin console + +⚠️ **Service Restart Required** +After rotating **JWT secret**, you MUST restart botserver: +```bash +botserver restart +``` + +All users will need to re-login (refresh tokens invalidated). Access tokens (15-minute expiry) will expire naturally. + +⚠️ **No Automatic Rollback** +If verification fails, you must manually restore from backups: +```bash +# Database: Re-run SQL with old password +# JWT: Restore .env.backup. +# Other: Use backup values shown in rotation output +``` + +### Available Components for Rotation + +| Component | Credential Type | Manual Update Required | Service Restart | +|-----------|----------------|------------------------|-----------------| +| `tables` | PostgreSQL password | ✅ Run SQL command | ❌ No | +| `drive` | MinIO S3 credentials | ✅ Run mc commands | ❌ No | +| `cache` | Redis/Valkey password | ✅ Run redis-cli | ❌ No | +| `email` | SMTP password | ✅ Update mail server | ❌ No | +| `directory` | Zitadel client secret | ✅ Update via console | ❌ No | +| `encryption` | Master encryption key | ⚠️ Re-encrypt all data | ❌ No | +| `jwt` | JWT signing secret | ❌ No | ✅ **Yes** | + +### Best Practices + +1. **Test in staging first** - Never rotate in production without testing +2. **Schedule during low traffic** - Rotate JWT outside peak hours +3. **Have rollback plan ready** - Save backup paths shown during rotation +4. **Monitor logs** - Check for authentication failures after rotation: + ```bash + tail -f /var/log/botserver/app.log | grep -i "authentication\\|jwt\\|token" + ``` +5. **Rotate regularly** - Every 90 days for production, per security compliance +6. **After JWT rotation** - Verify all services are healthy before declaring success + +### Verification + +The `rotate-secret` command includes automatic verification where possible: + +- **Database:** Tests PostgreSQL connection with new credentials +- **JWT:** Checks health endpoint (requires service to be running) +- **Other:** Displays manual verification instructions + +If verification fails: +1. Check the error message for specific failure details +2. Restore from backup if needed +3. Re-run rotation after fixing the issue + +--- + ## Complete Setup Example Here's a complete workflow to set up Vault and migrate secrets. diff --git a/src/19-maintenance/troubleshooting.md b/src/19-maintenance/troubleshooting.md index ed94262d..5d8a4c5f 100644 --- a/src/19-maintenance/troubleshooting.md +++ b/src/19-maintenance/troubleshooting.md @@ -63,7 +63,7 @@ ss -tlnp | grep LISTEN 1. **Port already in use** ```bash # Find what's using the port - lsof -i :8080 + lsof -i :9000 lsof -i :5432 # Kill conflicting process diff --git a/src/23-security/protection-tools.md b/src/23-security/protection-tools.md index dbb9d059..12cf2213 100644 --- a/src/23-security/protection-tools.md +++ b/src/23-security/protection-tools.md @@ -14,7 +14,7 @@ The Security Protection module provides comprehensive host-level security throug │ ▼ HTMX/API calls ┌─────────────────────────────────────────────────────────────┐ -│ botserver (port 8088) │ +│ botserver (port 9000) │ │ /api/security/protection/* │ └─────────────────────────────────────────────────────────────┘ │ diff --git a/src/assets/chapter-13/embedded-architecture.svg b/src/assets/chapter-13/embedded-architecture.svg index 72ec782b..c97ddc5a 100644 --- a/src/assets/chapter-13/embedded-architecture.svg +++ b/src/assets/chapter-13/embedded-architecture.svg @@ -79,7 +79,7 @@ botserver (Rust) - Port 8088 + Port 9000 ARM64 Binary diff --git a/src/assets/chapter-13/local-llm-architecture.svg b/src/assets/chapter-13/local-llm-architecture.svg index 5340972e..89f992d8 100644 --- a/src/assets/chapter-13/local-llm-architecture.svg +++ b/src/assets/chapter-13/local-llm-architecture.svg @@ -90,7 +90,7 @@ Rust Runtime Session Manager - Port 8088 + Port 9000 diff --git a/src/assets/diagrams/embedded-architecture.svg b/src/assets/diagrams/embedded-architecture.svg index ee951163..37a275a7 100644 --- a/src/assets/diagrams/embedded-architecture.svg +++ b/src/assets/diagrams/embedded-architecture.svg @@ -46,7 +46,7 @@ botserver (Rust) - Port 8088 + Port 9000 BASIC Interpreter diff --git a/src/executive-vision.md b/src/executive-vision.md index 4917392d..a817328a 100644 --- a/src/executive-vision.md +++ b/src/executive-vision.md @@ -299,7 +299,7 @@ Or continue reading for the full journey: diff --git a/src/introduction.md b/src/introduction.md index 2e9688de..eb883a92 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -250,7 +250,7 @@ chmod +x botserver ### 2. Open Browser ``` -http://localhost:8080 +http://localhost:9000 ``` ### 3. Start Chatting