Remove documentation files that have been merged into the mdbook
structure under docs/src/. These files were either duplicates, outdated, or have been properly integrated into the structured documentation.
This commit is contained in:
parent
10e578b1a3
commit
430ec12357
33 changed files with 7236 additions and 3309 deletions
|
|
@ -1,788 +0,0 @@
|
||||||
# HEAR Keyword - Input Validation Reference
|
|
||||||
|
|
||||||
> Complete reference for HEAR keyword with automatic input validation in General Bots BASIC
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The `HEAR` keyword waits for user input with optional automatic validation. When using `HEAR AS <TYPE>`, the system will:
|
|
||||||
|
|
||||||
1. Wait for user input
|
|
||||||
2. Validate against the specified type
|
|
||||||
3. **Automatically retry** with a helpful error message if invalid
|
|
||||||
4. Return the normalized/parsed value once valid
|
|
||||||
|
|
||||||
This eliminates the need for manual validation loops and provides a consistent, user-friendly experience.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
1. [Basic HEAR](#basic-hear)
|
|
||||||
2. [Text Validation Types](#text-validation-types)
|
|
||||||
3. [Numeric Types](#numeric-types)
|
|
||||||
4. [Date/Time Types](#datetime-types)
|
|
||||||
5. [Brazilian Document Types](#brazilian-document-types)
|
|
||||||
6. [Contact Types](#contact-types)
|
|
||||||
7. [Menu Selection](#menu-selection)
|
|
||||||
8. [Media Types](#media-types)
|
|
||||||
9. [Authentication Types](#authentication-types)
|
|
||||||
10. [Examples](#examples)
|
|
||||||
11. [Best Practices](#best-practices)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Basic HEAR
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Simple HEAR without validation - accepts any input
|
|
||||||
HEAR response
|
|
||||||
TALK "You said: " + response
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Text Validation Types
|
|
||||||
|
|
||||||
### HEAR AS EMAIL
|
|
||||||
|
|
||||||
Validates email address format and normalizes to lowercase.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What's your email address?"
|
|
||||||
HEAR email AS EMAIL
|
|
||||||
TALK "We'll send confirmation to: " + email
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Must contain `@` symbol
|
|
||||||
- Must have valid domain format
|
|
||||||
- Normalized to lowercase
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid email address (e.g., user@example.com)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS NAME
|
|
||||||
|
|
||||||
Validates name format (letters, spaces, hyphens, apostrophes).
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What's your full name?"
|
|
||||||
HEAR name AS NAME
|
|
||||||
TALK "Nice to meet you, " + name + "!"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Minimum 2 characters
|
|
||||||
- Maximum 100 characters
|
|
||||||
- Only letters, spaces, hyphens, apostrophes
|
|
||||||
- Auto-capitalizes first letter of each word
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid name (letters and spaces only)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS URL
|
|
||||||
|
|
||||||
Validates and normalizes URL format.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter your website URL:"
|
|
||||||
HEAR website AS URL
|
|
||||||
TALK "I'll check " + website
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Valid URL format
|
|
||||||
- Auto-adds `https://` if protocol missing
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid URL"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS PASSWORD
|
|
||||||
|
|
||||||
Validates password strength (minimum requirements).
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Create a password (minimum 8 characters):"
|
|
||||||
HEAR password AS PASSWORD
|
|
||||||
' Returns "[PASSWORD SET]" - actual password stored securely
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Minimum 8 characters
|
|
||||||
- Returns strength indicator (weak/medium/strong)
|
|
||||||
- Never echoes the actual password
|
|
||||||
|
|
||||||
**Error message:** "Password must be at least 8 characters"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS COLOR
|
|
||||||
|
|
||||||
Validates and normalizes color values.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Pick a color:"
|
|
||||||
HEAR color AS COLOR
|
|
||||||
TALK "You selected: " + color ' Returns hex format like #FF0000
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:**
|
|
||||||
- Named colors: "red", "blue", "green", etc.
|
|
||||||
- Hex format: "#FF0000" or "FF0000"
|
|
||||||
- RGB format: "rgb(255, 0, 0)"
|
|
||||||
|
|
||||||
**Returns:** Normalized hex format (#RRGGBB)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS UUID
|
|
||||||
|
|
||||||
Validates UUID/GUID format.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter the transaction ID:"
|
|
||||||
HEAR transaction_id AS UUID
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Numeric Types
|
|
||||||
|
|
||||||
### HEAR AS INTEGER
|
|
||||||
|
|
||||||
Validates and parses integer numbers.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "How old are you?"
|
|
||||||
HEAR age AS INTEGER
|
|
||||||
TALK "In 10 years you'll be " + STR(age + 10)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Accepts whole numbers only
|
|
||||||
- Removes formatting (commas, spaces)
|
|
||||||
- Returns numeric value
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid whole number"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS FLOAT / DECIMAL
|
|
||||||
|
|
||||||
Validates and parses decimal numbers.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter the temperature:"
|
|
||||||
HEAR temperature AS FLOAT
|
|
||||||
TALK "Temperature is " + STR(temperature) + "°C"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Accepts decimal numbers
|
|
||||||
- Handles both `.` and `,` as decimal separator
|
|
||||||
- Returns numeric value rounded to 2 decimal places
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS MONEY / CURRENCY / AMOUNT
|
|
||||||
|
|
||||||
Validates and normalizes monetary amounts.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "How much would you like to transfer?"
|
|
||||||
HEAR amount AS MONEY
|
|
||||||
TALK "Transferring R$ " + FORMAT(amount, "#,##0.00")
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:**
|
|
||||||
- "100"
|
|
||||||
- "100.00"
|
|
||||||
- "1,234.56" (US format)
|
|
||||||
- "1.234,56" (Brazilian/European format)
|
|
||||||
- "R$ 100,00"
|
|
||||||
- "$100.00"
|
|
||||||
|
|
||||||
**Returns:** Normalized decimal value (e.g., "1234.56")
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid amount (e.g., 100.00 or R$ 100,00)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS CREDITCARD / CARD
|
|
||||||
|
|
||||||
Validates credit card number using Luhn algorithm.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter your card number:"
|
|
||||||
HEAR card AS CREDITCARD
|
|
||||||
' Returns masked format: "4111 **** **** 1111"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- 13-19 digits
|
|
||||||
- Passes Luhn checksum
|
|
||||||
- Detects card type (Visa, Mastercard, Amex, etc.)
|
|
||||||
|
|
||||||
**Returns:** Masked card number with metadata about card type
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Date/Time Types
|
|
||||||
|
|
||||||
### HEAR AS DATE
|
|
||||||
|
|
||||||
Validates and parses date input.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "When is your birthday?"
|
|
||||||
HEAR birthday AS DATE
|
|
||||||
TALK "Your birthday is " + FORMAT(birthday, "MMMM d")
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts multiple formats:**
|
|
||||||
- "25/12/2024" (DD/MM/YYYY)
|
|
||||||
- "12/25/2024" (MM/DD/YYYY)
|
|
||||||
- "2024-12-25" (ISO format)
|
|
||||||
- "25 Dec 2024"
|
|
||||||
- "December 25, 2024"
|
|
||||||
- "today", "tomorrow", "yesterday"
|
|
||||||
- "hoje", "amanhã", "ontem" (Portuguese)
|
|
||||||
|
|
||||||
**Returns:** Normalized ISO date (YYYY-MM-DD)
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid date (e.g., 25/12/2024 or 2024-12-25)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS HOUR / TIME
|
|
||||||
|
|
||||||
Validates and parses time input.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What time should we schedule the meeting?"
|
|
||||||
HEAR meeting_time AS HOUR
|
|
||||||
TALK "Meeting scheduled for " + meeting_time
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:**
|
|
||||||
- "14:30" (24-hour format)
|
|
||||||
- "2:30 PM" (12-hour format)
|
|
||||||
- "14:30:00" (with seconds)
|
|
||||||
|
|
||||||
**Returns:** Normalized 24-hour format (HH:MM)
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid time (e.g., 14:30 or 2:30 PM)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Brazilian Document Types
|
|
||||||
|
|
||||||
### HEAR AS CPF
|
|
||||||
|
|
||||||
Validates Brazilian CPF (individual taxpayer ID).
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter your CPF:"
|
|
||||||
HEAR cpf AS CPF
|
|
||||||
TALK "CPF validated: " + cpf ' Returns formatted: 123.456.789-09
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- 11 digits
|
|
||||||
- Valid check digits (mod 11 algorithm)
|
|
||||||
- Rejects known invalid patterns (all same digit)
|
|
||||||
|
|
||||||
**Returns:** Formatted CPF (XXX.XXX.XXX-XX)
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid CPF (11 digits)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS CNPJ
|
|
||||||
|
|
||||||
Validates Brazilian CNPJ (company taxpayer ID).
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Enter your company's CNPJ:"
|
|
||||||
HEAR cnpj AS CNPJ
|
|
||||||
TALK "CNPJ validated: " + cnpj ' Returns formatted: 12.345.678/0001-95
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- 14 digits
|
|
||||||
- Valid check digits
|
|
||||||
|
|
||||||
**Returns:** Formatted CNPJ (XX.XXX.XXX/XXXX-XX)
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid CNPJ (14 digits)"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contact Types
|
|
||||||
|
|
||||||
### HEAR AS MOBILE / PHONE / TELEPHONE
|
|
||||||
|
|
||||||
Validates phone number format.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What's your phone number?"
|
|
||||||
HEAR phone AS MOBILE
|
|
||||||
TALK "We'll send SMS to: " + phone
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- 10-15 digits
|
|
||||||
- Auto-formats based on detected country
|
|
||||||
|
|
||||||
**Returns:** Formatted phone number
|
|
||||||
|
|
||||||
**Error message:** "Please enter a valid mobile number"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS ZIPCODE / CEP / POSTALCODE
|
|
||||||
|
|
||||||
Validates postal code format.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What's your ZIP code?"
|
|
||||||
HEAR cep AS ZIPCODE
|
|
||||||
TALK "Your ZIP code is: " + cep
|
|
||||||
```
|
|
||||||
|
|
||||||
**Supports:**
|
|
||||||
- Brazilian CEP: 8 digits → "12345-678"
|
|
||||||
- US ZIP: 5 or 9 digits → "12345" or "12345-6789"
|
|
||||||
- UK postcode: alphanumeric → "SW1A 1AA"
|
|
||||||
|
|
||||||
**Returns:** Formatted postal code with country detection
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Menu Selection
|
|
||||||
|
|
||||||
### HEAR AS "Option1", "Option2", "Option3"
|
|
||||||
|
|
||||||
Presents a menu and validates selection.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Choose your preferred fruit:"
|
|
||||||
HEAR fruit AS "Apple", "Banana", "Orange", "Mango"
|
|
||||||
TALK "You selected: " + fruit
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:**
|
|
||||||
- Exact match: "Apple"
|
|
||||||
- Case-insensitive: "apple"
|
|
||||||
- Numeric selection: "1", "2", "3"
|
|
||||||
- Partial match: "app" → "Apple" (if unique)
|
|
||||||
|
|
||||||
**Automatically adds suggestions** for the menu options.
|
|
||||||
|
|
||||||
**Error message:** "Please select one of: Apple, Banana, Orange, Mango"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS BOOLEAN
|
|
||||||
|
|
||||||
Validates yes/no response.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Do you agree to the terms?"
|
|
||||||
HEAR agreed AS BOOLEAN
|
|
||||||
IF agreed THEN
|
|
||||||
TALK "Thank you for agreeing!"
|
|
||||||
ELSE
|
|
||||||
TALK "You must agree to continue."
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts (true):** "yes", "y", "true", "1", "sim", "ok", "sure", "confirm"
|
|
||||||
|
|
||||||
**Accepts (false):** "no", "n", "false", "0", "não", "cancel", "deny"
|
|
||||||
|
|
||||||
**Returns:** "true" or "false" (with boolean metadata)
|
|
||||||
|
|
||||||
**Error message:** "Please answer yes or no"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS LANGUAGE
|
|
||||||
|
|
||||||
Validates language code or name.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "What language do you prefer?"
|
|
||||||
HEAR language AS LANGUAGE
|
|
||||||
SET CONTEXT LANGUAGE language
|
|
||||||
TALK "Language set to: " + language
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:**
|
|
||||||
- ISO codes: "en", "pt", "es", "fr", "de"
|
|
||||||
- Full names: "English", "Portuguese", "Spanish"
|
|
||||||
- Native names: "Português", "Español", "Français"
|
|
||||||
|
|
||||||
**Returns:** ISO 639-1 language code
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Media Types
|
|
||||||
|
|
||||||
### HEAR AS IMAGE / PHOTO / PICTURE
|
|
||||||
|
|
||||||
Waits for image upload.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Please send a photo of your document:"
|
|
||||||
HEAR document_photo AS IMAGE
|
|
||||||
TALK "Image received: " + document_photo
|
|
||||||
' Returns URL to the uploaded image
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation:**
|
|
||||||
- Must receive image attachment
|
|
||||||
- Accepts: JPG, PNG, GIF, WebP
|
|
||||||
|
|
||||||
**Error message:** "Please send an image"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS QRCODE
|
|
||||||
|
|
||||||
Waits for image with QR code and reads it.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Send me a photo of the QR code:"
|
|
||||||
HEAR qr_data AS QRCODE
|
|
||||||
TALK "QR code contains: " + qr_data
|
|
||||||
```
|
|
||||||
|
|
||||||
**Process:**
|
|
||||||
1. Waits for image upload
|
|
||||||
2. Calls BotModels vision API to decode QR
|
|
||||||
3. Returns the decoded data
|
|
||||||
|
|
||||||
**Error message:** "Please send an image containing a QR code"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS AUDIO / VOICE / SOUND
|
|
||||||
|
|
||||||
Waits for audio input and transcribes to text.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Send me a voice message:"
|
|
||||||
HEAR transcription AS AUDIO
|
|
||||||
TALK "You said: " + transcription
|
|
||||||
```
|
|
||||||
|
|
||||||
**Process:**
|
|
||||||
1. Waits for audio attachment
|
|
||||||
2. Calls BotModels speech-to-text API
|
|
||||||
3. Returns transcribed text
|
|
||||||
|
|
||||||
**Error message:** "Please send an audio file or voice message"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS VIDEO
|
|
||||||
|
|
||||||
Waits for video upload and describes content.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Send a video of the problem:"
|
|
||||||
HEAR video_description AS VIDEO
|
|
||||||
TALK "I can see: " + video_description
|
|
||||||
```
|
|
||||||
|
|
||||||
**Process:**
|
|
||||||
1. Waits for video attachment
|
|
||||||
2. Calls BotModels vision API to describe
|
|
||||||
3. Returns AI-generated description
|
|
||||||
|
|
||||||
**Error message:** "Please send a video"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### HEAR AS FILE / DOCUMENT / DOC / PDF
|
|
||||||
|
|
||||||
Waits for document upload.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Please upload your contract:"
|
|
||||||
HEAR contract AS DOCUMENT
|
|
||||||
TALK "Document received: " + contract
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accepts:** PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT, CSV
|
|
||||||
|
|
||||||
**Returns:** URL to the uploaded file
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Authentication Types
|
|
||||||
|
|
||||||
### HEAR AS LOGIN
|
|
||||||
|
|
||||||
Waits for Active Directory/OAuth login completion.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Please click the link to authenticate:"
|
|
||||||
HEAR user AS LOGIN
|
|
||||||
TALK "Welcome, " + user.name + "!"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Process:**
|
|
||||||
1. Generates authentication URL
|
|
||||||
2. Waits for OAuth callback
|
|
||||||
3. Returns user object with tokens
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Complete Registration Flow
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "Let's create your account!"
|
|
||||||
|
|
||||||
TALK "What's your full name?"
|
|
||||||
HEAR name AS NAME
|
|
||||||
|
|
||||||
TALK "Enter your email address:"
|
|
||||||
HEAR email AS EMAIL
|
|
||||||
|
|
||||||
TALK "Enter your CPF:"
|
|
||||||
HEAR cpf AS CPF
|
|
||||||
|
|
||||||
TALK "What's your phone number?"
|
|
||||||
HEAR phone AS MOBILE
|
|
||||||
|
|
||||||
TALK "Choose a password:"
|
|
||||||
HEAR password AS PASSWORD
|
|
||||||
|
|
||||||
TALK "What's your birth date?"
|
|
||||||
HEAR birthdate AS DATE
|
|
||||||
|
|
||||||
TALK "Select your gender:"
|
|
||||||
HEAR gender AS "Male", "Female", "Other", "Prefer not to say"
|
|
||||||
|
|
||||||
' All inputs are now validated and normalized
|
|
||||||
TALK "Creating account for " + name + "..."
|
|
||||||
|
|
||||||
TABLE new_user
|
|
||||||
ROW name, email, cpf, phone, birthdate, gender, NOW()
|
|
||||||
END TABLE
|
|
||||||
SAVE "users.csv", new_user
|
|
||||||
|
|
||||||
TALK "✅ Account created successfully!"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Payment Flow
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "💳 Let's process your payment"
|
|
||||||
|
|
||||||
TALK "Enter the amount:"
|
|
||||||
HEAR amount AS MONEY
|
|
||||||
|
|
||||||
IF amount < 1 THEN
|
|
||||||
TALK "Minimum payment is R$ 1.00"
|
|
||||||
RETURN
|
|
||||||
END IF
|
|
||||||
|
|
||||||
TALK "How would you like to pay?"
|
|
||||||
HEAR method AS "Credit Card", "Debit Card", "PIX", "Boleto"
|
|
||||||
|
|
||||||
IF method = "PIX" THEN
|
|
||||||
TALK "Enter the PIX key (phone, email, or CPF):"
|
|
||||||
' Note: We could create HEAR AS PIX_KEY if needed
|
|
||||||
HEAR pix_key
|
|
||||||
ELSEIF method = "Boleto" THEN
|
|
||||||
TALK "Enter the barcode (47-48 digits):"
|
|
||||||
HEAR barcode AS INTEGER
|
|
||||||
END IF
|
|
||||||
|
|
||||||
TALK "Confirm payment of R$ " + FORMAT(amount, "#,##0.00") + "?"
|
|
||||||
HEAR confirm AS BOOLEAN
|
|
||||||
|
|
||||||
IF confirm THEN
|
|
||||||
TALK "✅ Processing payment..."
|
|
||||||
ELSE
|
|
||||||
TALK "Payment cancelled."
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customer Support with Media
|
|
||||||
|
|
||||||
```basic
|
|
||||||
TALK "How can I help you today?"
|
|
||||||
HEAR issue AS "Report a bug", "Request feature", "Billing question", "Other"
|
|
||||||
|
|
||||||
IF issue = "Report a bug" THEN
|
|
||||||
TALK "Please describe the problem:"
|
|
||||||
HEAR description
|
|
||||||
|
|
||||||
TALK "Can you send a screenshot of the issue?"
|
|
||||||
HEAR screenshot AS IMAGE
|
|
||||||
|
|
||||||
TALK "Thank you! We've logged your bug report."
|
|
||||||
TALK "Reference: BUG-" + FORMAT(NOW(), "yyyyMMddHHmmss")
|
|
||||||
|
|
||||||
ELSEIF issue = "Billing question" THEN
|
|
||||||
TALK "Please upload your invoice or send the transaction ID:"
|
|
||||||
HEAR reference
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
### 1. Always Use Appropriate Types
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' ❌ Bad - no validation
|
|
||||||
HEAR email
|
|
||||||
IF NOT email CONTAINS "@" THEN
|
|
||||||
TALK "Invalid email"
|
|
||||||
' Need to implement retry logic...
|
|
||||||
END IF
|
|
||||||
|
|
||||||
' ✅ Good - automatic validation and retry
|
|
||||||
HEAR email AS EMAIL
|
|
||||||
' Guaranteed to be valid when we get here
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Combine with Context
|
|
||||||
|
|
||||||
```basic
|
|
||||||
SET CONTEXT "You are a helpful banking assistant.
|
|
||||||
When asking for monetary values, always confirm before processing."
|
|
||||||
|
|
||||||
TALK "How much would you like to withdraw?"
|
|
||||||
HEAR amount AS MONEY
|
|
||||||
' LLM and validation work together
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Use Menu for Limited Options
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' ❌ Bad - open-ended when options are known
|
|
||||||
HEAR payment_method
|
|
||||||
IF payment_method <> "credit" AND payment_method <> "debit" THEN
|
|
||||||
' Handle unknown input...
|
|
||||||
END IF
|
|
||||||
|
|
||||||
' ✅ Good - constrained to valid options
|
|
||||||
HEAR payment_method AS "Credit Card", "Debit Card", "PIX"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Provide Context Before HEAR
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' ❌ Bad - no context
|
|
||||||
HEAR value AS MONEY
|
|
||||||
|
|
||||||
' ✅ Good - user knows what to enter
|
|
||||||
TALK "Enter the transfer amount (minimum R$ 1.00):"
|
|
||||||
HEAR amount AS MONEY
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Use HEAR AS for Security-Sensitive Data
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' CPF is automatically validated
|
|
||||||
HEAR cpf AS CPF
|
|
||||||
|
|
||||||
' Credit card passes Luhn check and is masked
|
|
||||||
HEAR card AS CREDITCARD
|
|
||||||
|
|
||||||
' Password never echoed back
|
|
||||||
HEAR password AS PASSWORD
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
Validation errors are handled automatically, but you can customize:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' The system automatically retries up to 3 times
|
|
||||||
' After 3 failures, execution continues with empty value
|
|
||||||
|
|
||||||
' You can check if validation succeeded:
|
|
||||||
HEAR email AS EMAIL
|
|
||||||
IF email = "" THEN
|
|
||||||
TALK "Unable to validate email after multiple attempts."
|
|
||||||
TALK "Please contact support for assistance."
|
|
||||||
RETURN
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Metadata Access
|
|
||||||
|
|
||||||
Some validation types provide additional metadata:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
HEAR card AS CREDITCARD
|
|
||||||
' card = "**** **** **** 1234"
|
|
||||||
' Metadata available: card_type, last_four
|
|
||||||
|
|
||||||
HEAR date AS DATE
|
|
||||||
' date = "2024-12-25"
|
|
||||||
' Metadata available: original input, parsed format
|
|
||||||
|
|
||||||
HEAR audio AS AUDIO
|
|
||||||
' audio = "transcribed text here"
|
|
||||||
' Metadata available: language, confidence
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Integration with BotModels
|
|
||||||
|
|
||||||
Media types (QRCODE, AUDIO, VIDEO) automatically call BotModels services:
|
|
||||||
|
|
||||||
| Type | BotModels Endpoint | Service |
|
|
||||||
|------|-------------------|---------|
|
|
||||||
| QRCODE | `/api/v1/vision/qrcode` | QR Code detection |
|
|
||||||
| AUDIO | `/api/v1/speech/to-text` | Whisper transcription |
|
|
||||||
| VIDEO | `/api/v1/vision/describe-video` | BLIP2 video description |
|
|
||||||
| IMAGE (with question) | `/api/v1/vision/vqa` | Visual Q&A |
|
|
||||||
|
|
||||||
Configure BotModels URL in `config.csv`:
|
|
||||||
```
|
|
||||||
botmodels-url,http://localhost:8001
|
|
||||||
botmodels-enabled,true
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Summary Table
|
|
||||||
|
|
||||||
| Type | Example Input | Normalized Output |
|
|
||||||
|------|---------------|-------------------|
|
|
||||||
| EMAIL | "User@Example.COM" | "user@example.com" |
|
|
||||||
| NAME | "john DOE" | "John Doe" |
|
|
||||||
| INTEGER | "1,234" | 1234 |
|
|
||||||
| MONEY | "R$ 1.234,56" | "1234.56" |
|
|
||||||
| DATE | "25/12/2024" | "2024-12-25" |
|
|
||||||
| HOUR | "2:30 PM" | "14:30" |
|
|
||||||
| BOOLEAN | "yes" / "sim" | "true" |
|
|
||||||
| CPF | "12345678909" | "123.456.789-09" |
|
|
||||||
| MOBILE | "11999998888" | "(11) 99999-8888" |
|
|
||||||
| CREDITCARD | "4111111111111111" | "4111 **** **** 1111" |
|
|
||||||
| QRCODE | [image] | "decoded QR data" |
|
|
||||||
| AUDIO | [audio file] | "transcribed text" |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*HEAR AS validation - Making input handling simple, secure, and user-friendly.*
|
|
||||||
|
|
@ -1,242 +0,0 @@
|
||||||
# Minimal UI and Bot Core API Compliance Documentation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This document outlines the compliance between the Minimal UI (`ui/minimal/`) and the Bot Core API (`src/core/bot/`), ensuring proper integration and functionality.
|
|
||||||
|
|
||||||
## API Endpoints Compliance
|
|
||||||
|
|
||||||
### ✅ Implemented Endpoints
|
|
||||||
|
|
||||||
The Minimal UI correctly integrates with the following Bot Core API endpoints:
|
|
||||||
|
|
||||||
| Endpoint | Method | UI Function | Status |
|
|
||||||
|----------|--------|-------------|--------|
|
|
||||||
| `/ws` | WebSocket | `connectWebSocket()` | ✅ Working |
|
|
||||||
| `/api/auth` | GET | `initializeAuth()` | ✅ Working |
|
|
||||||
| `/api/sessions` | GET | `loadSessions()` | ✅ Working |
|
|
||||||
| `/api/sessions` | POST | `createNewSession()` | ✅ Working |
|
|
||||||
| `/api/sessions/{id}` | GET | `loadSessionHistory()` | ✅ Working |
|
|
||||||
| `/api/sessions/{id}/history` | GET | `loadSessionHistory()` | ✅ Working |
|
|
||||||
| `/api/sessions/{id}/start` | POST | `startSession()` | ✅ Working |
|
|
||||||
| `/api/voice/start` | POST | `startVoiceSession()` | ✅ Working |
|
|
||||||
| `/api/voice/stop` | POST | `stopVoiceSession()` | ✅ Working |
|
|
||||||
|
|
||||||
### WebSocket Protocol Compliance
|
|
||||||
|
|
||||||
The Minimal UI implements the WebSocket protocol correctly:
|
|
||||||
|
|
||||||
#### Message Types
|
|
||||||
```javascript
|
|
||||||
// UI Implementation matches Bot Core expectations
|
|
||||||
const MessageTypes = {
|
|
||||||
TEXT: 1, // Regular text message
|
|
||||||
VOICE: 2, // Voice message
|
|
||||||
CONTINUE: 3, // Continue interrupted response
|
|
||||||
CONTEXT: 4, // Context change
|
|
||||||
SYSTEM: 5 // System message
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Message Format
|
|
||||||
```javascript
|
|
||||||
// Minimal UI message structure (matches bot core)
|
|
||||||
{
|
|
||||||
bot_id: string,
|
|
||||||
user_id: string,
|
|
||||||
session_id: string,
|
|
||||||
channel: "web",
|
|
||||||
content: string,
|
|
||||||
message_type: number,
|
|
||||||
media_url: string | null,
|
|
||||||
timestamp: ISO8601 string,
|
|
||||||
is_suggestion?: boolean,
|
|
||||||
context_name?: string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Feature Compliance Matrix
|
|
||||||
|
|
||||||
| Feature | Bot Core Support | Minimal UI Support | Status |
|
|
||||||
|---------|-----------------|-------------------|---------|
|
|
||||||
| Text Chat | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Voice Input | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Session Management | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Context Switching | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Streaming Responses | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Markdown Rendering | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Suggestions | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Multi-tenant | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Authentication | ✅ | ✅ | Fully Compliant |
|
|
||||||
| Reconnection | ✅ | ✅ | Fully Compliant |
|
|
||||||
|
|
||||||
## Connection Flow Compliance
|
|
||||||
|
|
||||||
### 1. Initial Connection
|
|
||||||
```
|
|
||||||
Minimal UI Bot Core
|
|
||||||
| |
|
|
||||||
|---> GET /api/auth -------->|
|
|
||||||
|<--- {user_id, session_id} -|
|
|
||||||
| |
|
|
||||||
|---> WebSocket Connect ----->|
|
|
||||||
|<--- Connection Established -|
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Message Exchange
|
|
||||||
```
|
|
||||||
Minimal UI Bot Core
|
|
||||||
| |
|
|
||||||
|---> Send Message --------->|
|
|
||||||
|<--- Streaming Response <----|
|
|
||||||
|<--- Suggestions ------------|
|
|
||||||
|<--- Context Update ---------|
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Session Management
|
|
||||||
```
|
|
||||||
Minimal UI Bot Core
|
|
||||||
| |
|
|
||||||
|---> Create Session -------->|
|
|
||||||
|<--- Session ID -------------|
|
|
||||||
| |
|
|
||||||
|---> Load History ---------->|
|
|
||||||
|<--- Message Array ----------|
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling Compliance
|
|
||||||
|
|
||||||
The Minimal UI properly handles all Bot Core error scenarios:
|
|
||||||
|
|
||||||
### Connection Errors
|
|
||||||
- ✅ WebSocket disconnection with automatic reconnection
|
|
||||||
- ✅ Maximum retry attempts (10 attempts)
|
|
||||||
- ✅ Exponential backoff (1s to 10s)
|
|
||||||
- ✅ User notification of connection status
|
|
||||||
|
|
||||||
### API Errors
|
|
||||||
- ✅ HTTP error status handling
|
|
||||||
- ✅ Timeout handling
|
|
||||||
- ✅ Network failure recovery
|
|
||||||
- ✅ Graceful degradation
|
|
||||||
|
|
||||||
## Security Compliance
|
|
||||||
|
|
||||||
### CORS Headers
|
|
||||||
Bot Core provides appropriate CORS headers that Minimal UI expects:
|
|
||||||
- `Access-Control-Allow-Origin: *`
|
|
||||||
- `Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS`
|
|
||||||
- `Access-Control-Allow-Headers: Content-Type, Authorization`
|
|
||||||
|
|
||||||
### Authentication Flow
|
|
||||||
1. Minimal UI requests auth token from `/api/auth`
|
|
||||||
2. Bot Core generates and returns session credentials
|
|
||||||
3. UI includes credentials in WebSocket connection parameters
|
|
||||||
4. Bot Core validates credentials on connection
|
|
||||||
|
|
||||||
## Performance Compliance
|
|
||||||
|
|
||||||
### Resource Usage
|
|
||||||
| Metric | Bot Core Expectation | Minimal UI Usage | Status |
|
|
||||||
|--------|---------------------|------------------|---------|
|
|
||||||
| Initial Load | < 500KB | ~50KB | ✅ Excellent |
|
|
||||||
| WebSocket Payload | < 64KB | < 5KB avg | ✅ Excellent |
|
|
||||||
| Memory Usage | < 100MB | < 20MB | ✅ Excellent |
|
|
||||||
| CPU Usage | < 5% idle | < 1% idle | ✅ Excellent |
|
|
||||||
|
|
||||||
### Response Times
|
|
||||||
| Operation | Bot Core SLA | Minimal UI | Status |
|
|
||||||
|-----------|--------------|------------|---------|
|
|
||||||
| Initial Connect | < 1s | ~200ms | ✅ Excellent |
|
|
||||||
| Message Send | < 100ms | ~50ms | ✅ Excellent |
|
|
||||||
| Session Switch | < 500ms | ~300ms | ✅ Excellent |
|
|
||||||
| Voice Start | < 2s | ~1.5s | ✅ Excellent |
|
|
||||||
|
|
||||||
## Browser Compatibility
|
|
||||||
|
|
||||||
The Minimal UI is compatible with Bot Core across all modern browsers:
|
|
||||||
|
|
||||||
| Browser | Minimum Version | WebSocket | Voice | Status |
|
|
||||||
|---------|----------------|-----------|-------|---------|
|
|
||||||
| Chrome | 90+ | ✅ | ✅ | Fully Supported |
|
|
||||||
| Firefox | 88+ | ✅ | ✅ | Fully Supported |
|
|
||||||
| Safari | 14+ | ✅ | ✅ | Fully Supported |
|
|
||||||
| Edge | 90+ | ✅ | ✅ | Fully Supported |
|
|
||||||
| Mobile Chrome | 90+ | ✅ | ✅ | Fully Supported |
|
|
||||||
| Mobile Safari | 14+ | ✅ | ✅ | Fully Supported |
|
|
||||||
|
|
||||||
## Known Limitations
|
|
||||||
|
|
||||||
### Current Limitations
|
|
||||||
1. **File Upload**: Not implemented in Minimal UI (available in Suite UI)
|
|
||||||
2. **Rich Media**: Limited to images and links (full support in Suite UI)
|
|
||||||
3. **Multi-modal**: Text and voice only (video in Suite UI)
|
|
||||||
4. **Collaborative**: Single user sessions (multi-user in Suite UI)
|
|
||||||
|
|
||||||
### Planned Enhancements
|
|
||||||
1. **Progressive Web App**: Add service worker for offline support
|
|
||||||
2. **File Attachments**: Implement drag-and-drop file upload
|
|
||||||
3. **Rich Formatting**: Add toolbar for text formatting
|
|
||||||
4. **Keyboard Shortcuts**: Implement power user shortcuts
|
|
||||||
|
|
||||||
## Testing Checklist
|
|
||||||
|
|
||||||
### Manual Testing
|
|
||||||
- [ ] Load minimal UI at `http://localhost:8080`
|
|
||||||
- [ ] Verify WebSocket connection establishes
|
|
||||||
- [ ] Send text message and receive response
|
|
||||||
- [ ] Test voice input (if microphone available)
|
|
||||||
- [ ] Create new session
|
|
||||||
- [ ] Switch between sessions
|
|
||||||
- [ ] Test reconnection (kill and restart server)
|
|
||||||
- [ ] Verify markdown rendering
|
|
||||||
- [ ] Test suggestion buttons
|
|
||||||
- [ ] Check responsive design on mobile
|
|
||||||
|
|
||||||
### Automated Testing
|
|
||||||
```bash
|
|
||||||
# Run API compliance tests
|
|
||||||
cargo test --test minimal_ui_compliance
|
|
||||||
|
|
||||||
# Run WebSocket tests
|
|
||||||
cargo test --test websocket_protocol
|
|
||||||
|
|
||||||
# Run performance tests
|
|
||||||
cargo bench --bench minimal_ui_performance
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
### Common Issues and Solutions
|
|
||||||
|
|
||||||
1. **WebSocket Connection Fails**
|
|
||||||
- Check if server is running on port 8080
|
|
||||||
- Verify no CORS blocking in browser console
|
|
||||||
- Check WebSocket URL format in `getWebSocketUrl()`
|
|
||||||
|
|
||||||
2. **Session Not Persisting**
|
|
||||||
- Verify session_id is being stored
|
|
||||||
- Check localStorage is not disabled
|
|
||||||
- Ensure cookies are enabled
|
|
||||||
|
|
||||||
3. **Voice Not Working**
|
|
||||||
- Check microphone permissions
|
|
||||||
- Verify HTTPS or localhost (required for getUserMedia)
|
|
||||||
- Check LiveKit server connection
|
|
||||||
|
|
||||||
4. **Messages Not Displaying**
|
|
||||||
- Verify markdown parser is loaded
|
|
||||||
- Check message format matches expected structure
|
|
||||||
- Inspect browser console for JavaScript errors
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The Minimal UI is **fully compliant** with the Bot Core API. All critical features are implemented and working correctly. The interface provides a lightweight, fast, and responsive experience while maintaining complete compatibility with the backend services.
|
|
||||||
|
|
||||||
### Compliance Score: 98/100
|
|
||||||
|
|
||||||
Points deducted for:
|
|
||||||
- Missing file upload capability (-1)
|
|
||||||
- Limited rich media support (-1)
|
|
||||||
|
|
||||||
These are intentional design decisions to keep the Minimal UI lightweight. Full feature support is available in the Suite UI at `/suite`.
|
|
||||||
|
|
@ -1,860 +0,0 @@
|
||||||
# General Bots - New Keywords Reference
|
|
||||||
|
|
||||||
> Complete reference for all new BASIC keywords implemented for General Bots Office Suite
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
1. [Social Media Keywords](#social-media-keywords)
|
|
||||||
2. [Form Handling & Webhooks](#form-handling--webhooks)
|
|
||||||
3. [Template Messaging](#template-messaging)
|
|
||||||
4. [Lead Scoring & CRM](#lead-scoring--crm)
|
|
||||||
5. [Math Functions](#math-functions)
|
|
||||||
6. [Date/Time Functions](#datetime-functions)
|
|
||||||
7. [String Functions](#string-functions)
|
|
||||||
8. [Validation Functions](#validation-functions)
|
|
||||||
9. [Array Functions](#array-functions)
|
|
||||||
10. [Error Handling](#error-handling)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Social Media Keywords
|
|
||||||
|
|
||||||
### POST TO
|
|
||||||
|
|
||||||
Post content to social media platforms.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Post to single platform
|
|
||||||
POST TO INSTAGRAM image, "Check out our new feature! #AI #Automation"
|
|
||||||
|
|
||||||
' Post to specific platforms
|
|
||||||
POST TO FACEBOOK image, caption
|
|
||||||
POST TO LINKEDIN image, caption
|
|
||||||
POST TO TWITTER image, caption
|
|
||||||
|
|
||||||
' Post to multiple platforms at once
|
|
||||||
POST TO "instagram,facebook,linkedin" image, caption
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST TO ... AT (Scheduled Posting)
|
|
||||||
|
|
||||||
Schedule posts for future publishing.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Schedule a post
|
|
||||||
POST TO INSTAGRAM AT "2025-02-01 10:00" image, caption
|
|
||||||
POST TO FACEBOOK AT "2025-02-15 09:00" image, "Coming soon!"
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET METRICS
|
|
||||||
|
|
||||||
Retrieve engagement metrics for posts.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Get Instagram metrics
|
|
||||||
metrics = GET INSTAGRAM METRICS "post-id"
|
|
||||||
TALK "Likes: " + metrics.likes + ", Comments: " + metrics.comments
|
|
||||||
|
|
||||||
' Get Facebook metrics
|
|
||||||
fb_metrics = GET FACEBOOK METRICS "post-id"
|
|
||||||
TALK "Shares: " + fb_metrics.shares
|
|
||||||
|
|
||||||
' Get LinkedIn metrics
|
|
||||||
li_metrics = GET LINKEDIN METRICS "post-id"
|
|
||||||
|
|
||||||
' Get Twitter metrics
|
|
||||||
tw_metrics = GET TWITTER METRICS "post-id"
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET POSTS
|
|
||||||
|
|
||||||
List posts from a platform.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Get all Instagram posts
|
|
||||||
posts = GET INSTAGRAM POSTS
|
|
||||||
|
|
||||||
' Get Facebook posts
|
|
||||||
fb_posts = GET FACEBOOK POSTS
|
|
||||||
```
|
|
||||||
|
|
||||||
### DELETE POST
|
|
||||||
|
|
||||||
Remove a scheduled or published post.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
DELETE POST "post-id"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Form Handling & Webhooks
|
|
||||||
|
|
||||||
### ON FORM SUBMIT
|
|
||||||
|
|
||||||
Register webhook handlers for form submissions from landing pages.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Basic form handler
|
|
||||||
ON FORM SUBMIT "landing-page-form"
|
|
||||||
' Access form fields
|
|
||||||
name = fields.name
|
|
||||||
email = fields.email
|
|
||||||
phone = fields.phone
|
|
||||||
|
|
||||||
' Access metadata
|
|
||||||
source = metadata.utm_source
|
|
||||||
referrer = metadata.referrer
|
|
||||||
|
|
||||||
' Process the submission
|
|
||||||
SAVE "leads.csv", name, email, phone, source
|
|
||||||
SEND MAIL email, "Welcome!", "Thank you for your interest..."
|
|
||||||
END ON
|
|
||||||
|
|
||||||
' Form handler with validation
|
|
||||||
ON FORM SUBMIT "contact-form" WITH VALIDATION
|
|
||||||
' Validation is automatically applied
|
|
||||||
' Required fields, email format, phone format checked
|
|
||||||
END ON
|
|
||||||
```
|
|
||||||
|
|
||||||
### WEBHOOK
|
|
||||||
|
|
||||||
Create custom webhook endpoints.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Register a webhook endpoint
|
|
||||||
WEBHOOK "order-received"
|
|
||||||
|
|
||||||
' The webhook will be available at:
|
|
||||||
' https://your-server/bot-name/webhook/order-received
|
|
||||||
```
|
|
||||||
|
|
||||||
### SET SCHEDULE
|
|
||||||
|
|
||||||
Schedule scripts to run at specific times.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Run daily at 9 AM
|
|
||||||
SET SCHEDULE "0 9 * * *", "daily-report.bas"
|
|
||||||
|
|
||||||
' Run every Monday at 10 AM
|
|
||||||
SET SCHEDULE "0 10 * * 1", "weekly-summary.bas"
|
|
||||||
|
|
||||||
' Run on specific date
|
|
||||||
SET SCHEDULE DATEADD(TODAY(), 3, "day"), "followup.bas"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Template Messaging
|
|
||||||
|
|
||||||
### SEND TEMPLATE
|
|
||||||
|
|
||||||
Send templated messages across multiple channels.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Send email template
|
|
||||||
SEND TEMPLATE "welcome", "email", "user@example.com", #{name: "John", product: "Pro Plan"}
|
|
||||||
|
|
||||||
' Send WhatsApp template
|
|
||||||
SEND TEMPLATE "order-confirmation", "whatsapp", "+1234567890", #{order_id: "12345"}
|
|
||||||
|
|
||||||
' Send SMS template
|
|
||||||
SEND TEMPLATE "verification", "sms", "+1234567890", #{code: "123456"}
|
|
||||||
|
|
||||||
' Send to multiple channels at once
|
|
||||||
SEND TEMPLATE "announcement", "email,whatsapp", recipient, variables
|
|
||||||
|
|
||||||
' Simplified syntax without variables
|
|
||||||
SEND TEMPLATE "reminder", "email", "user@example.com"
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEND TEMPLATE TO (Bulk)
|
|
||||||
|
|
||||||
Send templates to multiple recipients.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Bulk email send
|
|
||||||
recipients = ["a@example.com", "b@example.com", "c@example.com"]
|
|
||||||
count = SEND TEMPLATE "newsletter" TO "email" recipients, #{month: "January"}
|
|
||||||
TALK "Sent to " + count + " recipients"
|
|
||||||
```
|
|
||||||
|
|
||||||
### CREATE TEMPLATE
|
|
||||||
|
|
||||||
Create new message templates.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Create email template
|
|
||||||
CREATE TEMPLATE "welcome", "email", "Welcome to {{company}}!", "Hello {{name}}, thank you for joining us!"
|
|
||||||
|
|
||||||
' Create WhatsApp template
|
|
||||||
CREATE TEMPLATE "order-update", "whatsapp", "", "Your order {{order_id}} is {{status}}."
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET TEMPLATE
|
|
||||||
|
|
||||||
Retrieve a template.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
template = GET TEMPLATE "welcome"
|
|
||||||
TALK "Template body: " + template.body
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Lead Scoring & CRM
|
|
||||||
|
|
||||||
### SCORE LEAD
|
|
||||||
|
|
||||||
Calculate lead score based on profile and behavior data.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Score a lead
|
|
||||||
lead_data = NEW OBJECT
|
|
||||||
lead_data.email = "john@company.com"
|
|
||||||
lead_data.name = "John Smith"
|
|
||||||
lead_data.company = "Acme Corp"
|
|
||||||
lead_data.job_title = "VP of Engineering"
|
|
||||||
lead_data.industry = "Technology"
|
|
||||||
lead_data.company_size = "Enterprise"
|
|
||||||
|
|
||||||
score = SCORE LEAD lead_data
|
|
||||||
|
|
||||||
TALK "Score: " + score.score
|
|
||||||
TALK "Grade: " + score.grade
|
|
||||||
TALK "Status: " + score.status
|
|
||||||
TALK "Recommendations: " + score.recommendations[0]
|
|
||||||
```
|
|
||||||
|
|
||||||
### AI SCORE LEAD
|
|
||||||
|
|
||||||
Use AI/LLM-enhanced scoring for better accuracy.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' AI-enhanced scoring
|
|
||||||
score = AI SCORE LEAD lead_data
|
|
||||||
|
|
||||||
TALK "AI Score: " + score.score
|
|
||||||
TALK "AI Confidence: " + score.breakdown.ai_confidence
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET LEAD SCORE
|
|
||||||
|
|
||||||
Retrieve existing lead score.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Get stored score
|
|
||||||
score = GET LEAD SCORE "lead-id"
|
|
||||||
TALK "Current score: " + score.score
|
|
||||||
```
|
|
||||||
|
|
||||||
### QUALIFY LEAD
|
|
||||||
|
|
||||||
Check if lead meets qualification threshold.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Default threshold (70)
|
|
||||||
result = QUALIFY LEAD "lead-id"
|
|
||||||
IF result.qualified THEN
|
|
||||||
TALK "Lead is qualified: " + result.status
|
|
||||||
END IF
|
|
||||||
|
|
||||||
' Custom threshold
|
|
||||||
result = QUALIFY LEAD "lead-id", 80
|
|
||||||
IF result.qualified THEN
|
|
||||||
TALK "Lead meets 80+ threshold"
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
### UPDATE LEAD SCORE
|
|
||||||
|
|
||||||
Manually adjust a lead's score.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Add points for engagement
|
|
||||||
new_score = UPDATE LEAD SCORE "lead-id", 10, "Attended webinar"
|
|
||||||
|
|
||||||
' Deduct points for inactivity
|
|
||||||
new_score = UPDATE LEAD SCORE "lead-id", -5, "No response to email"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Math Functions
|
|
||||||
|
|
||||||
### Basic Math
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Absolute value
|
|
||||||
result = ABS(-42) ' Returns 42
|
|
||||||
|
|
||||||
' Rounding
|
|
||||||
result = ROUND(3.7) ' Returns 4
|
|
||||||
result = ROUND(3.14159, 2) ' Returns 3.14
|
|
||||||
|
|
||||||
' Integer conversion
|
|
||||||
result = INT(3.9) ' Returns 3
|
|
||||||
result = FIX(-3.9) ' Returns -3
|
|
||||||
result = FLOOR(3.7) ' Returns 3
|
|
||||||
result = CEIL(3.2) ' Returns 4
|
|
||||||
```
|
|
||||||
|
|
||||||
### Min/Max
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Two values
|
|
||||||
result = MAX(10, 20) ' Returns 20
|
|
||||||
result = MIN(10, 20) ' Returns 10
|
|
||||||
|
|
||||||
' Array values
|
|
||||||
arr = [5, 2, 8, 1, 9]
|
|
||||||
result = MAX(arr) ' Returns 9
|
|
||||||
result = MIN(arr) ' Returns 1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other Math Functions
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Modulo
|
|
||||||
result = MOD(17, 5) ' Returns 2
|
|
||||||
|
|
||||||
' Random numbers
|
|
||||||
result = RANDOM() ' Random 0-1
|
|
||||||
result = RANDOM(100) ' Random 0-99
|
|
||||||
result = RANDOM(1, 10) ' Random 1-10
|
|
||||||
|
|
||||||
' Sign
|
|
||||||
result = SGN(-5) ' Returns -1
|
|
||||||
result = SGN(5) ' Returns 1
|
|
||||||
result = SGN(0) ' Returns 0
|
|
||||||
|
|
||||||
' Square root
|
|
||||||
result = SQR(16) ' Returns 4
|
|
||||||
result = SQRT(25) ' Returns 5
|
|
||||||
|
|
||||||
' Logarithms
|
|
||||||
result = LOG(10) ' Natural log
|
|
||||||
result = LOG10(100) ' Base 10 log
|
|
||||||
|
|
||||||
' Exponential
|
|
||||||
result = EXP(2) ' e^2
|
|
||||||
|
|
||||||
' Power
|
|
||||||
result = POW(2, 8) ' Returns 256
|
|
||||||
result = POWER(3, 4) ' Returns 81
|
|
||||||
|
|
||||||
' Trigonometry
|
|
||||||
result = SIN(0) ' Returns 0
|
|
||||||
result = COS(0) ' Returns 1
|
|
||||||
result = TAN(0) ' Returns 0
|
|
||||||
pi = PI() ' Returns 3.14159...
|
|
||||||
|
|
||||||
' Aggregation
|
|
||||||
arr = [10, 20, 30, 40, 50]
|
|
||||||
result = SUM(arr) ' Returns 150
|
|
||||||
result = AVG(arr) ' Returns 30
|
|
||||||
result = AVERAGE(arr) ' Returns 30
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Date/Time Functions
|
|
||||||
|
|
||||||
### Current Date/Time
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Current date and time
|
|
||||||
now = NOW() ' "2025-01-22 14:30:45"
|
|
||||||
now_utc = NOW_UTC() ' UTC time
|
|
||||||
|
|
||||||
' Current date only
|
|
||||||
today = TODAY() ' "2025-01-22"
|
|
||||||
|
|
||||||
' Current time only
|
|
||||||
time = TIME() ' "14:30:45"
|
|
||||||
|
|
||||||
' Unix timestamp
|
|
||||||
ts = TIMESTAMP() ' 1737556245
|
|
||||||
```
|
|
||||||
|
|
||||||
### Date Components
|
|
||||||
|
|
||||||
```basic
|
|
||||||
date = "2025-01-22"
|
|
||||||
|
|
||||||
year = YEAR(date) ' Returns 2025
|
|
||||||
month = MONTH(date) ' Returns 1
|
|
||||||
day = DAY(date) ' Returns 22
|
|
||||||
weekday = WEEKDAY(date) ' Returns 4 (Wednesday)
|
|
||||||
week = WEEKNUM(date) ' Returns 4
|
|
||||||
|
|
||||||
datetime = "2025-01-22 14:30:45"
|
|
||||||
hour = HOUR(datetime) ' Returns 14
|
|
||||||
minute = MINUTE(datetime) ' Returns 30
|
|
||||||
second = SECOND(datetime) ' Returns 45
|
|
||||||
```
|
|
||||||
|
|
||||||
### Date Arithmetic
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Add to date
|
|
||||||
future = DATEADD("2025-01-22", 7, "day") ' "2025-01-29"
|
|
||||||
future = DATEADD("2025-01-22", 1, "month") ' "2025-02-22"
|
|
||||||
future = DATEADD("2025-01-22", 1, "year") ' "2026-01-22"
|
|
||||||
future = DATEADD("2025-01-22 10:00", 2, "hour") ' "2025-01-22 12:00:00"
|
|
||||||
|
|
||||||
' Subtract from date (negative values)
|
|
||||||
past = DATEADD("2025-01-22", -7, "day") ' "2025-01-15"
|
|
||||||
|
|
||||||
' Date difference
|
|
||||||
days = DATEDIFF("2025-01-01", "2025-01-22", "day") ' 21
|
|
||||||
months = DATEDIFF("2025-01-01", "2025-06-01", "month") ' 5
|
|
||||||
years = DATEDIFF("2020-01-01", "2025-01-01", "year") ' 5
|
|
||||||
```
|
|
||||||
|
|
||||||
### Date Formatting
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Format date
|
|
||||||
formatted = FORMAT_DATE("2025-01-22", "DD/MM/YYYY") ' "22/01/2025"
|
|
||||||
formatted = FORMAT_DATE("2025-01-22", "MMMM DD, YYYY") ' "January 22, 2025"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Date Validation
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Check if valid date
|
|
||||||
valid = ISDATE("2025-01-22") ' true
|
|
||||||
valid = ISDATE("invalid") ' false
|
|
||||||
```
|
|
||||||
|
|
||||||
### End of Month
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Get last day of month
|
|
||||||
eom = EOMONTH("2025-01-15", 0) ' "2025-01-31"
|
|
||||||
eom = EOMONTH("2025-01-15", 1) ' "2025-02-28"
|
|
||||||
eom = EOMONTH("2025-01-15", -1) ' "2024-12-31"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## String Functions
|
|
||||||
|
|
||||||
### Length and Substrings
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' String length
|
|
||||||
length = LEN("Hello World") ' Returns 11
|
|
||||||
|
|
||||||
' Left portion
|
|
||||||
result = LEFT("Hello World", 5) ' Returns "Hello"
|
|
||||||
|
|
||||||
' Right portion
|
|
||||||
result = RIGHT("Hello World", 5) ' Returns "World"
|
|
||||||
|
|
||||||
' Middle portion
|
|
||||||
result = MID("Hello World", 7) ' Returns "World"
|
|
||||||
result = MID("Hello World", 7, 3) ' Returns "Wor"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Case Conversion
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Uppercase
|
|
||||||
result = UCASE("hello") ' Returns "HELLO"
|
|
||||||
result = UPPER("hello") ' Returns "HELLO"
|
|
||||||
|
|
||||||
' Lowercase
|
|
||||||
result = LCASE("HELLO") ' Returns "hello"
|
|
||||||
result = LOWER("HELLO") ' Returns "hello"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Trimming
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Trim whitespace
|
|
||||||
result = TRIM(" hello ") ' Returns "hello"
|
|
||||||
result = LTRIM(" hello") ' Returns "hello"
|
|
||||||
result = RTRIM("hello ") ' Returns "hello"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Search and Replace
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Find position (1-based)
|
|
||||||
pos = INSTR("Hello World", "World") ' Returns 7
|
|
||||||
pos = INSTR(5, "one two one", "one") ' Returns 9 (starting from position 5)
|
|
||||||
|
|
||||||
' Replace
|
|
||||||
result = REPLACE("Hello World", "World", "Universe") ' Returns "Hello Universe"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Split and Join
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Split string to array
|
|
||||||
parts = SPLIT("a,b,c,d", ",") ' Returns ["a", "b", "c", "d"]
|
|
||||||
|
|
||||||
' Join array to string
|
|
||||||
arr = ["a", "b", "c"]
|
|
||||||
result = JOIN(arr, "-") ' Returns "a-b-c"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Validation Functions
|
|
||||||
|
|
||||||
### Type Conversion
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' String to number
|
|
||||||
num = VAL("42") ' Returns 42.0
|
|
||||||
num = VAL("3.14") ' Returns 3.14
|
|
||||||
num = CINT("42.7") ' Returns 43 (rounded integer)
|
|
||||||
num = CDBL("3.14") ' Returns 3.14
|
|
||||||
|
|
||||||
' Number to string
|
|
||||||
str = STR(42) ' Returns "42"
|
|
||||||
str = CSTR(3.14) ' Returns "3.14"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Null/Empty Checks
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Check for null
|
|
||||||
result = ISNULL(value) ' true if null/unit
|
|
||||||
|
|
||||||
' Check for empty
|
|
||||||
result = ISEMPTY("") ' true
|
|
||||||
result = ISEMPTY([]) ' true (empty array)
|
|
||||||
result = ISEMPTY(#{}) ' true (empty map)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Checks
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Check types
|
|
||||||
result = ISSTRING("hello") ' true
|
|
||||||
result = ISNUMBER(42) ' true
|
|
||||||
result = ISNUMBER(3.14) ' true
|
|
||||||
result = ISBOOL(true) ' true
|
|
||||||
result = ISARRAY([1, 2, 3]) ' true
|
|
||||||
result = ISOBJECT(#{a: 1}) ' true
|
|
||||||
result = IS_NUMERIC("42") ' true
|
|
||||||
result = IS_DATE("2025-01-22") ' true
|
|
||||||
|
|
||||||
' Get type name
|
|
||||||
type = TYPEOF(value) ' Returns type name as string
|
|
||||||
```
|
|
||||||
|
|
||||||
### Coalesce/Default Values
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Return first non-null value
|
|
||||||
result = NVL(null_value, "default") ' Returns "default"
|
|
||||||
result = COALESCE(null_value, "default") ' Same as NVL
|
|
||||||
```
|
|
||||||
|
|
||||||
### Conditional
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Inline if
|
|
||||||
result = IIF(score >= 70, "Pass", "Fail")
|
|
||||||
|
|
||||||
' Choose from list (1-based index)
|
|
||||||
result = CHOOSE(2, ["A", "B", "C"]) ' Returns "B"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Array Functions
|
|
||||||
|
|
||||||
### Creating Arrays
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Create array
|
|
||||||
arr = ARRAY(1, 2, 3, 4, 5)
|
|
||||||
|
|
||||||
' Create range
|
|
||||||
arr = RANGE(1, 10) ' [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
||||||
arr = RANGE(0, 10, 2) ' [0, 2, 4, 6, 8, 10]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array Info
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Array bounds
|
|
||||||
arr = [10, 20, 30, 40, 50]
|
|
||||||
upper = UBOUND(arr) ' Returns 4 (last index)
|
|
||||||
lower = LBOUND(arr) ' Returns 0 (first index)
|
|
||||||
count = COUNT(arr) ' Returns 5 (length)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Searching
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Check if contains
|
|
||||||
result = CONTAINS(arr, 30) ' true
|
|
||||||
result = IN_ARRAY(30, arr) ' true (alternate syntax)
|
|
||||||
|
|
||||||
' Find index
|
|
||||||
index = INDEX_OF(arr, 30) ' Returns 2 (-1 if not found)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sorting
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Sort ascending
|
|
||||||
sorted = SORT(arr)
|
|
||||||
|
|
||||||
' Sort descending
|
|
||||||
sorted = SORT_DESC(arr)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Uniqueness
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Remove duplicates
|
|
||||||
arr = [1, 2, 2, 3, 3, 3]
|
|
||||||
unique = UNIQUE(arr) ' [1, 2, 3]
|
|
||||||
unique = DISTINCT(arr) ' Same as UNIQUE
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manipulation
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Add to end
|
|
||||||
arr = PUSH(arr, 60)
|
|
||||||
|
|
||||||
' Remove from end
|
|
||||||
last = POP(arr)
|
|
||||||
|
|
||||||
' Add to beginning
|
|
||||||
arr = UNSHIFT(arr, 0)
|
|
||||||
|
|
||||||
' Remove from beginning
|
|
||||||
first = SHIFT(arr)
|
|
||||||
|
|
||||||
' Reverse
|
|
||||||
reversed = REVERSE(arr)
|
|
||||||
|
|
||||||
' Get slice
|
|
||||||
part = SLICE(arr, 1) ' From index 1 to end
|
|
||||||
part = SLICE(arr, 1, 3) ' From index 1 to 3 (exclusive)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Combining
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Concatenate arrays
|
|
||||||
combined = CONCAT(arr1, arr2)
|
|
||||||
|
|
||||||
' Flatten nested arrays
|
|
||||||
nested = [[1, 2], [3, 4], [5]]
|
|
||||||
flat = FLATTEN(nested) ' [1, 2, 3, 4, 5]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Element Access
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' First and last elements
|
|
||||||
first = FIRST_ELEM(arr)
|
|
||||||
last = LAST_ELEM(arr)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
### Throwing Errors
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Throw an error
|
|
||||||
THROW "Something went wrong"
|
|
||||||
|
|
||||||
' Raise (alias for THROW)
|
|
||||||
RAISE "Invalid input"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error Objects
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Create error object (for inspection)
|
|
||||||
err = ERROR("Validation failed")
|
|
||||||
' err.error = true
|
|
||||||
' err.message = "Validation failed"
|
|
||||||
' err.timestamp = "2025-01-22 14:30:45"
|
|
||||||
|
|
||||||
' Check if value is error
|
|
||||||
IF IS_ERROR(result) THEN
|
|
||||||
msg = GET_ERROR_MESSAGE(result)
|
|
||||||
TALK "Error occurred: " + msg
|
|
||||||
END IF
|
|
||||||
```
|
|
||||||
|
|
||||||
### Assertions
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Assert condition
|
|
||||||
ASSERT score >= 0, "Score cannot be negative"
|
|
||||||
ASSERT NOT ISEMPTY(name), "Name is required"
|
|
||||||
|
|
||||||
' If assertion fails, throws error with message
|
|
||||||
```
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Log messages at different levels
|
|
||||||
LOG_ERROR "Critical failure in processing"
|
|
||||||
LOG_WARN "Unusual condition detected"
|
|
||||||
LOG_INFO "Processing completed"
|
|
||||||
LOG_DEBUG "Variable value: " + STR(x)
|
|
||||||
```
|
|
||||||
|
|
||||||
### TRY/CATCH Pattern
|
|
||||||
|
|
||||||
While Rhai doesn't support traditional TRY...CATCH, use this pattern:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Using error checking pattern
|
|
||||||
result = potentially_failing_operation()
|
|
||||||
|
|
||||||
IF IS_ERROR(result) THEN
|
|
||||||
LOG_ERROR GET_ERROR_MESSAGE(result)
|
|
||||||
result = TRY_RESULT(false, (), "Operation failed")
|
|
||||||
ELSE
|
|
||||||
result = TRY_RESULT(true, result, "")
|
|
||||||
END IF
|
|
||||||
|
|
||||||
' result.success = true/false
|
|
||||||
' result.value = the actual value if successful
|
|
||||||
' result.error = error message if failed
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Campaign Examples
|
|
||||||
|
|
||||||
### Welcome Campaign
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Start welcome campaign for new lead
|
|
||||||
lead_email = "newuser@example.com"
|
|
||||||
lead_name = "John"
|
|
||||||
|
|
||||||
' Send immediate welcome
|
|
||||||
vars = #{name: lead_name, company: "Acme"}
|
|
||||||
SEND TEMPLATE "welcome-email-1", "email", lead_email, vars
|
|
||||||
|
|
||||||
' Schedule follow-ups
|
|
||||||
SET SCHEDULE DATEADD(TODAY(), 2, "day"), "send-welcome-2.bas"
|
|
||||||
SET SCHEDULE DATEADD(TODAY(), 5, "day"), "send-welcome-3.bas"
|
|
||||||
SET SCHEDULE DATEADD(TODAY(), 14, "day"), "send-welcome-final.bas"
|
|
||||||
|
|
||||||
' Score the lead
|
|
||||||
score = SCORE LEAD #{email: lead_email, name: lead_name}
|
|
||||||
TALK "Welcome campaign started. Initial score: " + score.score
|
|
||||||
```
|
|
||||||
|
|
||||||
### Social Media Campaign
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Product launch social media campaign
|
|
||||||
product_name = "AI Assistant Pro"
|
|
||||||
launch_date = "2025-02-15"
|
|
||||||
|
|
||||||
' Generate image
|
|
||||||
product_image = IMAGE "Product launch graphic for " + product_name
|
|
||||||
|
|
||||||
' Schedule posts across platforms
|
|
||||||
hashtags = "#AI #Automation #NewProduct"
|
|
||||||
|
|
||||||
' Day -7: Teaser
|
|
||||||
POST TO "instagram,facebook,linkedin" AT DATEADD(launch_date, -7, "day") + " 10:00" product_image, "Something big is coming... 🔥 " + hashtags
|
|
||||||
|
|
||||||
' Day -3: Feature preview
|
|
||||||
POST TO "instagram,twitter" AT DATEADD(launch_date, -3, "day") + " 10:00" product_image, "Sneak peek! " + hashtags
|
|
||||||
|
|
||||||
' Launch day
|
|
||||||
POST TO "instagram,facebook,twitter,linkedin" AT launch_date + " 09:00" product_image, "🚀 IT'S HERE! " + product_name + " is now LIVE! " + hashtags
|
|
||||||
|
|
||||||
TALK "Social media campaign scheduled with " + 6 + " posts"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lead Nurturing with AI Scoring
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Process form submission
|
|
||||||
ON FORM SUBMIT "landing-page"
|
|
||||||
' Extract data
|
|
||||||
lead = #{
|
|
||||||
email: fields.email,
|
|
||||||
name: fields.name,
|
|
||||||
company: fields.company,
|
|
||||||
job_title: fields.title,
|
|
||||||
industry: fields.industry
|
|
||||||
}
|
|
||||||
|
|
||||||
' AI-powered scoring
|
|
||||||
score = AI SCORE LEAD lead
|
|
||||||
|
|
||||||
' Route based on score
|
|
||||||
IF score.score >= 85 THEN
|
|
||||||
' Hot lead - immediate action
|
|
||||||
CREATE TASK "Contact hot lead: " + lead.email, "sales", "high"
|
|
||||||
SEND TEMPLATE "hot-lead-welcome", "email,sms", lead.email, lead
|
|
||||||
ELSE IF score.score >= 70 THEN
|
|
||||||
' Warm lead - accelerated nurture
|
|
||||||
SEND TEMPLATE "warm-welcome", "email", lead.email, lead
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 3, "day"), "warm-nurture-2.bas"
|
|
||||||
ELSE
|
|
||||||
' Cold lead - standard drip
|
|
||||||
SEND TEMPLATE "cold-welcome", "email", lead.email, lead
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 7, "day"), "cold-nurture-2.bas"
|
|
||||||
END IF
|
|
||||||
|
|
||||||
' Save to CRM
|
|
||||||
SAVE "leads", lead.email, lead.name, score.score, score.grade, NOW()
|
|
||||||
END ON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Social Media Credentials
|
|
||||||
|
|
||||||
Store in `bot_settings` table:
|
|
||||||
- `instagram_credentials`: `{access_token, user_id}`
|
|
||||||
- `facebook_credentials`: `{access_token, page_id}`
|
|
||||||
- `linkedin_credentials`: `{access_token, person_urn}`
|
|
||||||
- `twitter_credentials`: `{bearer_token}`
|
|
||||||
|
|
||||||
### Lead Scoring Weights
|
|
||||||
|
|
||||||
Default weights (customizable per bot):
|
|
||||||
|
|
||||||
| Factor | Default Weight |
|
|
||||||
|--------|---------------|
|
|
||||||
| Company Size | 10 |
|
|
||||||
| Industry Match | 15 |
|
|
||||||
| Job Title | 15 |
|
|
||||||
| Location | 5 |
|
|
||||||
| Email Opens | 5 |
|
|
||||||
| Email Clicks | 10 |
|
|
||||||
| Page Visits | 5 |
|
|
||||||
| Form Submissions | 15 |
|
|
||||||
| Content Downloads | 10 |
|
|
||||||
| Pricing Page Visits | 20 |
|
|
||||||
| Demo Requests | 25 |
|
|
||||||
| Trial Signups | 30 |
|
|
||||||
| Inactivity Penalty | -15 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Last updated: January 2025*
|
|
||||||
*General Bots v5.0*
|
|
||||||
|
|
@ -1,264 +0,0 @@
|
||||||
# Quick Start Guide
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Rust 1.75+ and Cargo
|
|
||||||
- PostgreSQL 14+ (or Docker)
|
|
||||||
- Optional: MinIO for S3-compatible storage
|
|
||||||
- Optional: Redis/Valkey for caching
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### 1. Clone the Repository
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/GeneralBots/BotServer.git
|
|
||||||
cd BotServer
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Build the Project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build with default features (includes console UI)
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Build with all features
|
|
||||||
cargo build --all-features
|
|
||||||
|
|
||||||
# Build for release
|
|
||||||
cargo build --release
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running BotServer
|
|
||||||
|
|
||||||
### Default Mode (with Console UI)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run with console UI showing real-time status, logs, and file browser
|
|
||||||
cargo run
|
|
||||||
|
|
||||||
# The console UI provides:
|
|
||||||
# - System metrics (CPU, Memory, GPU if available)
|
|
||||||
# - Service status monitoring
|
|
||||||
# - Real-time logs
|
|
||||||
# - File browser for drive storage
|
|
||||||
# - Database status
|
|
||||||
```
|
|
||||||
|
|
||||||
### Background Service Mode
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run without console UI (background service)
|
|
||||||
cargo run -- --noconsole
|
|
||||||
|
|
||||||
# Run without any UI
|
|
||||||
cargo run -- --noui
|
|
||||||
```
|
|
||||||
|
|
||||||
### Desktop Mode
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run with Tauri desktop application
|
|
||||||
cargo run -- --desktop
|
|
||||||
```
|
|
||||||
|
|
||||||
### Advanced Options
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Specify a tenant
|
|
||||||
cargo run -- --tenant my-organization
|
|
||||||
|
|
||||||
# Container deployment mode
|
|
||||||
cargo run -- --container
|
|
||||||
|
|
||||||
# Combine options
|
|
||||||
cargo run -- --noconsole --tenant production
|
|
||||||
```
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
When you run BotServer for the first time, it will:
|
|
||||||
|
|
||||||
1. **Automatically start required services:**
|
|
||||||
- PostgreSQL database (if not running)
|
|
||||||
- MinIO S3-compatible storage (if configured)
|
|
||||||
- Redis cache (if configured)
|
|
||||||
|
|
||||||
2. **Run database migrations automatically:**
|
|
||||||
- Creates all required tables and indexes
|
|
||||||
- Sets up initial schema
|
|
||||||
|
|
||||||
3. **Bootstrap initial configuration:**
|
|
||||||
- Creates `.env` file with defaults
|
|
||||||
- Sets up bot templates
|
|
||||||
- Configures service endpoints
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
Copy the example environment file and customize:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
```
|
|
||||||
|
|
||||||
Key configuration options in `.env`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Database
|
|
||||||
DATABASE_URL=postgres://postgres:postgres@localhost:5432/botserver
|
|
||||||
|
|
||||||
# Server
|
|
||||||
SERVER_HOST=127.0.0.1
|
|
||||||
SERVER_PORT=8080
|
|
||||||
|
|
||||||
# Drive (MinIO)
|
|
||||||
DRIVE_SERVER=http://localhost:9000
|
|
||||||
DRIVE_ACCESSKEY=minioadmin
|
|
||||||
DRIVE_SECRET=minioadmin
|
|
||||||
|
|
||||||
# LLM Configuration
|
|
||||||
LLM_SERVER=http://localhost:8081
|
|
||||||
LLM_MODEL=llama2
|
|
||||||
|
|
||||||
# Logging (automatically configured)
|
|
||||||
# All external library traces are suppressed by default
|
|
||||||
# Use RUST_LOG=botserver=trace for detailed debugging
|
|
||||||
RUST_LOG=info
|
|
||||||
```
|
|
||||||
|
|
||||||
## Accessing the Application
|
|
||||||
|
|
||||||
### Web Interface
|
|
||||||
|
|
||||||
Once running, access the web interface at:
|
|
||||||
```
|
|
||||||
http://localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
### API Endpoints
|
|
||||||
|
|
||||||
- Health Check: `GET http://localhost:8080/api/health`
|
|
||||||
- Chat: `POST http://localhost:8080/api/chat`
|
|
||||||
- Tasks: `GET/POST http://localhost:8080/api/tasks`
|
|
||||||
- Drive: `GET http://localhost:8080/api/drive/files`
|
|
||||||
|
|
||||||
## Console UI Controls
|
|
||||||
|
|
||||||
When running with the console UI (default):
|
|
||||||
|
|
||||||
### Keyboard Shortcuts
|
|
||||||
|
|
||||||
- `Tab` - Switch between panels
|
|
||||||
- `↑/↓` - Navigate lists
|
|
||||||
- `Enter` - Select/Open
|
|
||||||
- `Esc` - Go back/Cancel
|
|
||||||
- `q` - Quit application
|
|
||||||
- `l` - View logs
|
|
||||||
- `f` - File browser
|
|
||||||
- `s` - System status
|
|
||||||
- `h` - Help
|
|
||||||
|
|
||||||
### Panels
|
|
||||||
|
|
||||||
1. **Status Panel** - System metrics and service health
|
|
||||||
2. **Logs Panel** - Real-time application logs
|
|
||||||
3. **File Browser** - Navigate drive storage
|
|
||||||
4. **Database Panel** - Connection status and stats
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Database Connection Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check if PostgreSQL is running
|
|
||||||
ps aux | grep postgres
|
|
||||||
|
|
||||||
# Start PostgreSQL manually if needed
|
|
||||||
sudo systemctl start postgresql
|
|
||||||
|
|
||||||
# Verify connection
|
|
||||||
psql -U postgres -h localhost
|
|
||||||
```
|
|
||||||
|
|
||||||
### Drive/MinIO Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check if MinIO is running
|
|
||||||
ps aux | grep minio
|
|
||||||
|
|
||||||
# Start MinIO manually
|
|
||||||
./botserver-stack/bin/drive/minio server ./botserver-stack/data/drive
|
|
||||||
```
|
|
||||||
|
|
||||||
### Console UI Not Showing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ensure console feature is compiled
|
|
||||||
cargo build --features console
|
|
||||||
|
|
||||||
# Check terminal compatibility
|
|
||||||
echo $TERM # Should be xterm-256color or similar
|
|
||||||
```
|
|
||||||
|
|
||||||
### High CPU/Memory Usage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run without console for lower resource usage
|
|
||||||
cargo run -- --noconsole
|
|
||||||
|
|
||||||
# Check running services
|
|
||||||
htop
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Running Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
cargo test
|
|
||||||
|
|
||||||
# Run with specific features
|
|
||||||
cargo test --features console
|
|
||||||
|
|
||||||
# Run integration tests
|
|
||||||
cargo test --test '*'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable Detailed Logging
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Trace level for botserver only
|
|
||||||
RUST_LOG=botserver=trace cargo run
|
|
||||||
|
|
||||||
# Debug level
|
|
||||||
RUST_LOG=botserver=debug cargo run
|
|
||||||
|
|
||||||
# Info level (default)
|
|
||||||
RUST_LOG=info cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building Documentation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build and open Rust documentation
|
|
||||||
cargo doc --open
|
|
||||||
|
|
||||||
# Build book documentation
|
|
||||||
cd docs && mdbook build
|
|
||||||
```
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. **Configure your first bot** - See [Bot Configuration Guide](./BOT_CONFIGURATION.md)
|
|
||||||
2. **Set up integrations** - See [Integration Guide](./05-INTEGRATION_STATUS.md)
|
|
||||||
3. **Deploy to production** - See [Deployment Guide](./DEPLOYMENT.md)
|
|
||||||
4. **Explore the API** - See [API Documentation](./API.md)
|
|
||||||
|
|
||||||
## Getting Help
|
|
||||||
|
|
||||||
- **Documentation**: [Complete Docs](./INDEX.md)
|
|
||||||
- **Issues**: [GitHub Issues](https://github.com/GeneralBots/BotServer/issues)
|
|
||||||
- **Community**: [Discussions](https://github.com/GeneralBots/BotServer/discussions)
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
||||||
# SET SCHEDULE Keyword Reference
|
|
||||||
|
|
||||||
> Documentation for scheduling scripts and automations in General Bots
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
SET SCHEDULE has two distinct usages:
|
|
||||||
|
|
||||||
1. **File-level scheduler**: When placed at the top of a `.bas` file, defines when the script runs automatically
|
|
||||||
2. **Runtime scheduling**: When used within code, schedules another script to run at a specific time
|
|
||||||
|
|
||||||
## Usage 1: File-Level Scheduler
|
|
||||||
|
|
||||||
When SET SCHEDULE appears at the top of a file (before any executable code), it registers the entire script to run on a cron schedule.
|
|
||||||
|
|
||||||
### Syntax
|
|
||||||
|
|
||||||
```basic
|
|
||||||
SET SCHEDULE "cron_expression"
|
|
||||||
|
|
||||||
' Rest of script follows
|
|
||||||
TALK "This runs on schedule"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Run every day at 9 AM
|
|
||||||
SET SCHEDULE "0 9 * * *"
|
|
||||||
|
|
||||||
TALK "Good morning! Running daily report..."
|
|
||||||
stats = AGGREGATE "sales", "SUM", "amount", "date = TODAY()"
|
|
||||||
SEND TEMPLATE "daily-report", "email", "team@company.com", #{total: stats}
|
|
||||||
```
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Run every Monday at 10 AM
|
|
||||||
SET SCHEDULE "0 10 * * 1"
|
|
||||||
|
|
||||||
TALK "Weekly summary starting..."
|
|
||||||
' Generate weekly report
|
|
||||||
```
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Run first day of every month at midnight
|
|
||||||
SET SCHEDULE "0 0 1 * *"
|
|
||||||
|
|
||||||
TALK "Monthly billing cycle..."
|
|
||||||
' Process monthly billing
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cron Expression Reference
|
|
||||||
|
|
||||||
```
|
|
||||||
┌───────────── minute (0-59)
|
|
||||||
│ ┌───────────── hour (0-23)
|
|
||||||
│ │ ┌───────────── day of month (1-31)
|
|
||||||
│ │ │ ┌───────────── month (1-12)
|
|
||||||
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
|
|
||||||
│ │ │ │ │
|
|
||||||
* * * * *
|
|
||||||
```
|
|
||||||
|
|
||||||
| Expression | Description |
|
|
||||||
|------------|-------------|
|
|
||||||
| `0 9 * * *` | Every day at 9:00 AM |
|
|
||||||
| `0 9 * * 1-5` | Weekdays at 9:00 AM |
|
|
||||||
| `0 */2 * * *` | Every 2 hours |
|
|
||||||
| `30 8 * * 1` | Mondays at 8:30 AM |
|
|
||||||
| `0 0 1 * *` | First of each month at midnight |
|
|
||||||
| `0 12 * * 0` | Sundays at noon |
|
|
||||||
| `*/15 * * * *` | Every 15 minutes |
|
|
||||||
| `0 9,17 * * *` | At 9 AM and 5 PM daily |
|
|
||||||
|
|
||||||
## Usage 2: Runtime Scheduling
|
|
||||||
|
|
||||||
When used within code (not at file top), schedules another script to run at a specified time.
|
|
||||||
|
|
||||||
### Syntax
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Schedule with cron + date
|
|
||||||
SET SCHEDULE "cron_expression" date, "script.bas"
|
|
||||||
|
|
||||||
' Schedule for specific date/time
|
|
||||||
SET SCHEDULE datetime, "script.bas"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Schedule script to run in 3 days at 9 AM
|
|
||||||
SET SCHEDULE "0 9 * * *" DATEADD(TODAY(), 3, "day"), "followup-email.bas"
|
|
||||||
```
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Schedule for specific datetime
|
|
||||||
SET SCHEDULE "2025-02-15 10:00", "product-launch.bas"
|
|
||||||
```
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Schedule relative to now
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 1, "hour"), "reminder.bas"
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 30, "minute"), "check-status.bas"
|
|
||||||
```
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Campaign scheduling example
|
|
||||||
ON FORM SUBMIT "signup"
|
|
||||||
' Welcome email immediately
|
|
||||||
SEND TEMPLATE "welcome", "email", fields.email, #{name: fields.name}
|
|
||||||
|
|
||||||
' Schedule follow-up sequence
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 2, "day"), "nurture-day-2.bas"
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 5, "day"), "nurture-day-5.bas"
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 14, "day"), "nurture-day-14.bas"
|
|
||||||
END ON
|
|
||||||
```
|
|
||||||
|
|
||||||
## Passing Data to Scheduled Scripts
|
|
||||||
|
|
||||||
Use SET BOT MEMORY to pass data to scheduled scripts:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' In the scheduling script
|
|
||||||
SET BOT MEMORY "scheduled_lead_" + lead_id, lead_email
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 7, "day"), "followup.bas"
|
|
||||||
|
|
||||||
' In followup.bas
|
|
||||||
PARAM lead_id AS string
|
|
||||||
lead_email = GET BOT MEMORY "scheduled_lead_" + lead_id
|
|
||||||
SEND TEMPLATE "followup", "email", lead_email, #{id: lead_id}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Campaign Drip Sequence Example
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' welcome-sequence.bas - File-level scheduler not used here
|
|
||||||
' This is triggered by form submission
|
|
||||||
|
|
||||||
PARAM email AS string
|
|
||||||
PARAM name AS string
|
|
||||||
|
|
||||||
DESCRIPTION "Start welcome email sequence"
|
|
||||||
|
|
||||||
' Day 0: Immediate welcome
|
|
||||||
WITH vars
|
|
||||||
.name = name
|
|
||||||
.date = TODAY()
|
|
||||||
END WITH
|
|
||||||
|
|
||||||
SEND TEMPLATE "welcome-1", "email", email, vars
|
|
||||||
|
|
||||||
' Store lead info for scheduled scripts
|
|
||||||
SET BOT MEMORY "welcome_" + email + "_name", name
|
|
||||||
|
|
||||||
' Schedule remaining emails
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 2, "day"), "welcome-day-2.bas"
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 5, "day"), "welcome-day-5.bas"
|
|
||||||
SET SCHEDULE DATEADD(NOW(), 7, "day"), "welcome-day-7.bas"
|
|
||||||
|
|
||||||
TALK "Welcome sequence started for " + email
|
|
||||||
```
|
|
||||||
|
|
||||||
## Daily Report Example
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' daily-sales-report.bas
|
|
||||||
SET SCHEDULE "0 18 * * 1-5"
|
|
||||||
|
|
||||||
' This runs every weekday at 6 PM
|
|
||||||
|
|
||||||
today_sales = AGGREGATE "orders", "SUM", "total", "date = TODAY()"
|
|
||||||
order_count = AGGREGATE "orders", "COUNT", "id", "date = TODAY()"
|
|
||||||
avg_order = IIF(order_count > 0, today_sales / order_count, 0)
|
|
||||||
|
|
||||||
WITH report
|
|
||||||
.date = TODAY()
|
|
||||||
.total_sales = today_sales
|
|
||||||
.order_count = order_count
|
|
||||||
.average_order = ROUND(avg_order, 2)
|
|
||||||
END WITH
|
|
||||||
|
|
||||||
SEND TEMPLATE "daily-sales", "email", "sales@company.com", report
|
|
||||||
|
|
||||||
TALK "Daily report sent: $" + today_sales
|
|
||||||
```
|
|
||||||
|
|
||||||
## Canceling Scheduled Tasks
|
|
||||||
|
|
||||||
Scheduled tasks are stored in `system_automations` table. To cancel:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Remove scheduled automation
|
|
||||||
DELETE "system_automations", "param = 'followup.bas' AND bot_id = '" + bot_id + "'"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
1. **Use descriptive script names**: `welcome-day-2.bas` not `email2.bas`
|
|
||||||
2. **Store context in BOT MEMORY**: Pass lead ID, not entire objects
|
|
||||||
3. **Check for unsubscribes**: Before sending scheduled emails
|
|
||||||
4. **Handle errors gracefully**: Scheduled scripts should not crash
|
|
||||||
5. **Log execution**: Track when scheduled scripts run
|
|
||||||
6. **Use appropriate times**: Consider timezone and recipient preferences
|
|
||||||
7. **Avoid overlapping schedules**: Don't schedule too many scripts at same time
|
|
||||||
|
|
||||||
## Database Schema
|
|
||||||
|
|
||||||
Scheduled tasks are stored in `system_automations`:
|
|
||||||
|
|
||||||
| Column | Type | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| `id` | UUID | Automation ID |
|
|
||||||
| `bot_id` | UUID | Bot owner |
|
|
||||||
| `kind` | INT | Trigger type (Scheduled = 1) |
|
|
||||||
| `schedule` | TEXT | Cron expression |
|
|
||||||
| `param` | TEXT | Script filename |
|
|
||||||
| `is_active` | BOOL | Active status |
|
|
||||||
| `last_triggered` | TIMESTAMP | Last execution time |
|
|
||||||
|
|
||||||
## Comparison
|
|
||||||
|
|
||||||
| Feature | File-Level | Runtime |
|
|
||||||
|---------|------------|---------|
|
|
||||||
| Location | Top of file | Anywhere in code |
|
|
||||||
| Purpose | Recurring execution | One-time scheduling |
|
|
||||||
| Timing | Cron-based recurring | Specific date/time |
|
|
||||||
| Script | Self (current file) | Other script |
|
|
||||||
| Use case | Reports, cleanup | Drip campaigns, reminders |
|
|
||||||
|
|
@ -1,243 +0,0 @@
|
||||||
# UI Structure Documentation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The BotServer UI system consists of two main interface implementations designed for different use cases and deployment scenarios.
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
ui/
|
|
||||||
├── suite/ # Full-featured suite interface (formerly desktop)
|
|
||||||
│ ├── index.html
|
|
||||||
│ ├── js/
|
|
||||||
│ ├── css/
|
|
||||||
│ ├── public/
|
|
||||||
│ ├── drive/
|
|
||||||
│ ├── chat/
|
|
||||||
│ ├── mail/
|
|
||||||
│ ├── tasks/
|
|
||||||
│ ├── default.gbui
|
|
||||||
│ └── single.gbui
|
|
||||||
│
|
|
||||||
└── minimal/ # Lightweight minimal interface (formerly html)
|
|
||||||
├── index.html
|
|
||||||
├── styles.css
|
|
||||||
└── app.js
|
|
||||||
```
|
|
||||||
|
|
||||||
## Interface Types
|
|
||||||
|
|
||||||
### Suite Interface (`ui/suite/`)
|
|
||||||
|
|
||||||
The **Suite** interface is the comprehensive, full-featured UI that provides:
|
|
||||||
|
|
||||||
- **Multi-application integration**: Chat, Drive, Tasks, Mail modules
|
|
||||||
- **Desktop-class experience**: Rich interactions and complex workflows
|
|
||||||
- **Responsive design**: Works on desktop, tablet, and mobile
|
|
||||||
- **GBUI templates**: Customizable interface templates
|
|
||||||
- `default.gbui`: Full multi-app layout
|
|
||||||
- `single.gbui`: Streamlined chat-focused interface
|
|
||||||
- **Tauri integration**: Can be packaged as a desktop application
|
|
||||||
|
|
||||||
**Use Cases:**
|
|
||||||
- Enterprise deployments
|
|
||||||
- Power users requiring full functionality
|
|
||||||
- Desktop application distribution
|
|
||||||
- Multi-service integrations
|
|
||||||
|
|
||||||
**Access:**
|
|
||||||
- Web: `http://localhost:8080/suite` (explicit suite access)
|
|
||||||
- Desktop: Via Tauri build with `--desktop` flag
|
|
||||||
|
|
||||||
### Minimal Interface (`ui/minimal/`)
|
|
||||||
|
|
||||||
The **Minimal** interface is a lightweight, fast-loading UI that provides:
|
|
||||||
|
|
||||||
- **Essential features only**: Core chat and basic interactions
|
|
||||||
- **Fast loading**: Minimal dependencies and assets
|
|
||||||
- **Low resource usage**: Optimized for constrained environments
|
|
||||||
- **Easy embedding**: Simple to integrate into existing applications
|
|
||||||
- **Mobile-first**: Designed primarily for mobile and embedded use
|
|
||||||
|
|
||||||
**Use Cases:**
|
|
||||||
- Mobile web access
|
|
||||||
- Embedded chatbots
|
|
||||||
- Low-bandwidth environments
|
|
||||||
- Quick access terminals
|
|
||||||
- Kiosk deployments
|
|
||||||
|
|
||||||
**Access:**
|
|
||||||
- Direct: `http://localhost:8080` (default)
|
|
||||||
- Explicit: `http://localhost:8080/minimal`
|
|
||||||
- Embedded: Via iframe or WebView
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Server Configuration
|
|
||||||
|
|
||||||
The UI paths are configured in multiple locations:
|
|
||||||
|
|
||||||
1. **Main Server** (`src/main.rs`):
|
|
||||||
```rust
|
|
||||||
let static_path = std::path::Path::new("./web/suite");
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **UI Server Module** (`src/core/ui_server/mod.rs`):
|
|
||||||
```rust
|
|
||||||
let static_path = PathBuf::from("./ui/suite");
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Tauri Configuration** (`tauri.conf.json`):
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"build": {
|
|
||||||
"frontendDist": "./ui/suite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Switching Between Interfaces
|
|
||||||
|
|
||||||
#### Default Interface Selection
|
|
||||||
|
|
||||||
The minimal interface is served by default at the root path. This provides faster loading and lower resource usage for most users.
|
|
||||||
|
|
||||||
1. Update `ui_server/mod.rs`:
|
|
||||||
```rust
|
|
||||||
// For minimal (default)
|
|
||||||
match fs::read_to_string("ui/minimal/index.html")
|
|
||||||
|
|
||||||
// For suite
|
|
||||||
match fs::read_to_string("ui/suite/index.html")
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Routing Configuration
|
|
||||||
|
|
||||||
Both interfaces can be served simultaneously with different routes:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
Router::new()
|
|
||||||
.route("/", get(serve_minimal)) // Minimal at root (default)
|
|
||||||
.route("/minimal", get(serve_minimal)) // Explicit minimal route
|
|
||||||
.route("/suite", get(serve_suite)) // Suite at /suite
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development Guidelines
|
|
||||||
|
|
||||||
### When to Use Suite Interface
|
|
||||||
|
|
||||||
Choose the Suite interface when you need:
|
|
||||||
- Full application functionality
|
|
||||||
- Multi-module integration
|
|
||||||
- Desktop-like user experience
|
|
||||||
- Complex workflows and data management
|
|
||||||
- Rich media handling
|
|
||||||
|
|
||||||
### When to Use Minimal Interface
|
|
||||||
|
|
||||||
Choose the Minimal interface when you need:
|
|
||||||
- Fast, lightweight deployment
|
|
||||||
- Mobile-optimized experience
|
|
||||||
- Embedded chatbot functionality
|
|
||||||
- Limited bandwidth scenarios
|
|
||||||
- Simple, focused interactions
|
|
||||||
|
|
||||||
## Migration Notes
|
|
||||||
|
|
||||||
### From Previous Structure
|
|
||||||
|
|
||||||
The UI directories were renamed for clarity:
|
|
||||||
- `ui/desktop` → `ui/suite` (reflects full-featured nature)
|
|
||||||
- `ui/html` → `ui/minimal` (reflects lightweight design)
|
|
||||||
|
|
||||||
### Updating Existing Code
|
|
||||||
|
|
||||||
When migrating existing code:
|
|
||||||
|
|
||||||
1. Update static file paths:
|
|
||||||
```rust
|
|
||||||
// Old
|
|
||||||
let static_path = PathBuf::from("./ui/desktop");
|
|
||||||
|
|
||||||
// New
|
|
||||||
let static_path = PathBuf::from("./ui/suite");
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Update documentation references:
|
|
||||||
```markdown
|
|
||||||
<!-- Old -->
|
|
||||||
Location: `ui/desktop/default.gbui`
|
|
||||||
|
|
||||||
<!-- New -->
|
|
||||||
Location: `ui/suite/default.gbui`
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Update build configurations:
|
|
||||||
```json
|
|
||||||
// Old
|
|
||||||
"frontendDist": "./ui/desktop"
|
|
||||||
|
|
||||||
// New
|
|
||||||
"frontendDist": "./ui/suite"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
### Planned Features
|
|
||||||
|
|
||||||
1. **Dynamic UI Selection**: Runtime switching between suite and minimal
|
|
||||||
2. **Progressive Enhancement**: Start with minimal, upgrade to suite as needed
|
|
||||||
3. **Custom Themes**: User-selectable themes for both interfaces
|
|
||||||
4. **Module Lazy Loading**: Load suite modules on-demand
|
|
||||||
5. **Offline Support**: Service worker implementation for both UIs
|
|
||||||
|
|
||||||
### Interface Convergence
|
|
||||||
|
|
||||||
Future versions may introduce:
|
|
||||||
- **Adaptive Interface**: Single UI that adapts based on device capabilities
|
|
||||||
- **Micro-frontends**: Independent module deployment
|
|
||||||
- **WebAssembly Components**: High-performance UI components
|
|
||||||
- **Native Mobile Apps**: React Native or Flutter implementations
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
1. **404 Errors After Rename**:
|
|
||||||
- Clear browser cache
|
|
||||||
- Rebuild the project: `cargo clean && cargo build`
|
|
||||||
- Verify file paths in `ui/suite/` or `ui/minimal/`
|
|
||||||
|
|
||||||
2. **Tauri Build Failures**:
|
|
||||||
- Update `tauri.conf.json` with correct `frontendDist` path
|
|
||||||
- Ensure `ui/suite/index.html` exists
|
|
||||||
|
|
||||||
3. **Static Files Not Loading**:
|
|
||||||
- Check `ServeDir` configuration in router
|
|
||||||
- Verify subdirectories (js, css, public) exist in new location
|
|
||||||
|
|
||||||
### Debug Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Verify UI structure
|
|
||||||
ls -la ui/suite/
|
|
||||||
ls -la ui/minimal/
|
|
||||||
|
|
||||||
# Test minimal interface (default)
|
|
||||||
curl http://localhost:8080/
|
|
||||||
|
|
||||||
# Test suite interface
|
|
||||||
curl http://localhost:8080/suite/
|
|
||||||
|
|
||||||
# Check static file serving
|
|
||||||
curl http://localhost:8080/js/app.js
|
|
||||||
curl http://localhost:8080/css/styles.css
|
|
||||||
```
|
|
||||||
|
|
||||||
## Related Documentation
|
|
||||||
|
|
||||||
- [GBUI Templates](./chapter-04-gbui/README.md)
|
|
||||||
- [UI Server Module](../src/core/ui_server/README.md)
|
|
||||||
- [Desktop Application](./DESKTOP.md)
|
|
||||||
- [Web Deployment](./WEB_DEPLOYMENT.md)
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
# Multimodal Configuration Guide
|
|
||||||
|
|
||||||
This document describes how to configure botserver to use the botmodels service for image, video, audio generation, and vision/captioning capabilities.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The multimodal feature connects botserver to botmodels - a Python-based service similar to llama.cpp but for multimodal AI tasks. This enables BASIC scripts to generate images, videos, audio, and analyze visual content.
|
|
||||||
|
|
||||||
## Configuration Keys
|
|
||||||
|
|
||||||
Add the following configuration to your bot's `config.csv` file:
|
|
||||||
|
|
||||||
### Image Generator Settings
|
|
||||||
|
|
||||||
| Key | Default | Description |
|
|
||||||
|-----|---------|-------------|
|
|
||||||
| `image-generator-model` | - | Path to the image generation model (e.g., `../../../../data/diffusion/sd_turbo_f16.gguf`) |
|
|
||||||
| `image-generator-steps` | `4` | Number of inference steps for image generation |
|
|
||||||
| `image-generator-width` | `512` | Output image width in pixels |
|
|
||||||
| `image-generator-height` | `512` | Output image height in pixels |
|
|
||||||
| `image-generator-gpu-layers` | `20` | Number of layers to offload to GPU |
|
|
||||||
| `image-generator-batch-size` | `1` | Batch size for generation |
|
|
||||||
|
|
||||||
### Video Generator Settings
|
|
||||||
|
|
||||||
| Key | Default | Description |
|
|
||||||
|-----|---------|-------------|
|
|
||||||
| `video-generator-model` | - | Path to the video generation model (e.g., `../../../../data/diffusion/zeroscope_v2_576w`) |
|
|
||||||
| `video-generator-frames` | `24` | Number of frames to generate |
|
|
||||||
| `video-generator-fps` | `8` | Frames per second for output video |
|
|
||||||
| `video-generator-width` | `320` | Output video width in pixels |
|
|
||||||
| `video-generator-height` | `576` | Output video height in pixels |
|
|
||||||
| `video-generator-gpu-layers` | `15` | Number of layers to offload to GPU |
|
|
||||||
| `video-generator-batch-size` | `1` | Batch size for generation |
|
|
||||||
|
|
||||||
### BotModels Service Settings
|
|
||||||
|
|
||||||
| Key | Default | Description |
|
|
||||||
|-----|---------|-------------|
|
|
||||||
| `botmodels-enabled` | `false` | Enable/disable botmodels integration |
|
|
||||||
| `botmodels-host` | `0.0.0.0` | Host address for botmodels service |
|
|
||||||
| `botmodels-port` | `8085` | Port for botmodels service |
|
|
||||||
| `botmodels-api-key` | - | API key for authentication with botmodels |
|
|
||||||
| `botmodels-https` | `false` | Use HTTPS for connection to botmodels |
|
|
||||||
|
|
||||||
## Example config.csv
|
|
||||||
|
|
||||||
```csv
|
|
||||||
key,value
|
|
||||||
image-generator-model,../../../../data/diffusion/sd_turbo_f16.gguf
|
|
||||||
image-generator-steps,4
|
|
||||||
image-generator-width,512
|
|
||||||
image-generator-height,512
|
|
||||||
image-generator-gpu-layers,20
|
|
||||||
image-generator-batch-size,1
|
|
||||||
video-generator-model,../../../../data/diffusion/zeroscope_v2_576w
|
|
||||||
video-generator-frames,24
|
|
||||||
video-generator-fps,8
|
|
||||||
video-generator-width,320
|
|
||||||
video-generator-height,576
|
|
||||||
video-generator-gpu-layers,15
|
|
||||||
video-generator-batch-size,1
|
|
||||||
botmodels-enabled,true
|
|
||||||
botmodels-host,0.0.0.0
|
|
||||||
botmodels-port,8085
|
|
||||||
botmodels-api-key,your-secret-key
|
|
||||||
botmodels-https,false
|
|
||||||
```
|
|
||||||
|
|
||||||
## BASIC Keywords
|
|
||||||
|
|
||||||
Once configured, the following keywords become available in BASIC scripts:
|
|
||||||
|
|
||||||
### IMAGE
|
|
||||||
|
|
||||||
Generate an image from a text prompt.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
file = IMAGE "a cute cat playing with yarn"
|
|
||||||
SEND FILE TO user, file
|
|
||||||
```
|
|
||||||
|
|
||||||
### VIDEO
|
|
||||||
|
|
||||||
Generate a video from a text prompt.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
file = VIDEO "a rocket launching into space"
|
|
||||||
SEND FILE TO user, file
|
|
||||||
```
|
|
||||||
|
|
||||||
### AUDIO
|
|
||||||
|
|
||||||
Generate speech audio from text.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
file = AUDIO "Hello, welcome to our service!"
|
|
||||||
SEND FILE TO user, file
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE
|
|
||||||
|
|
||||||
Get a caption/description of an image or video file.
|
|
||||||
|
|
||||||
```basic
|
|
||||||
caption = SEE "/path/to/image.jpg"
|
|
||||||
TALK caption
|
|
||||||
|
|
||||||
// Also works with video files
|
|
||||||
description = SEE "/path/to/video.mp4"
|
|
||||||
TALK description
|
|
||||||
```
|
|
||||||
|
|
||||||
## Starting BotModels Service
|
|
||||||
|
|
||||||
Before using multimodal features, start the botmodels service:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd botmodels
|
|
||||||
python -m uvicorn src.main:app --host 0.0.0.0 --port 8085
|
|
||||||
```
|
|
||||||
|
|
||||||
Or with HTTPS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python -m uvicorn src.main:app --host 0.0.0.0 --port 8085 --ssl-keyfile key.pem --ssl-certfile cert.pem
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Endpoints (BotModels)
|
|
||||||
|
|
||||||
The botmodels service exposes these REST endpoints:
|
|
||||||
|
|
||||||
| Endpoint | Method | Description |
|
|
||||||
|----------|--------|-------------|
|
|
||||||
| `/api/image/generate` | POST | Generate image from prompt |
|
|
||||||
| `/api/video/generate` | POST | Generate video from prompt |
|
|
||||||
| `/api/speech/generate` | POST | Generate speech from text |
|
|
||||||
| `/api/speech/totext` | POST | Convert audio to text |
|
|
||||||
| `/api/vision/describe` | POST | Get description of an image |
|
|
||||||
| `/api/vision/describe_video` | POST | Get description of a video |
|
|
||||||
| `/api/vision/vqa` | POST | Visual question answering |
|
|
||||||
| `/api/health` | GET | Health check |
|
|
||||||
|
|
||||||
All endpoints require the `X-API-Key` header for authentication.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────┐ HTTPS ┌─────────────┐
|
|
||||||
│ botserver │ ────────────▶ │ botmodels │
|
|
||||||
│ (Rust) │ │ (Python) │
|
|
||||||
└─────────────┘ └─────────────┘
|
|
||||||
│ │
|
|
||||||
│ BASIC Keywords │ AI Models
|
|
||||||
│ - IMAGE │ - Stable Diffusion
|
|
||||||
│ - VIDEO │ - Zeroscope
|
|
||||||
│ - AUDIO │ - TTS/Whisper
|
|
||||||
│ - SEE │ - BLIP2
|
|
||||||
▼ ▼
|
|
||||||
┌─────────────┐ ┌─────────────┐
|
|
||||||
│ config │ │ outputs │
|
|
||||||
│ .csv │ │ (files) │
|
|
||||||
└─────────────┘ └─────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### "BotModels is not enabled"
|
|
||||||
|
|
||||||
Set `botmodels-enabled=true` in your config.csv.
|
|
||||||
|
|
||||||
### Connection refused
|
|
||||||
|
|
||||||
1. Ensure botmodels service is running
|
|
||||||
2. Check host/port configuration
|
|
||||||
3. Verify firewall settings
|
|
||||||
|
|
||||||
### Authentication failed
|
|
||||||
|
|
||||||
Ensure `botmodels-api-key` in config.csv matches `API_KEY` environment variable in botmodels.
|
|
||||||
|
|
||||||
### Model not found
|
|
||||||
|
|
||||||
Verify model paths are correct and models are downloaded to the expected locations.
|
|
||||||
|
|
||||||
## Security Notes
|
|
||||||
|
|
||||||
1. Always use HTTPS in production (`botmodels-https=true`)
|
|
||||||
2. Use strong, unique API keys
|
|
||||||
3. Restrict network access to botmodels service
|
|
||||||
4. Consider running botmodels on a separate GPU server
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
# Part IV - User Interface
|
# Part IV - User Interface
|
||||||
|
|
||||||
- [Chapter 04: .gbui Interface Reference](./chapter-04-gbui/README.md)
|
- [Chapter 04: .gbui Interface Reference](./chapter-04-gbui/README.md)
|
||||||
|
- [UI Structure](./chapter-04-gbui/ui-structure.md)
|
||||||
- [default.gbui - Full Desktop](./chapter-04-gbui/default-gbui.md)
|
- [default.gbui - Full Desktop](./chapter-04-gbui/default-gbui.md)
|
||||||
- [single.gbui - Simple Chat](./chapter-04-gbui/single-gbui.md)
|
- [single.gbui - Simple Chat](./chapter-04-gbui/single-gbui.md)
|
||||||
- [Console Mode](./chapter-04-gbui/console-mode.md)
|
- [Console Mode](./chapter-04-gbui/console-mode.md)
|
||||||
|
|
@ -54,6 +55,7 @@
|
||||||
- [Dialog Basics](./chapter-06-gbdialog/basics.md)
|
- [Dialog Basics](./chapter-06-gbdialog/basics.md)
|
||||||
- [Universal Messaging & Multi-Channel](./chapter-06-gbdialog/universal-messaging.md)
|
- [Universal Messaging & Multi-Channel](./chapter-06-gbdialog/universal-messaging.md)
|
||||||
- [BASIC vs n8n/Zapier/Make](./chapter-06-gbdialog/basic-vs-automation-tools.md)
|
- [BASIC vs n8n/Zapier/Make](./chapter-06-gbdialog/basic-vs-automation-tools.md)
|
||||||
|
- [Template Variables](./chapter-06-gbdialog/template-variables.md)
|
||||||
- [Template Examples](./chapter-06-gbdialog/templates.md)
|
- [Template Examples](./chapter-06-gbdialog/templates.md)
|
||||||
- [start.bas](./chapter-06-gbdialog/templates/start.md)
|
- [start.bas](./chapter-06-gbdialog/templates/start.md)
|
||||||
- [enrollment.bas](./chapter-06-gbdialog/templates/enrollment.md)
|
- [enrollment.bas](./chapter-06-gbdialog/templates/enrollment.md)
|
||||||
|
|
@ -99,6 +101,8 @@
|
||||||
- [KB DOCUMENTS ADDED SINCE](./chapter-06-gbdialog/keyword-kb-documents-added-since.md)
|
- [KB DOCUMENTS ADDED SINCE](./chapter-06-gbdialog/keyword-kb-documents-added-since.md)
|
||||||
- [KB LIST COLLECTIONS](./chapter-06-gbdialog/keyword-kb-list-collections.md)
|
- [KB LIST COLLECTIONS](./chapter-06-gbdialog/keyword-kb-list-collections.md)
|
||||||
- [KB STORAGE SIZE](./chapter-06-gbdialog/keyword-kb-storage-size.md)
|
- [KB STORAGE SIZE](./chapter-06-gbdialog/keyword-kb-storage-size.md)
|
||||||
|
- [Social Media Keywords](./chapter-06-gbdialog/keywords-social-media.md)
|
||||||
|
- [Lead Scoring Keywords](./chapter-06-gbdialog/keywords-lead-scoring.md)
|
||||||
- [HTTP & API Operations](./chapter-06-gbdialog/keywords-http.md)
|
- [HTTP & API Operations](./chapter-06-gbdialog/keywords-http.md)
|
||||||
- [POST](./chapter-06-gbdialog/keyword-post.md)
|
- [POST](./chapter-06-gbdialog/keyword-post.md)
|
||||||
- [PUT](./chapter-06-gbdialog/keyword-put.md)
|
- [PUT](./chapter-06-gbdialog/keyword-put.md)
|
||||||
|
|
@ -158,6 +162,7 @@
|
||||||
- [LLM Configuration](./chapter-08-config/llm-config.md)
|
- [LLM Configuration](./chapter-08-config/llm-config.md)
|
||||||
- [Context Configuration](./chapter-08-config/context-config.md)
|
- [Context Configuration](./chapter-08-config/context-config.md)
|
||||||
- [Drive Integration](./chapter-08-config/drive.md)
|
- [Drive Integration](./chapter-08-config/drive.md)
|
||||||
|
- [Multimodal Configuration](./chapter-08-config/multimodal.md)
|
||||||
- [Secrets Management](./chapter-08-config/secrets-management.md)
|
- [Secrets Management](./chapter-08-config/secrets-management.md)
|
||||||
|
|
||||||
# Part IX - Tools and Integration
|
# Part IX - Tools and Integration
|
||||||
|
|
@ -173,7 +178,6 @@
|
||||||
- [LLM REST Server](./chapter-09-api/llm-rest-server.md)
|
- [LLM REST Server](./chapter-09-api/llm-rest-server.md)
|
||||||
- [NVIDIA GPU Setup for LXC](./chapter-09-api/nvidia-gpu-setup.md)
|
- [NVIDIA GPU Setup for LXC](./chapter-09-api/nvidia-gpu-setup.md)
|
||||||
|
|
||||||
|
|
||||||
- [Chapter 10: REST API Reference](./chapter-10-api/README.md)
|
- [Chapter 10: REST API Reference](./chapter-10-api/README.md)
|
||||||
- [Files API](./chapter-10-api/files-api.md)
|
- [Files API](./chapter-10-api/files-api.md)
|
||||||
- [Document Processing API](./chapter-10-api/document-processing.md)
|
- [Document Processing API](./chapter-10-api/document-processing.md)
|
||||||
|
|
@ -213,7 +217,10 @@
|
||||||
- [Storage and Data](./chapter-11-features/storage.md)
|
- [Storage and Data](./chapter-11-features/storage.md)
|
||||||
- [Multi-Channel Support](./chapter-11-features/channels.md)
|
- [Multi-Channel Support](./chapter-11-features/channels.md)
|
||||||
- [Drive Monitor](./chapter-11-features/drive-monitor.md)
|
- [Drive Monitor](./chapter-11-features/drive-monitor.md)
|
||||||
- [Platform Comparison](./chapter-11-features/platform-comparison.md)
|
- [Platform Capabilities](./chapter-11-features/platform-comparison.md)
|
||||||
|
- [Enterprise Platform Migration](./chapter-11-features/m365-comparison.md)
|
||||||
|
- [Projects](./chapter-11-features/projects.md)
|
||||||
|
- [Multi-Agent Office Suite Design](./chapter-11-features/multi-agent-design.md)
|
||||||
|
|
||||||
# Part XI - Security
|
# Part XI - Security
|
||||||
|
|
||||||
|
|
@ -243,10 +250,19 @@
|
||||||
|
|
||||||
- [Chapter 14: Migration Guide](./chapter-14-migration/README.md)
|
- [Chapter 14: Migration Guide](./chapter-14-migration/README.md)
|
||||||
- [Migration Overview](./chapter-14-migration/overview.md)
|
- [Migration Overview](./chapter-14-migration/overview.md)
|
||||||
|
- [Platform Comparison Matrix](./chapter-14-migration/comparison-matrix.md)
|
||||||
|
- [Migration Resources](./chapter-14-migration/resources.md)
|
||||||
- [Common Concepts](./chapter-14-migration/common-concepts.md)
|
- [Common Concepts](./chapter-14-migration/common-concepts.md)
|
||||||
- [Knowledge Base Migration](./chapter-14-migration/kb-migration.md)
|
- [Knowledge Base Migration](./chapter-14-migration/kb-migration.md)
|
||||||
- [Google Workspace Integration](./chapter-14-migration/google-workspace.md)
|
- [Cloud Productivity Migration](./chapter-14-migration/google-workspace.md)
|
||||||
- [Microsoft 365 Integration](./chapter-14-migration/microsoft-365.md)
|
- [Enterprise Platform Migration](./chapter-14-migration/microsoft-365.md)
|
||||||
|
- [n8n Migration](./chapter-14-migration/n8n.md)
|
||||||
|
- [Notion Migration](./chapter-14-migration/notion.md)
|
||||||
|
- [Perplexity Migration](./chapter-14-migration/perplexity.md)
|
||||||
|
- [Zapier and Make Migration](./chapter-14-migration/zapier-make.md)
|
||||||
|
- [Intercom Migration](./chapter-14-migration/intercom.md)
|
||||||
|
- [Dialogflow Migration](./chapter-14-migration/dialogflow.md)
|
||||||
|
- [Botpress Migration](./chapter-14-migration/botpress.md)
|
||||||
- [Automation Migration](./chapter-14-migration/automation.md)
|
- [Automation Migration](./chapter-14-migration/automation.md)
|
||||||
- [Validation and Testing](./chapter-14-migration/validation.md)
|
- [Validation and Testing](./chapter-14-migration/validation.md)
|
||||||
|
|
||||||
|
|
|
||||||
207
docs/src/assets/api-comparison-matrix.svg
Normal file
207
docs/src/assets/api-comparison-matrix.svg
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
<svg width="1400" height="800" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<!-- Modern Gradients -->
|
||||||
|
<linearGradient id="gbGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="cloudGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#64748B;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#94A3B8;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="successGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="headerGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
|
||||||
|
<stop offset="50%" style="stop-color:#312E81;stop-opacity:0.08" />
|
||||||
|
<stop offset="100%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="flowLine" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:0.2" />
|
||||||
|
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:0.6" />
|
||||||
|
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:0.2" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="softGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="dropShadow" x="-10%" y="-10%" width="120%" height="120%">
|
||||||
|
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="#000" flood-opacity="0.1"/>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Arrow marker -->
|
||||||
|
<marker id="arrowGreen" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||||
|
<path d="M0,0 L0,6 L9,3 z" fill="#10B981"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main-text { fill: #1a1a1a; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.white-text { fill: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.mono-text { fill: #475569; font-family: 'SF Mono', 'Fira Code', Consolas, monospace; }
|
||||||
|
.accent-text { fill: #6366F1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.main-text { fill: #F1F5F9; }
|
||||||
|
.secondary-text { fill: #94A3B8; }
|
||||||
|
.mono-text { fill: #CBD5E1; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Background subtle pattern -->
|
||||||
|
<rect width="1400" height="800" fill="#FAFBFC"/>
|
||||||
|
<rect x="0" y="0" width="1400" height="120" fill="url(#headerGradient)"/>
|
||||||
|
|
||||||
|
<!-- Title Section -->
|
||||||
|
<text x="700" y="50" text-anchor="middle" font-size="28" font-weight="600" class="main-text">API Migration Matrix</text>
|
||||||
|
<text x="700" y="80" text-anchor="middle" font-size="16" class="secondary-text">Enterprise Cloud APIs → General Bots Keywords</text>
|
||||||
|
|
||||||
|
<!-- Platform Labels -->
|
||||||
|
<g transform="translate(100, 130)">
|
||||||
|
<!-- Cloud Platform Box -->
|
||||||
|
<rect x="0" y="0" width="180" height="50" rx="8" fill="url(#cloudGradient)" filter="url(#dropShadow)"/>
|
||||||
|
<text x="90" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">Cloud Platform</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(1120, 130)">
|
||||||
|
<!-- General Bots Box -->
|
||||||
|
<rect x="0" y="0" width="180" height="50" rx="8" fill="url(#gbGradient)" filter="url(#dropShadow)"/>
|
||||||
|
<text x="90" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">General Bots</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Flow Arrow -->
|
||||||
|
<path d="M300 155 Q700 155 1100 155" stroke="url(#flowLine)" stroke-width="3" fill="none" stroke-dasharray="8,4"/>
|
||||||
|
<text x="700" y="150" text-anchor="middle" font-size="12" font-weight="500" class="accent-text">MIGRATION PATH</text>
|
||||||
|
|
||||||
|
<!-- Comparison Rows -->
|
||||||
|
<g transform="translate(50, 200)">
|
||||||
|
<!-- Row 1: Mail -->
|
||||||
|
<g transform="translate(0, 0)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Email / Mail</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Messages, Send, Folders</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">SEND MAIL keyword</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">SEND MAIL TO email SUBJECT s BODY b</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 2: Calendar -->
|
||||||
|
<g transform="translate(0, 70)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Calendar Events</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Events, Scheduling, Free/Busy</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">BOOK keyword + Calendar API</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">BOOK "Meeting" AT datetime</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 3: Drive/Files -->
|
||||||
|
<g transform="translate(0, 140)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Cloud Storage / Files</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Files, Versions, Sharing</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">SeaweedFS + File Keywords</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">READ, WRITE, LIST, COPY, MOVE, DELETE</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 4: Tasks -->
|
||||||
|
<g transform="translate(0, 210)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Tasks / Planning</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Tasks, Lists, Assignments</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">CREATE TASK + Projects</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">CREATE TASK "title" DUE date IN PROJECT id</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 5: Messaging -->
|
||||||
|
<g transform="translate(0, 280)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Team Messaging</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Chat, Channels, Messages</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">TALK + Multi-Channel</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">Web, WhatsApp, Teams, Slack, Telegram</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 6: Users -->
|
||||||
|
<g transform="translate(0, 350)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Users / Directory</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Users, Groups, Permissions</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">Zitadel IAM + Users API</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">OIDC/OAuth2 + SCIM provisioning</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Row 7: Automation -->
|
||||||
|
<g transform="translate(0, 420)">
|
||||||
|
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<circle cx="30" cy="30" r="8" fill="#10B981"/>
|
||||||
|
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Workflow Automation</text>
|
||||||
|
<text x="55" y="44" font-size="11" class="mono-text">Flows, Triggers, Connectors</text>
|
||||||
|
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text">→</text>
|
||||||
|
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">BASIC Scripts + SET SCHEDULE</text>
|
||||||
|
<text x="900" y="44" font-size="11" class="mono-text">90+ keywords, webhooks, cron, full logic</text>
|
||||||
|
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#gbGradient)"/>
|
||||||
|
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">BETTER</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Summary Stats -->
|
||||||
|
<g transform="translate(100, 720)">
|
||||||
|
<rect x="0" y="0" width="250" height="60" rx="8" fill="#EEF2FF" stroke="#C7D2FE" stroke-width="1"/>
|
||||||
|
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" class="accent-text">100%</text>
|
||||||
|
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">Feature Parity</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(400, 720)">
|
||||||
|
<rect x="0" y="0" width="250" height="60" rx="8" fill="#ECFDF5" stroke="#A7F3D0" stroke-width="1"/>
|
||||||
|
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#10B981">90+</text>
|
||||||
|
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">BASIC Keywords</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(700, 720)">
|
||||||
|
<rect x="0" y="0" width="250" height="60" rx="8" fill="#FEF3C7" stroke="#FCD34D" stroke-width="1"/>
|
||||||
|
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#D97706">$0</text>
|
||||||
|
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">Per-User Licensing</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(1000, 720)">
|
||||||
|
<rect x="0" y="0" width="300" height="60" rx="8" fill="#F0FDF4" stroke="#86EFAC" stroke-width="1"/>
|
||||||
|
<text x="150" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#16A34A">Self-Hosted</text>
|
||||||
|
<text x="150" y="48" text-anchor="middle" font-size="12" class="secondary-text">Full Data Sovereignty</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
234
docs/src/assets/architecture-overview.svg
Normal file
234
docs/src/assets/architecture-overview.svg
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
<svg width="1200" height="500" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<!-- Modern Gradients -->
|
||||||
|
<linearGradient id="primaryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="cyanGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#06B6D4;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#0EA5E9;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="greenGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="orangeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#FBBF24;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="flowGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:0.2" />
|
||||||
|
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:0.5" />
|
||||||
|
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:0.2" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Filters -->
|
||||||
|
<filter id="cardShadow" x="-10%" y="-10%" width="120%" height="130%">
|
||||||
|
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#6366F1" flood-opacity="0.15"/>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Arrow markers -->
|
||||||
|
<marker id="arrowPurple" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||||
|
<path d="M0,0 L0,6 L9,3 z" fill="#8B5CF6"/>
|
||||||
|
</marker>
|
||||||
|
|
||||||
|
<!-- Dot pattern -->
|
||||||
|
<pattern id="dots" patternUnits="userSpaceOnUse" width="20" height="20">
|
||||||
|
<circle cx="10" cy="10" r="1" fill="#6366F1" opacity="0.08"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.title-text { fill: #1E1B4B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.main-text { fill: #334155; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.white-text { fill: #FFFFFF; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.mono-text { fill: #475569; font-family: 'SF Mono', 'Fira Code', Consolas, monospace; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.title-text { fill: #F1F5F9; }
|
||||||
|
.main-text { fill: #E2E8F0; }
|
||||||
|
.secondary-text { fill: #94A3B8; }
|
||||||
|
.mono-text { fill: #CBD5E1; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Background -->
|
||||||
|
<rect width="1200" height="500" fill="#FAFBFC"/>
|
||||||
|
<rect width="1200" height="500" fill="url(#dots)"/>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<text x="600" y="40" text-anchor="middle" font-size="22" font-weight="600" class="title-text">General Bots Architecture</text>
|
||||||
|
<text x="600" y="65" text-anchor="middle" font-size="13" class="secondary-text">Single binary • Zero dependencies • Production ready</text>
|
||||||
|
|
||||||
|
<!-- Input Layer -->
|
||||||
|
<g transform="translate(50, 100)">
|
||||||
|
<text x="80" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">CHANNELS</text>
|
||||||
|
|
||||||
|
<!-- Web -->
|
||||||
|
<rect x="0" y="20" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="45" r="15" fill="url(#cyanGrad)"/>
|
||||||
|
<text x="28" y="50" text-anchor="middle" font-size="12" font-weight="700" class="white-text">W</text>
|
||||||
|
<text x="100" y="42" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Web Chat</text>
|
||||||
|
<text x="100" y="56" text-anchor="middle" font-size="10" class="mono-text">WebSocket</text>
|
||||||
|
|
||||||
|
<!-- WhatsApp -->
|
||||||
|
<rect x="0" y="80" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="105" r="15" fill="url(#greenGrad)"/>
|
||||||
|
<text x="28" y="110" text-anchor="middle" font-size="12" font-weight="700" class="white-text">WA</text>
|
||||||
|
<text x="100" y="102" text-anchor="middle" font-size="12" font-weight="500" class="main-text">WhatsApp</text>
|
||||||
|
<text x="100" y="116" text-anchor="middle" font-size="10" class="mono-text">Business API</text>
|
||||||
|
|
||||||
|
<!-- Teams -->
|
||||||
|
<rect x="0" y="140" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="165" r="15" fill="url(#primaryGrad)"/>
|
||||||
|
<text x="28" y="170" text-anchor="middle" font-size="12" font-weight="700" class="white-text">T</text>
|
||||||
|
<text x="100" y="162" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Teams</text>
|
||||||
|
<text x="100" y="176" text-anchor="middle" font-size="10" class="mono-text">Bot Framework</text>
|
||||||
|
|
||||||
|
<!-- Voice -->
|
||||||
|
<rect x="0" y="200" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="225" r="15" fill="url(#orangeGrad)"/>
|
||||||
|
<text x="28" y="230" text-anchor="middle" font-size="12" font-weight="700" class="white-text">V</text>
|
||||||
|
<text x="100" y="222" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Voice</text>
|
||||||
|
<text x="100" y="236" text-anchor="middle" font-size="10" class="mono-text">LiveKit</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Flow Arrows to Core -->
|
||||||
|
<g stroke="url(#flowGrad)" stroke-width="2" fill="none">
|
||||||
|
<path d="M220 145 Q280 145 340 200" marker-end="url(#arrowPurple)"/>
|
||||||
|
<path d="M220 180 Q270 180 340 210" marker-end="url(#arrowPurple)"/>
|
||||||
|
<path d="M220 240 Q270 240 340 230" marker-end="url(#arrowPurple)"/>
|
||||||
|
<path d="M220 320 Q280 320 340 260" marker-end="url(#arrowPurple)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Core Processing -->
|
||||||
|
<g transform="translate(350, 100)">
|
||||||
|
<text x="225" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">CORE RUNTIME</text>
|
||||||
|
|
||||||
|
<!-- Main processing box -->
|
||||||
|
<rect x="0" y="20" width="450" height="260" rx="12" fill="#FFFFFF" stroke="#C7D2FE" stroke-width="2" filter="url(#cardShadow)"/>
|
||||||
|
<rect x="0" y="20" width="450" height="40" rx="12" fill="url(#primaryGrad)"/>
|
||||||
|
<rect x="0" y="48" width="450" height="12" fill="url(#primaryGrad)"/>
|
||||||
|
<text x="225" y="47" text-anchor="middle" font-size="14" font-weight="600" class="white-text">BotServer (Rust)</text>
|
||||||
|
|
||||||
|
<!-- Session Manager -->
|
||||||
|
<rect x="20" y="75" width="200" height="45" rx="6" fill="#EEF2FF" stroke="#C7D2FE" stroke-width="1"/>
|
||||||
|
<text x="120" y="95" text-anchor="middle" font-size="11" font-weight="600" class="main-text">Session Manager</text>
|
||||||
|
<text x="120" y="110" text-anchor="middle" font-size="9" class="mono-text">Tokio Async Runtime</text>
|
||||||
|
|
||||||
|
<!-- BASIC Interpreter -->
|
||||||
|
<rect x="230" y="75" width="200" height="45" rx="6" fill="#FEF3C7" stroke="#FCD34D" stroke-width="1"/>
|
||||||
|
<text x="330" y="95" text-anchor="middle" font-size="11" font-weight="600" class="main-text">BASIC Interpreter</text>
|
||||||
|
<text x="330" y="110" text-anchor="middle" font-size="9" class="mono-text">90+ Keywords</text>
|
||||||
|
|
||||||
|
<!-- LLM Integration -->
|
||||||
|
<rect x="20" y="130" width="200" height="45" rx="6" fill="#F5F3FF" stroke="#DDD6FE" stroke-width="1"/>
|
||||||
|
<text x="120" y="150" text-anchor="middle" font-size="11" font-weight="600" class="main-text">LLM Integration</text>
|
||||||
|
<text x="120" y="165" text-anchor="middle" font-size="9" class="mono-text">OpenAI, Anthropic, Local</text>
|
||||||
|
|
||||||
|
<!-- Package Manager -->
|
||||||
|
<rect x="230" y="130" width="200" height="45" rx="6" fill="#ECFDF5" stroke="#A7F3D0" stroke-width="1"/>
|
||||||
|
<text x="330" y="150" text-anchor="middle" font-size="11" font-weight="600" class="main-text">Package Manager</text>
|
||||||
|
<text x="330" y="165" text-anchor="middle" font-size="9" class="mono-text">.gbai, .gbkb, .gbdialog</text>
|
||||||
|
|
||||||
|
<!-- RAG Engine -->
|
||||||
|
<rect x="20" y="185" width="130" height="40" rx="6" fill="#F0FDF4" stroke="#86EFAC" stroke-width="1"/>
|
||||||
|
<text x="85" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">RAG Engine</text>
|
||||||
|
<text x="85" y="216" text-anchor="middle" font-size="8" class="mono-text">Qdrant Vectors</text>
|
||||||
|
|
||||||
|
<!-- Tool Executor -->
|
||||||
|
<rect x="160" y="185" width="130" height="40" rx="6" fill="#FFF7ED" stroke="#FDBA74" stroke-width="1"/>
|
||||||
|
<text x="225" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">Tool Executor</text>
|
||||||
|
<text x="225" y="216" text-anchor="middle" font-size="8" class="mono-text">Function Calling</text>
|
||||||
|
|
||||||
|
<!-- API Server -->
|
||||||
|
<rect x="300" y="185" width="130" height="40" rx="6" fill="#EFF6FF" stroke="#93C5FD" stroke-width="1"/>
|
||||||
|
<text x="365" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">REST API</text>
|
||||||
|
<text x="365" y="216" text-anchor="middle" font-size="8" class="mono-text">Axum Server</text>
|
||||||
|
|
||||||
|
<!-- Data services bar -->
|
||||||
|
<rect x="20" y="235" width="410" height="35" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<text x="60" y="257" text-anchor="middle" font-size="9" class="mono-text">PostgreSQL</text>
|
||||||
|
<text x="140" y="257" text-anchor="middle" font-size="9" class="mono-text">SeaweedFS</text>
|
||||||
|
<text x="220" y="257" text-anchor="middle" font-size="9" class="mono-text">Valkey</text>
|
||||||
|
<text x="300" y="257" text-anchor="middle" font-size="9" class="mono-text">Zitadel</text>
|
||||||
|
<text x="380" y="257" text-anchor="middle" font-size="9" class="mono-text">Stalwart</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Flow Arrows to Output -->
|
||||||
|
<g stroke="url(#flowGrad)" stroke-width="2" fill="none">
|
||||||
|
<path d="M810 200 Q870 200 920 150" marker-end="url(#arrowPurple)"/>
|
||||||
|
<path d="M810 230 Q870 230 920 230" marker-end="url(#arrowPurple)"/>
|
||||||
|
<path d="M810 260 Q870 260 920 310" marker-end="url(#arrowPurple)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Output Layer -->
|
||||||
|
<g transform="translate(930, 100)">
|
||||||
|
<text x="110" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">OUTPUT</text>
|
||||||
|
|
||||||
|
<!-- Responses -->
|
||||||
|
<rect x="0" y="30" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="55" r="15" fill="url(#primaryGrad)"/>
|
||||||
|
<text x="28" y="60" text-anchor="middle" font-size="10" font-weight="700" class="white-text">💬</text>
|
||||||
|
<text x="130" y="52" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Conversations</text>
|
||||||
|
<text x="130" y="66" text-anchor="middle" font-size="10" class="mono-text">Text, Voice, Rich Media</text>
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<rect x="0" y="95" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="120" r="15" fill="url(#greenGrad)"/>
|
||||||
|
<text x="28" y="125" text-anchor="middle" font-size="10" font-weight="700" class="white-text">⚡</text>
|
||||||
|
<text x="130" y="117" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Automations</text>
|
||||||
|
<text x="130" y="131" text-anchor="middle" font-size="10" class="mono-text">Webhooks, Schedules</text>
|
||||||
|
|
||||||
|
<!-- Data -->
|
||||||
|
<rect x="0" y="160" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
<circle cx="30" cy="185" r="15" fill="url(#cyanGrad)"/>
|
||||||
|
<text x="28" y="190" text-anchor="middle" font-size="10" font-weight="700" class="white-text">📊</text>
|
||||||
|
<text x="130" y="182" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Data & Files</text>
|
||||||
|
<text x="130" y="196" text-anchor="middle" font-size="10" class="mono-text">Drive, Mail, Calendar</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Bottom stats bar -->
|
||||||
|
<g transform="translate(100, 420)">
|
||||||
|
<rect x="0" y="0" width="1000" height="60" rx="10" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
|
||||||
|
|
||||||
|
<g transform="translate(50, 15)">
|
||||||
|
<rect x="0" y="0" width="150" height="30" rx="6" fill="#EEF2FF"/>
|
||||||
|
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Single Binary</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(230, 15)">
|
||||||
|
<rect x="0" y="0" width="150" height="30" rx="6" fill="#ECFDF5"/>
|
||||||
|
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Self-Hosted</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(410, 15)">
|
||||||
|
<rect x="0" y="0" width="150" height="30" rx="6" fill="#FEF3C7"/>
|
||||||
|
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Open Source</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(590, 15)">
|
||||||
|
<rect x="0" y="0" width="150" height="30" rx="6" fill="#F0FDF4"/>
|
||||||
|
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">AI-First</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(770, 15)">
|
||||||
|
<rect x="0" y="0" width="150" height="30" rx="6" fill="#F5F3FF"/>
|
||||||
|
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">No Forms</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 13 KiB |
261
docs/src/assets/feature-parity-flow.svg
Normal file
261
docs/src/assets/feature-parity-flow.svg
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
<svg width="1200" height="650" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<!-- Modern Gradients -->
|
||||||
|
<linearGradient id="primaryGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="secondaryGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#06B6D4;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#0EA5E9;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="successGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="warningGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#FBBF24;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="flowLineGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:0.3" />
|
||||||
|
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:0.7" />
|
||||||
|
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:0.3" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#F8FAFC;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#F1F5F9;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Filters -->
|
||||||
|
<filter id="cardShadow" x="-10%" y="-10%" width="120%" height="130%">
|
||||||
|
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#6366F1" flood-opacity="0.15"/>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="glowEffect" x="-30%" y="-30%" width="160%" height="160%">
|
||||||
|
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Arrow markers -->
|
||||||
|
<marker id="arrowPrimary" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto" markerUnits="strokeWidth">
|
||||||
|
<path d="M0,0 L0,8 L12,4 z" fill="#8B5CF6"/>
|
||||||
|
</marker>
|
||||||
|
|
||||||
|
<marker id="arrowSuccess" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||||
|
<path d="M0,0 L0,6 L10,3 z" fill="#10B981"/>
|
||||||
|
</marker>
|
||||||
|
|
||||||
|
<!-- Dot pattern -->
|
||||||
|
<pattern id="dots" patternUnits="userSpaceOnUse" width="20" height="20">
|
||||||
|
<circle cx="10" cy="10" r="1" fill="#6366F1" opacity="0.1"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.title-text { fill: #1E1B4B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.main-text { fill: #334155; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.white-text { fill: #FFFFFF; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.mono-text { fill: #475569; font-family: 'SF Mono', 'Fira Code', Consolas, monospace; }
|
||||||
|
.accent-text { fill: #6366F1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.title-text { fill: #F1F5F9; }
|
||||||
|
.main-text { fill: #E2E8F0; }
|
||||||
|
.secondary-text { fill: #94A3B8; }
|
||||||
|
.mono-text { fill: #CBD5E1; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Background -->
|
||||||
|
<rect width="1200" height="650" fill="url(#bgGradient)"/>
|
||||||
|
<rect width="1200" height="650" fill="url(#dots)"/>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<text x="600" y="45" text-anchor="middle" font-size="26" font-weight="700" class="title-text">Feature Parity Flow</text>
|
||||||
|
<text x="600" y="72" text-anchor="middle" font-size="14" class="secondary-text">From Enterprise Cloud Services to Self-Hosted Freedom</text>
|
||||||
|
|
||||||
|
<!-- Source Platform Box -->
|
||||||
|
<g transform="translate(50, 110)">
|
||||||
|
<rect x="0" y="0" width="300" height="400" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="2" filter="url(#cardShadow)"/>
|
||||||
|
<rect x="0" y="0" width="300" height="50" rx="12" fill="url(#secondaryGradient)"/>
|
||||||
|
<rect x="0" y="38" width="300" height="12" fill="url(#secondaryGradient)"/>
|
||||||
|
<text x="150" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">Enterprise Cloud</text>
|
||||||
|
|
||||||
|
<!-- Service items -->
|
||||||
|
<g transform="translate(20, 70)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F1F5F9"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Exchange Online</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Mail, Calendar, Contacts</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 120)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F8FAFC"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">OneDrive / SharePoint</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Files, Versioning, Sharing</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 170)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F1F5F9"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Teams</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Chat, Video, Collaboration</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 220)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F8FAFC"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Power Automate</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Workflows, Triggers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 270)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F1F5F9"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Copilot</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">AI Assistant ($30/user)</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 320)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F8FAFC"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="#0078D4"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Azure AD / Entra</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Identity, Auth, SSO</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Migration Arrow Center -->
|
||||||
|
<g transform="translate(380, 250)">
|
||||||
|
<!-- Flow line -->
|
||||||
|
<path d="M0,60 Q220,60 440,60" stroke="url(#flowLineGradient)" stroke-width="4" fill="none" marker-end="url(#arrowPrimary)"/>
|
||||||
|
|
||||||
|
<!-- Migration badge -->
|
||||||
|
<rect x="170" y="20" width="100" height="80" rx="10" fill="url(#primaryGradient)" filter="url(#glowEffect)"/>
|
||||||
|
<text x="220" y="55" text-anchor="middle" font-size="11" font-weight="600" class="white-text">MIGRATE</text>
|
||||||
|
<text x="220" y="72" text-anchor="middle" font-size="10" class="white-text" opacity="0.8">100% Parity</text>
|
||||||
|
|
||||||
|
<!-- Checkmarks -->
|
||||||
|
<g transform="translate(190, 95)">
|
||||||
|
<circle cx="0" cy="0" r="10" fill="url(#successGradient)"/>
|
||||||
|
<path d="M-4,0 L-1,3 L5,-3" stroke="#FFF" stroke-width="2" fill="none"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(220, 95)">
|
||||||
|
<circle cx="0" cy="0" r="10" fill="url(#successGradient)"/>
|
||||||
|
<path d="M-4,0 L-1,3 L5,-3" stroke="#FFF" stroke-width="2" fill="none"/>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(250, 95)">
|
||||||
|
<circle cx="0" cy="0" r="10" fill="url(#successGradient)"/>
|
||||||
|
<path d="M-4,0 L-1,3 L5,-3" stroke="#FFF" stroke-width="2" fill="none"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Target Platform Box -->
|
||||||
|
<g transform="translate(850, 110)">
|
||||||
|
<rect x="0" y="0" width="300" height="400" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="2" filter="url(#cardShadow)"/>
|
||||||
|
<rect x="0" y="0" width="300" height="50" rx="12" fill="url(#primaryGradient)"/>
|
||||||
|
<rect x="0" y="38" width="300" height="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="150" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">General Bots</text>
|
||||||
|
|
||||||
|
<!-- Service items -->
|
||||||
|
<g transform="translate(20, 70)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#EEF2FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Stalwart Mail</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">IMAP/SMTP/JMAP + CalDAV</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 120)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F5F3FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">SeaweedFS Drive</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">S3-compatible + Versioning</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 170)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#EEF2FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">LiveKit Meet</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">WebRTC + Multi-channel</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 220)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F5F3FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">BASIC Scripts</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">90+ Keywords + Cron</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 270)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#EEF2FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">LLM Integration</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">Any Provider (Free)</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(20, 320)">
|
||||||
|
<rect x="0" y="0" width="260" height="40" rx="6" fill="#F5F3FF"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="45" y="17" font-size="12" font-weight="600" class="main-text">Zitadel IAM</text>
|
||||||
|
<text x="45" y="32" font-size="10" class="mono-text">OIDC/OAuth2 + MFA</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Benefits Bar -->
|
||||||
|
<g transform="translate(50, 540)">
|
||||||
|
<rect x="0" y="0" width="1100" height="80" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- Benefit 1 -->
|
||||||
|
<g transform="translate(50, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="50" rx="8" fill="#ECFDF5"/>
|
||||||
|
<circle cx="25" cy="25" r="15" fill="url(#successGradient)"/>
|
||||||
|
<text x="22" y="30" text-anchor="middle" font-size="14" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="55" y="22" font-size="12" font-weight="600" class="main-text">Self-Hosted</text>
|
||||||
|
<text x="55" y="38" font-size="10" class="secondary-text">Full Data Control</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Benefit 2 -->
|
||||||
|
<g transform="translate(280, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="50" rx="8" fill="#EEF2FF"/>
|
||||||
|
<circle cx="25" cy="25" r="15" fill="url(#primaryGradient)"/>
|
||||||
|
<text x="25" y="31" text-anchor="middle" font-size="14" font-weight="700" class="white-text">$0</text>
|
||||||
|
<text x="55" y="22" font-size="12" font-weight="600" class="main-text">No Per-User Fee</text>
|
||||||
|
<text x="55" y="38" font-size="10" class="secondary-text">Unlimited Users</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Benefit 3 -->
|
||||||
|
<g transform="translate(510, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="50" rx="8" fill="#FEF3C7"/>
|
||||||
|
<circle cx="25" cy="25" r="15" fill="url(#warningGradient)"/>
|
||||||
|
<text x="25" y="31" text-anchor="middle" font-size="12" font-weight="700" class="white-text">AI</text>
|
||||||
|
<text x="55" y="22" font-size="12" font-weight="600" class="main-text">Native LLM</text>
|
||||||
|
<text x="55" y="38" font-size="10" class="secondary-text">Built-in RAG + Tools</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Benefit 4 -->
|
||||||
|
<g transform="translate(740, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="50" rx="8" fill="#F0FDF4"/>
|
||||||
|
<circle cx="25" cy="25" r="15" fill="url(#successGradient)"/>
|
||||||
|
<text x="25" y="31" text-anchor="middle" font-size="10" font-weight="700" class="white-text">OSS</text>
|
||||||
|
<text x="55" y="22" font-size="12" font-weight="600" class="main-text">Open Source</text>
|
||||||
|
<text x="55" y="38" font-size="10" class="secondary-text">AGPL Licensed</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Benefit 5 -->
|
||||||
|
<g transform="translate(970, 15)">
|
||||||
|
<rect x="0" y="0" width="80" height="50" rx="8" fill="#EEF2FF"/>
|
||||||
|
<text x="40" y="30" text-anchor="middle" font-size="20" font-weight="700" class="accent-text">90+</text>
|
||||||
|
<text x="40" y="45" text-anchor="middle" font-size="9" class="secondary-text">Keywords</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 13 KiB |
124
docs/src/assets/gb-decorative-header.svg
Normal file
124
docs/src/assets/gb-decorative-header.svg
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
<svg width="1200" height="200" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<!-- Primary brand gradient -->
|
||||||
|
<linearGradient id="brandGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
<stop offset="30%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||||
|
<stop offset="60%" style="stop-color:#A855F7;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#D946EF;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Accent gradient -->
|
||||||
|
<linearGradient id="accentGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#06B6D4;stop-opacity:1" />
|
||||||
|
<stop offset="50%" style="stop-color:#3B82F6;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Subtle mesh gradient background -->
|
||||||
|
<radialGradient id="meshGradient1" cx="20%" cy="30%" r="60%" fx="20%" fy="30%">
|
||||||
|
<stop offset="0%" style="stop-color:#818CF8;stop-opacity:0.15" />
|
||||||
|
<stop offset="100%" style="stop-color:#818CF8;stop-opacity:0" />
|
||||||
|
</radialGradient>
|
||||||
|
|
||||||
|
<radialGradient id="meshGradient2" cx="80%" cy="70%" r="50%" fx="80%" fy="70%">
|
||||||
|
<stop offset="0%" style="stop-color:#C084FC;stop-opacity:0.12" />
|
||||||
|
<stop offset="100%" style="stop-color:#C084FC;stop-opacity:0" />
|
||||||
|
</radialGradient>
|
||||||
|
|
||||||
|
<radialGradient id="meshGradient3" cx="50%" cy="20%" r="40%" fx="50%" fy="20%">
|
||||||
|
<stop offset="0%" style="stop-color:#22D3EE;stop-opacity:0.1" />
|
||||||
|
<stop offset="100%" style="stop-color:#22D3EE;stop-opacity:0" />
|
||||||
|
</radialGradient>
|
||||||
|
|
||||||
|
<!-- Glow filter -->
|
||||||
|
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Soft shadow -->
|
||||||
|
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feDropShadow dx="0" dy="2" stdDeviation="6" flood-color="#6366F1" flood-opacity="0.25"/>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Wave pattern -->
|
||||||
|
<pattern id="wavePattern" patternUnits="userSpaceOnUse" width="100" height="20" patternTransform="rotate(-5)">
|
||||||
|
<path d="M0 10 Q25 0 50 10 T100 10" stroke="url(#brandGradient)" stroke-width="0.5" fill="none" opacity="0.3"/>
|
||||||
|
</pattern>
|
||||||
|
|
||||||
|
<!-- Dot pattern -->
|
||||||
|
<pattern id="dotPattern" patternUnits="userSpaceOnUse" width="30" height="30">
|
||||||
|
<circle cx="15" cy="15" r="1" fill="#6366F1" opacity="0.15"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.header-text { fill: #1E1B4B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.sub-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.header-text { fill: #F1F5F9; }
|
||||||
|
.sub-text { fill: #94A3B8; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Background layers -->
|
||||||
|
<rect width="1200" height="200" fill="#FAFBFC"/>
|
||||||
|
<rect width="1200" height="200" fill="url(#dotPattern)"/>
|
||||||
|
<rect width="1200" height="200" fill="url(#meshGradient1)"/>
|
||||||
|
<rect width="1200" height="200" fill="url(#meshGradient2)"/>
|
||||||
|
<rect width="1200" height="200" fill="url(#meshGradient3)"/>
|
||||||
|
|
||||||
|
<!-- Decorative wave lines -->
|
||||||
|
<rect x="0" y="60" width="1200" height="80" fill="url(#wavePattern)" opacity="0.5"/>
|
||||||
|
|
||||||
|
<!-- Decorative circles -->
|
||||||
|
<circle cx="100" cy="100" r="80" fill="none" stroke="url(#brandGradient)" stroke-width="1" opacity="0.2"/>
|
||||||
|
<circle cx="100" cy="100" r="60" fill="none" stroke="url(#accentGradient)" stroke-width="0.5" opacity="0.3"/>
|
||||||
|
<circle cx="100" cy="100" r="40" fill="none" stroke="url(#brandGradient)" stroke-width="0.5" opacity="0.4"/>
|
||||||
|
|
||||||
|
<circle cx="1100" cy="100" r="70" fill="none" stroke="url(#brandGradient)" stroke-width="1" opacity="0.2"/>
|
||||||
|
<circle cx="1100" cy="100" r="50" fill="none" stroke="url(#accentGradient)" stroke-width="0.5" opacity="0.3"/>
|
||||||
|
<circle cx="1100" cy="100" r="30" fill="none" stroke="url(#brandGradient)" stroke-width="0.5" opacity="0.4"/>
|
||||||
|
|
||||||
|
<!-- Floating shapes -->
|
||||||
|
<g opacity="0.6">
|
||||||
|
<rect x="200" y="30" width="12" height="12" rx="2" fill="url(#brandGradient)" transform="rotate(15 206 36)"/>
|
||||||
|
<rect x="950" y="150" width="10" height="10" rx="2" fill="url(#accentGradient)" transform="rotate(-20 955 155)"/>
|
||||||
|
<circle cx="300" cy="160" r="5" fill="#A855F7" opacity="0.5"/>
|
||||||
|
<circle cx="850" cy="40" r="4" fill="#06B6D4" opacity="0.6"/>
|
||||||
|
<circle cx="1000" cy="80" r="3" fill="#8B5CF6" opacity="0.5"/>
|
||||||
|
<circle cx="180" cy="70" r="3" fill="#3B82F6" opacity="0.5"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Central decorative element -->
|
||||||
|
<g transform="translate(600, 100)" filter="url(#softShadow)">
|
||||||
|
<!-- Outer ring -->
|
||||||
|
<circle cx="0" cy="0" r="45" fill="none" stroke="url(#brandGradient)" stroke-width="2" stroke-dasharray="8 4" opacity="0.4"/>
|
||||||
|
|
||||||
|
<!-- Inner hexagon shape -->
|
||||||
|
<path d="M0,-30 L26,-15 L26,15 L0,30 L-26,15 L-26,-15 Z"
|
||||||
|
fill="none" stroke="url(#accentGradient)" stroke-width="1.5" opacity="0.5"/>
|
||||||
|
|
||||||
|
<!-- Center dot -->
|
||||||
|
<circle cx="0" cy="0" r="8" fill="url(#brandGradient)" filter="url(#glow)"/>
|
||||||
|
<circle cx="0" cy="0" r="4" fill="#FFFFFF"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Connecting lines -->
|
||||||
|
<g stroke="url(#brandGradient)" stroke-width="1" opacity="0.2">
|
||||||
|
<line x1="170" y1="100" x2="555" y2="100"/>
|
||||||
|
<line x1="645" y1="100" x2="1030" y2="100"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gradient accent line at bottom -->
|
||||||
|
<rect x="0" y="195" width="1200" height="5" fill="url(#brandGradient)" opacity="0.8"/>
|
||||||
|
|
||||||
|
<!-- Corner accents -->
|
||||||
|
<path d="M0,0 L50,0 L50,5 L5,5 L5,50 L0,50 Z" fill="url(#brandGradient)" opacity="0.3"/>
|
||||||
|
<path d="M1200,0 L1150,0 L1150,5 L1195,5 L1195,50 L1200,50 Z" fill="url(#brandGradient)" opacity="0.3"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
329
docs/src/assets/platform-comparison-summary.svg
Normal file
329
docs/src/assets/platform-comparison-summary.svg
Normal file
|
|
@ -0,0 +1,329 @@
|
||||||
|
<svg width="1200" height="700" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<!-- Gradients -->
|
||||||
|
<linearGradient id="gbGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
|
||||||
|
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="successGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="grayGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#64748B;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#94A3B8;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="headerBg" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
|
||||||
|
<stop offset="50%" style="stop-color:#312E81;stop-opacity:0.08" />
|
||||||
|
<stop offset="100%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Filters -->
|
||||||
|
<filter id="shadow" x="-10%" y="-10%" width="120%" height="130%">
|
||||||
|
<feDropShadow dx="0" dy="4" stdDeviation="6" flood-color="#6366F1" flood-opacity="0.15"/>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Pattern -->
|
||||||
|
<pattern id="dots" patternUnits="userSpaceOnUse" width="20" height="20">
|
||||||
|
<circle cx="10" cy="10" r="1" fill="#6366F1" opacity="0.08"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.title-text { fill: #1E1B4B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.main-text { fill: #334155; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.white-text { fill: #FFFFFF; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
.accent-text { fill: #6366F1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.title-text { fill: #F1F5F9; }
|
||||||
|
.main-text { fill: #E2E8F0; }
|
||||||
|
.secondary-text { fill: #94A3B8; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Background -->
|
||||||
|
<rect width="1200" height="700" fill="#FAFBFC"/>
|
||||||
|
<rect width="1200" height="700" fill="url(#dots)"/>
|
||||||
|
<rect x="0" y="0" width="1200" height="100" fill="url(#headerBg)"/>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<text x="600" y="45" text-anchor="middle" font-size="26" font-weight="700" class="title-text">Platform Comparison Summary</text>
|
||||||
|
<text x="600" y="75" text-anchor="middle" font-size="14" class="secondary-text">General Bots vs Enterprise Cloud Platforms</text>
|
||||||
|
|
||||||
|
<!-- General Bots Card (Highlighted) -->
|
||||||
|
<g transform="translate(50, 120)">
|
||||||
|
<rect x="0" y="0" width="280" height="460" rx="12" fill="#FFFFFF" stroke="#C7D2FE" stroke-width="2" filter="url(#shadow)"/>
|
||||||
|
<rect x="0" y="0" width="280" height="60" rx="12" fill="url(#gbGradient)"/>
|
||||||
|
<rect x="0" y="48" width="280" height="12" fill="url(#gbGradient)"/>
|
||||||
|
<text x="140" y="40" text-anchor="middle" font-size="18" font-weight="700" class="white-text">General Bots</text>
|
||||||
|
|
||||||
|
<!-- Features -->
|
||||||
|
<g transform="translate(20, 80)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Self-Hosted</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 115)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Open Source (AGPL)</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 150)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">No Per-User Fees</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 185)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Native AI (Any LLM)</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 220)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Full Productivity Suite</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 255)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Multi-Channel Chat</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 290)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Unlimited Automation</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 325)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">BASIC Scripting</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 360)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Data Sovereignty</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Price -->
|
||||||
|
<rect x="20" y="395" width="240" height="45" rx="8" fill="#ECFDF5" stroke="#A7F3D0" stroke-width="1"/>
|
||||||
|
<text x="140" y="418" text-anchor="middle" font-size="14" font-weight="700" fill="#10B981">$3K-12K/year</text>
|
||||||
|
<text x="140" y="433" text-anchor="middle" font-size="10" class="secondary-text">100 users • Infrastructure only</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Enterprise Cloud Card -->
|
||||||
|
<g transform="translate(360, 120)">
|
||||||
|
<rect x="0" y="0" width="280" height="460" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#shadow)"/>
|
||||||
|
<rect x="0" y="0" width="280" height="60" rx="12" fill="url(#grayGradient)"/>
|
||||||
|
<rect x="0" y="48" width="280" height="12" fill="url(#grayGradient)"/>
|
||||||
|
<text x="140" y="40" text-anchor="middle" font-size="18" font-weight="700" class="white-text">Enterprise Cloud</text>
|
||||||
|
|
||||||
|
<!-- Features -->
|
||||||
|
<g transform="translate(20, 80)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Cloud Only</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 115)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Proprietary</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 150)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">$12-57/user/month</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 185)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">AI Extra ($30/user)</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 220)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Full Productivity Suite</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 255)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Limited Channels</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 290)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Per-Flow Fees</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 325)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">~</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Limited Scripting</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(20, 360)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="30" y="16" font-size="13" font-weight="500" class="main-text">Vendor Controlled</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Price -->
|
||||||
|
<rect x="20" y="395" width="240" height="45" rx="8" fill="#FEF2F2" stroke="#FECACA" stroke-width="1"/>
|
||||||
|
<text x="140" y="418" text-anchor="middle" font-size="14" font-weight="700" fill="#DC2626">$50K-90K/year</text>
|
||||||
|
<text x="140" y="433" text-anchor="middle" font-size="10" class="secondary-text">100 users • Base + AI + Automation</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Automation Platforms Card -->
|
||||||
|
<g transform="translate(670, 120)">
|
||||||
|
<rect x="0" y="0" width="230" height="460" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#shadow)"/>
|
||||||
|
<rect x="0" y="0" width="230" height="60" rx="12" fill="url(#grayGradient)"/>
|
||||||
|
<rect x="0" y="48" width="230" height="12" fill="url(#grayGradient)"/>
|
||||||
|
<text x="115" y="40" text-anchor="middle" font-size="16" font-weight="700" class="white-text">Automation Tools</text>
|
||||||
|
|
||||||
|
<g transform="translate(15, 80)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">~</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Some Self-Host</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 115)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">~</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Fair-code/Proprietary</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 150)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Per-Task Pricing</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 185)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">AI via Connectors</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 220)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Productivity Suite</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 255)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Native Chat</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 290)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Visual Workflows</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 325)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">~</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">JS/Visual Only</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 360)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">~</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Partial Control</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect x="15" y="395" width="200" height="45" rx="8" fill="#FEF3C7" stroke="#FCD34D" stroke-width="1"/>
|
||||||
|
<text x="115" y="418" text-anchor="middle" font-size="14" font-weight="700" fill="#D97706">$15K-30K/year</text>
|
||||||
|
<text x="115" y="433" text-anchor="middle" font-size="10" class="secondary-text">+ external tools needed</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- AI Assistants Card -->
|
||||||
|
<g transform="translate(920, 120)">
|
||||||
|
<rect x="0" y="0" width="230" height="460" rx="12" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#shadow)"/>
|
||||||
|
<rect x="0" y="0" width="230" height="60" rx="12" fill="url(#grayGradient)"/>
|
||||||
|
<rect x="0" y="48" width="230" height="12" fill="url(#grayGradient)"/>
|
||||||
|
<text x="115" y="40" text-anchor="middle" font-size="16" font-weight="700" class="white-text">AI Assistants</text>
|
||||||
|
|
||||||
|
<g transform="translate(15, 80)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Cloud Only</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 115)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Proprietary</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 150)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#FBBF24"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">$</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Subscription Based</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 185)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="url(#successGradient)"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✓</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Strong AI Built-in</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 220)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Productivity Suite</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 255)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">Web Interface Only</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 290)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Automation</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 325)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Scripting</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(15, 360)">
|
||||||
|
<circle cx="10" cy="12" r="8" fill="#F87171"/>
|
||||||
|
<text x="8" y="16" text-anchor="middle" font-size="10" font-weight="700" class="white-text">✗</text>
|
||||||
|
<text x="28" y="16" font-size="12" font-weight="500" class="main-text">No Data Control</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect x="15" y="395" width="200" height="45" rx="8" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
|
||||||
|
<text x="115" y="418" text-anchor="middle" font-size="14" font-weight="700" class="secondary-text">$2K-5K/year</text>
|
||||||
|
<text x="115" y="433" text-anchor="middle" font-size="10" class="secondary-text">Chat only • Limited scope</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Bottom Summary -->
|
||||||
|
<g transform="translate(50, 605)">
|
||||||
|
<rect x="0" y="0" width="1100" height="70" rx="10" fill="#FFFFFF" stroke="#C7D2FE" stroke-width="2" filter="url(#shadow)"/>
|
||||||
|
|
||||||
|
<g transform="translate(30, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="40" rx="6" fill="#EEF2FF"/>
|
||||||
|
<text x="100" y="18" text-anchor="middle" font-size="18" font-weight="700" class="accent-text">75-95%</text>
|
||||||
|
<text x="100" y="33" text-anchor="middle" font-size="10" class="secondary-text">Cost Reduction</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(260, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="40" rx="6" fill="#ECFDF5"/>
|
||||||
|
<text x="100" y="18" text-anchor="middle" font-size="18" font-weight="700" fill="#10B981">100%</text>
|
||||||
|
<text x="100" y="33" text-anchor="middle" font-size="10" class="secondary-text">Data Sovereignty</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(490, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="40" rx="6" fill="#F5F3FF"/>
|
||||||
|
<text x="100" y="18" text-anchor="middle" font-size="18" font-weight="700" class="accent-text">90+</text>
|
||||||
|
<text x="100" y="33" text-anchor="middle" font-size="10" class="secondary-text">BASIC Keywords</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(720, 15)">
|
||||||
|
<rect x="0" y="0" width="200" height="40" rx="6" fill="#FEF3C7"/>
|
||||||
|
<text x="100" y="18" text-anchor="middle" font-size="18" font-weight="700" fill="#D97706">∞</text>
|
||||||
|
<text x="100" y="33" text-anchor="middle" font-size="10" class="secondary-text">Unlimited Users</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(950, 15)">
|
||||||
|
<rect x="0" y="0" width="120" height="40" rx="6" fill="url(#gbGradient)"/>
|
||||||
|
<text x="60" y="27" text-anchor="middle" font-size="12" font-weight="600" class="white-text">Open Source</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 19 KiB |
240
docs/src/chapter-04-gbui/ui-structure.md
Normal file
240
docs/src/chapter-04-gbui/ui-structure.md
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
# UI Structure
|
||||||
|
|
||||||
|
The BotServer UI system provides two interface implementations designed for different deployment scenarios. Choose the right interface based on your use case and performance requirements.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Directory Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
ui/
|
||||||
|
├── suite/ # Full-featured interface
|
||||||
|
│ ├── index.html
|
||||||
|
│ ├── js/
|
||||||
|
│ ├── css/
|
||||||
|
│ ├── public/
|
||||||
|
│ ├── drive/
|
||||||
|
│ ├── chat/
|
||||||
|
│ ├── mail/
|
||||||
|
│ ├── tasks/
|
||||||
|
│ ├── default.gbui
|
||||||
|
│ └── single.gbui
|
||||||
|
│
|
||||||
|
└── minimal/ # Lightweight interface
|
||||||
|
├── index.html
|
||||||
|
├── styles.css
|
||||||
|
└── app.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Suite Interface
|
||||||
|
|
||||||
|
The Suite interface (`ui/suite/`) delivers a comprehensive, desktop-class experience with multi-application integration. It includes Chat, Drive, Tasks, and Mail modules in a unified workspace.
|
||||||
|
|
||||||
|
**Capabilities:**
|
||||||
|
- Multi-application integration with seamless navigation
|
||||||
|
- Rich interactions and complex workflows
|
||||||
|
- Responsive design across desktop, tablet, and mobile
|
||||||
|
- Customizable GBUI templates (`default.gbui` for full layout, `single.gbui` for chat-focused)
|
||||||
|
- Tauri integration for native desktop packaging
|
||||||
|
|
||||||
|
**When to use Suite:**
|
||||||
|
- Enterprise deployments requiring full functionality
|
||||||
|
- Power users working with multiple services
|
||||||
|
- Desktop application distribution via Tauri
|
||||||
|
- Multi-service integrations where context switching matters
|
||||||
|
|
||||||
|
**Access:**
|
||||||
|
- Web: `http://localhost:8080/suite`
|
||||||
|
- Desktop: Via Tauri build with `--desktop` flag
|
||||||
|
|
||||||
|
## Minimal Interface
|
||||||
|
|
||||||
|
The Minimal interface (`ui/minimal/`) prioritizes speed and simplicity. It loads fast, uses minimal resources, and focuses on essential chat interactions.
|
||||||
|
|
||||||
|
**Capabilities:**
|
||||||
|
- Core chat and basic interactions only
|
||||||
|
- Fast loading with minimal dependencies
|
||||||
|
- Low resource usage for constrained environments
|
||||||
|
- Easy embedding into existing applications
|
||||||
|
- Mobile-first design approach
|
||||||
|
|
||||||
|
**When to use Minimal:**
|
||||||
|
- Mobile web access
|
||||||
|
- Embedded chatbots in external websites
|
||||||
|
- Low-bandwidth environments
|
||||||
|
- Quick access terminals and kiosks
|
||||||
|
- Scenarios where simplicity matters more than features
|
||||||
|
|
||||||
|
**Access:**
|
||||||
|
- Default: `http://localhost:8080` (served at root)
|
||||||
|
- Explicit: `http://localhost:8080/minimal`
|
||||||
|
- Embedded: Via iframe or WebView
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Server Configuration
|
||||||
|
|
||||||
|
UI paths are configured in several locations:
|
||||||
|
|
||||||
|
**Main Server** (`src/main.rs`):
|
||||||
|
```rust
|
||||||
|
let static_path = std::path::Path::new("./web/suite");
|
||||||
|
```
|
||||||
|
|
||||||
|
**UI Server Module** (`src/core/ui_server/mod.rs`):
|
||||||
|
```rust
|
||||||
|
let static_path = PathBuf::from("./ui/suite");
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tauri Configuration** (`tauri.conf.json`):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"frontendDist": "./ui/suite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Routing
|
||||||
|
|
||||||
|
Both interfaces can be served simultaneously with different routes:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
Router::new()
|
||||||
|
.route("/", get(serve_minimal))
|
||||||
|
.route("/minimal", get(serve_minimal))
|
||||||
|
.route("/suite", get(serve_suite))
|
||||||
|
```
|
||||||
|
|
||||||
|
The minimal interface serves at root by default, providing faster loading for most users.
|
||||||
|
|
||||||
|
## API Compliance
|
||||||
|
|
||||||
|
The Minimal UI implements full compliance with the Bot Core API. Both interfaces support the same backend endpoints.
|
||||||
|
|
||||||
|
**Supported Endpoints:**
|
||||||
|
|
||||||
|
| Endpoint | Method | Purpose |
|
||||||
|
|----------|--------|---------|
|
||||||
|
| `/ws` | WebSocket | Real-time messaging |
|
||||||
|
| `/api/auth` | GET | Authentication |
|
||||||
|
| `/api/sessions` | GET/POST | Session management |
|
||||||
|
| `/api/sessions/{id}` | GET | Session details |
|
||||||
|
| `/api/sessions/{id}/history` | GET | Message history |
|
||||||
|
| `/api/sessions/{id}/start` | POST | Start session |
|
||||||
|
| `/api/voice/start` | POST | Voice input start |
|
||||||
|
| `/api/voice/stop` | POST | Voice input stop |
|
||||||
|
|
||||||
|
**WebSocket Protocol:**
|
||||||
|
|
||||||
|
Both interfaces use the same message types:
|
||||||
|
- `TEXT (1)` - Regular text messages
|
||||||
|
- `VOICE (2)` - Voice messages
|
||||||
|
- `CONTINUE (3)` - Continue interrupted responses
|
||||||
|
- `CONTEXT (4)` - Context changes
|
||||||
|
- `SYSTEM (5)` - System messages
|
||||||
|
|
||||||
|
## Performance Characteristics
|
||||||
|
|
||||||
|
### Suite Interface
|
||||||
|
|
||||||
|
| Metric | Typical Value |
|
||||||
|
|--------|---------------|
|
||||||
|
| Initial load | ~500KB |
|
||||||
|
| Time to interactive | ~1.5s |
|
||||||
|
| Memory usage | ~80MB |
|
||||||
|
| Best for | Full productivity |
|
||||||
|
|
||||||
|
### Minimal Interface
|
||||||
|
|
||||||
|
| Metric | Typical Value |
|
||||||
|
|--------|---------------|
|
||||||
|
| Initial load | ~50KB |
|
||||||
|
| Time to interactive | ~200ms |
|
||||||
|
| Memory usage | ~20MB |
|
||||||
|
| Best for | Quick interactions |
|
||||||
|
|
||||||
|
## Browser Support
|
||||||
|
|
||||||
|
Both interfaces support modern browsers:
|
||||||
|
|
||||||
|
| Browser | Minimum Version | WebSocket | Voice |
|
||||||
|
|---------|----------------|-----------|-------|
|
||||||
|
| Chrome | 90+ | ✅ | ✅ |
|
||||||
|
| Firefox | 88+ | ✅ | ✅ |
|
||||||
|
| Safari | 14+ | ✅ | ✅ |
|
||||||
|
| Edge | 90+ | ✅ | ✅ |
|
||||||
|
| Mobile Chrome | 90+ | ✅ | ✅ |
|
||||||
|
| Mobile Safari | 14+ | ✅ | ✅ |
|
||||||
|
|
||||||
|
## Switching Interfaces
|
||||||
|
|
||||||
|
Users can switch between interfaces by navigating to the appropriate URL. For programmatic switching, update the `ui_server/mod.rs` to change the default:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Serve minimal at root (default)
|
||||||
|
match fs::read_to_string("ui/minimal/index.html")
|
||||||
|
|
||||||
|
// Or serve suite at root
|
||||||
|
match fs::read_to_string("ui/suite/index.html")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**404 Errors:**
|
||||||
|
- Clear browser cache
|
||||||
|
- Rebuild: `cargo clean && cargo build`
|
||||||
|
- Verify files exist in `ui/suite/` or `ui/minimal/`
|
||||||
|
|
||||||
|
**Tauri Build Failures:**
|
||||||
|
- Check `tauri.conf.json` has correct `frontendDist` path
|
||||||
|
- Ensure `ui/suite/index.html` exists
|
||||||
|
|
||||||
|
**Static Files Not Loading:**
|
||||||
|
- Verify `ServeDir` configuration in router
|
||||||
|
- Check subdirectories (js, css, public) exist
|
||||||
|
|
||||||
|
**Debug Commands:**
|
||||||
|
```bash
|
||||||
|
# Verify UI structure
|
||||||
|
ls -la ui/suite/
|
||||||
|
ls -la ui/minimal/
|
||||||
|
|
||||||
|
# Test interfaces
|
||||||
|
curl http://localhost:8080/
|
||||||
|
curl http://localhost:8080/suite/
|
||||||
|
|
||||||
|
# Check static file serving
|
||||||
|
curl http://localhost:8080/js/app.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### GBUI Templates
|
||||||
|
|
||||||
|
The Suite interface uses GBUI templates for layout customization:
|
||||||
|
|
||||||
|
- `default.gbui` - Full multi-app layout with sidebar
|
||||||
|
- `single.gbui` - Streamlined chat-focused view
|
||||||
|
|
||||||
|
Edit these files to customize the interface structure without modifying core code.
|
||||||
|
|
||||||
|
### CSS Theming
|
||||||
|
|
||||||
|
Both interfaces support CSS customization through their respective stylesheets. The Suite interface provides more theming options through CSS custom properties.
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
Planned improvements include:
|
||||||
|
|
||||||
|
- Dynamic UI selection based on device capabilities
|
||||||
|
- Progressive enhancement from minimal to suite
|
||||||
|
- Service worker implementation for offline support
|
||||||
|
- WebAssembly components for high-performance features
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [default.gbui Reference](./default-gbui.md) - Full desktop template
|
||||||
|
- [single.gbui Reference](./single-gbui.md) - Simple chat template
|
||||||
|
- [Console Mode](./console-mode.md) - Terminal interface
|
||||||
|
- [Monitoring Dashboard](./monitoring.md) - System observability
|
||||||
|
|
@ -1 +1,158 @@
|
||||||
# DELETE FILE
|
# DELETE
|
||||||
|
|
||||||
|
The `DELETE` keyword removes resources using dynamic path interpretation, similar to how `GET` works. The system automatically determines the appropriate operation based on the path provided.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE path
|
||||||
|
DELETE path, options
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dynamic Path Interpretation
|
||||||
|
|
||||||
|
Like `GET`, `DELETE` interprets the path and selects the appropriate engine:
|
||||||
|
|
||||||
|
| Path Pattern | Operation |
|
||||||
|
|--------------|-----------|
|
||||||
|
| `/files/document.pdf` | Delete file from storage |
|
||||||
|
| `/users/user-id` | Delete user |
|
||||||
|
| `/tasks/task-id` | Delete task |
|
||||||
|
| `/projects/project-id` | Delete project |
|
||||||
|
| `https://api.example.com/items/123` | HTTP DELETE to external API |
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Delete a File
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "/reports/old-report.pdf"
|
||||||
|
TALK "File deleted"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete from External API
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "https://api.crm.com/contacts/12345"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete with Condition
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Delete all files older than 30 days
|
||||||
|
files = LIST "/temp/"
|
||||||
|
FOR EACH file IN files
|
||||||
|
IF DATEDIFF("day", file.modified, NOW()) > 30 THEN
|
||||||
|
DELETE "/temp/" + file.name
|
||||||
|
END IF
|
||||||
|
NEXT file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete a Task
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "/tasks/" + task_id
|
||||||
|
TALK "Task removed"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete a User
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "/users/" + user_id
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete a Project
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "/projects/" + project_id
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
Pass options as a second parameter for additional control:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Soft delete (archive instead of permanent removal)
|
||||||
|
DELETE "/files/report.pdf", #{soft: true}
|
||||||
|
|
||||||
|
' Force delete (bypass confirmation)
|
||||||
|
DELETE "/files/temp/", #{force: true, recursive: true}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Return Value
|
||||||
|
|
||||||
|
`DELETE` returns information about the operation:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
result = DELETE "/files/document.pdf"
|
||||||
|
IF result.success THEN
|
||||||
|
TALK "Deleted: " + result.path
|
||||||
|
ELSE
|
||||||
|
TALK "Failed: " + result.error
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTTP DELETE
|
||||||
|
|
||||||
|
When the path is a full URL, `DELETE` performs an HTTP DELETE request:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Delete via REST API
|
||||||
|
DELETE "https://api.service.com/items/456"
|
||||||
|
|
||||||
|
' With authentication
|
||||||
|
SET HEADER "Authorization", "Bearer " + token
|
||||||
|
DELETE "https://api.service.com/items/456"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Records
|
||||||
|
|
||||||
|
For database operations, use the `DELETE` keyword with table syntax:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Delete specific records
|
||||||
|
DELETE "orders", "status = 'cancelled' AND created_at < '2024-01-01'"
|
||||||
|
|
||||||
|
' Delete by ID
|
||||||
|
DELETE "customers", "id = '" + customer_id + "'"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Verify before deleting.** Confirm the resource exists and the user has permission:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
file = GET "/files/" + filename
|
||||||
|
IF file THEN
|
||||||
|
DELETE "/files/" + filename
|
||||||
|
ELSE
|
||||||
|
TALK "File not found"
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use soft deletes for important data.** Archive rather than permanently remove:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Move to archive instead of delete
|
||||||
|
MOVE "/active/" + filename, "/archive/" + filename
|
||||||
|
```
|
||||||
|
|
||||||
|
**Log deletions for audit trails:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE "/files/" + filename
|
||||||
|
INSERT "audit_log", #{
|
||||||
|
action: "delete",
|
||||||
|
path: filename,
|
||||||
|
user: user.id,
|
||||||
|
timestamp: NOW()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [GET](./keyword-get.md) - Dynamic resource retrieval
|
||||||
|
- [LIST](./keyword-list.md) - List resources before deletion
|
||||||
|
- [MOVE](./keyword-move.md) - Move instead of delete
|
||||||
|
|
@ -1,26 +1,398 @@
|
||||||
# HEAR Keyword
|
# HEAR Keyword
|
||||||
|
|
||||||
**Syntax**
|
The `HEAR` keyword pauses script execution and waits for user input. With optional type validation, it automatically verifies and normalizes input, retrying with helpful error messages when validation fails.
|
||||||
|
|
||||||
```
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
HEAR variable_name
|
|
||||||
```
|
|
||||||
|
|
||||||
**Parameters**
|
## Basic Syntax
|
||||||
|
|
||||||
- `variable_name` – Identifier where the user’s next message will be stored.
|
|
||||||
|
|
||||||
**Description**
|
|
||||||
|
|
||||||
`HEAR` pauses script execution and waits for the next user input. The received text is assigned to the specified variable, which can then be used in subsequent commands.
|
|
||||||
|
|
||||||
**Example (from `start.bas`)**
|
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
HEAR user_input
|
HEAR variable_name
|
||||||
IF user_input = "help" THEN
|
HEAR variable_name AS TYPE
|
||||||
TALK "Sure, I can assist with account info, orders, or support."
|
HEAR variable_name AS "Option1", "Option2", "Option3"
|
||||||
ENDIF
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The script waits for the user to type a message, stores it in `user_input`, and then evaluates the condition.
|
The simplest form accepts any input. Adding `AS TYPE` enables automatic validation with user-friendly retry prompts.
|
||||||
|
|
||||||
|
## Simple HEAR
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What would you like to know?"
|
||||||
|
HEAR question
|
||||||
|
TALK "You asked: " + question
|
||||||
|
```
|
||||||
|
|
||||||
|
The script waits for any user message and stores it in the variable.
|
||||||
|
|
||||||
|
## Validated Input Types
|
||||||
|
|
||||||
|
When using `HEAR AS <TYPE>`, the system validates input automatically, retries up to 3 times with helpful messages, and returns normalized values.
|
||||||
|
|
||||||
|
### Text Types
|
||||||
|
|
||||||
|
**EMAIL** validates email format and normalizes to lowercase:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What's your email address?"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
TALK "We'll send confirmation to: " + email
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `User@Example.COM` → Returns: `user@example.com`
|
||||||
|
|
||||||
|
**NAME** validates name format with proper capitalization:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What's your full name?"
|
||||||
|
HEAR name AS NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts letters, spaces, hyphens, apostrophes. Auto-capitalizes: `john doe` → `John Doe`
|
||||||
|
|
||||||
|
**URL** validates and normalizes URLs:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter your website:"
|
||||||
|
HEAR website AS URL
|
||||||
|
```
|
||||||
|
|
||||||
|
Auto-adds `https://` if protocol missing.
|
||||||
|
|
||||||
|
**PASSWORD** validates minimum strength:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Create a password (minimum 8 characters):"
|
||||||
|
HEAR password AS PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires 8+ characters. Never echoes the actual password back.
|
||||||
|
|
||||||
|
**COLOR** accepts color names or hex values:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR color AS COLOR
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `red`, `#FF0000`, `rgb(255, 0, 0)` → Returns: `#FF0000`
|
||||||
|
|
||||||
|
### Numeric Types
|
||||||
|
|
||||||
|
**INTEGER** validates whole numbers:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "How many items?"
|
||||||
|
HEAR quantity AS INTEGER
|
||||||
|
```
|
||||||
|
|
||||||
|
Removes formatting (commas, spaces). Returns numeric value.
|
||||||
|
|
||||||
|
**FLOAT** / **DECIMAL** validates decimal numbers:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter the temperature:"
|
||||||
|
HEAR temperature AS FLOAT
|
||||||
|
```
|
||||||
|
|
||||||
|
Handles both `.` and `,` as decimal separators.
|
||||||
|
|
||||||
|
**MONEY** / **CURRENCY** / **AMOUNT** validates monetary values:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "How much to transfer?"
|
||||||
|
HEAR amount AS MONEY
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `100`, `1,234.56`, `R$ 100,00`, `$100.00` → Returns: `1234.56`
|
||||||
|
|
||||||
|
**CREDITCARD** / **CARD** validates card numbers with Luhn algorithm:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter your card number:"
|
||||||
|
HEAR card AS CREDITCARD
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns masked format: `4111 **** **** 1111`
|
||||||
|
|
||||||
|
### Date and Time Types
|
||||||
|
|
||||||
|
**DATE** validates and parses dates:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "When is your birthday?"
|
||||||
|
HEAR birthday AS DATE
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `25/12/2024`, `12/25/2024`, `2024-12-25`, `December 25, 2024`, `today`, `tomorrow`, `hoje`, `amanhã`
|
||||||
|
|
||||||
|
Returns: ISO format `YYYY-MM-DD`
|
||||||
|
|
||||||
|
**HOUR** / **TIME** validates time input:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What time for the meeting?"
|
||||||
|
HEAR meeting_time AS HOUR
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `14:30`, `2:30 PM` → Returns: `14:30`
|
||||||
|
|
||||||
|
### Brazilian Document Types
|
||||||
|
|
||||||
|
**CPF** validates Brazilian individual taxpayer ID:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter your CPF:"
|
||||||
|
HEAR cpf AS CPF
|
||||||
|
```
|
||||||
|
|
||||||
|
Validates 11 digits with mod 11 check. Returns: `123.456.789-09`
|
||||||
|
|
||||||
|
**CNPJ** validates Brazilian company taxpayer ID:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter your company's CNPJ:"
|
||||||
|
HEAR cnpj AS CNPJ
|
||||||
|
```
|
||||||
|
|
||||||
|
Validates 14 digits. Returns: `12.345.678/0001-95`
|
||||||
|
|
||||||
|
### Contact Types
|
||||||
|
|
||||||
|
**MOBILE** / **PHONE** validates phone numbers:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What's your phone number?"
|
||||||
|
HEAR phone AS MOBILE
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts 10-15 digits, auto-formats based on detected country.
|
||||||
|
|
||||||
|
**ZIPCODE** / **CEP** / **POSTALCODE** validates postal codes:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR cep AS ZIPCODE
|
||||||
|
```
|
||||||
|
|
||||||
|
Supports Brazilian CEP, US ZIP, UK postcode formats.
|
||||||
|
|
||||||
|
### Menu Selection
|
||||||
|
|
||||||
|
Provide options directly in the HEAR statement:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Choose your fruit:"
|
||||||
|
HEAR fruit AS "Apple", "Banana", "Orange", "Mango"
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts exact match, case-insensitive match, numeric selection (`1`, `2`, `3`), or partial match if unique.
|
||||||
|
|
||||||
|
**BOOLEAN** validates yes/no responses:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Do you agree to the terms?"
|
||||||
|
HEAR agreed AS BOOLEAN
|
||||||
|
IF agreed THEN
|
||||||
|
TALK "Thank you!"
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
True: `yes`, `y`, `sim`, `ok`, `sure`, `confirm`
|
||||||
|
False: `no`, `n`, `não`, `cancel`, `deny`
|
||||||
|
|
||||||
|
**LANGUAGE** validates language codes:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR language AS LANGUAGE
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts: `en`, `pt`, `English`, `Português` → Returns: ISO 639-1 code
|
||||||
|
|
||||||
|
### Media Types
|
||||||
|
|
||||||
|
**IMAGE** / **PHOTO** waits for image upload:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Send a photo of your document:"
|
||||||
|
HEAR document_photo AS IMAGE
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns URL to uploaded image.
|
||||||
|
|
||||||
|
**QRCODE** waits for image and decodes QR:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Send me the QR code:"
|
||||||
|
HEAR qr_data AS QRCODE
|
||||||
|
```
|
||||||
|
|
||||||
|
Uses vision API to decode. Returns decoded data.
|
||||||
|
|
||||||
|
**AUDIO** / **VOICE** transcribes audio input:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Send a voice message:"
|
||||||
|
HEAR transcription AS AUDIO
|
||||||
|
```
|
||||||
|
|
||||||
|
Uses Whisper for transcription. Returns text.
|
||||||
|
|
||||||
|
**VIDEO** analyzes video content:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Send a video of the issue:"
|
||||||
|
HEAR video_description AS VIDEO
|
||||||
|
```
|
||||||
|
|
||||||
|
Uses vision API to describe. Returns description.
|
||||||
|
|
||||||
|
**FILE** / **DOCUMENT** waits for file upload:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Upload your contract:"
|
||||||
|
HEAR contract AS DOCUMENT
|
||||||
|
```
|
||||||
|
|
||||||
|
Accepts PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT, CSV. Returns URL.
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
**LOGIN** waits for OAuth completion:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Click the link to authenticate:"
|
||||||
|
HEAR user AS LOGIN
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns user object with tokens after OAuth callback.
|
||||||
|
|
||||||
|
## Complete Examples
|
||||||
|
|
||||||
|
### Registration Flow
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Let's create your account!"
|
||||||
|
|
||||||
|
TALK "What's your full name?"
|
||||||
|
HEAR name AS NAME
|
||||||
|
|
||||||
|
TALK "Enter your email address:"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
TALK "Enter your CPF:"
|
||||||
|
HEAR cpf AS CPF
|
||||||
|
|
||||||
|
TALK "What's your phone number?"
|
||||||
|
HEAR phone AS MOBILE
|
||||||
|
|
||||||
|
TALK "Choose a password:"
|
||||||
|
HEAR password AS PASSWORD
|
||||||
|
|
||||||
|
TALK "What's your birth date?"
|
||||||
|
HEAR birthdate AS DATE
|
||||||
|
|
||||||
|
TALK "Select your gender:"
|
||||||
|
HEAR gender AS "Male", "Female", "Other", "Prefer not to say"
|
||||||
|
|
||||||
|
SAVE "users.csv", name, email, cpf, phone, birthdate, gender, NOW()
|
||||||
|
TALK "Account created for " + name + "!"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Payment Flow
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter the amount:"
|
||||||
|
HEAR amount AS MONEY
|
||||||
|
|
||||||
|
IF amount < 1 THEN
|
||||||
|
TALK "Minimum payment is R$ 1.00"
|
||||||
|
RETURN
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "How would you like to pay?"
|
||||||
|
HEAR method AS "Credit Card", "Debit Card", "PIX", "Boleto"
|
||||||
|
|
||||||
|
TALK "Confirm payment of R$ " + FORMAT(amount, "#,##0.00") + "?"
|
||||||
|
HEAR confirm AS BOOLEAN
|
||||||
|
|
||||||
|
IF confirm THEN
|
||||||
|
TALK "Processing payment..."
|
||||||
|
ELSE
|
||||||
|
TALK "Payment cancelled."
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Behavior
|
||||||
|
|
||||||
|
When validation fails, the system automatically prompts for correction:
|
||||||
|
|
||||||
|
```
|
||||||
|
User: my email
|
||||||
|
Bot: Please enter a valid email address (e.g., user@example.com)
|
||||||
|
User: test@example.com
|
||||||
|
Bot: Email confirmed!
|
||||||
|
```
|
||||||
|
|
||||||
|
After 3 failed attempts, execution continues with an empty value. Check for this:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
IF email = "" THEN
|
||||||
|
TALK "Unable to validate email. Please contact support."
|
||||||
|
RETURN
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Always use appropriate types** — automatic validation is safer than manual checking:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Good
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
' Avoid
|
||||||
|
HEAR email
|
||||||
|
IF NOT email CONTAINS "@" THEN ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Provide context before HEAR** — users should know what to enter:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Enter the transfer amount (minimum R$ 1.00):"
|
||||||
|
HEAR amount AS MONEY
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use menus for limited options**:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR method AS "Credit Card", "Debit Card", "PIX"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Combine with SET CONTEXT** for AI-enhanced input handling:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are a banking assistant. Confirm amounts before processing."
|
||||||
|
HEAR amount AS MONEY
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Summary
|
||||||
|
|
||||||
|
| Type | Example Input | Normalized Output |
|
||||||
|
|------|---------------|-------------------|
|
||||||
|
| EMAIL | `User@Example.COM` | `user@example.com` |
|
||||||
|
| NAME | `john DOE` | `John Doe` |
|
||||||
|
| INTEGER | `1,234` | `1234` |
|
||||||
|
| MONEY | `R$ 1.234,56` | `1234.56` |
|
||||||
|
| DATE | `25/12/2024` | `2024-12-25` |
|
||||||
|
| HOUR | `2:30 PM` | `14:30` |
|
||||||
|
| BOOLEAN | `yes` / `sim` | `true` |
|
||||||
|
| CPF | `12345678909` | `123.456.789-09` |
|
||||||
|
| MOBILE | `11999998888` | `(11) 99999-8888` |
|
||||||
|
| CREDITCARD | `4111111111111111` | `4111 **** **** 1111` |
|
||||||
|
| QRCODE | [image] | decoded data |
|
||||||
|
| AUDIO | [audio file] | transcribed text |
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [TALK Keyword](./keyword-talk.md) - Output messages
|
||||||
|
- [Dialog Basics](./basics.md) - Conversation patterns
|
||||||
|
- [Template Variables](./template-variables.md) - Variable substitution
|
||||||
342
docs/src/chapter-06-gbdialog/keywords-lead-scoring.md
Normal file
342
docs/src/chapter-06-gbdialog/keywords-lead-scoring.md
Normal file
|
|
@ -0,0 +1,342 @@
|
||||||
|
# Lead Scoring Keywords
|
||||||
|
|
||||||
|
General Bots includes native lead scoring capabilities through BASIC keywords, enabling automated lead qualification, AI-enhanced scoring, and CRM integration directly from conversational flows.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Lead scoring assigns numeric values to prospects based on their attributes and behaviors. Higher scores indicate greater sales readiness. General Bots provides both rule-based and AI-enhanced scoring approaches.
|
||||||
|
|
||||||
|
## SCORE LEAD
|
||||||
|
|
||||||
|
Calculate a lead score based on profile and behavior data using configurable rules.
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
```basic
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```basic
|
||||||
|
lead_data = NEW OBJECT
|
||||||
|
lead_data.email = "john@company.com"
|
||||||
|
lead_data.name = "John Smith"
|
||||||
|
lead_data.company = "Acme Corp"
|
||||||
|
lead_data.job_title = "VP of Engineering"
|
||||||
|
lead_data.industry = "Technology"
|
||||||
|
lead_data.company_size = "Enterprise"
|
||||||
|
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
|
||||||
|
TALK "Score: " + score.score
|
||||||
|
TALK "Grade: " + score.grade
|
||||||
|
TALK "Status: " + score.status
|
||||||
|
TALK "Top recommendation: " + score.recommendations[0]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Return Object
|
||||||
|
|
||||||
|
The `SCORE LEAD` keyword returns an object containing:
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `score` | Integer | Numeric score (0-100) |
|
||||||
|
| `grade` | String | Letter grade (A, B, C, D, F) |
|
||||||
|
| `status` | String | hot, warm, cold, or unqualified |
|
||||||
|
| `breakdown` | Object | Score components by category |
|
||||||
|
| `recommendations` | Array | Suggested next actions |
|
||||||
|
|
||||||
|
### Score Breakdown
|
||||||
|
|
||||||
|
```basic
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
|
||||||
|
TALK "Demographic score: " + score.breakdown.demographic
|
||||||
|
TALK "Firmographic score: " + score.breakdown.firmographic
|
||||||
|
TALK "Behavioral score: " + score.breakdown.behavioral
|
||||||
|
TALK "Engagement score: " + score.breakdown.engagement
|
||||||
|
```
|
||||||
|
|
||||||
|
## AI SCORE LEAD
|
||||||
|
|
||||||
|
Use AI/LLM-enhanced scoring for more nuanced lead evaluation.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
score = AI SCORE LEAD lead_data
|
||||||
|
|
||||||
|
TALK "AI Score: " + score.score
|
||||||
|
TALK "Confidence: " + score.breakdown.ai_confidence
|
||||||
|
TALK "Reasoning: " + score.breakdown.ai_reasoning
|
||||||
|
```
|
||||||
|
|
||||||
|
AI scoring considers factors that rule-based scoring might miss, such as company news, market conditions, and subtle signals in communication patterns.
|
||||||
|
|
||||||
|
### When to Use AI Scoring
|
||||||
|
|
||||||
|
AI scoring works best for complex B2B scenarios where context matters significantly. Rule-based scoring is faster and sufficient for high-volume B2C leads with clear qualification criteria.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Use AI for enterprise leads, rules for SMB
|
||||||
|
IF lead_data.company_size = "Enterprise" THEN
|
||||||
|
score = AI SCORE LEAD lead_data
|
||||||
|
ELSE
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## GET LEAD SCORE
|
||||||
|
|
||||||
|
Retrieve an existing lead score from the database.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
score = GET LEAD SCORE "lead-id"
|
||||||
|
TALK "Current score: " + score.score
|
||||||
|
TALK "Last updated: " + score.updated_at
|
||||||
|
```
|
||||||
|
|
||||||
|
## QUALIFY LEAD
|
||||||
|
|
||||||
|
Check if a lead meets the qualification threshold for sales handoff.
|
||||||
|
|
||||||
|
### Default Threshold (70)
|
||||||
|
|
||||||
|
```basic
|
||||||
|
result = QUALIFY LEAD "lead-id"
|
||||||
|
IF result.qualified THEN
|
||||||
|
TALK "Lead is qualified: " + result.status
|
||||||
|
' Notify sales team
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "New Qualified Lead" BODY result
|
||||||
|
ELSE
|
||||||
|
TALK "Lead needs more nurturing. Score: " + result.score
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Threshold
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Enterprise deals require higher qualification
|
||||||
|
result = QUALIFY LEAD "lead-id", 85
|
||||||
|
|
||||||
|
IF result.qualified THEN
|
||||||
|
TALK "Enterprise lead qualified for sales"
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Qualification Result
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `qualified` | Boolean | Meets threshold |
|
||||||
|
| `score` | Integer | Current score |
|
||||||
|
| `threshold` | Integer | Applied threshold |
|
||||||
|
| `status` | String | Current lead status |
|
||||||
|
| `gap` | Integer | Points needed if not qualified |
|
||||||
|
|
||||||
|
## UPDATE LEAD SCORE
|
||||||
|
|
||||||
|
Manually adjust a lead's score based on specific actions or behaviors.
|
||||||
|
|
||||||
|
### Add Points
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Lead attended webinar
|
||||||
|
new_score = UPDATE LEAD SCORE "lead-id", 10, "Attended product webinar"
|
||||||
|
TALK "Score updated to: " + new_score.score
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deduct Points
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Lead unsubscribed from newsletter
|
||||||
|
new_score = UPDATE LEAD SCORE "lead-id", -15, "Unsubscribed from email"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Behavioral Scoring
|
||||||
|
|
||||||
|
```basic
|
||||||
|
ON "webinar:attended"
|
||||||
|
UPDATE LEAD SCORE params.lead_id, 15, "Webinar attendance"
|
||||||
|
END ON
|
||||||
|
|
||||||
|
ON "pricing:viewed"
|
||||||
|
UPDATE LEAD SCORE params.lead_id, 20, "Viewed pricing page"
|
||||||
|
END ON
|
||||||
|
|
||||||
|
ON "demo:requested"
|
||||||
|
UPDATE LEAD SCORE params.lead_id, 30, "Requested demo"
|
||||||
|
END ON
|
||||||
|
|
||||||
|
ON "email:bounced"
|
||||||
|
UPDATE LEAD SCORE params.lead_id, -25, "Email bounced"
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Lead Nurturing Flow
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' lead-nurturing.bas
|
||||||
|
PARAM email AS string
|
||||||
|
PARAM name AS string
|
||||||
|
PARAM company AS string
|
||||||
|
PARAM source AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Process and score new leads"
|
||||||
|
|
||||||
|
' Build lead profile
|
||||||
|
WITH lead
|
||||||
|
.email = email
|
||||||
|
.name = name
|
||||||
|
.company = company
|
||||||
|
.source = source
|
||||||
|
.created_at = NOW()
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
' Initial scoring
|
||||||
|
score = SCORE LEAD lead
|
||||||
|
|
||||||
|
' Store lead
|
||||||
|
INSERT "leads", lead
|
||||||
|
SET BOT MEMORY "lead_" + email + "_score", score.score
|
||||||
|
|
||||||
|
' Route based on score
|
||||||
|
IF score.status = "hot" THEN
|
||||||
|
' Immediate sales notification
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Hot Lead: " + name BODY score
|
||||||
|
SEND TEMPLATE "hot-lead-welcome", "email", email, #{name: name}
|
||||||
|
|
||||||
|
ELSEIF score.status = "warm" THEN
|
||||||
|
' Schedule nurture sequence
|
||||||
|
SEND TEMPLATE "welcome", "email", email, #{name: name}
|
||||||
|
SET SCHEDULE DATEADD(NOW(), 3, "day"), "nurture-day-3.bas"
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
' Cold lead - educational content
|
||||||
|
SEND TEMPLATE "educational", "email", email, #{name: name}
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Lead " + name + " processed with score " + score.score + " (" + score.status + ")"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lead Scoring Configuration
|
||||||
|
|
||||||
|
Configure scoring weights in your bot's `config.csv`:
|
||||||
|
|
||||||
|
```csv
|
||||||
|
key,value
|
||||||
|
lead-score-job-title-weight,20
|
||||||
|
lead-score-company-size-weight,15
|
||||||
|
lead-score-industry-weight,10
|
||||||
|
lead-score-engagement-weight,25
|
||||||
|
lead-score-behavioral-weight,30
|
||||||
|
lead-score-qualification-threshold,70
|
||||||
|
```
|
||||||
|
|
||||||
|
### Title-Based Scoring
|
||||||
|
|
||||||
|
| Job Title Pattern | Points |
|
||||||
|
|-------------------|--------|
|
||||||
|
| C-Level (CEO, CTO, CFO) | 25 |
|
||||||
|
| VP / Vice President | 20 |
|
||||||
|
| Director | 15 |
|
||||||
|
| Manager | 10 |
|
||||||
|
| Individual Contributor | 5 |
|
||||||
|
|
||||||
|
### Company Size Scoring
|
||||||
|
|
||||||
|
| Company Size | Points |
|
||||||
|
|--------------|--------|
|
||||||
|
| Enterprise (1000+) | 20 |
|
||||||
|
| Mid-Market (100-999) | 15 |
|
||||||
|
| SMB (10-99) | 10 |
|
||||||
|
| Small (1-9) | 5 |
|
||||||
|
|
||||||
|
### Behavioral Actions
|
||||||
|
|
||||||
|
| Action | Typical Points |
|
||||||
|
|--------|---------------|
|
||||||
|
| Demo request | +30 |
|
||||||
|
| Pricing page view | +20 |
|
||||||
|
| Case study download | +15 |
|
||||||
|
| Webinar attendance | +15 |
|
||||||
|
| Blog subscription | +10 |
|
||||||
|
| Email open | +2 |
|
||||||
|
| Email click | +5 |
|
||||||
|
| Unsubscribe | -15 |
|
||||||
|
| Email bounce | -25 |
|
||||||
|
|
||||||
|
## Scheduled Score Decay
|
||||||
|
|
||||||
|
Implement score decay for inactive leads:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' score-decay.bas
|
||||||
|
SET SCHEDULE "every day at 2am"
|
||||||
|
|
||||||
|
' Find leads with no activity in 30 days
|
||||||
|
stale_leads = FIND "leads", "last_activity < DATEADD(NOW(), -30, 'day') AND score > 20"
|
||||||
|
|
||||||
|
FOR EACH lead IN stale_leads
|
||||||
|
UPDATE LEAD SCORE lead.id, -5, "Inactivity decay"
|
||||||
|
NEXT lead
|
||||||
|
|
||||||
|
TALK "Processed " + LEN(stale_leads) + " stale leads"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with CRM
|
||||||
|
|
||||||
|
Push qualified leads to external CRM systems:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
result = QUALIFY LEAD lead_id
|
||||||
|
|
||||||
|
IF result.qualified THEN
|
||||||
|
' Push to Salesforce
|
||||||
|
crm_payload = NEW OBJECT
|
||||||
|
crm_payload.email = lead.email
|
||||||
|
crm_payload.name = lead.name
|
||||||
|
crm_payload.score = result.score
|
||||||
|
crm_payload.status = "Qualified"
|
||||||
|
|
||||||
|
POST "https://api.salesforce.com/leads", crm_payload
|
||||||
|
|
||||||
|
' Mark as synced
|
||||||
|
UPDATE "leads", "id = " + lead_id, #{crm_synced: true, synced_at: NOW()}
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Start with simple rules.** Begin with basic demographic and firmographic scoring, then add behavioral triggers as you gather data.
|
||||||
|
|
||||||
|
**Align scoring with sales.** Work with your sales team to define what makes a "qualified" lead. Their input ensures scores reflect actual sales readiness.
|
||||||
|
|
||||||
|
**Review and adjust regularly.** Analyze conversion rates by score range monthly. Adjust weights if high-scoring leads aren't converting.
|
||||||
|
|
||||||
|
**Combine rule-based and AI scoring.** Use rule-based scoring for speed and consistency, AI scoring for complex enterprise deals requiring nuanced evaluation.
|
||||||
|
|
||||||
|
**Implement score decay.** Leads that go cold should have their scores decrease over time to keep the pipeline accurate.
|
||||||
|
|
||||||
|
**Track score history.** Store score changes with timestamps and reasons for audit trails and analysis.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Log all score changes
|
||||||
|
ON "lead:score:changed"
|
||||||
|
INSERT "score_history", #{
|
||||||
|
lead_id: params.lead_id,
|
||||||
|
old_score: params.old_score,
|
||||||
|
new_score: params.new_score,
|
||||||
|
reason: params.reason,
|
||||||
|
changed_at: NOW()
|
||||||
|
}
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [SEND TEMPLATE](./keywords.md) - Nurture campaign emails
|
||||||
|
- [SET SCHEDULE](./keyword-set-schedule.md) - Automated scoring jobs
|
||||||
|
- [ON Keyword](./keyword-on.md) - Event-driven score updates
|
||||||
|
- [GET / POST](./keywords-http.md) - CRM integration
|
||||||
259
docs/src/chapter-06-gbdialog/keywords-social-media.md
Normal file
259
docs/src/chapter-06-gbdialog/keywords-social-media.md
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
# Social Media Keywords
|
||||||
|
|
||||||
|
General Bots provides native social media integration through BASIC keywords for posting content, scheduling, retrieving metrics, and managing posts across multiple platforms.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Platform Support
|
||||||
|
|
||||||
|
Supported platforms include Instagram, Facebook, LinkedIn, and Twitter/X. Each platform requires appropriate API credentials configured in your bot's `config.csv`.
|
||||||
|
|
||||||
|
## POST TO
|
||||||
|
|
||||||
|
Publish content to one or more social media platforms.
|
||||||
|
|
||||||
|
### Single Platform
|
||||||
|
|
||||||
|
```basic
|
||||||
|
POST TO INSTAGRAM image, "Check out our new feature! #AI #Automation"
|
||||||
|
POST TO FACEBOOK image, caption
|
||||||
|
POST TO LINKEDIN image, caption
|
||||||
|
POST TO TWITTER image, caption
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Platforms
|
||||||
|
|
||||||
|
Post to several platforms simultaneously:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
POST TO "instagram,facebook,linkedin" image, caption
|
||||||
|
```
|
||||||
|
|
||||||
|
The keyword returns a post ID that can be used for metrics retrieval or deletion.
|
||||||
|
|
||||||
|
### Example: Product Announcement
|
||||||
|
|
||||||
|
```basic
|
||||||
|
image = "/products/new-release.jpg"
|
||||||
|
caption = "Introducing our latest innovation! Available now. #NewProduct #Innovation"
|
||||||
|
|
||||||
|
post_id = POST TO "instagram,facebook" image, caption
|
||||||
|
SET BOT MEMORY "latest_post_id", post_id
|
||||||
|
TALK "Posted to Instagram and Facebook"
|
||||||
|
```
|
||||||
|
|
||||||
|
## POST TO ... AT (Scheduled)
|
||||||
|
|
||||||
|
Schedule posts for future publishing at a specific date and time.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
POST TO INSTAGRAM AT "2025-02-01 10:00" image, caption
|
||||||
|
POST TO FACEBOOK AT "2025-02-15 09:00" image, "Coming soon!"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Campaign Scheduling
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Schedule a week of posts
|
||||||
|
images = LIST "/campaign/week1/"
|
||||||
|
dates = ["2025-02-03 09:00", "2025-02-04 09:00", "2025-02-05 09:00"]
|
||||||
|
|
||||||
|
FOR i = 0 TO LEN(images) - 1
|
||||||
|
POST TO "instagram,facebook" AT dates[i] images[i].path, captions[i]
|
||||||
|
NEXT i
|
||||||
|
|
||||||
|
TALK "Campaign scheduled: " + LEN(images) + " posts"
|
||||||
|
```
|
||||||
|
|
||||||
|
## GET METRICS
|
||||||
|
|
||||||
|
Retrieve engagement metrics for published posts.
|
||||||
|
|
||||||
|
### Platform-Specific Metrics
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Instagram metrics
|
||||||
|
metrics = GET INSTAGRAM METRICS "post-id"
|
||||||
|
TALK "Likes: " + metrics.likes + ", Comments: " + metrics.comments
|
||||||
|
|
||||||
|
' Facebook metrics
|
||||||
|
fb_metrics = GET FACEBOOK METRICS "post-id"
|
||||||
|
TALK "Shares: " + fb_metrics.shares + ", Reactions: " + fb_metrics.reactions
|
||||||
|
|
||||||
|
' LinkedIn metrics
|
||||||
|
li_metrics = GET LINKEDIN METRICS "post-id"
|
||||||
|
TALK "Impressions: " + li_metrics.impressions
|
||||||
|
|
||||||
|
' Twitter metrics
|
||||||
|
tw_metrics = GET TWITTER METRICS "post-id"
|
||||||
|
TALK "Retweets: " + tw_metrics.retweets + ", Likes: " + tw_metrics.likes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Metrics Report
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every monday at 9am"
|
||||||
|
|
||||||
|
post_id = GET BOT MEMORY "latest_post_id"
|
||||||
|
metrics = GET INSTAGRAM METRICS post_id
|
||||||
|
|
||||||
|
WITH report
|
||||||
|
.post_id = post_id
|
||||||
|
.likes = metrics.likes
|
||||||
|
.comments = metrics.comments
|
||||||
|
.reach = metrics.reach
|
||||||
|
.engagement_rate = ROUND((metrics.likes + metrics.comments) / metrics.reach * 100, 2)
|
||||||
|
.report_date = NOW()
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
SEND MAIL TO "marketing@company.com" SUBJECT "Weekly Social Report" BODY report
|
||||||
|
```
|
||||||
|
|
||||||
|
## GET POSTS
|
||||||
|
|
||||||
|
List posts from a platform.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Get all Instagram posts
|
||||||
|
posts = GET INSTAGRAM POSTS
|
||||||
|
FOR EACH post IN posts
|
||||||
|
TALK post.id + ": " + post.caption
|
||||||
|
NEXT post
|
||||||
|
|
||||||
|
' Get Facebook posts
|
||||||
|
fb_posts = GET FACEBOOK POSTS
|
||||||
|
```
|
||||||
|
|
||||||
|
## DELETE POST
|
||||||
|
|
||||||
|
Remove a scheduled or published post.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE POST "post-id"
|
||||||
|
TALK "Post removed"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Deletion
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Delete posts with low engagement
|
||||||
|
posts = GET INSTAGRAM POSTS
|
||||||
|
FOR EACH post IN posts
|
||||||
|
metrics = GET INSTAGRAM METRICS post.id
|
||||||
|
IF metrics.likes < 10 AND DATEDIFF("day", post.created_at, NOW()) > 30 THEN
|
||||||
|
DELETE POST post.id
|
||||||
|
TALK "Deleted low-engagement post: " + post.id
|
||||||
|
END IF
|
||||||
|
NEXT post
|
||||||
|
```
|
||||||
|
|
||||||
|
## Campaign Examples
|
||||||
|
|
||||||
|
### Welcome Campaign
|
||||||
|
|
||||||
|
```basic
|
||||||
|
ON FORM SUBMIT "signup"
|
||||||
|
name = fields.name
|
||||||
|
email = fields.email
|
||||||
|
|
||||||
|
' Welcome email immediately
|
||||||
|
SEND TEMPLATE "welcome", "email", email, #{name: name}
|
||||||
|
|
||||||
|
' Schedule social proof post
|
||||||
|
IF fields.share_permission = "yes" THEN
|
||||||
|
caption = "Welcome to our community, " + name + "! 🎉 #NewMember #Community"
|
||||||
|
POST TO INSTAGRAM AT DATEADD(NOW(), 1, "hour") "/templates/welcome-card.png", caption
|
||||||
|
END IF
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
### Social Media Campaign
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' social-campaign.bas
|
||||||
|
SET SCHEDULE "every day at 10am"
|
||||||
|
|
||||||
|
' Rotate through content library
|
||||||
|
content_index = GET BOT MEMORY "content_index"
|
||||||
|
IF content_index = "" THEN content_index = 0
|
||||||
|
|
||||||
|
content_library = [
|
||||||
|
#{image: "/content/tip1.png", caption: "Pro tip: Automate your workflows! #Productivity"},
|
||||||
|
#{image: "/content/tip2.png", caption: "Save hours every week with automation #Efficiency"},
|
||||||
|
#{image: "/content/tip3.png", caption: "Let AI handle the repetitive tasks #AI #Automation"}
|
||||||
|
]
|
||||||
|
|
||||||
|
current = content_library[content_index MOD LEN(content_library)]
|
||||||
|
post_id = POST TO "instagram,linkedin" current.image, current.caption
|
||||||
|
|
||||||
|
SET BOT MEMORY "content_index", content_index + 1
|
||||||
|
SET BOT MEMORY "last_post_id", post_id
|
||||||
|
|
||||||
|
TALK "Posted content #" + (content_index + 1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Engagement Monitoring
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every 6 hours"
|
||||||
|
|
||||||
|
posts = GET INSTAGRAM POSTS
|
||||||
|
total_engagement = 0
|
||||||
|
post_count = 0
|
||||||
|
|
||||||
|
FOR EACH post IN posts
|
||||||
|
IF DATEDIFF("day", post.created_at, NOW()) <= 7 THEN
|
||||||
|
metrics = GET INSTAGRAM METRICS post.id
|
||||||
|
total_engagement = total_engagement + metrics.likes + metrics.comments
|
||||||
|
post_count = post_count + 1
|
||||||
|
END IF
|
||||||
|
NEXT post
|
||||||
|
|
||||||
|
avg_engagement = IIF(post_count > 0, ROUND(total_engagement / post_count, 0), 0)
|
||||||
|
|
||||||
|
IF avg_engagement < 50 THEN
|
||||||
|
SEND MAIL TO "marketing@company.com" SUBJECT "Low Engagement Alert" BODY "Average engagement this week: " + avg_engagement
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Add social media credentials to your bot's `config.csv`:
|
||||||
|
|
||||||
|
```csv
|
||||||
|
key,value
|
||||||
|
instagram-access-token,your-instagram-token
|
||||||
|
instagram-account-id,your-account-id
|
||||||
|
facebook-access-token,your-facebook-token
|
||||||
|
facebook-page-id,your-page-id
|
||||||
|
linkedin-access-token,your-linkedin-token
|
||||||
|
linkedin-organization-id,your-org-id
|
||||||
|
twitter-api-key,your-api-key
|
||||||
|
twitter-api-secret,your-api-secret
|
||||||
|
twitter-access-token,your-access-token
|
||||||
|
twitter-access-secret,your-access-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Schedule posts strategically.** Analyze your audience engagement patterns and post when your followers are most active.
|
||||||
|
|
||||||
|
**Use hashtags effectively.** Include relevant hashtags but avoid overloading—3 to 5 well-chosen tags typically perform better than 30 generic ones.
|
||||||
|
|
||||||
|
**Monitor metrics regularly.** Set up scheduled reports to track engagement trends and adjust your content strategy.
|
||||||
|
|
||||||
|
**Handle rate limits gracefully.** Social platforms enforce API rate limits. Space out bulk operations and implement retry logic.
|
||||||
|
|
||||||
|
**Store post IDs.** Save post identifiers in BOT MEMORY for later metrics retrieval or deletion.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
post_id = POST TO INSTAGRAM image, caption
|
||||||
|
SET BOT MEMORY "post_" + FORMAT(NOW(), "yyyyMMdd"), post_id
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [SET SCHEDULE](./keyword-set-schedule.md) - Automate posting schedules
|
||||||
|
- [Template Variables](./template-variables.md) - Dynamic content in captions
|
||||||
|
- [SEND TEMPLATE](./keywords.md) - Multi-channel messaging
|
||||||
|
- [GET BOT MEMORY](./keyword-get-bot-memory.md) - Store post tracking data
|
||||||
|
|
@ -1,28 +1,26 @@
|
||||||
# Template Variables Reference
|
# Template Variables
|
||||||
|
|
||||||
> Documentation for SEND TEMPLATE variables and built-in placeholders
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Templates support variable substitution using double curly braces `{{variable_name}}`. Variables are replaced at send time with values from the provided data object.
|
Templates support variable substitution using double curly braces `{{variable_name}}`. Variables are replaced at send time with values from the provided data object.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
## Built-in Variables
|
## Built-in Variables
|
||||||
|
|
||||||
These variables are automatically available in all templates:
|
These variables are automatically available in all templates without explicit declaration:
|
||||||
|
|
||||||
| Variable | Description | Example Output |
|
| Variable | Description | Example |
|
||||||
|----------|-------------|----------------|
|
|----------|-------------|---------|
|
||||||
| `{{recipient}}` | Recipient email/phone | `john@example.com` |
|
| `{{recipient}}` | Recipient email or phone | `john@example.com` |
|
||||||
| `{{to}}` | Alias for recipient | `john@example.com` |
|
| `{{to}}` | Alias for recipient | `john@example.com` |
|
||||||
| `{{date}}` | Current date (YYYY-MM-DD) | `2025-01-22` |
|
| `{{date}}` | Current date (YYYY-MM-DD) | `2025-01-22` |
|
||||||
| `{{time}}` | Current time (HH:MM) | `14:30` |
|
| `{{time}}` | Current time (HH:MM) | `14:30` |
|
||||||
| `{{datetime}}` | Date and time | `2025-01-22 14:30` |
|
| `{{datetime}}` | Combined date and time | `2025-01-22 14:30` |
|
||||||
| `{{year}}` | Current year | `2025` |
|
| `{{year}}` | Current year | `2025` |
|
||||||
| `{{month}}` | Current month name | `January` |
|
| `{{month}}` | Current month name | `January` |
|
||||||
|
|
||||||
## Custom Variables
|
## Custom Variables
|
||||||
|
|
||||||
Pass custom variables via the variables parameter:
|
Pass custom variables via the variables parameter in `SEND TEMPLATE`:
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
WITH vars
|
WITH vars
|
||||||
|
|
@ -35,7 +33,8 @@ END WITH
|
||||||
SEND TEMPLATE "welcome", "email", "john@example.com", vars
|
SEND TEMPLATE "welcome", "email", "john@example.com", vars
|
||||||
```
|
```
|
||||||
|
|
||||||
Template content:
|
The template content would reference these variables:
|
||||||
|
|
||||||
```
|
```
|
||||||
Hello {{name}},
|
Hello {{name}},
|
||||||
|
|
||||||
|
|
@ -51,7 +50,7 @@ The Team
|
||||||
|
|
||||||
### Email Templates
|
### Email Templates
|
||||||
|
|
||||||
Email templates support `Subject:` line extraction:
|
Email templates support automatic `Subject:` line extraction. Place the subject on the first line:
|
||||||
|
|
||||||
```
|
```
|
||||||
Subject: Welcome to {{company}}, {{name}}!
|
Subject: Welcome to {{company}}, {{name}}!
|
||||||
|
|
@ -61,15 +60,18 @@ Hello {{name}},
|
||||||
Thank you for joining us...
|
Thank you for joining us...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The system extracts the subject line and uses the remainder as the body.
|
||||||
|
|
||||||
### WhatsApp Templates
|
### WhatsApp Templates
|
||||||
|
|
||||||
WhatsApp templates must be pre-approved by Meta. Use numbered placeholders:
|
WhatsApp templates must be pre-approved by Meta. Use numbered placeholders as required by the WhatsApp Business API:
|
||||||
|
|
||||||
```
|
```
|
||||||
Hello {{1}}, your order {{2}} has shipped. Track at {{3}}
|
Hello {{1}}, your order {{2}} has shipped. Track at {{3}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Map variables:
|
Map variables using numeric keys:
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
WITH vars
|
WITH vars
|
||||||
.1 = customer_name
|
.1 = customer_name
|
||||||
|
|
@ -82,7 +84,7 @@ SEND TEMPLATE "order-shipped", "whatsapp", phone, vars
|
||||||
|
|
||||||
### SMS Templates
|
### SMS Templates
|
||||||
|
|
||||||
Keep SMS templates under 160 characters for single segment:
|
Keep SMS templates under 160 characters for single-segment delivery:
|
||||||
|
|
||||||
```
|
```
|
||||||
Hi {{name}}, your code is {{code}}. Valid for 10 minutes.
|
Hi {{name}}, your code is {{code}}. Valid for 10 minutes.
|
||||||
|
|
@ -131,25 +133,6 @@ Shipping to:
|
||||||
Track your order: {{tracking_url}}
|
Track your order: {{tracking_url}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lead Nurture
|
|
||||||
|
|
||||||
```
|
|
||||||
Subject: {{name}}, here's your exclusive resource
|
|
||||||
|
|
||||||
Hi {{name}},
|
|
||||||
|
|
||||||
As a {{company}} professional, we thought you'd find this helpful:
|
|
||||||
|
|
||||||
{{resource_title}}
|
|
||||||
|
|
||||||
{{resource_description}}
|
|
||||||
|
|
||||||
Download now: {{resource_url}}
|
|
||||||
|
|
||||||
Best,
|
|
||||||
{{sender_name}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Appointment Reminder
|
### Appointment Reminder
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -176,46 +159,33 @@ See you soon!
|
||||||
CREATE TEMPLATE "welcome", "email", "Welcome {{name}}!", "Hello {{name}}, thank you for joining {{company}}!"
|
CREATE TEMPLATE "welcome", "email", "Welcome {{name}}!", "Hello {{name}}, thank you for joining {{company}}!"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via Database
|
### Retrieving Templates
|
||||||
|
|
||||||
Templates are stored in `message_templates` table:
|
```basic
|
||||||
|
template = GET TEMPLATE "welcome"
|
||||||
| Column | Type | Description |
|
TALK "Template body: " + template.body
|
||||||
|--------|------|-------------|
|
```
|
||||||
| `id` | UUID | Template ID |
|
|
||||||
| `bot_id` | UUID | Bot owner |
|
|
||||||
| `name` | TEXT | Template name |
|
|
||||||
| `channel` | TEXT | email/whatsapp/sms/telegram/push |
|
|
||||||
| `subject` | TEXT | Email subject (nullable) |
|
|
||||||
| `body` | TEXT | Template body |
|
|
||||||
| `variables` | JSONB | List of variable names |
|
|
||||||
| `is_active` | BOOL | Active status |
|
|
||||||
|
|
||||||
## Variable Extraction
|
## Variable Extraction
|
||||||
|
|
||||||
Variables are automatically extracted from template body:
|
Variables are automatically extracted from template content when the template is created. The system identifies all `{{variable}}` patterns and stores them for validation. Built-in variables (recipient, date, time, etc.) are excluded from the extraction.
|
||||||
|
|
||||||
```basic
|
|
||||||
body = "Hello {{name}}, your order {{order_id}} is {{status}}."
|
|
||||||
' Extracted variables: ["name", "order_id", "status"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Built-in variables (recipient, date, time, etc.) are excluded from extraction.
|
|
||||||
|
|
||||||
## Fallback Values
|
## Fallback Values
|
||||||
|
|
||||||
Use NVL for fallback values in your code:
|
Handle missing variables using `NVL` in your code:
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
WITH vars
|
WITH vars
|
||||||
.name = NVL(user_name, "Friend")
|
.name = NVL(user_name, "Friend")
|
||||||
.company = NVL(user_company, "your organization")
|
.company = NVL(user_company, "your organization")
|
||||||
END WITH
|
END WITH
|
||||||
|
|
||||||
|
SEND TEMPLATE "greeting", "email", email, vars
|
||||||
```
|
```
|
||||||
|
|
||||||
## Multi-Channel Example
|
## Multi-Channel Delivery
|
||||||
|
|
||||||
Send same template to multiple channels:
|
Send the same template to multiple channels in one call:
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
WITH vars
|
WITH vars
|
||||||
|
|
@ -223,19 +193,57 @@ WITH vars
|
||||||
.message = "Your appointment is confirmed"
|
.message = "Your appointment is confirmed"
|
||||||
END WITH
|
END WITH
|
||||||
|
|
||||||
' Send to all channels
|
|
||||||
SEND TEMPLATE "appointment-confirm", "email,sms,whatsapp", recipient, vars
|
SEND TEMPLATE "appointment-confirm", "email,sms,whatsapp", recipient, vars
|
||||||
|
```
|
||||||
|
|
||||||
' Or send separately with channel-specific content
|
Or send channel-specific versions:
|
||||||
|
|
||||||
|
```basic
|
||||||
SEND TEMPLATE "appointment-email", "email", email, vars
|
SEND TEMPLATE "appointment-email", "email", email, vars
|
||||||
SEND TEMPLATE "appointment-sms", "sms", phone, vars
|
SEND TEMPLATE "appointment-sms", "sms", phone, vars
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Bulk Sending
|
||||||
|
|
||||||
|
Send templates to multiple recipients:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
recipients = ["a@example.com", "b@example.com", "c@example.com"]
|
||||||
|
count = SEND TEMPLATE "newsletter" TO "email" recipients, #{month: "January"}
|
||||||
|
TALK "Sent to " + count + " recipients"
|
||||||
|
```
|
||||||
|
|
||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
1. **Keep variable names simple**: Use `name` not `customer_first_name`
|
**Keep variable names simple.** Use `name` rather than `customer_first_name_from_database`. Shorter names are easier to maintain.
|
||||||
2. **Provide fallbacks**: Always handle missing variables
|
|
||||||
3. **Test templates**: Verify all variables are populated
|
**Provide fallbacks.** Always handle the case where a variable might be missing or empty.
|
||||||
4. **Channel limits**: SMS 160 chars, WhatsApp requires approval
|
|
||||||
5. **Personalization**: Use `{{name}}` for better engagement
|
**Test templates.** Verify all variables populate correctly before deploying to production.
|
||||||
6. **Unsubscribe**: Include unsubscribe link in marketing emails
|
|
||||||
|
**Respect channel limits.** SMS has a 160-character single-segment limit. WhatsApp templates require Meta approval.
|
||||||
|
|
||||||
|
**Personalize thoughtfully.** Using `{{name}}` improves engagement, but avoid over-personalization that feels intrusive.
|
||||||
|
|
||||||
|
**Include unsubscribe options.** Marketing emails should always provide an unsubscribe mechanism.
|
||||||
|
|
||||||
|
## Database Storage
|
||||||
|
|
||||||
|
Templates are stored in the `message_templates` table:
|
||||||
|
|
||||||
|
| Column | Type | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `id` | UUID | Template identifier |
|
||||||
|
| `bot_id` | UUID | Owning bot |
|
||||||
|
| `name` | TEXT | Template name |
|
||||||
|
| `channel` | TEXT | email/whatsapp/sms/telegram/push |
|
||||||
|
| `subject` | TEXT | Email subject (nullable) |
|
||||||
|
| `body` | TEXT | Template body |
|
||||||
|
| `variables` | JSONB | List of variable names |
|
||||||
|
| `is_active` | BOOL | Active status |
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [SEND TEMPLATE Keyword](./keywords.md) - Full keyword reference
|
||||||
|
- [SET SCHEDULE](./keyword-set-schedule.md) - Scheduled template delivery
|
||||||
|
- [Universal Messaging](./universal-messaging.md) - Multi-channel patterns
|
||||||
247
docs/src/chapter-08-config/multimodal.md
Normal file
247
docs/src/chapter-08-config/multimodal.md
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
# Multimodal Configuration
|
||||||
|
|
||||||
|
General Bots integrates with botmodels—a Python service for multimodal AI tasks—to enable image generation, video creation, audio synthesis, and vision capabilities directly from BASIC scripts.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐ HTTPS ┌─────────────┐
|
||||||
|
│ botserver │ ────────────▶ │ botmodels │
|
||||||
|
│ (Rust) │ │ (Python) │
|
||||||
|
└─────────────┘ └─────────────┘
|
||||||
|
│ │
|
||||||
|
│ BASIC Keywords │ AI Models
|
||||||
|
│ - IMAGE │ - Stable Diffusion
|
||||||
|
│ - VIDEO │ - Zeroscope
|
||||||
|
│ - AUDIO │ - TTS/Whisper
|
||||||
|
│ - SEE │ - BLIP2
|
||||||
|
```
|
||||||
|
|
||||||
|
When a BASIC script calls a multimodal keyword, botserver forwards the request to botmodels, which runs the appropriate AI model and returns the generated content.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Add these settings to your bot's `config.csv` file to enable multimodal capabilities.
|
||||||
|
|
||||||
|
### BotModels Service
|
||||||
|
|
||||||
|
| Key | Default | Description |
|
||||||
|
|-----|---------|-------------|
|
||||||
|
| `botmodels-enabled` | `false` | Enable botmodels integration |
|
||||||
|
| `botmodels-host` | `0.0.0.0` | Host address for botmodels service |
|
||||||
|
| `botmodels-port` | `8085` | Port for botmodels service |
|
||||||
|
| `botmodels-api-key` | — | API key for authentication |
|
||||||
|
| `botmodels-https` | `false` | Use HTTPS for connection |
|
||||||
|
|
||||||
|
### Image Generation
|
||||||
|
|
||||||
|
| Key | Default | Description |
|
||||||
|
|-----|---------|-------------|
|
||||||
|
| `image-generator-model` | — | Path to image generation model |
|
||||||
|
| `image-generator-steps` | `4` | Inference steps (more = higher quality, slower) |
|
||||||
|
| `image-generator-width` | `512` | Output image width in pixels |
|
||||||
|
| `image-generator-height` | `512` | Output image height in pixels |
|
||||||
|
| `image-generator-gpu-layers` | `20` | Layers to offload to GPU |
|
||||||
|
| `image-generator-batch-size` | `1` | Batch size for generation |
|
||||||
|
|
||||||
|
### Video Generation
|
||||||
|
|
||||||
|
| Key | Default | Description |
|
||||||
|
|-----|---------|-------------|
|
||||||
|
| `video-generator-model` | — | Path to video generation model |
|
||||||
|
| `video-generator-frames` | `24` | Number of frames to generate |
|
||||||
|
| `video-generator-fps` | `8` | Output frames per second |
|
||||||
|
| `video-generator-width` | `320` | Output video width in pixels |
|
||||||
|
| `video-generator-height` | `576` | Output video height in pixels |
|
||||||
|
| `video-generator-gpu-layers` | `15` | Layers to offload to GPU |
|
||||||
|
| `video-generator-batch-size` | `1` | Batch size for generation |
|
||||||
|
|
||||||
|
## Example Configuration
|
||||||
|
|
||||||
|
```csv
|
||||||
|
key,value
|
||||||
|
botmodels-enabled,true
|
||||||
|
botmodels-host,0.0.0.0
|
||||||
|
botmodels-port,8085
|
||||||
|
botmodels-api-key,your-secret-key
|
||||||
|
botmodels-https,false
|
||||||
|
image-generator-model,../../../../data/diffusion/sd_turbo_f16.gguf
|
||||||
|
image-generator-steps,4
|
||||||
|
image-generator-width,512
|
||||||
|
image-generator-height,512
|
||||||
|
image-generator-gpu-layers,20
|
||||||
|
video-generator-model,../../../../data/diffusion/zeroscope_v2_576w
|
||||||
|
video-generator-frames,24
|
||||||
|
video-generator-fps,8
|
||||||
|
```
|
||||||
|
|
||||||
|
## BASIC Keywords
|
||||||
|
|
||||||
|
Once configured, these keywords become available in your scripts.
|
||||||
|
|
||||||
|
### IMAGE
|
||||||
|
|
||||||
|
Generate an image from a text prompt:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
file = IMAGE "a sunset over mountains with purple clouds"
|
||||||
|
SEND FILE TO user, file
|
||||||
|
```
|
||||||
|
|
||||||
|
The keyword returns a path to the generated image file.
|
||||||
|
|
||||||
|
### VIDEO
|
||||||
|
|
||||||
|
Generate a video from a text prompt:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
file = VIDEO "a rocket launching into space"
|
||||||
|
SEND FILE TO user, file
|
||||||
|
```
|
||||||
|
|
||||||
|
Video generation is more resource-intensive than image generation. Expect longer processing times.
|
||||||
|
|
||||||
|
### AUDIO
|
||||||
|
|
||||||
|
Generate speech audio from text:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
file = AUDIO "Hello, welcome to our service!"
|
||||||
|
SEND FILE TO user, file
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE
|
||||||
|
|
||||||
|
Analyze an image or video and get a description:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Describe an image
|
||||||
|
caption = SEE "/path/to/image.jpg"
|
||||||
|
TALK caption
|
||||||
|
|
||||||
|
' Describe a video
|
||||||
|
description = SEE "/path/to/video.mp4"
|
||||||
|
TALK description
|
||||||
|
```
|
||||||
|
|
||||||
|
The SEE keyword uses vision models to understand visual content and return natural language descriptions.
|
||||||
|
|
||||||
|
## Starting BotModels
|
||||||
|
|
||||||
|
Before using multimodal features, start the botmodels service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd botmodels
|
||||||
|
python -m uvicorn src.main:app --host 0.0.0.0 --port 8085
|
||||||
|
```
|
||||||
|
|
||||||
|
For production with HTTPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m uvicorn src.main:app \
|
||||||
|
--host 0.0.0.0 \
|
||||||
|
--port 8085 \
|
||||||
|
--ssl-keyfile key.pem \
|
||||||
|
--ssl-certfile cert.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
## BotModels API Endpoints
|
||||||
|
|
||||||
|
The botmodels service exposes these REST endpoints:
|
||||||
|
|
||||||
|
| Endpoint | Method | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/api/image/generate` | POST | Generate image from prompt |
|
||||||
|
| `/api/video/generate` | POST | Generate video from prompt |
|
||||||
|
| `/api/speech/generate` | POST | Generate speech from text |
|
||||||
|
| `/api/speech/totext` | POST | Transcribe audio to text |
|
||||||
|
| `/api/vision/describe` | POST | Describe an image |
|
||||||
|
| `/api/vision/describe_video` | POST | Describe a video |
|
||||||
|
| `/api/vision/vqa` | POST | Visual question answering |
|
||||||
|
| `/api/health` | GET | Health check |
|
||||||
|
|
||||||
|
All endpoints except `/api/health` require the `X-API-Key` header for authentication.
|
||||||
|
|
||||||
|
## Model Paths
|
||||||
|
|
||||||
|
Configure model paths relative to the botmodels service directory. Typical layout:
|
||||||
|
|
||||||
|
```
|
||||||
|
data/
|
||||||
|
├── diffusion/
|
||||||
|
│ ├── sd_turbo_f16.gguf # Stable Diffusion
|
||||||
|
│ └── zeroscope_v2_576w/ # Zeroscope video
|
||||||
|
├── tts/
|
||||||
|
│ └── model.onnx # Text-to-speech
|
||||||
|
├── whisper/
|
||||||
|
│ └── model.bin # Speech-to-text
|
||||||
|
└── vision/
|
||||||
|
└── blip2/ # Vision model
|
||||||
|
```
|
||||||
|
|
||||||
|
## GPU Acceleration
|
||||||
|
|
||||||
|
Both image and video generation benefit significantly from GPU acceleration. Configure GPU layers based on your hardware:
|
||||||
|
|
||||||
|
| GPU VRAM | Recommended GPU Layers |
|
||||||
|
|----------|----------------------|
|
||||||
|
| 4GB | 8-12 |
|
||||||
|
| 8GB | 15-20 |
|
||||||
|
| 12GB+ | 25-35 |
|
||||||
|
|
||||||
|
Lower GPU layers if you experience out-of-memory errors.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**"BotModels is not enabled"**
|
||||||
|
|
||||||
|
Set `botmodels-enabled=true` in your config.csv.
|
||||||
|
|
||||||
|
**Connection refused**
|
||||||
|
|
||||||
|
Verify botmodels service is running and check host/port configuration. Test connectivity:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8085/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
**Authentication failed**
|
||||||
|
|
||||||
|
Ensure `botmodels-api-key` in config.csv matches the `API_KEY` environment variable in botmodels.
|
||||||
|
|
||||||
|
**Model not found**
|
||||||
|
|
||||||
|
Verify model paths are correct and models are downloaded to the expected locations.
|
||||||
|
|
||||||
|
**Out of memory**
|
||||||
|
|
||||||
|
Reduce `gpu-layers` or `batch-size`. Video generation is particularly memory-intensive.
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
**Use HTTPS in production.** Set `botmodels-https=true` and configure SSL certificates on the botmodels service.
|
||||||
|
|
||||||
|
**Use strong API keys.** Generate cryptographically random keys for the `botmodels-api-key` setting.
|
||||||
|
|
||||||
|
**Restrict network access.** Limit botmodels service access to trusted hosts only.
|
||||||
|
|
||||||
|
**Consider GPU isolation.** Run botmodels on a dedicated GPU server if sharing resources with other services.
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
**Image generation** runs fastest with SD Turbo models and 4-8 inference steps. More steps improve quality but increase generation time linearly.
|
||||||
|
|
||||||
|
**Video generation** is the most resource-intensive operation. Keep frame counts low (24-48) for reasonable response times.
|
||||||
|
|
||||||
|
**Batch processing** improves throughput when generating multiple items. Increase `batch-size` if you have sufficient GPU memory.
|
||||||
|
|
||||||
|
**Caching** generated content when appropriate. If multiple users request similar content, consider storing results.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [LLM Configuration](./llm-config.md) - Language model settings
|
||||||
|
- [Bot Parameters](./parameters.md) - All configuration options
|
||||||
|
- [IMAGE Keyword](../chapter-06-gbdialog/keywords.md) - Image generation reference
|
||||||
|
- [SEE Keyword](../chapter-06-gbdialog/keywords.md) - Vision capabilities
|
||||||
294
docs/src/chapter-11-features/m365-comparison.md
Normal file
294
docs/src/chapter-11-features/m365-comparison.md
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
# Enterprise Platform Migration
|
||||||
|
|
||||||
|
<img src="../assets/feature-parity-flow.svg" alt="Feature Parity Flow" style="max-height: 400px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
General Bots provides complete feature parity with enterprise cloud productivity suites while offering significant advantages: self-hosting, open source licensing, no per-user fees, and native AI integration.
|
||||||
|
|
||||||
|
## Migration Overview
|
||||||
|
|
||||||
|
<img src="../assets/api-comparison-matrix.svg" alt="API Comparison Matrix" style="max-height: 500px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
Organizations evaluating self-hosted alternatives find General Bots delivers equivalent functionality with full data sovereignty. The sections below map common enterprise APIs to their General Bots equivalents.
|
||||||
|
|
||||||
|
## API Endpoint Mapping
|
||||||
|
|
||||||
|
### Mail and Communication
|
||||||
|
|
||||||
|
Enterprise mail APIs handle sending, receiving, and managing email. General Bots provides the same capabilities through Stalwart Mail Server and BASIC keywords.
|
||||||
|
|
||||||
|
| Enterprise API | General Bots Equivalent | Implementation |
|
||||||
|
|----------------|------------------------|----------------|
|
||||||
|
| Messages endpoint | Stalwart IMAP/JMAP | Full mailbox access |
|
||||||
|
| Send mail endpoint | `SEND MAIL` keyword | `SEND MAIL TO email SUBJECT s BODY b` |
|
||||||
|
| Mail folders | Stalwart folders | Standard IMAP folders |
|
||||||
|
| Attachments | File keywords | `READ`, `WRITE` with attachments |
|
||||||
|
|
||||||
|
The BASIC syntax is straightforward:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SEND MAIL TO "client@company.com" SUBJECT "Report Ready" BODY report_content
|
||||||
|
```
|
||||||
|
|
||||||
|
For receiving mail, configure webhooks or use scheduled scripts to process incoming messages through the Stalwart API.
|
||||||
|
|
||||||
|
### Calendar and Scheduling
|
||||||
|
|
||||||
|
Calendar APIs manage events, appointments, and scheduling. General Bots integrates CalDAV with the `BOOK` keyword.
|
||||||
|
|
||||||
|
| Enterprise API | General Bots Equivalent | Implementation |
|
||||||
|
|----------------|------------------------|----------------|
|
||||||
|
| Calendar events | Calendar API | `/api/calendar/events` |
|
||||||
|
| Create event | `BOOK` keyword | `BOOK "Meeting" AT datetime` |
|
||||||
|
| Calendar view | Calendar range query | Date-filtered event retrieval |
|
||||||
|
| Free/busy lookup | Availability API | Schedule availability |
|
||||||
|
|
||||||
|
Schedule appointments conversationally:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "When would you like to schedule your appointment?"
|
||||||
|
HEAR appointment_time AS DATE
|
||||||
|
BOOK "Consultation" AT appointment_time
|
||||||
|
TALK "Your appointment is confirmed for " + FORMAT(appointment_time, "MMMM d 'at' h:mm a")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Files and Storage
|
||||||
|
|
||||||
|
Cloud storage APIs handle file operations, versioning, and sharing. SeaweedFS provides S3-compatible storage with full versioning support.
|
||||||
|
|
||||||
|
| Enterprise API | General Bots Equivalent | Implementation |
|
||||||
|
|----------------|------------------------|----------------|
|
||||||
|
| List files | `LIST` keyword | `LIST "/documents/"` |
|
||||||
|
| File listing | Drive API | `/api/files/list` |
|
||||||
|
| File content | `READ` keyword | `content = READ "file.pdf"` |
|
||||||
|
| File versions | Versions API | `/api/files/versions` |
|
||||||
|
| Permissions | Sharing API | Permission management |
|
||||||
|
|
||||||
|
File operations in BASIC:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
files = LIST "/reports/"
|
||||||
|
FOR EACH file IN files
|
||||||
|
content = READ file.path
|
||||||
|
processed = LLM "Summarize this document: " + content
|
||||||
|
WRITE "/summaries/" + file.name + ".summary.txt", processed
|
||||||
|
NEXT file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tasks and Planning
|
||||||
|
|
||||||
|
Task management APIs create, update, and track work items. General Bots implements a complete task system with project organization.
|
||||||
|
|
||||||
|
| Enterprise API | General Bots Equivalent | Implementation |
|
||||||
|
|----------------|------------------------|----------------|
|
||||||
|
| Tasks endpoint | Tasks API | `/api/tasks` |
|
||||||
|
| Task lists | Task lists | Board-based organization |
|
||||||
|
| Create task | `CREATE TASK` keyword | Task creation |
|
||||||
|
| Task details | Task CRUD | Full task lifecycle |
|
||||||
|
|
||||||
|
Create tasks from conversations:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What task should I create?"
|
||||||
|
HEAR task_title
|
||||||
|
|
||||||
|
TALK "When is it due?"
|
||||||
|
HEAR due_date AS DATE
|
||||||
|
|
||||||
|
CREATE TASK task_title DUE due_date
|
||||||
|
TALK "Task created: " + task_title
|
||||||
|
```
|
||||||
|
|
||||||
|
### Users and Directory
|
||||||
|
|
||||||
|
User management APIs handle identity, groups, and permissions. Zitadel provides enterprise-grade IAM with OIDC/OAuth2.
|
||||||
|
|
||||||
|
| Enterprise API | General Bots Equivalent | Implementation |
|
||||||
|
|----------------|------------------------|----------------|
|
||||||
|
| Users endpoint | Users API | `/api/users` |
|
||||||
|
| Current user | Current user | Session context |
|
||||||
|
| Groups | Groups API | `/api/groups` |
|
||||||
|
| Directory | Directory API | Zitadel directory |
|
||||||
|
| Memberships | Membership API | Group memberships |
|
||||||
|
|
||||||
|
### Automation and Workflows
|
||||||
|
|
||||||
|
Cloud automation platforms provide flow-based workflow design. General Bots offers BASIC scripting with more power and flexibility.
|
||||||
|
|
||||||
|
| Cloud Automation | General Bots Equivalent | Advantage |
|
||||||
|
|------------------|------------------------|-----------|
|
||||||
|
| Scheduled flows | `SET SCHEDULE` | Cron syntax, unlimited |
|
||||||
|
| HTTP triggers | `WEBHOOK` | Instant API creation |
|
||||||
|
| Connectors | `GET`, `POST`, GraphQL | Any REST/GraphQL API |
|
||||||
|
| Conditions | `IF/THEN/ELSE` | Full programming logic |
|
||||||
|
| Loops | `FOR EACH` | Native iteration |
|
||||||
|
| Data operations | `TABLE`, `INSERT`, `UPDATE` | Direct database access |
|
||||||
|
|
||||||
|
A workflow that would require a visual designer elsewhere becomes simple BASIC:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "0 9 * * 1-5"
|
||||||
|
|
||||||
|
' Daily sales report - runs weekdays at 9 AM
|
||||||
|
sales = AGGREGATE "orders", "SUM", "total", "date = TODAY()"
|
||||||
|
count = AGGREGATE "orders", "COUNT", "id", "date = TODAY()"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a business analyst. Create a brief executive summary."
|
||||||
|
summary = LLM "Sales: $" + sales + ", Orders: " + count
|
||||||
|
|
||||||
|
SEND MAIL TO "executives@company.com" SUBJECT "Daily Sales Report" BODY summary
|
||||||
|
```
|
||||||
|
|
||||||
|
### AI and Intelligence
|
||||||
|
|
||||||
|
Cloud AI assistants typically require additional per-user licensing. General Bots includes AI capabilities at no extra cost.
|
||||||
|
|
||||||
|
| Cloud AI Feature | General Bots Equivalent | Advantage |
|
||||||
|
|------------------|------------------------|-----------|
|
||||||
|
| AI Assistant | `LLM` keyword | Free (bring your API key) |
|
||||||
|
| Document analysis | `USE KB` + `LLM` | Built-in RAG |
|
||||||
|
| Image generation | `IMAGE` keyword | Local generation available |
|
||||||
|
| Speech-to-text | `HEAR AS AUDIO` | Whisper integration |
|
||||||
|
| Text-to-speech | `AUDIO` keyword | TTS models |
|
||||||
|
| Vision/OCR | `SEE` keyword | Vision models |
|
||||||
|
|
||||||
|
AI integration is native:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "product-docs"
|
||||||
|
SET CONTEXT "You are a helpful product specialist."
|
||||||
|
|
||||||
|
TALK "How can I help you today?"
|
||||||
|
HEAR question
|
||||||
|
response = LLM question
|
||||||
|
TALK response
|
||||||
|
```
|
||||||
|
|
||||||
|
## Feature Parity Matrix
|
||||||
|
|
||||||
|
### Core Services
|
||||||
|
|
||||||
|
| Service Category | Enterprise Cloud | General Bots | Status |
|
||||||
|
|------------------|------------------|--------------|--------|
|
||||||
|
| Email | Cloud mail service | Stalwart Mail | ✅ Complete |
|
||||||
|
| Calendar | Cloud calendar | CalDAV + Calendar API | ✅ Complete |
|
||||||
|
| Files | Cloud storage | SeaweedFS | ✅ Complete |
|
||||||
|
| Video | Cloud meetings | LiveKit | ✅ Complete |
|
||||||
|
| Chat | Cloud messaging | Multi-channel | ✅ Complete |
|
||||||
|
| Tasks | Cloud tasks | Tasks Module | ✅ Complete |
|
||||||
|
| Identity | Cloud identity | Zitadel | ✅ Complete |
|
||||||
|
| Search | Cloud search | Qdrant Vectors | ✅ Semantic |
|
||||||
|
|
||||||
|
### Automation
|
||||||
|
|
||||||
|
| Capability | Cloud Platform | General Bots | Status |
|
||||||
|
|------------|----------------|--------------|--------|
|
||||||
|
| Scheduled tasks | Scheduled flows | `SET SCHEDULE` | ✅ Complete |
|
||||||
|
| Webhooks | HTTP triggers | `WEBHOOK` | ✅ Complete |
|
||||||
|
| API calls | Connectors | HTTP keywords | ✅ Flexible |
|
||||||
|
| Custom logic | Expressions | Full BASIC | ✅ Powerful |
|
||||||
|
| Database | Cloud datastore | Direct SQL | ✅ Direct |
|
||||||
|
| Pricing | Per-user fees | Included | ✅ Free |
|
||||||
|
|
||||||
|
### AI Capabilities
|
||||||
|
|
||||||
|
| Feature | Cloud AI (extra cost) | General Bots | Status |
|
||||||
|
|---------|----------------------|--------------|--------|
|
||||||
|
| Chat assistance | ✅ | `LLM` keyword | ✅ Included |
|
||||||
|
| Document Q&A | ✅ | `USE KB` + RAG | ✅ Included |
|
||||||
|
| Code generation | ✅ | `LLM` with context | ✅ Included |
|
||||||
|
| Image generation | Limited | `IMAGE` keyword | ✅ Full |
|
||||||
|
| Video generation | ❌ | `VIDEO` keyword | ✅ Available |
|
||||||
|
| Custom models | ❌ | Any provider | ✅ Flexible |
|
||||||
|
|
||||||
|
## Cost Comparison
|
||||||
|
|
||||||
|
### Typical Per-User Cloud Licensing
|
||||||
|
|
||||||
|
| License Tier | Monthly Cost | 100 Users/Year |
|
||||||
|
|--------------|--------------|----------------|
|
||||||
|
| Basic | $6/user | $7,200 |
|
||||||
|
| Standard | $12.50/user | $15,000 |
|
||||||
|
| Premium | $22/user | $26,400 |
|
||||||
|
| + AI features | $30/user | $36,000 |
|
||||||
|
| **Total Premium + AI** | **$52/user** | **$62,400** |
|
||||||
|
|
||||||
|
### General Bots Self-Hosted
|
||||||
|
|
||||||
|
| Component | Monthly Cost | Notes |
|
||||||
|
|-----------|--------------|-------|
|
||||||
|
| Software | $0 | AGPL licensed |
|
||||||
|
| Infrastructure | $50-200 | Your servers |
|
||||||
|
| LLM API (optional) | $50-500 | Pay per use |
|
||||||
|
| **Total** | **$100-700** | **Unlimited users** |
|
||||||
|
|
||||||
|
For 100 users, General Bots costs roughly 1-2% of typical cloud licensing while providing equivalent or better functionality.
|
||||||
|
|
||||||
|
## Migration Approach
|
||||||
|
|
||||||
|
### Phase 1: Assessment
|
||||||
|
|
||||||
|
Inventory current service usage and map to General Bots equivalents. Most organizations find complete feature coverage for core productivity scenarios.
|
||||||
|
|
||||||
|
### Phase 2: Parallel Deployment
|
||||||
|
|
||||||
|
Run General Bots alongside existing services during transition. Configure identity federation between Zitadel and existing directory services.
|
||||||
|
|
||||||
|
### Phase 3: Data Migration
|
||||||
|
|
||||||
|
Use provided migration tools and APIs:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Example: Migrate files from external storage
|
||||||
|
files = GET "https://api.storage.example/files"
|
||||||
|
FOR EACH file IN files
|
||||||
|
content = DOWNLOAD file.url
|
||||||
|
WRITE "/" + file.name, content
|
||||||
|
NEXT file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 4: Cutover
|
||||||
|
|
||||||
|
Redirect DNS, update client configurations, and deprecate cloud subscriptions.
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
**Data Sovereignty** - Your data stays on your infrastructure. No third-party access, no cross-border data concerns.
|
||||||
|
|
||||||
|
**Cost Control** - Predictable infrastructure costs instead of per-user licensing that scales with your organization.
|
||||||
|
|
||||||
|
**Customization** - Full source code access. Modify, extend, and integrate as needed.
|
||||||
|
|
||||||
|
**AI Integration** - Native LLM support without additional licensing. Use any provider or run models locally.
|
||||||
|
|
||||||
|
**Automation Power** - BASIC scripting provides more flexibility than visual flow builders with no per-automation limits.
|
||||||
|
|
||||||
|
**No Vendor Lock-in** - Open standards (IMAP, CalDAV, S3, OIDC) mean your data is always portable.
|
||||||
|
|
||||||
|
## Migration Resources
|
||||||
|
|
||||||
|
General Bots provides tools and documentation for smooth migration:
|
||||||
|
|
||||||
|
- **Import utilities** for common data formats
|
||||||
|
- **API compatibility layers** for gradual transition
|
||||||
|
- **Identity federation** for single sign-on during migration
|
||||||
|
- **Data validation tools** to verify migration completeness
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
General Bots delivers enterprise productivity features without enterprise pricing:
|
||||||
|
|
||||||
|
- 100% API coverage for core productivity services
|
||||||
|
- Self-hosted deployment with full data sovereignty
|
||||||
|
- No per-user licensing fees
|
||||||
|
- Native AI integration without additional cost
|
||||||
|
- More powerful automation with BASIC scripting
|
||||||
|
- Open source with full code access
|
||||||
|
|
||||||
|
The choice between cloud and self-hosted depends on organizational priorities. For those valuing control, cost efficiency, and customization, General Bots delivers enterprise-grade productivity without enterprise-grade pricing.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Quick Start](../chapter-01/quick-start.md) - Deploy in minutes
|
||||||
|
- [Keywords Reference](../chapter-06-gbdialog/keywords.md) - Full BASIC reference
|
||||||
|
- [REST API Reference](../chapter-10-api/README.md) - Complete API documentation
|
||||||
|
- [Migration Guide](../chapter-14-migration/README.md) - Detailed migration steps
|
||||||
|
|
@ -1,40 +1,35 @@
|
||||||
# Platform Comparison: General Bots vs Notion AI vs Perplexity
|
# Platform Capabilities
|
||||||
|
|
||||||
This document compares General Bots with popular AI-powered platforms to highlight unique capabilities and help users understand when to choose each solution.
|
General Bots provides a unique combination of capabilities that differentiate it from other AI platforms. This document outlines what makes General Bots suitable for organizations seeking customizable, self-hosted AI automation.
|
||||||
|
|
||||||
## Executive Summary
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
| Capability | General Bots | Notion AI | Perplexity |
|
## Core Differentiators
|
||||||
|------------|-------------|-----------|------------|
|
|
||||||
| **Primary Focus** | Customizable AI automation platform | Document collaboration with AI | AI-powered search engine |
|
|
||||||
| **Self-hosted** | ✅ Yes | ❌ No | ❌ No |
|
|
||||||
| **Open Source** | ✅ AGPL | ❌ Proprietary | ❌ Proprietary |
|
|
||||||
| **Custom APIs/Webhooks** | ✅ Full control | ❌ No | ❌ No |
|
|
||||||
| **Database Integration** | ✅ Full SQL | ⚠️ Limited (Notion DBs) | ❌ No |
|
|
||||||
| **Custom LLM Backend** | ✅ Any provider | ❌ OpenAI only | ❌ Proprietary |
|
|
||||||
| **BASIC Programming** | ✅ Native | ❌ No | ❌ No |
|
|
||||||
| **Multi-channel** | ✅ WhatsApp, Teams, Web, etc. | ❌ Web only | ❌ Web only |
|
|
||||||
| **File Storage** | ✅ .gbdrive | ⚠️ Notion pages | ❌ No |
|
|
||||||
| **Email Integration** | ✅ Send/receive | ❌ No | ❌ No |
|
|
||||||
| **Pricing** | Free (self-hosted) | $10/user/month | $20/month |
|
|
||||||
|
|
||||||
## Detailed Comparison
|
### Self-Hosted & Open Source
|
||||||
|
|
||||||
### 1. Customization & Extensibility
|
General Bots runs entirely on your infrastructure. Your data never leaves your servers, and you have full access to the source code under AGPL licensing.
|
||||||
|
|
||||||
#### General Bots
|
| Capability | General Bots |
|
||||||
|
|------------|-------------|
|
||||||
|
| Self-hosted deployment | ✅ Full control |
|
||||||
|
| Open source | ✅ AGPL licensed |
|
||||||
|
| Data sovereignty | ✅ Your infrastructure |
|
||||||
|
| Custom modifications | ✅ Full source access |
|
||||||
|
| Per-user licensing | ✅ None required |
|
||||||
|
|
||||||
General Bots is designed for maximum customization:
|
### Customization & Extensibility
|
||||||
|
|
||||||
|
Build exactly what you need with BASIC scripting and instant API creation:
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
' Create a custom API endpoint in one line
|
' Create a custom API endpoint
|
||||||
WEBHOOK "customer-lookup"
|
WEBHOOK "customer-lookup"
|
||||||
|
|
||||||
customer_id = params.id
|
customer_id = params.id
|
||||||
USE KB "customer-data"
|
USE KB "customer-data"
|
||||||
|
|
||||||
' AI-powered response
|
response = LLM "Get information about customer " + customer_id
|
||||||
response = LLM "Get all information about customer " + customer_id
|
|
||||||
|
|
||||||
WITH result = NEW OBJECT
|
WITH result = NEW OBJECT
|
||||||
.customer_id = customer_id
|
.customer_id = customer_id
|
||||||
|
|
@ -43,37 +38,19 @@ WITH result = NEW OBJECT
|
||||||
END WITH
|
END WITH
|
||||||
```
|
```
|
||||||
|
|
||||||
**Capabilities:**
|
This creates a working API endpoint in seconds—no separate deployment, no infrastructure configuration.
|
||||||
- Create unlimited custom webhooks/APIs
|
|
||||||
- Write automation in BASIC syntax
|
|
||||||
- Integrate with any external system
|
|
||||||
- Self-host with full control
|
|
||||||
- Modify source code (AGPL license)
|
|
||||||
|
|
||||||
#### Notion AI
|
**What you can build:**
|
||||||
|
- Custom webhooks and APIs
|
||||||
|
- Automated workflows with BASIC scripts
|
||||||
|
- Integrations with any external system
|
||||||
|
- Multi-channel chatbots
|
||||||
|
- Document processing pipelines
|
||||||
|
- Scheduled automation tasks
|
||||||
|
|
||||||
Limited to built-in features:
|
### Knowledge Base & RAG
|
||||||
- Summarize pages
|
|
||||||
- Generate content
|
|
||||||
- Translate text
|
|
||||||
- Brainstorm ideas
|
|
||||||
- No custom API creation
|
|
||||||
- No webhook support
|
|
||||||
- No programmatic automation
|
|
||||||
|
|
||||||
#### Perplexity
|
Full control over your knowledge base with built-in retrieval-augmented generation:
|
||||||
|
|
||||||
Search-focused only:
|
|
||||||
- Ask questions, get answers
|
|
||||||
- No customization
|
|
||||||
- No API creation
|
|
||||||
- No automation capabilities
|
|
||||||
|
|
||||||
### 2. Knowledge Base & RAG
|
|
||||||
|
|
||||||
#### General Bots
|
|
||||||
|
|
||||||
Full control over your knowledge base:
|
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
' Load multiple knowledge sources
|
' Load multiple knowledge sources
|
||||||
|
|
@ -81,20 +58,16 @@ USE KB "company-policies"
|
||||||
USE KB "product-catalog"
|
USE KB "product-catalog"
|
||||||
USE KB "customer-faq"
|
USE KB "customer-faq"
|
||||||
|
|
||||||
' Set custom context
|
SET CONTEXT "You are a helpful customer service agent."
|
||||||
SET CONTEXT "You are a helpful customer service agent for Acme Corp."
|
|
||||||
|
|
||||||
' Query with RAG
|
|
||||||
answer = LLM user_question
|
answer = LLM user_question
|
||||||
|
|
||||||
' Save conversation for training
|
' Save for training and analysis
|
||||||
WITH conversation = NEW OBJECT
|
INSERT "conversations", #{
|
||||||
.question = user_question
|
question: user_question,
|
||||||
.answer = answer
|
answer: answer,
|
||||||
.timestamp = NOW()
|
timestamp: NOW()
|
||||||
.user_id = user.id
|
}
|
||||||
END WITH
|
|
||||||
INSERT "conversations", conversation
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
|
|
@ -105,401 +78,138 @@ INSERT "conversations", conversation
|
||||||
- Semantic caching
|
- Semantic caching
|
||||||
- Full document indexing
|
- Full document indexing
|
||||||
|
|
||||||
#### Notion AI
|
### Multi-Channel Deployment
|
||||||
|
|
||||||
- Only searches within Notion workspace
|
Deploy once, reach users everywhere:
|
||||||
- No external document upload for AI
|
|
||||||
- Limited to Notion page structure
|
|
||||||
- No custom embeddings
|
|
||||||
|
|
||||||
#### Perplexity
|
|
||||||
|
|
||||||
- Searches the web in real-time
|
|
||||||
- No custom document upload (free tier)
|
|
||||||
- Pro tier allows file upload
|
|
||||||
- No persistent knowledge base
|
|
||||||
|
|
||||||
### 3. Automation & Workflows
|
|
||||||
|
|
||||||
#### General Bots
|
|
||||||
|
|
||||||
Complete automation platform:
|
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
' Scheduled automation
|
' Same code works across all channels
|
||||||
SET SCHEDULE "daily-report", "0 9 * * *"
|
TALK "How can I help you today?"
|
||||||
|
|
||||||
' Fetch data from multiple sources
|
|
||||||
sales = GET "https://api.crm.com/sales/today"
|
|
||||||
inventory = FIND "inventory", "stock < 10"
|
|
||||||
support_tickets = GET "https://api.zendesk.com/tickets/open"
|
|
||||||
|
|
||||||
' AI-generated summary
|
|
||||||
SET CONTEXT "You are a business analyst. Create an executive summary."
|
|
||||||
summary = LLM "Summarize: Sales: " + sales + ", Low stock: " + inventory + ", Open tickets: " + support_tickets
|
|
||||||
|
|
||||||
' Send report
|
|
||||||
SEND MAIL "executives@company.com", "Daily Business Report", summary
|
|
||||||
|
|
||||||
' Post to Slack
|
|
||||||
WITH slack_msg = NEW OBJECT
|
|
||||||
.text = summary
|
|
||||||
.channel = "#daily-reports"
|
|
||||||
END WITH
|
|
||||||
POST "https://hooks.slack.com/services/xxx", slack_msg
|
|
||||||
```
|
|
||||||
|
|
||||||
**Automation types:**
|
|
||||||
- Scheduled tasks (cron)
|
|
||||||
- Webhooks (event-driven)
|
|
||||||
- Database triggers (ON keyword)
|
|
||||||
- Multi-channel messaging
|
|
||||||
- Email workflows
|
|
||||||
- File processing pipelines
|
|
||||||
|
|
||||||
#### Notion AI
|
|
||||||
|
|
||||||
- No automation capabilities
|
|
||||||
- Manual AI invocation only
|
|
||||||
- No scheduled tasks
|
|
||||||
- No webhooks
|
|
||||||
- No external integrations
|
|
||||||
|
|
||||||
#### Perplexity
|
|
||||||
|
|
||||||
- No automation
|
|
||||||
- Interactive queries only
|
|
||||||
- No scheduling
|
|
||||||
- No integrations
|
|
||||||
|
|
||||||
### 4. Multi-Channel Communication
|
|
||||||
|
|
||||||
#### General Bots
|
|
||||||
|
|
||||||
Deploy to any channel:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Same BASIC code works on all channels
|
|
||||||
TALK "Hello! How can I help you today?"
|
|
||||||
|
|
||||||
HEAR question
|
HEAR question
|
||||||
|
response = LLM question
|
||||||
USE KB "support-docs"
|
TALK response
|
||||||
answer = LLM question
|
|
||||||
|
|
||||||
TALK answer
|
|
||||||
|
|
||||||
' Channel-specific features
|
|
||||||
IF channel = "whatsapp" THEN
|
|
||||||
' Send WhatsApp-specific media
|
|
||||||
TALK IMAGE "product-photo.jpg"
|
|
||||||
ELSE IF channel = "teams" THEN
|
|
||||||
' Teams adaptive card
|
|
||||||
TALK CARD "product-details"
|
|
||||||
END IF
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Supported channels:**
|
**Supported channels:**
|
||||||
|
- Web chat
|
||||||
- WhatsApp Business
|
- WhatsApp Business
|
||||||
- Microsoft Teams
|
- Teams
|
||||||
- Slack
|
- Slack
|
||||||
- Telegram
|
- Telegram
|
||||||
- Web chat
|
|
||||||
- SMS
|
- SMS
|
||||||
- Email
|
- Email
|
||||||
- Voice (coming soon)
|
- Voice (LiveKit)
|
||||||
|
|
||||||
#### Notion AI
|
### Database & Integration
|
||||||
|
|
||||||
- Web interface only
|
Direct database access and unlimited API integrations:
|
||||||
- No mobile app AI
|
|
||||||
- No chat deployments
|
|
||||||
- No messaging integrations
|
|
||||||
|
|
||||||
#### Perplexity
|
|
||||||
|
|
||||||
- Web interface
|
|
||||||
- Mobile apps
|
|
||||||
- No third-party deployments
|
|
||||||
- No messaging integrations
|
|
||||||
|
|
||||||
### 5. Data Privacy & Control
|
|
||||||
|
|
||||||
#### General Bots
|
|
||||||
|
|
||||||
**Full data sovereignty:**
|
|
||||||
- Self-hosted on your infrastructure
|
|
||||||
- Data never leaves your servers
|
|
||||||
- Choose your own LLM provider
|
|
||||||
- Audit logs and compliance
|
|
||||||
- GDPR/HIPAA ready
|
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
' All data stays on your servers
|
' Direct SQL access
|
||||||
SAVE "customer_data", customer_id, sensitive_info
|
customers = FIND "customers", "region = 'EMEA'"
|
||||||
|
|
||||||
' Use local LLM if needed
|
|
||||||
SET CONTEXT "Use local Llama model"
|
|
||||||
response = LLM query
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Notion AI
|
|
||||||
|
|
||||||
- Data stored on Notion servers (US/EU)
|
|
||||||
- Uses OpenAI (data sent to OpenAI)
|
|
||||||
- Limited compliance features
|
|
||||||
- SOC 2 Type 2 certified
|
|
||||||
|
|
||||||
#### Perplexity
|
|
||||||
|
|
||||||
- Data stored on Perplexity servers
|
|
||||||
- Search queries may be logged
|
|
||||||
- Limited privacy controls
|
|
||||||
- No self-hosting option
|
|
||||||
|
|
||||||
### 6. Integration Capabilities
|
|
||||||
|
|
||||||
#### General Bots
|
|
||||||
|
|
||||||
Native HTTP/API support:
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' REST APIs
|
' REST APIs
|
||||||
customers = GET "https://api.salesforce.com/customers"
|
data = GET "https://api.example.com/data"
|
||||||
POST "https://api.hubspot.com/contacts", contact_data
|
POST "https://api.crm.com/leads", lead_data
|
||||||
PUT "https://api.stripe.com/customers/123", update_data
|
|
||||||
DELETE "https://api.service.com/items/456"
|
|
||||||
|
|
||||||
' GraphQL
|
' GraphQL
|
||||||
query = "query { user(id: 123) { name email } }"
|
|
||||||
result = GRAPHQL "https://api.github.com/graphql", query, vars
|
result = GRAPHQL "https://api.github.com/graphql", query, vars
|
||||||
|
|
||||||
' SOAP (legacy systems)
|
|
||||||
result = SOAP "https://legacy.corp.com/service.wsdl", "GetCustomer", params
|
|
||||||
|
|
||||||
' Database
|
|
||||||
data = FIND "products", "category='electronics'"
|
|
||||||
INSERT "orders", order_data
|
|
||||||
UPDATE "inventory", "sku=ABC123", stock_update
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Integrations:**
|
No connector marketplace, no per-integration fees—connect to anything with HTTP.
|
||||||
- Any REST API
|
|
||||||
- GraphQL endpoints
|
|
||||||
- SOAP services
|
|
||||||
- SQL databases
|
|
||||||
- S3-compatible storage
|
|
||||||
- Email (SMTP/IMAP)
|
|
||||||
- Calendar (CalDAV)
|
|
||||||
- Any webhook-capable service
|
|
||||||
|
|
||||||
#### Notion AI
|
### AI Capabilities
|
||||||
|
|
||||||
- Notion API only
|
Native AI integration without additional licensing:
|
||||||
- Limited integrations via Notion
|
|
||||||
- No direct external API calls
|
|
||||||
- No database connections
|
|
||||||
|
|
||||||
#### Perplexity
|
| Feature | Implementation |
|
||||||
|
|---------|---------------|
|
||||||
|
| Chat assistance | `LLM` keyword |
|
||||||
|
| Document Q&A | `USE KB` + RAG |
|
||||||
|
| Image generation | `IMAGE` keyword |
|
||||||
|
| Video generation | `VIDEO` keyword |
|
||||||
|
| Speech-to-text | `HEAR AS AUDIO` |
|
||||||
|
| Text-to-speech | `AUDIO` keyword |
|
||||||
|
| Vision/OCR | `SEE` keyword |
|
||||||
|
|
||||||
- No API integrations
|
Use any LLM provider (OpenAI, Anthropic, local models) or run entirely offline with local inference.
|
||||||
- Search only
|
|
||||||
- No external data sources
|
|
||||||
|
|
||||||
### 7. Document Processing
|
## Automation Power
|
||||||
|
|
||||||
#### General Bots
|
BASIC scripting provides full programming capabilities:
|
||||||
|
|
||||||
Full document pipeline:
|
|
||||||
|
|
||||||
```basic
|
```basic
|
||||||
' Upload and process documents
|
SET SCHEDULE "every day at 9am"
|
||||||
HEAR document AS FILE
|
|
||||||
url = UPLOAD document, "uploads/"
|
|
||||||
|
|
||||||
' Extract text from various formats
|
' Daily report automation
|
||||||
content = GET "documents/report.pdf"
|
sales = AGGREGATE "orders", "SUM", "total", "date = TODAY()"
|
||||||
|
count = AGGREGATE "orders", "COUNT", "id", "date = TODAY()"
|
||||||
|
|
||||||
' AI processing
|
SET CONTEXT "You are a business analyst."
|
||||||
SET CONTEXT "Extract key metrics from this report"
|
summary = LLM "Sales: $" + sales + ", Orders: " + count
|
||||||
metrics = LLM content
|
|
||||||
|
|
||||||
' Generate new documents
|
SEND MAIL TO "team@company.com" SUBJECT "Daily Report" BODY summary
|
||||||
WITH invoice_data = NEW OBJECT
|
|
||||||
.customer = customer_name
|
|
||||||
.items = order_items
|
|
||||||
.total = order_total
|
|
||||||
END WITH
|
|
||||||
pdf = GENERATE PDF "templates/invoice.html", invoice_data, "invoices/inv-001.pdf"
|
|
||||||
|
|
||||||
' Merge multiple PDFs
|
|
||||||
merged = MERGE PDF ["cover.pdf", "report.pdf", "appendix.pdf"], "final-report.pdf"
|
|
||||||
|
|
||||||
' Compress and send
|
|
||||||
archive = COMPRESS ["report.pdf", "data.xlsx"], "delivery.zip"
|
|
||||||
SEND MAIL customer_email, "Your Report", "Please find attached.", archive
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Supported formats:**
|
**Automation features:**
|
||||||
- PDF (read, generate, merge)
|
- Scheduled tasks (cron syntax)
|
||||||
- Office documents (Word, Excel, PowerPoint)
|
- Event-driven webhooks
|
||||||
- Images (OCR support)
|
- Database triggers
|
||||||
- CSV/JSON data
|
- Conditional logic
|
||||||
- Archives (ZIP, TAR)
|
- Loops and iterations
|
||||||
|
- Error handling
|
||||||
|
- Multi-step workflows
|
||||||
|
|
||||||
#### Notion AI
|
## When General Bots Excels
|
||||||
|
|
||||||
- Notion pages only
|
General Bots is the right choice when you need:
|
||||||
- Export to PDF/Markdown
|
|
||||||
- No document generation
|
|
||||||
- No PDF processing
|
|
||||||
|
|
||||||
#### Perplexity
|
**Custom chatbots** for customer service, internal support, or specialized domains where you control the knowledge base and conversation flow.
|
||||||
|
|
||||||
- Can read uploaded PDFs (Pro)
|
**Workflow automation** that goes beyond simple triggers—full programming logic with database access, API calls, and AI integration.
|
||||||
- No document generation
|
|
||||||
- No processing capabilities
|
|
||||||
|
|
||||||
### 8. Cost Comparison
|
**Multi-channel deployment** where the same bot serves users on web, mobile messaging, and enterprise platforms.
|
||||||
|
|
||||||
#### General Bots (Self-hosted)
|
**Data sovereignty** with self-hosted deployment keeping all data on your infrastructure.
|
||||||
|
|
||||||
| Component | Cost |
|
**Cost control** without per-user licensing that scales with your organization.
|
||||||
|-----------|------|
|
|
||||||
| Software | Free (AGPL) |
|
|
||||||
| Infrastructure | $20-100/month (your servers) |
|
|
||||||
| LLM API | Pay per use (OpenAI, etc.) |
|
|
||||||
| **Total** | **$20-200/month** (unlimited users) |
|
|
||||||
|
|
||||||
#### Notion AI
|
**Integration flexibility** connecting to any system without marketplace limitations.
|
||||||
|
|
||||||
| Plan | Cost |
|
## Deployment Options
|
||||||
|------|------|
|
|
||||||
| Free | Limited AI features |
|
|
||||||
| Plus | $10/user/month |
|
|
||||||
| Business | $18/user/month |
|
|
||||||
| **10 users** | **$100-180/month** |
|
|
||||||
|
|
||||||
#### Perplexity
|
### Self-Hosted
|
||||||
|
|
||||||
| Plan | Cost |
|
Run General Bots on your own infrastructure:
|
||||||
|------|------|
|
- Single binary deployment
|
||||||
| Free | Limited queries |
|
- Container support (LXC, Docker)
|
||||||
| Pro | $20/month |
|
- Scales horizontally
|
||||||
| Team | $20/user/month |
|
- Full observability
|
||||||
| **10 users** | **$200/month** |
|
|
||||||
|
|
||||||
### 9. Use Case Recommendations
|
### Quick Start
|
||||||
|
|
||||||
#### Choose General Bots when you need:
|
```bash
|
||||||
|
./botserver
|
||||||
- ✅ Custom chatbots for customer service
|
|
||||||
- ✅ Internal automation workflows
|
|
||||||
- ✅ Multi-channel deployment (WhatsApp, Teams, etc.)
|
|
||||||
- ✅ Integration with existing systems
|
|
||||||
- ✅ Custom APIs without traditional development
|
|
||||||
- ✅ Data privacy and self-hosting
|
|
||||||
- ✅ Complex business logic in simple BASIC
|
|
||||||
- ✅ Document processing pipelines
|
|
||||||
- ✅ Scheduled tasks and webhooks
|
|
||||||
|
|
||||||
#### Choose Notion AI when you need:
|
|
||||||
|
|
||||||
- ✅ Document collaboration with AI assist
|
|
||||||
- ✅ Team knowledge management
|
|
||||||
- ✅ Content writing assistance
|
|
||||||
- ✅ Simple Q&A within documents
|
|
||||||
- ✅ Project management with AI
|
|
||||||
|
|
||||||
#### Choose Perplexity when you need:
|
|
||||||
|
|
||||||
- ✅ Research and fact-checking
|
|
||||||
- ✅ Real-time web search with AI
|
|
||||||
- ✅ Quick answers with citations
|
|
||||||
- ✅ Exploring topics
|
|
||||||
|
|
||||||
## Feature Matrix
|
|
||||||
|
|
||||||
| Feature | General Bots | Notion AI | Perplexity |
|
|
||||||
|---------|-------------|-----------|------------|
|
|
||||||
| **AI Chat** | ✅ | ✅ | ✅ |
|
|
||||||
| **Custom Knowledge Base** | ✅ | ⚠️ | ⚠️ |
|
|
||||||
| **API Creation** | ✅ | ❌ | ❌ |
|
|
||||||
| **Webhooks** | ✅ | ❌ | ❌ |
|
|
||||||
| **Scheduled Tasks** | ✅ | ❌ | ❌ |
|
|
||||||
| **Database** | ✅ | ⚠️ | ❌ |
|
|
||||||
| **File Storage** | ✅ | ⚠️ | ❌ |
|
|
||||||
| **Email** | ✅ | ❌ | ❌ |
|
|
||||||
| **WhatsApp** | ✅ | ❌ | ❌ |
|
|
||||||
| **Teams** | ✅ | ❌ | ❌ |
|
|
||||||
| **Slack** | ✅ | ⚠️ | ❌ |
|
|
||||||
| **PDF Generation** | ✅ | ❌ | ❌ |
|
|
||||||
| **Custom LLM** | ✅ | ❌ | ❌ |
|
|
||||||
| **Self-hosted** | ✅ | ❌ | ❌ |
|
|
||||||
| **Open Source** | ✅ | ❌ | ❌ |
|
|
||||||
| **Real-time Web Search** | ⚠️ | ❌ | ✅ |
|
|
||||||
| **Document Collaboration** | ⚠️ | ✅ | ❌ |
|
|
||||||
|
|
||||||
## Migration Path
|
|
||||||
|
|
||||||
### From Notion AI to General Bots
|
|
||||||
|
|
||||||
1. Export Notion pages as Markdown
|
|
||||||
2. Upload to General Bots knowledge base
|
|
||||||
3. Create BASIC scripts for automation
|
|
||||||
4. Deploy to additional channels
|
|
||||||
|
|
||||||
```basic
|
|
||||||
' Import Notion export
|
|
||||||
files = LIST "notion-export/"
|
|
||||||
FOR EACH file IN files
|
|
||||||
content = GET file
|
|
||||||
USE KB "imported-docs"
|
|
||||||
' Documents automatically indexed
|
|
||||||
NEXT file
|
|
||||||
|
|
||||||
TALK "Notion content imported and ready for AI queries!"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### From Perplexity to General Bots
|
Access at `http://localhost:8080` and start building.
|
||||||
|
|
||||||
1. Identify common queries
|
## Summary
|
||||||
2. Build knowledge base from trusted sources
|
|
||||||
3. Create custom Q&A endpoint
|
|
||||||
|
|
||||||
```basic
|
General Bots combines:
|
||||||
' Replace Perplexity with custom research endpoint
|
|
||||||
WEBHOOK "research"
|
|
||||||
|
|
||||||
query = body.query
|
- **Self-hosting** for complete data control
|
||||||
USE KB "trusted-sources"
|
- **BASIC scripting** for powerful automation
|
||||||
USE WEBSITE "https://docs.company.com"
|
- **Multi-channel** for broad reach
|
||||||
|
- **Native AI** without extra licensing
|
||||||
|
- **Open source** for transparency and customization
|
||||||
|
- **No per-user fees** for predictable costs
|
||||||
|
|
||||||
SET CONTEXT "Provide accurate, cited answers based on the knowledge base."
|
For organizations that need more than a simple chatbot—those requiring custom integrations, complex workflows, and full control over their AI deployment—General Bots provides the foundation to build exactly what you need.
|
||||||
answer = LLM query
|
|
||||||
|
|
||||||
WITH result = NEW OBJECT
|
|
||||||
.query = query
|
|
||||||
.answer = answer
|
|
||||||
.sources = "Internal knowledge base"
|
|
||||||
END WITH
|
|
||||||
```
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
**General Bots** stands apart as the only platform that combines:
|
|
||||||
|
|
||||||
1. **Full customization** - Write BASIC code for any automation
|
|
||||||
2. **Self-hosting** - Complete data control
|
|
||||||
3. **Multi-channel** - Deploy anywhere
|
|
||||||
4. **Open source** - Modify and extend freely
|
|
||||||
5. **Cost-effective** - No per-user pricing
|
|
||||||
|
|
||||||
While Notion AI excels at document collaboration and Perplexity at web search, General Bots is the choice for organizations that need **customizable, self-hosted AI automation** with **enterprise-grade capabilities**.
|
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- [Quick Start](../chapter-01/quick-start.md) - Get started in 5 minutes
|
- [Quick Start](../chapter-01/quick-start.md) - Get running in minutes
|
||||||
- [WEBHOOK](../chapter-06-gbdialog/keyword-webhook.md) - Create instant APIs
|
|
||||||
- [Keywords Reference](../chapter-06-gbdialog/keywords.md) - Full BASIC reference
|
- [Keywords Reference](../chapter-06-gbdialog/keywords.md) - Full BASIC reference
|
||||||
- [Architecture](../chapter-07-gbapp/architecture.md) - Technical deep dive
|
- [REST API](../chapter-10-api/README.md) - API documentation
|
||||||
|
- [Projects](./projects.md) - Team collaboration features
|
||||||
348
docs/src/chapter-11-features/projects.md
Normal file
348
docs/src/chapter-11-features/projects.md
Normal file
|
|
@ -0,0 +1,348 @@
|
||||||
|
# Projects
|
||||||
|
|
||||||
|
Projects organize work and enable team collaboration within General Bots. A project groups related tasks, conversations, documents, and team members into a shared workspace where everyone stays aligned.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Every bot starts with a default project. Users can create additional projects to organize different initiatives, clients, or departments. When chatting with the bot, selecting a project scopes the conversation to that context—the AI understands what you're working on and who else is involved.
|
||||||
|
|
||||||
|
Projects connect three core capabilities:
|
||||||
|
|
||||||
|
- **Tasks** belong to projects, making it easy to track work across teams
|
||||||
|
- **Conversations** can be project-scoped, so the AI has relevant context
|
||||||
|
- **Team members** are assigned to projects, enabling collaboration
|
||||||
|
|
||||||
|
## Creating Projects
|
||||||
|
|
||||||
|
### Via Chat
|
||||||
|
|
||||||
|
```
|
||||||
|
User: Create a new project called Website Redesign
|
||||||
|
Bot: Project "Website Redesign" created. Would you like to add team members?
|
||||||
|
User: Yes, add maria@company.com and john@company.com
|
||||||
|
Bot: Added Maria and John to the project. You can now assign tasks and chat within this project context.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Via BASIC
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' create-project.bas
|
||||||
|
PARAM name AS string
|
||||||
|
PARAM description AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Create a new project workspace"
|
||||||
|
|
||||||
|
project_id = CREATE PROJECT name WITH DESCRIPTION description
|
||||||
|
TALK "Project created: " + name
|
||||||
|
|
||||||
|
' Add current user as owner
|
||||||
|
ADD USER TO PROJECT project_id, user.id, "owner"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Via API
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/projects
|
||||||
|
{
|
||||||
|
"name": "Website Redesign",
|
||||||
|
"description": "Q2 website refresh initiative",
|
||||||
|
"members": ["user-id-1", "user-id-2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
Each project contains:
|
||||||
|
|
||||||
|
```
|
||||||
|
Project
|
||||||
|
├── Settings
|
||||||
|
│ ├── Name and description
|
||||||
|
│ ├── Visibility (private/team/public)
|
||||||
|
│ └── Default assignee
|
||||||
|
├── Members
|
||||||
|
│ ├── Owners (full control)
|
||||||
|
│ ├── Members (can edit)
|
||||||
|
│ └── Viewers (read only)
|
||||||
|
├── Tasks
|
||||||
|
│ ├── Boards and columns
|
||||||
|
│ ├── Task items
|
||||||
|
│ └── Dependencies
|
||||||
|
├── Conversations
|
||||||
|
│ ├── Project chat history
|
||||||
|
│ └── AI context from project docs
|
||||||
|
└── Files
|
||||||
|
└── Project-specific documents
|
||||||
|
```
|
||||||
|
|
||||||
|
## Working with Projects
|
||||||
|
|
||||||
|
### Switching Project Context
|
||||||
|
|
||||||
|
In the chat interface, select a project from the project dropdown. All subsequent conversations use that project's context:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Project: Website Redesign ▼]
|
||||||
|
|
||||||
|
User: What tasks are due this week?
|
||||||
|
Bot: In the Website Redesign project, you have 3 tasks due this week:
|
||||||
|
1. Finalize homepage mockups (Friday)
|
||||||
|
2. Review navigation structure (Wednesday)
|
||||||
|
3. Content inventory spreadsheet (Thursday)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project-Scoped AI
|
||||||
|
|
||||||
|
When a project is selected, the AI automatically:
|
||||||
|
|
||||||
|
- References project documents in responses
|
||||||
|
- Knows about team members and their roles
|
||||||
|
- Understands project-specific terminology from past conversations
|
||||||
|
- Suggests relevant tasks and next steps
|
||||||
|
|
||||||
|
```
|
||||||
|
User: Who's working on the design?
|
||||||
|
Bot: Maria is assigned to the design tasks. She completed the color palette
|
||||||
|
yesterday and is currently working on the homepage mockups. John is
|
||||||
|
handling the technical implementation once designs are approved.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Team Collaboration
|
||||||
|
|
||||||
|
Project members can chat together with AI assistance:
|
||||||
|
|
||||||
|
```
|
||||||
|
Maria: @bot summarize what we discussed about the navigation
|
||||||
|
Bot: Based on your project conversations, the team decided on:
|
||||||
|
- Simplified top nav with 5 main sections
|
||||||
|
- Mega menu for product categories
|
||||||
|
- Mobile-first hamburger menu
|
||||||
|
John raised concerns about dropdown accessibility that still need addressing.
|
||||||
|
```
|
||||||
|
|
||||||
|
## BASIC Keywords for Projects
|
||||||
|
|
||||||
|
### CREATE PROJECT
|
||||||
|
|
||||||
|
```basic
|
||||||
|
project_id = CREATE PROJECT "Marketing Campaign" WITH DESCRIPTION "Q3 launch"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GET PROJECT
|
||||||
|
|
||||||
|
```basic
|
||||||
|
project = GET PROJECT project_id
|
||||||
|
TALK "Project: " + project.name
|
||||||
|
TALK "Members: " + LEN(project.members)
|
||||||
|
TALK "Open tasks: " + project.task_count
|
||||||
|
```
|
||||||
|
|
||||||
|
### LIST PROJECTS
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' List user's projects
|
||||||
|
projects = LIST PROJECTS
|
||||||
|
FOR EACH p IN projects
|
||||||
|
TALK p.name + " (" + p.role + ")"
|
||||||
|
NEXT p
|
||||||
|
|
||||||
|
' List projects with filter
|
||||||
|
active = LIST PROJECTS WHERE "status = 'active'"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ADD USER TO PROJECT
|
||||||
|
|
||||||
|
```basic
|
||||||
|
ADD USER TO PROJECT project_id, user_id, "member"
|
||||||
|
ADD USER TO PROJECT project_id, email, "owner"
|
||||||
|
```
|
||||||
|
|
||||||
|
### REMOVE USER FROM PROJECT
|
||||||
|
|
||||||
|
```basic
|
||||||
|
REMOVE USER FROM PROJECT project_id, user_id
|
||||||
|
```
|
||||||
|
|
||||||
|
### SET PROJECT
|
||||||
|
|
||||||
|
Set the current conversation's project context:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET PROJECT project_id
|
||||||
|
' Subsequent operations use this project context
|
||||||
|
CREATE TASK "Review designs" ' Task created in the selected project
|
||||||
|
```
|
||||||
|
|
||||||
|
### DELETE PROJECT
|
||||||
|
|
||||||
|
```basic
|
||||||
|
DELETE PROJECT project_id
|
||||||
|
' Or via dynamic path
|
||||||
|
DELETE "/projects/" + project_id
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### List Projects
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/projects
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns projects the authenticated user can access.
|
||||||
|
|
||||||
|
### Get Project
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/projects/{id}
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns project details including members and task summary.
|
||||||
|
|
||||||
|
### Create Project
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/projects
|
||||||
|
{
|
||||||
|
"name": "Project Name",
|
||||||
|
"description": "Optional description",
|
||||||
|
"visibility": "team",
|
||||||
|
"members": [
|
||||||
|
{"user_id": "...", "role": "owner"},
|
||||||
|
{"user_id": "...", "role": "member"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update Project
|
||||||
|
|
||||||
|
```
|
||||||
|
PUT /api/projects/{id}
|
||||||
|
{
|
||||||
|
"name": "Updated Name",
|
||||||
|
"description": "Updated description"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete Project
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /api/projects/{id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project Members
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/projects/{id}/members
|
||||||
|
POST /api/projects/{id}/members
|
||||||
|
DELETE /api/projects/{id}/members/{user_id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project Tasks
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/projects/{id}/tasks
|
||||||
|
POST /api/projects/{id}/tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project Conversations
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/projects/{id}/conversations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
Projects are stored in the `projects` table:
|
||||||
|
|
||||||
|
| Column | Type | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `id` | UUID | Project identifier |
|
||||||
|
| `bot_id` | UUID | Owning bot |
|
||||||
|
| `name` | TEXT | Project name |
|
||||||
|
| `description` | TEXT | Optional description |
|
||||||
|
| `visibility` | TEXT | private, team, or public |
|
||||||
|
| `settings` | JSONB | Project configuration |
|
||||||
|
| `created_by` | UUID | Creator user ID |
|
||||||
|
| `created_at` | TIMESTAMP | Creation time |
|
||||||
|
| `updated_at` | TIMESTAMP | Last update |
|
||||||
|
|
||||||
|
Project membership in `project_members`:
|
||||||
|
|
||||||
|
| Column | Type | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `project_id` | UUID | Project reference |
|
||||||
|
| `user_id` | UUID | User reference |
|
||||||
|
| `role` | TEXT | owner, member, or viewer |
|
||||||
|
| `joined_at` | TIMESTAMP | When user joined |
|
||||||
|
|
||||||
|
## Default Project
|
||||||
|
|
||||||
|
Every bot has a default project that cannot be deleted. Tasks created without specifying a project go here. Users can:
|
||||||
|
|
||||||
|
- Rename the default project
|
||||||
|
- Move tasks from default to specific projects
|
||||||
|
- Use the default for personal/unorganized work
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Get the default project
|
||||||
|
default = GET DEFAULT PROJECT
|
||||||
|
TALK "Default project: " + default.name
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Templates
|
||||||
|
|
||||||
|
Create projects from templates for common scenarios:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Create from template
|
||||||
|
project_id = CREATE PROJECT FROM TEMPLATE "client-onboarding", "Acme Corp Onboarding"
|
||||||
|
|
||||||
|
' Available templates
|
||||||
|
templates = LIST PROJECT TEMPLATES
|
||||||
|
```
|
||||||
|
|
||||||
|
Built-in templates include:
|
||||||
|
|
||||||
|
- **Client Onboarding** - Tasks for new client setup
|
||||||
|
- **Product Launch** - Launch checklist and milestones
|
||||||
|
- **Sprint** - Two-week sprint with standard ceremonies
|
||||||
|
- **Content Calendar** - Monthly content planning
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Keep projects focused.** A project should represent a distinct initiative with clear boundaries. If a project grows too large, consider splitting it.
|
||||||
|
|
||||||
|
**Assign clear ownership.** Every project needs at least one owner responsible for keeping it organized and moving forward.
|
||||||
|
|
||||||
|
**Use project context in chat.** When discussing project-specific topics, select the project first so the AI has full context.
|
||||||
|
|
||||||
|
**Archive completed projects.** Rather than deleting, archive finished projects to preserve history:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
UPDATE PROJECT project_id SET status = "archived"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Review project membership regularly.** Remove users who are no longer involved to keep conversations relevant.
|
||||||
|
|
||||||
|
## Integration with Tasks
|
||||||
|
|
||||||
|
Tasks belong to exactly one project. The task view shows the default project by default, with options to filter by project or view all tasks across projects.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Create task in specific project
|
||||||
|
SET PROJECT project_id
|
||||||
|
CREATE TASK "Design review" DUE DATEADD(NOW(), 7, "day")
|
||||||
|
|
||||||
|
' Or specify project directly
|
||||||
|
CREATE TASK "Design review" IN PROJECT project_id
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Tasks API](../chapter-10-api/tasks-api.md) - Task management endpoints
|
||||||
|
- [Conversations API](../chapter-10-api/conversations-api.md) - Chat history
|
||||||
|
- [Groups API](../chapter-10-api/groups-api.md) - User group management
|
||||||
|
- [SET CONTEXT](../chapter-06-gbdialog/keyword-set-context.md) - AI context configuration
|
||||||
461
docs/src/chapter-14-migration/botpress.md
Normal file
461
docs/src/chapter-14-migration/botpress.md
Normal file
|
|
@ -0,0 +1,461 @@
|
||||||
|
# Botpress Migration Guide
|
||||||
|
|
||||||
|
Migrating chatbots from Botpress to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Botpress is an open-source chatbot platform with visual flow builder and NLU. General Bots provides a simpler approach using LLM-based understanding and BASIC scripting, with integrated productivity features and native multi-channel support.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Botpress | General Bots |
|
||||||
|
|--------|----------|--------------|
|
||||||
|
| NLU Approach | Intent training required | LLM-based (no training) |
|
||||||
|
| Flow Building | Visual + code | BASIC scripts |
|
||||||
|
| Self-hosting | Available | Available |
|
||||||
|
| AI Integration | Via hooks | Native LLM keywords |
|
||||||
|
| Knowledge Base | Limited | Full RAG system |
|
||||||
|
| Productivity Suite | Not included | Email, calendar, files, tasks |
|
||||||
|
| Multi-channel | Via connectors | Native support |
|
||||||
|
| Learning Curve | Moderate | Simple BASIC |
|
||||||
|
|
||||||
|
## Concept Mapping
|
||||||
|
|
||||||
|
| Botpress Concept | General Bots Equivalent |
|
||||||
|
|------------------|------------------------|
|
||||||
|
| Flows | BASIC scripts |
|
||||||
|
| Nodes | BASIC statements |
|
||||||
|
| Intents | LLM understanding |
|
||||||
|
| Entities | `HEAR AS <type>` |
|
||||||
|
| Slots | Variables |
|
||||||
|
| Actions | BASIC keywords |
|
||||||
|
| Hooks | `ON` triggers |
|
||||||
|
| Content Types | TALK variations |
|
||||||
|
| Knowledge Base | `.gbkb` folders |
|
||||||
|
| Channels | Native multi-channel |
|
||||||
|
|
||||||
|
## Flow Migration
|
||||||
|
|
||||||
|
### Botpress Flow Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Botpress flow (simplified)
|
||||||
|
nodes:
|
||||||
|
- id: entry
|
||||||
|
type: standard
|
||||||
|
next: ask_name
|
||||||
|
- id: ask_name
|
||||||
|
type: say_something
|
||||||
|
content: "What's your name?"
|
||||||
|
next: capture_name
|
||||||
|
- id: capture_name
|
||||||
|
type: listen
|
||||||
|
slot: name
|
||||||
|
next: greet
|
||||||
|
- id: greet
|
||||||
|
type: say_something
|
||||||
|
content: "Hello {{name}}!"
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Equivalent
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Simple and readable
|
||||||
|
TALK "What's your name?"
|
||||||
|
HEAR name AS NAME
|
||||||
|
TALK "Hello " + name + "!"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Examples
|
||||||
|
|
||||||
|
### Simple Welcome Flow
|
||||||
|
|
||||||
|
**Botpress:**
|
||||||
|
- Entry node → Say "Welcome" → Listen for intent → Route to sub-flow
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "help-docs"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a friendly assistant for Acme Corp."
|
||||||
|
|
||||||
|
TALK "Welcome! How can I help you today?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lead Capture Flow
|
||||||
|
|
||||||
|
**Botpress:**
|
||||||
|
```
|
||||||
|
Entry → Ask Name → Capture Slot → Ask Email → Capture Slot →
|
||||||
|
Ask Company → Capture Slot → Save to CRM → Thank You
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' lead-capture.bas
|
||||||
|
TALK "I'd love to learn more about you!"
|
||||||
|
|
||||||
|
TALK "What's your name?"
|
||||||
|
HEAR name AS NAME
|
||||||
|
|
||||||
|
TALK "And your work email?"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
TALK "What company are you with?"
|
||||||
|
HEAR company
|
||||||
|
|
||||||
|
' Save directly - no external action needed
|
||||||
|
INSERT "leads", #{
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
company: company,
|
||||||
|
source: "chatbot",
|
||||||
|
created_at: NOW()
|
||||||
|
}
|
||||||
|
|
||||||
|
' Score the lead
|
||||||
|
score = SCORE LEAD #{name: name, email: email, company: company}
|
||||||
|
|
||||||
|
IF score.status = "hot" THEN
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Hot Lead" BODY "New lead: " + name + " from " + company
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Thanks, " + name + "! Someone from our team will be in touch soon."
|
||||||
|
```
|
||||||
|
|
||||||
|
### FAQ Bot with Fallback
|
||||||
|
|
||||||
|
**Botpress:**
|
||||||
|
- NLU intent matching
|
||||||
|
- Knowledge base query
|
||||||
|
- Fallback to human
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "faq"
|
||||||
|
USE KB "product-docs"
|
||||||
|
|
||||||
|
SET CONTEXT "Answer customer questions helpfully. If you cannot answer confidently, offer to connect with a human."
|
||||||
|
|
||||||
|
TALK "What can I help you with?"
|
||||||
|
HEAR question
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
|
||||||
|
' Check if confident answer
|
||||||
|
IF CONTAINS(LOWER(answer), "i don't") OR CONTAINS(LOWER(answer), "not sure") THEN
|
||||||
|
TALK "I'm not certain about that. Would you like to speak with someone?"
|
||||||
|
HEAR wants_human AS BOOLEAN
|
||||||
|
IF wants_human THEN
|
||||||
|
CREATE TASK "Customer inquiry: " + question
|
||||||
|
SEND MAIL TO "support@company.com" SUBJECT "Chat Handoff" BODY question
|
||||||
|
TALK "I've notified our team. Someone will reach out shortly."
|
||||||
|
END IF
|
||||||
|
ELSE
|
||||||
|
TALK answer
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Step Booking Flow
|
||||||
|
|
||||||
|
**Botpress:**
|
||||||
|
```
|
||||||
|
Select Service → Choose Date → Choose Time → Confirm → Book
|
||||||
|
(Multiple nodes with slot filling)
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "Let's book your appointment."
|
||||||
|
|
||||||
|
TALK "What service do you need?"
|
||||||
|
HEAR service AS "Consultation", "Checkup", "Follow-up", "Emergency"
|
||||||
|
|
||||||
|
TALK "What date works for you?"
|
||||||
|
HEAR appt_date AS DATE
|
||||||
|
|
||||||
|
TALK "What time?"
|
||||||
|
HEAR appt_time AS HOUR
|
||||||
|
|
||||||
|
' Check availability
|
||||||
|
available = GET "https://calendar.api/available?date=" + appt_date + "&time=" + appt_time
|
||||||
|
|
||||||
|
IF available THEN
|
||||||
|
BOOK service AT appt_date + " " + appt_time
|
||||||
|
TALK "Your " + service + " is confirmed for " + FORMAT(appt_date, "MMMM d") + " at " + appt_time
|
||||||
|
ELSE
|
||||||
|
TALK "That slot isn't available. Would " + available.next + " work instead?"
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## NLU Migration
|
||||||
|
|
||||||
|
### Botpress Intents
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Botpress intent definition
|
||||||
|
intents:
|
||||||
|
- name: order_status
|
||||||
|
utterances:
|
||||||
|
- where is my order
|
||||||
|
- track my order
|
||||||
|
- order status
|
||||||
|
- what happened to my order
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Approach
|
||||||
|
|
||||||
|
No intent definition needed. The LLM understands naturally:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "order-help"
|
||||||
|
SET CONTEXT "Help customers with their orders."
|
||||||
|
|
||||||
|
TALK "How can I help with your order?"
|
||||||
|
HEAR question
|
||||||
|
|
||||||
|
' LLM understands "where is my order", "track order", etc.
|
||||||
|
' without explicit training
|
||||||
|
answer = LLM question
|
||||||
|
```
|
||||||
|
|
||||||
|
### Entity Extraction
|
||||||
|
|
||||||
|
**Botpress:**
|
||||||
|
```yaml
|
||||||
|
entities:
|
||||||
|
- name: order_number
|
||||||
|
type: pattern
|
||||||
|
pattern: "ORD-[0-9]{6}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
TALK "What's your order number?"
|
||||||
|
HEAR order_number
|
||||||
|
|
||||||
|
' Or with validation pattern
|
||||||
|
IF NOT MATCH(order_number, "ORD-[0-9]{6}") THEN
|
||||||
|
TALK "Please enter a valid order number (e.g., ORD-123456)"
|
||||||
|
HEAR order_number
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Actions Migration
|
||||||
|
|
||||||
|
### Botpress Custom Actions
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Botpress action
|
||||||
|
const checkOrderStatus = async (orderId) => {
|
||||||
|
const response = await axios.get(`/api/orders/${orderId}`);
|
||||||
|
return response.data.status;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Direct API call - no separate action file
|
||||||
|
order = GET "https://api.company.com/orders/" + order_id
|
||||||
|
TALK "Your order status is: " + order.status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hooks Migration
|
||||||
|
|
||||||
|
### Botpress Hooks
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// before_incoming_middleware hook
|
||||||
|
bp.events.on('before_incoming_middleware', async (event) => {
|
||||||
|
// Custom logic
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Triggers
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Event-driven triggers
|
||||||
|
ON "message:received"
|
||||||
|
' Log all messages
|
||||||
|
INSERT "message_log", #{
|
||||||
|
content: params.content,
|
||||||
|
user: params.user_id,
|
||||||
|
timestamp: NOW()
|
||||||
|
}
|
||||||
|
END ON
|
||||||
|
|
||||||
|
ON "session:started"
|
||||||
|
' Track new sessions
|
||||||
|
INSERT "sessions", #{
|
||||||
|
id: params.session_id,
|
||||||
|
started: NOW()
|
||||||
|
}
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## Content Types
|
||||||
|
|
||||||
|
### Botpress Content
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Botpress content types
|
||||||
|
{
|
||||||
|
type: 'builtin_card',
|
||||||
|
title: 'Product',
|
||||||
|
image: 'product.jpg',
|
||||||
|
actions: [{ title: 'Buy', action: 'buy' }]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Text
|
||||||
|
TALK "Hello!"
|
||||||
|
|
||||||
|
' Image
|
||||||
|
TALK IMAGE "/products/featured.jpg"
|
||||||
|
|
||||||
|
' File
|
||||||
|
TALK FILE "/docs/brochure.pdf"
|
||||||
|
|
||||||
|
' Suggestions
|
||||||
|
ADD SUGGESTION "View Products"
|
||||||
|
ADD SUGGESTION "Contact Sales"
|
||||||
|
ADD SUGGESTION "Get Help"
|
||||||
|
TALK "What would you like to do?"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Knowledge Base Migration
|
||||||
|
|
||||||
|
### Botpress Q&A
|
||||||
|
|
||||||
|
Limited to question-answer pairs.
|
||||||
|
|
||||||
|
### General Bots RAG
|
||||||
|
|
||||||
|
Full document support:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-bot.gbkb/
|
||||||
|
├── products/
|
||||||
|
│ ├── catalog.pdf
|
||||||
|
│ ├── specs.xlsx
|
||||||
|
│ └── pricing.md
|
||||||
|
├── support/
|
||||||
|
│ ├── faq.md
|
||||||
|
│ └── troubleshooting.md
|
||||||
|
└── company/
|
||||||
|
├── about.md
|
||||||
|
└── policies.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "products"
|
||||||
|
USE KB "support"
|
||||||
|
USE KB "company"
|
||||||
|
|
||||||
|
answer = LLM customer_question
|
||||||
|
```
|
||||||
|
|
||||||
|
## Channel Migration
|
||||||
|
|
||||||
|
### Botpress Channels
|
||||||
|
|
||||||
|
Requires separate connector configuration for each channel.
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
Native multi-channel with same code:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Works everywhere: Web, WhatsApp, Teams, Slack, Telegram, SMS
|
||||||
|
TALK "How can I help?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database and State
|
||||||
|
|
||||||
|
### Botpress State
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Botpress user state
|
||||||
|
event.state.user.name = 'John';
|
||||||
|
event.state.session.orderId = '12345';
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Session/conversation memory
|
||||||
|
SET BOT MEMORY "customer_name", name
|
||||||
|
SET BOT MEMORY "current_order", order_id
|
||||||
|
|
||||||
|
' Retrieve
|
||||||
|
name = GET BOT MEMORY "customer_name"
|
||||||
|
|
||||||
|
' Persistent storage
|
||||||
|
INSERT "customers", #{name: name, email: email}
|
||||||
|
customer = FIND "customers", "email = '" + email + "'"
|
||||||
|
```
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
**Simpler Development:** BASIC scripts are more readable than visual flows with scattered code.
|
||||||
|
|
||||||
|
**No NLU Training:** LLM understands variations without explicit intent training.
|
||||||
|
|
||||||
|
**Native AI:** Full LLM integration without plugins.
|
||||||
|
|
||||||
|
**Productivity Suite:** Built-in email, calendar, files, and tasks.
|
||||||
|
|
||||||
|
**Unified Platform:** Chat, automation, and productivity in one system.
|
||||||
|
|
||||||
|
**True Multi-Channel:** Same code works everywhere without channel-specific configuration.
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export Botpress flows and content
|
||||||
|
- [ ] Document intents and entities
|
||||||
|
- [ ] List custom actions
|
||||||
|
- [ ] Export Q&A/knowledge base
|
||||||
|
- [ ] Note channel configurations
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
- [ ] Create BASIC scripts for main flows
|
||||||
|
- [ ] Build knowledge base structure
|
||||||
|
- [ ] Implement entity validation
|
||||||
|
- [ ] Configure channels
|
||||||
|
- [ ] Test all flows
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Compare conversation quality
|
||||||
|
- [ ] Verify integrations
|
||||||
|
- [ ] Train team
|
||||||
|
- [ ] Redirect channel endpoints
|
||||||
|
- [ ] Decommission Botpress
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Dialog Basics](../chapter-06-gbdialog/basics.md) - Script fundamentals
|
||||||
|
- [HEAR Keyword](../chapter-06-gbdialog/keyword-hear.md) - Input validation
|
||||||
|
- [Knowledge Base](../chapter-03/README.md) - RAG configuration
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full comparison
|
||||||
200
docs/src/chapter-14-migration/comparison-matrix.md
Normal file
200
docs/src/chapter-14-migration/comparison-matrix.md
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
# Platform Comparison Matrix
|
||||||
|
|
||||||
|
This comprehensive comparison helps organizations evaluate General Bots against major productivity, automation, and AI platforms.
|
||||||
|
|
||||||
|
<img src="../assets/platform-comparison-summary.svg" alt="Platform Comparison Summary" style="max-height: 450px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
General Bots uniquely combines self-hosted deployment, open source licensing, native AI integration, and powerful BASIC scripting—capabilities that typically require multiple expensive subscriptions across competing platforms.
|
||||||
|
|
||||||
|
## Complete Platform Comparison
|
||||||
|
|
||||||
|
### Deployment & Licensing
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Self-hosted | ✅ Full | ❌ Cloud only | ❌ Cloud only | ✅ Available | ❌ Cloud only | ❌ Cloud only | ❌ Cloud only | ❌ Cloud only |
|
||||||
|
| Open source | ✅ AGPL | ❌ Proprietary | ❌ Proprietary | ✅ Fair-code | ❌ Proprietary | ❌ Proprietary | ❌ Proprietary | ❌ Proprietary |
|
||||||
|
| Data sovereignty | ✅ Your servers | ❌ Microsoft servers | ❌ Google servers | ✅ Self-host option | ❌ AWS/GCP | ❌ Their servers | ❌ Anthropic servers | ❌ Their servers |
|
||||||
|
| Per-user licensing | ✅ None | ❌ $12-57/user/mo | ❌ $6-18/user/mo | ⚠️ Cloud version | ❌ $10-15/user/mo | ❌ $20/mo | ❌ $20/mo | ❌ Per-task pricing |
|
||||||
|
| Source code access | ✅ Full | ❌ None | ❌ None | ✅ Available | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Modify & extend | ✅ Unlimited | ❌ API only | ❌ API only | ✅ Possible | ❌ API only | ❌ None | ❌ None | ❌ None |
|
||||||
|
|
||||||
|
### Productivity Suite
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Email | ✅ Stalwart | ✅ Exchange | ✅ Gmail | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Calendar | ✅ CalDAV | ✅ Outlook | ✅ Calendar | ❌ None | ❌ Basic | ❌ None | ❌ None | ❌ None |
|
||||||
|
| File storage | ✅ SeaweedFS | ✅ OneDrive | ✅ Drive | ❌ None | ⚠️ Limited | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Tasks/Projects | ✅ Full | ✅ Planner | ✅ Tasks | ❌ None | ✅ Strong | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Video meetings | ✅ LiveKit | ✅ Teams | ✅ Meet | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Team chat | ✅ Multi-channel | ✅ Teams | ✅ Chat | ❌ None | ⚠️ Comments | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Document editing | ✅ Available | ✅ Office apps | ✅ Docs/Sheets | ❌ None | ✅ Pages | ❌ None | ❌ None | ❌ None |
|
||||||
|
| Identity/SSO | ✅ Zitadel | ✅ Entra ID | ✅ Identity | ❌ None | ⚠️ Basic | ❌ None | ❌ None | ❌ None |
|
||||||
|
|
||||||
|
### AI & Intelligence
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| LLM integration | ✅ Any provider | ⚠️ Copilot ($30/user) | ⚠️ Gemini (extra) | ⚠️ Via nodes | ⚠️ Limited | ✅ Built-in | ✅ Built-in | ⚠️ Via connectors |
|
||||||
|
| Custom prompts | ✅ Full control | ⚠️ Limited | ⚠️ Limited | ✅ Available | ⚠️ Basic | ⚠️ Limited | ✅ Available | ⚠️ Limited |
|
||||||
|
| RAG/Knowledge base | ✅ Built-in | ⚠️ Extra cost | ⚠️ Extra cost | ⚠️ Custom build | ⚠️ Page search | ⚠️ Pro only | ⚠️ Projects | ❌ None |
|
||||||
|
| Image generation | ✅ Local SD | ⚠️ Designer | ⚠️ Limited | ⚠️ Via API | ❌ None | ⚠️ Limited | ✅ Available | ⚠️ Via API |
|
||||||
|
| Video generation | ✅ Zeroscope | ❌ None | ❌ None | ⚠️ Via API | ❌ None | ❌ None | ❌ None | ⚠️ Via API |
|
||||||
|
| Speech-to-text | ✅ Whisper | ⚠️ Extra | ⚠️ Extra | ⚠️ Via API | ❌ None | ❌ None | ❌ None | ⚠️ Via API |
|
||||||
|
| Vision/OCR | ✅ BLIP2 | ⚠️ Extra | ⚠️ Extra | ⚠️ Via API | ❌ None | ❌ None | ✅ Available | ⚠️ Via API |
|
||||||
|
| Local/offline AI | ✅ Full support | ❌ None | ❌ None | ⚠️ Possible | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
| AI cost | ✅ Bring your key | ❌ $30/user/mo | ❌ $20/user/mo | ⚠️ API costs | ❌ $10/user/mo | ❌ $20/mo | ❌ $20/mo | ⚠️ Per operation |
|
||||||
|
|
||||||
|
### Automation & Integration
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Workflow automation | ✅ BASIC scripts | ⚠️ Power Automate ($) | ⚠️ AppSheet ($) | ✅ Visual builder | ⚠️ Basic | ❌ None | ❌ None | ✅ Visual builder |
|
||||||
|
| Scheduled tasks | ✅ Cron + natural | ⚠️ Extra license | ⚠️ Limited | ✅ Available | ❌ None | ❌ None | ❌ None | ✅ Available |
|
||||||
|
| Webhooks | ✅ Instant creation | ⚠️ Complex setup | ⚠️ Limited | ✅ Available | ⚠️ Limited | ❌ None | ❌ None | ✅ Available |
|
||||||
|
| Custom APIs | ✅ One line | ❌ Azure required | ❌ GCP required | ✅ Possible | ❌ None | ❌ None | ✅ API available | ❌ None |
|
||||||
|
| Database access | ✅ Direct SQL | ⚠️ Dataverse ($) | ⚠️ BigQuery ($) | ✅ Multiple DBs | ⚠️ Notion DBs | ❌ None | ❌ None | ⚠️ Limited |
|
||||||
|
| REST API calls | ✅ GET/POST/etc | ⚠️ Premium connectors | ⚠️ Limited | ✅ HTTP nodes | ❌ None | ❌ None | ❌ None | ✅ HTTP module |
|
||||||
|
| GraphQL | ✅ Native | ❌ None | ❌ None | ✅ Available | ❌ None | ❌ None | ❌ None | ⚠️ Limited |
|
||||||
|
| SOAP/Legacy | ✅ Supported | ⚠️ Limited | ❌ None | ✅ Available | ❌ None | ❌ None | ❌ None | ⚠️ Limited |
|
||||||
|
| Automation pricing | ✅ Unlimited | ❌ Per-flow fees | ❌ Per-run fees | ⚠️ Execution limits | ❌ None | ❌ None | ❌ None | ❌ Per-task fees |
|
||||||
|
|
||||||
|
### Multi-Channel Communication
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Web chat | ✅ Built-in | ⚠️ Bot Framework | ❌ None | ❌ None | ❌ None | ✅ Web only | ✅ Web only | ❌ None |
|
||||||
|
| WhatsApp | ✅ Native | ⚠️ Extra setup | ❌ None | ⚠️ Via nodes | ❌ None | ❌ None | ❌ None | ⚠️ Connector |
|
||||||
|
| Teams | ✅ Native | ✅ Native | ❌ None | ⚠️ Via nodes | ❌ None | ❌ None | ❌ None | ⚠️ Connector |
|
||||||
|
| Slack | ✅ Native | ⚠️ Connector | ⚠️ Limited | ⚠️ Via nodes | ⚠️ Integration | ❌ None | ⚠️ Integration | ⚠️ Connector |
|
||||||
|
| Telegram | ✅ Native | ❌ None | ❌ None | ⚠️ Via nodes | ❌ None | ❌ None | ❌ None | ⚠️ Connector |
|
||||||
|
| SMS | ✅ Native | ⚠️ Extra | ❌ None | ⚠️ Via nodes | ❌ None | ❌ None | ❌ None | ⚠️ Connector |
|
||||||
|
| Email bot | ✅ Native | ⚠️ Complex | ⚠️ Limited | ⚠️ Via nodes | ❌ None | ❌ None | ❌ None | ⚠️ Connector |
|
||||||
|
| Voice | ✅ LiveKit | ⚠️ Extra | ⚠️ Extra | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
|
||||||
|
### Developer Experience
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Scripting language | ✅ BASIC (simple) | ⚠️ Power Fx | ⚠️ Apps Script | ✅ JavaScript | ❌ None | ❌ None | ❌ None | ❌ Visual only |
|
||||||
|
| No-code option | ✅ Conversational | ⚠️ Power Apps | ⚠️ AppSheet | ✅ Visual builder | ✅ Pages | ✅ Chat | ✅ Chat | ✅ Visual builder |
|
||||||
|
| Custom keywords | ✅ Rust extensible | ❌ None | ❌ None | ✅ Custom nodes | ❌ None | ❌ None | ❌ None | ❌ None |
|
||||||
|
| API-first | ✅ Full REST | ✅ Graph API | ✅ Workspace API | ✅ REST API | ⚠️ Limited | ⚠️ Limited | ✅ Full API | ⚠️ Limited |
|
||||||
|
| Debugging | ✅ Console + logs | ⚠️ Complex | ⚠️ Complex | ✅ Execution logs | ❌ None | ❌ None | ❌ None | ⚠️ Limited |
|
||||||
|
| Version control | ✅ File-based | ⚠️ Limited | ⚠️ Limited | ✅ Git support | ⚠️ Page history | ❌ None | ❌ None | ⚠️ Limited |
|
||||||
|
|
||||||
|
### Security & Compliance
|
||||||
|
|
||||||
|
| Capability | General Bots | Microsoft 365 | Google Workspace | n8n | Notion | Perplexity | Claude | Make/Zapier |
|
||||||
|
|------------|-------------|---------------|------------------|-----|--------|------------|--------|-------------|
|
||||||
|
| Data residency control | ✅ Your choice | ⚠️ Limited regions | ⚠️ Limited regions | ✅ Self-host | ❌ US/EU only | ❌ No control | ❌ No control | ❌ No control |
|
||||||
|
| GDPR compliance | ✅ Self-managed | ✅ Available | ✅ Available | ✅ Self-host | ⚠️ Depends | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited |
|
||||||
|
| HIPAA capable | ✅ Self-managed | ⚠️ Extra cost | ⚠️ Extra cost | ✅ Self-host | ❌ No | ❌ No | ❌ No | ❌ No |
|
||||||
|
| Audit logs | ✅ Full control | ✅ Available | ✅ Available | ✅ Available | ⚠️ Limited | ❌ Limited | ❌ Limited | ⚠️ Limited |
|
||||||
|
| Encryption at rest | ✅ Configurable | ✅ Standard | ✅ Standard | ✅ Configurable | ✅ Standard | ✅ Standard | ✅ Standard | ✅ Standard |
|
||||||
|
| SSO/OIDC | ✅ Zitadel | ✅ Entra | ✅ Identity | ⚠️ Enterprise | ⚠️ Business | ❌ Basic | ⚠️ Enterprise | ⚠️ Enterprise |
|
||||||
|
| MFA | ✅ Built-in | ✅ Built-in | ✅ Built-in | ⚠️ Configure | ⚠️ Basic | ⚠️ Basic | ⚠️ Basic | ⚠️ Basic |
|
||||||
|
|
||||||
|
## Cost Analysis (100 Users, Annual)
|
||||||
|
|
||||||
|
| Platform | Base License | AI Features | Automation | Storage | Total Annual |
|
||||||
|
|----------|-------------|-------------|------------|---------|--------------|
|
||||||
|
| **General Bots** | $0 | $0 (bring key) | $0 | Included | **$3,000-12,000*** |
|
||||||
|
| Microsoft 365 E3 + Copilot | $43,200 | $36,000 | $12,000+ | Included | **$91,200+** |
|
||||||
|
| Google Workspace Business + Gemini | $21,600 | $24,000 | $6,000+ | Included | **$51,600+** |
|
||||||
|
| n8n Cloud + separate tools | $0-6,000 | API costs | Included | None | **$20,000+** |
|
||||||
|
| Notion Team + AI | $12,000 | $12,000 | None | Limited | **$24,000** |
|
||||||
|
| Multiple point solutions | Varies | Varies | Varies | Varies | **$50,000+** |
|
||||||
|
|
||||||
|
*General Bots cost = infrastructure + optional LLM API usage
|
||||||
|
|
||||||
|
## Feature Availability by Use Case
|
||||||
|
|
||||||
|
### Customer Service Bot
|
||||||
|
|
||||||
|
| Requirement | General Bots | Microsoft | Google | n8n | Notion | AI Assistants |
|
||||||
|
|-------------|-------------|-----------|--------|-----|--------|---------------|
|
||||||
|
| Knowledge base | ✅ | ⚠️ Extra | ⚠️ Extra | ⚠️ Build | ⚠️ Limited | ⚠️ Limited |
|
||||||
|
| WhatsApp channel | ✅ | ⚠️ Complex | ❌ | ⚠️ Build | ❌ | ❌ |
|
||||||
|
| Web widget | ✅ | ⚠️ Complex | ❌ | ❌ | ❌ | ❌ |
|
||||||
|
| Ticket creation | ✅ | ⚠️ Extra | ⚠️ Extra | ✅ | ⚠️ Manual | ❌ |
|
||||||
|
| Human handoff | ✅ | ⚠️ Extra | ❌ | ⚠️ Build | ❌ | ❌ |
|
||||||
|
| Analytics | ✅ | ⚠️ Extra | ⚠️ Extra | ⚠️ Build | ❌ | ❌ |
|
||||||
|
|
||||||
|
### Internal Automation
|
||||||
|
|
||||||
|
| Requirement | General Bots | Microsoft | Google | n8n | Notion | AI Assistants |
|
||||||
|
|-------------|-------------|-----------|--------|-----|--------|---------------|
|
||||||
|
| Scheduled reports | ✅ | ⚠️ Extra | ⚠️ Extra | ✅ | ❌ | ❌ |
|
||||||
|
| Database sync | ✅ | ⚠️ Extra | ⚠️ Extra | ✅ | ❌ | ❌ |
|
||||||
|
| API orchestration | ✅ | ⚠️ Premium | ⚠️ Limited | ✅ | ❌ | ❌ |
|
||||||
|
| Document processing | ✅ | ⚠️ Extra | ⚠️ Extra | ⚠️ Build | ❌ | ⚠️ Limited |
|
||||||
|
| Email automation | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
| Custom logic | ✅ | ⚠️ Limited | ⚠️ Limited | ✅ | ❌ | ❌ |
|
||||||
|
|
||||||
|
### Team Collaboration
|
||||||
|
|
||||||
|
| Requirement | General Bots | Microsoft | Google | n8n | Notion | AI Assistants |
|
||||||
|
|-------------|-------------|-----------|--------|-----|--------|---------------|
|
||||||
|
| Project management | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
|
||||||
|
| Team chat | ✅ | ✅ | ✅ | ❌ | ⚠️ | ❌ |
|
||||||
|
| File sharing | ✅ | ✅ | ✅ | ❌ | ⚠️ | ❌ |
|
||||||
|
| Video meetings | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||||
|
| AI assistant | ✅ | ⚠️ Extra | ⚠️ Extra | ⚠️ Build | ⚠️ Extra | ✅ |
|
||||||
|
| Self-hosted | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
||||||
|
|
||||||
|
## Migration Complexity
|
||||||
|
|
||||||
|
| From Platform | To General Bots | Effort | Data Portability | Tool Support |
|
||||||
|
|---------------|-----------------|--------|------------------|--------------|
|
||||||
|
| Microsoft 365 | Full migration | Medium | Good (APIs) | Scripts provided |
|
||||||
|
| Google Workspace | Full migration | Medium | Good (APIs) | Scripts provided |
|
||||||
|
| n8n | Automation only | Low | Easy (JSON) | Direct import |
|
||||||
|
| Notion | Content migration | Low | Good (Export) | Scripts provided |
|
||||||
|
| Zapier/Make | Workflow rebuild | Medium | Manual | Templates available |
|
||||||
|
| Custom solution | Varies | Varies | Depends | API compatible |
|
||||||
|
|
||||||
|
## Decision Matrix
|
||||||
|
|
||||||
|
### Choose General Bots when you need:
|
||||||
|
|
||||||
|
- ✅ Complete data sovereignty and self-hosting
|
||||||
|
- ✅ No per-user licensing costs at scale
|
||||||
|
- ✅ Native AI without additional subscriptions
|
||||||
|
- ✅ Full productivity suite in one platform
|
||||||
|
- ✅ Multi-channel chatbot deployment
|
||||||
|
- ✅ Powerful automation without limits
|
||||||
|
- ✅ Open source transparency and extensibility
|
||||||
|
- ✅ Custom integrations and modifications
|
||||||
|
|
||||||
|
### Consider alternatives when:
|
||||||
|
|
||||||
|
- You require specific certifications only available from large vendors
|
||||||
|
- Your organization mandates a particular cloud provider
|
||||||
|
- You have no infrastructure or IT capacity for self-hosting
|
||||||
|
- You need only a single narrow feature (e.g., just document editing)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
General Bots provides the most comprehensive feature set for organizations seeking:
|
||||||
|
|
||||||
|
| Advantage | Impact |
|
||||||
|
|-----------|--------|
|
||||||
|
| **75-95% cost reduction** | Eliminate per-user fees, AI add-ons, automation limits |
|
||||||
|
| **Complete data control** | Self-hosted, your infrastructure, your rules |
|
||||||
|
| **Unified platform** | Email, files, chat, automation, AI in one system |
|
||||||
|
| **No artificial limits** | Unlimited users, workflows, API calls, storage |
|
||||||
|
| **Full transparency** | Open source code, audit everything |
|
||||||
|
| **Future-proof** | No vendor lock-in, standard formats, portable data |
|
||||||
|
|
||||||
|
The combination of enterprise productivity features, native AI, powerful automation, and self-hosted deployment makes General Bots unique in the market—delivering capabilities that would otherwise require subscriptions to multiple expensive platforms.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Migration Overview](./overview.md) - Getting started
|
||||||
|
- [Migration Resources](./resources.md) - Tools and templates
|
||||||
|
- [Enterprise Platform Migration](./microsoft-365.md) - Detailed migration guide
|
||||||
|
- [Quick Start](../chapter-01/quick-start.md) - Deploy in minutes
|
||||||
476
docs/src/chapter-14-migration/dialogflow.md
Normal file
476
docs/src/chapter-14-migration/dialogflow.md
Normal file
|
|
@ -0,0 +1,476 @@
|
||||||
|
# Dialogflow Migration Guide
|
||||||
|
|
||||||
|
Migrating chatbots and conversational agents from Dialogflow to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Dialogflow is Google's conversational AI platform for building chatbots with intent-based NLU. General Bots provides a simpler, more powerful approach using LLM-based understanding and BASIC scripting—without cloud lock-in or complex intent management.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Dialogflow | General Bots |
|
||||||
|
|--------|------------|--------------|
|
||||||
|
| Hosting | Google Cloud only | Self-hosted |
|
||||||
|
| Pricing | Per-request fees | No per-request costs |
|
||||||
|
| NLU Approach | Intent + entity training | LLM-based (zero training) |
|
||||||
|
| Fulfillment | Cloud Functions/webhooks | Native BASIC scripts |
|
||||||
|
| Knowledge Base | Limited connector | Full RAG system |
|
||||||
|
| Channels | Via integrations | Native multi-channel |
|
||||||
|
| Customization | Limited | Full source access |
|
||||||
|
| Maintenance | Intent training required | LLM handles variations |
|
||||||
|
|
||||||
|
## Cost Comparison
|
||||||
|
|
||||||
|
### Dialogflow Pricing
|
||||||
|
|
||||||
|
| Edition | Cost |
|
||||||
|
|---------|------|
|
||||||
|
| ES (Standard) | Free tier + $0.002/request |
|
||||||
|
| CX | $0.007/request |
|
||||||
|
| Mega Agent | $0.06/request |
|
||||||
|
|
||||||
|
**10,000 requests/month:** $20-600/month
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
| Component | Cost |
|
||||||
|
|-----------|------|
|
||||||
|
| Software | $0 |
|
||||||
|
| Infrastructure | $50-200/month |
|
||||||
|
| LLM API | Usage-based (typically lower) |
|
||||||
|
|
||||||
|
## Architecture Comparison
|
||||||
|
|
||||||
|
### Dialogflow Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
User → Dialogflow Agent → Intent Matching → Fulfillment Webhook → Response
|
||||||
|
↓
|
||||||
|
Entity Extraction
|
||||||
|
↓
|
||||||
|
Context Management
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
User → BASIC Script → LLM Processing → Response
|
||||||
|
↓
|
||||||
|
Knowledge Base (RAG)
|
||||||
|
↓
|
||||||
|
Direct Actions (DB, API, etc.)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Concept Mapping
|
||||||
|
|
||||||
|
### Intents to BASIC
|
||||||
|
|
||||||
|
| Dialogflow Concept | General Bots Equivalent |
|
||||||
|
|--------------------|------------------------|
|
||||||
|
| Intent | LLM understanding + conditions |
|
||||||
|
| Training Phrases | Not needed (LLM handles) |
|
||||||
|
| Entity | `HEAR AS <type>` |
|
||||||
|
| Context | `SET CONTEXT` / `SET BOT MEMORY` |
|
||||||
|
| Fulfillment | Direct BASIC code |
|
||||||
|
| Follow-up Intent | Conversation flow |
|
||||||
|
| Event | `ON` triggers |
|
||||||
|
| Knowledge Connector | `USE KB` |
|
||||||
|
|
||||||
|
### Entity Types
|
||||||
|
|
||||||
|
| Dialogflow Entity | General Bots HEAR AS |
|
||||||
|
|-------------------|---------------------|
|
||||||
|
| @sys.date | `HEAR AS DATE` |
|
||||||
|
| @sys.time | `HEAR AS HOUR` |
|
||||||
|
| @sys.number | `HEAR AS INTEGER` / `FLOAT` |
|
||||||
|
| @sys.email | `HEAR AS EMAIL` |
|
||||||
|
| @sys.phone-number | `HEAR AS MOBILE` |
|
||||||
|
| @sys.currency-name | `HEAR AS MONEY` |
|
||||||
|
| @sys.person | `HEAR AS NAME` |
|
||||||
|
| Custom entity | Menu options or LLM extraction |
|
||||||
|
|
||||||
|
## Migration Examples
|
||||||
|
|
||||||
|
### Simple FAQ Bot
|
||||||
|
|
||||||
|
**Dialogflow:**
|
||||||
|
- Intent: "hours" with training phrases
|
||||||
|
- Response: "We're open 9 AM to 5 PM"
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "company-info"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a helpful assistant for Acme Corp. Answer questions about our business."
|
||||||
|
|
||||||
|
TALK "Hi! How can I help you today?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
The LLM understands "hours", "when are you open", "opening times", etc. without explicit training.
|
||||||
|
|
||||||
|
### Order Status Bot
|
||||||
|
|
||||||
|
**Dialogflow:**
|
||||||
|
```
|
||||||
|
Intent: order.status
|
||||||
|
Training phrases: "where is my order", "track order", "order status"
|
||||||
|
Entity: @order_number
|
||||||
|
Fulfillment: Webhook to order API
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' order-status.bas
|
||||||
|
SET CONTEXT "You help customers check their order status."
|
||||||
|
|
||||||
|
TALK "I can help you track your order. What's your order number?"
|
||||||
|
HEAR order_number
|
||||||
|
|
||||||
|
' Direct API call - no webhook needed
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "orders-api-key"
|
||||||
|
order = GET "https://api.company.com/orders/" + order_number
|
||||||
|
|
||||||
|
IF order.error THEN
|
||||||
|
TALK "I couldn't find that order. Please check the number and try again."
|
||||||
|
ELSE
|
||||||
|
TALK "Your order #" + order_number + " is " + order.status + "."
|
||||||
|
|
||||||
|
IF order.status = "shipped" THEN
|
||||||
|
TALK "Tracking number: " + order.tracking
|
||||||
|
TALK "Expected delivery: " + FORMAT(order.delivery_date, "MMMM d")
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Is there anything else I can help with?"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Appointment Booking
|
||||||
|
|
||||||
|
**Dialogflow:**
|
||||||
|
```
|
||||||
|
Intent: book.appointment
|
||||||
|
Entities: @sys.date, @sys.time, @service_type
|
||||||
|
Slot filling for required parameters
|
||||||
|
Fulfillment: Calendar API webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' appointment-booking.bas
|
||||||
|
SET CONTEXT "You help customers book appointments."
|
||||||
|
|
||||||
|
TALK "I'd be happy to help you book an appointment."
|
||||||
|
|
||||||
|
TALK "What type of service do you need?"
|
||||||
|
HEAR service AS "Consultation", "Follow-up", "New Patient", "Urgent Care"
|
||||||
|
|
||||||
|
TALK "What date works for you?"
|
||||||
|
HEAR appointment_date AS DATE
|
||||||
|
|
||||||
|
TALK "And what time?"
|
||||||
|
HEAR appointment_time AS HOUR
|
||||||
|
|
||||||
|
' Check availability
|
||||||
|
available = GET "https://api.calendar.com/check?date=" + appointment_date + "&time=" + appointment_time
|
||||||
|
|
||||||
|
IF available.open THEN
|
||||||
|
' Book directly
|
||||||
|
BOOK service + " Appointment" AT appointment_date + " " + appointment_time
|
||||||
|
|
||||||
|
TALK "Perfect! Your " + service + " appointment is confirmed for " + FORMAT(appointment_date, "MMMM d") + " at " + appointment_time
|
||||||
|
|
||||||
|
' Send confirmation
|
||||||
|
TALK "What email should I send the confirmation to?"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
SEND MAIL TO email SUBJECT "Appointment Confirmation" BODY "Your " + service + " is scheduled for " + appointment_date
|
||||||
|
ELSE
|
||||||
|
TALK "That time isn't available. How about " + available.next_slot + "?"
|
||||||
|
HEAR confirm AS BOOLEAN
|
||||||
|
' ... continue flow
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Turn Conversation
|
||||||
|
|
||||||
|
**Dialogflow:**
|
||||||
|
- Follow-up intents
|
||||||
|
- Context management
|
||||||
|
- Lifespan settings
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' pizza-order.bas
|
||||||
|
SET CONTEXT "You help customers order pizza."
|
||||||
|
|
||||||
|
TALK "Welcome to Pizza Bot! What would you like to order?"
|
||||||
|
|
||||||
|
' Size
|
||||||
|
TALK "What size pizza?"
|
||||||
|
HEAR size AS "Small", "Medium", "Large", "Extra Large"
|
||||||
|
|
||||||
|
' Type
|
||||||
|
TALK "What type would you like?"
|
||||||
|
HEAR pizza_type AS "Pepperoni", "Margherita", "Supreme", "Hawaiian", "Custom"
|
||||||
|
|
||||||
|
IF pizza_type = "Custom" THEN
|
||||||
|
TALK "What toppings would you like? (comma separated)"
|
||||||
|
HEAR toppings
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Confirm
|
||||||
|
TALK "So that's a " + size + " " + pizza_type + " pizza. Is that correct?"
|
||||||
|
HEAR confirmed AS BOOLEAN
|
||||||
|
|
||||||
|
IF confirmed THEN
|
||||||
|
' Store order
|
||||||
|
order_id = INSERT "orders", #{
|
||||||
|
size: size,
|
||||||
|
type: pizza_type,
|
||||||
|
toppings: toppings,
|
||||||
|
status: "pending",
|
||||||
|
created_at: NOW()
|
||||||
|
}
|
||||||
|
|
||||||
|
TALK "Great! Your order #" + order_id + " has been placed."
|
||||||
|
TALK "Would you like to add anything else?"
|
||||||
|
HEAR add_more AS BOOLEAN
|
||||||
|
|
||||||
|
IF add_more THEN
|
||||||
|
' Continue ordering
|
||||||
|
ELSE
|
||||||
|
TALK "What's your delivery address?"
|
||||||
|
HEAR address
|
||||||
|
' ... complete order
|
||||||
|
END IF
|
||||||
|
ELSE
|
||||||
|
TALK "No problem, let's start over."
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migrating Fulfillment Code
|
||||||
|
|
||||||
|
### Dialogflow Webhook
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Dialogflow fulfillment
|
||||||
|
exports.webhook = (req, res) => {
|
||||||
|
const intent = req.body.queryResult.intent.displayName;
|
||||||
|
const params = req.body.queryResult.parameters;
|
||||||
|
|
||||||
|
if (intent === 'order.status') {
|
||||||
|
const orderId = params.order_number;
|
||||||
|
// Call API
|
||||||
|
fetch(`https://api.example.com/orders/${orderId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(order => {
|
||||||
|
res.json({
|
||||||
|
fulfillmentText: `Your order is ${order.status}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Equivalent
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' The logic is inline - no separate webhook needed
|
||||||
|
order = GET "https://api.example.com/orders/" + order_id
|
||||||
|
TALK "Your order is " + order.status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Knowledge Base Migration
|
||||||
|
|
||||||
|
### Dialogflow Knowledge Connector
|
||||||
|
|
||||||
|
Limited to FAQ format, requires Google Cloud.
|
||||||
|
|
||||||
|
### General Bots Knowledge Base
|
||||||
|
|
||||||
|
Full document support with RAG:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-bot.gbkb/
|
||||||
|
├── products/
|
||||||
|
│ ├── catalog.pdf
|
||||||
|
│ └── specifications.xlsx
|
||||||
|
├── support/
|
||||||
|
│ ├── faq.md
|
||||||
|
│ └── troubleshooting.md
|
||||||
|
└── policies/
|
||||||
|
├── returns.pdf
|
||||||
|
└── warranty.md
|
||||||
|
```
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "products"
|
||||||
|
USE KB "support"
|
||||||
|
USE KB "policies"
|
||||||
|
|
||||||
|
answer = LLM customer_question
|
||||||
|
```
|
||||||
|
|
||||||
|
## Context Migration
|
||||||
|
|
||||||
|
### Dialogflow Contexts
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Setting context in fulfillment
|
||||||
|
outputContexts: [{
|
||||||
|
name: `projects/.../contexts/order-context`,
|
||||||
|
lifespanCount: 5,
|
||||||
|
parameters: { orderId: '12345' }
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Bots Memory
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Store context
|
||||||
|
SET BOT MEMORY "current_order_id", order_id
|
||||||
|
SET BOT MEMORY "customer_name", customer_name
|
||||||
|
|
||||||
|
' Retrieve context
|
||||||
|
order_id = GET BOT MEMORY "current_order_id"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multi-Channel Deployment
|
||||||
|
|
||||||
|
### Dialogflow Integrations
|
||||||
|
|
||||||
|
Requires separate configuration for each channel:
|
||||||
|
- Web: Dialogflow Messenger
|
||||||
|
- Telephony: CCAI
|
||||||
|
- Other: Custom integrations
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
Same code works everywhere:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Works on Web, WhatsApp, Teams, Slack, Telegram, SMS
|
||||||
|
TALK "How can I help?"
|
||||||
|
HEAR question
|
||||||
|
USE KB "support"
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Small Talk
|
||||||
|
|
||||||
|
**Dialogflow:** Enable small talk prebuilt agent
|
||||||
|
|
||||||
|
**General Bots:** LLM handles naturally
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are a friendly assistant. Engage in casual conversation when appropriate while staying helpful."
|
||||||
|
|
||||||
|
' LLM naturally handles:
|
||||||
|
' - "Hello"
|
||||||
|
' - "How are you?"
|
||||||
|
' - "Thanks"
|
||||||
|
' - "Goodbye"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sentiment Analysis
|
||||||
|
|
||||||
|
**Dialogflow:** Enable sentiment in settings
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
HEAR customer_message
|
||||||
|
|
||||||
|
sentiment = LLM "Analyze the sentiment of this message and respond with: positive, neutral, or negative. Message: " + customer_message
|
||||||
|
|
||||||
|
IF sentiment = "negative" THEN
|
||||||
|
SET CONTEXT "The customer seems frustrated. Be extra helpful and empathetic."
|
||||||
|
' Or escalate
|
||||||
|
CREATE TASK "Review negative sentiment conversation"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
answer = LLM customer_message
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rich Responses
|
||||||
|
|
||||||
|
**Dialogflow:** Card, suggestion chips, etc.
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Suggestions
|
||||||
|
ADD SUGGESTION "Check Order"
|
||||||
|
ADD SUGGESTION "Track Shipment"
|
||||||
|
ADD SUGGESTION "Contact Support"
|
||||||
|
TALK "What would you like to do?"
|
||||||
|
|
||||||
|
' Images
|
||||||
|
TALK IMAGE "/products/featured.jpg"
|
||||||
|
|
||||||
|
' Files
|
||||||
|
TALK FILE "/documents/brochure.pdf"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export Dialogflow agent (JSON)
|
||||||
|
- [ ] Document all intents and training phrases
|
||||||
|
- [ ] List entities and their values
|
||||||
|
- [ ] Map fulfillment webhooks
|
||||||
|
- [ ] Identify knowledge connectors
|
||||||
|
- [ ] Note channel integrations
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
- [ ] Create knowledge base from FAQs/docs
|
||||||
|
- [ ] Build BASIC scripts for main flows
|
||||||
|
- [ ] Implement entity validation with HEAR AS
|
||||||
|
- [ ] Convert fulfillment logic to BASIC
|
||||||
|
- [ ] Configure channels
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Test all conversation flows
|
||||||
|
- [ ] Compare response quality
|
||||||
|
- [ ] Verify API integrations
|
||||||
|
- [ ] Train team on new system
|
||||||
|
- [ ] Redirect channel integrations
|
||||||
|
- [ ] Decommission Dialogflow agent
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
**No Intent Training:** LLM understands variations without explicit training phrases.
|
||||||
|
|
||||||
|
**Simpler Architecture:** Logic lives in BASIC scripts, not spread across intents and webhooks.
|
||||||
|
|
||||||
|
**Self-Hosted:** No Google Cloud dependency or per-request fees.
|
||||||
|
|
||||||
|
**Native Integrations:** Direct API calls and database access without webhook complexity.
|
||||||
|
|
||||||
|
**Full RAG:** Rich knowledge base support beyond simple FAQ.
|
||||||
|
|
||||||
|
**Multi-Channel Native:** Deploy everywhere with one codebase.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [HEAR Keyword](../chapter-06-gbdialog/keyword-hear.md) - Input validation (replaces entities)
|
||||||
|
- [SET CONTEXT](../chapter-06-gbdialog/keyword-set-context.md) - AI behavior configuration
|
||||||
|
- [Knowledge Base](../chapter-03/README.md) - RAG setup
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full feature comparison
|
||||||
471
docs/src/chapter-14-migration/intercom.md
Normal file
471
docs/src/chapter-14-migration/intercom.md
Normal file
|
|
@ -0,0 +1,471 @@
|
||||||
|
# Intercom Migration Guide
|
||||||
|
|
||||||
|
Migrating customer messaging and support from Intercom to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Intercom is a customer messaging platform with live chat, chatbots, and help desk features. General Bots provides equivalent capabilities with self-hosting, no per-seat pricing, and native AI integration.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Intercom | General Bots |
|
||||||
|
|--------|----------|--------------|
|
||||||
|
| Pricing | $39-139/seat/month | No per-seat fees |
|
||||||
|
| Hosting | Cloud only | Self-hosted |
|
||||||
|
| AI Features | Fin AI ($0.99/resolution) | Native LLM (any provider) |
|
||||||
|
| Channels | Web, email, mobile | Web, WhatsApp, Teams, Slack, SMS, more |
|
||||||
|
| Automation | Limited workflows | Full BASIC scripting |
|
||||||
|
| Knowledge Base | Included | Built-in RAG |
|
||||||
|
| Data Ownership | Their servers | Your infrastructure |
|
||||||
|
| Customization | Limited | Full source access |
|
||||||
|
|
||||||
|
## Cost Comparison
|
||||||
|
|
||||||
|
### Intercom Pricing (per seat/month)
|
||||||
|
|
||||||
|
| Plan | Cost | Features |
|
||||||
|
|------|------|----------|
|
||||||
|
| Essential | $39 | Basic chat, inbox |
|
||||||
|
| Advanced | $99 | Automation, reporting |
|
||||||
|
| Expert | $139 | Full platform |
|
||||||
|
| Fin AI | $0.99/resolution | AI answers |
|
||||||
|
|
||||||
|
**10 support agents:** $990-1,390/month + AI costs
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
| Component | Cost |
|
||||||
|
|-----------|------|
|
||||||
|
| Software | $0 |
|
||||||
|
| Infrastructure | $50-200/month |
|
||||||
|
| LLM API (optional) | Usage-based |
|
||||||
|
|
||||||
|
**10 agents:** ~$100-300/month total
|
||||||
|
|
||||||
|
## Feature Mapping
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
|
||||||
|
| Intercom Feature | General Bots Equivalent |
|
||||||
|
|------------------|------------------------|
|
||||||
|
| Messenger | Web chat widget |
|
||||||
|
| Inbox | Conversation management |
|
||||||
|
| Help Center | Knowledge base (.gbkb) |
|
||||||
|
| Bots | BASIC dialog scripts |
|
||||||
|
| Product Tours | Guided conversations |
|
||||||
|
| Outbound Messages | Automated messaging |
|
||||||
|
|
||||||
|
### Bot Capabilities
|
||||||
|
|
||||||
|
| Intercom Bots | General Bots Equivalent |
|
||||||
|
|---------------|------------------------|
|
||||||
|
| Custom Bots | BASIC scripts |
|
||||||
|
| Resolution Bot | LLM + USE KB |
|
||||||
|
| Task Bots | Automated workflows |
|
||||||
|
| Qualification Bots | HEAR AS + lead scoring |
|
||||||
|
| Article Suggestions | RAG responses |
|
||||||
|
|
||||||
|
## Migration Process
|
||||||
|
|
||||||
|
### Step 1: Export Intercom Data
|
||||||
|
|
||||||
|
1. Go to Settings → Data Management
|
||||||
|
2. Export conversations, contacts, and articles
|
||||||
|
3. Download Help Center articles
|
||||||
|
4. Export custom attributes and tags
|
||||||
|
|
||||||
|
### Step 2: Migrate Knowledge Base
|
||||||
|
|
||||||
|
Convert Help Center articles to General Bots knowledge base:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-bot.gbkb/
|
||||||
|
├── getting-started/
|
||||||
|
│ ├── quick-start.md
|
||||||
|
│ └── setup-guide.md
|
||||||
|
├── features/
|
||||||
|
│ ├── feature-overview.md
|
||||||
|
│ └── tutorials.md
|
||||||
|
├── troubleshooting/
|
||||||
|
│ ├── common-issues.md
|
||||||
|
│ └── faq.md
|
||||||
|
└── billing/
|
||||||
|
├── plans.md
|
||||||
|
└── payments.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Create Support Bot
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' support-bot.bas
|
||||||
|
' Main customer support entry point
|
||||||
|
|
||||||
|
USE KB "getting-started"
|
||||||
|
USE KB "features"
|
||||||
|
USE KB "troubleshooting"
|
||||||
|
USE KB "billing"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a friendly customer support assistant.
|
||||||
|
- Be helpful and concise
|
||||||
|
- If you cannot answer, offer to connect with a human
|
||||||
|
- Always maintain a professional, positive tone"
|
||||||
|
|
||||||
|
TALK "Hi! I'm here to help. What can I assist you with today?"
|
||||||
|
|
||||||
|
LOOP
|
||||||
|
HEAR question
|
||||||
|
|
||||||
|
' Check for handoff request
|
||||||
|
IF CONTAINS(LOWER(question), "human") OR CONTAINS(LOWER(question), "agent") OR CONTAINS(LOWER(question), "person") THEN
|
||||||
|
CALL REQUEST_HUMAN_HANDOFF()
|
||||||
|
EXIT LOOP
|
||||||
|
END IF
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
|
||||||
|
TALK "Is there anything else I can help you with?"
|
||||||
|
LOOP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Implement Human Handoff
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SUB REQUEST_HUMAN_HANDOFF()
|
||||||
|
TALK "I'll connect you with a support agent. Let me gather some information first."
|
||||||
|
|
||||||
|
TALK "What's your email address?"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
TALK "Please briefly describe your issue:"
|
||||||
|
HEAR issue_summary
|
||||||
|
|
||||||
|
' Create support ticket
|
||||||
|
ticket_id = INSERT "support_tickets", #{
|
||||||
|
customer_email: email,
|
||||||
|
summary: issue_summary,
|
||||||
|
conversation_id: session.id,
|
||||||
|
status: "pending",
|
||||||
|
created_at: NOW()
|
||||||
|
}
|
||||||
|
|
||||||
|
' Notify support team
|
||||||
|
SEND MAIL TO "support@company.com" SUBJECT "New Support Request #" + ticket_id BODY "Customer: " + email + "\n\nIssue: " + issue_summary
|
||||||
|
|
||||||
|
POST GET CONFIG "slack-support", #{
|
||||||
|
text: "New support request from " + email + ": " + issue_summary
|
||||||
|
}
|
||||||
|
|
||||||
|
TALK "Thanks! A support agent will reach out to you at " + email + " shortly. Your ticket number is #" + ticket_id
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recreating Intercom Features
|
||||||
|
|
||||||
|
### Messenger Widget
|
||||||
|
|
||||||
|
General Bots provides embeddable chat widgets:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Embed in your website -->
|
||||||
|
<script src="https://your-bot-server/widget.js"></script>
|
||||||
|
<script>
|
||||||
|
GeneralBots.init({
|
||||||
|
botId: 'your-bot-id',
|
||||||
|
position: 'bottom-right',
|
||||||
|
greeting: 'Hi! How can we help?'
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Qualification Bot
|
||||||
|
|
||||||
|
**Intercom:** Qualification workflow
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' lead-qualification.bas
|
||||||
|
PARAM source AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Qualify incoming leads"
|
||||||
|
|
||||||
|
TALK "Welcome! I'd love to learn more about you."
|
||||||
|
|
||||||
|
TALK "What's your name?"
|
||||||
|
HEAR name AS NAME
|
||||||
|
|
||||||
|
TALK "And your work email?"
|
||||||
|
HEAR email AS EMAIL
|
||||||
|
|
||||||
|
TALK "What company are you with?"
|
||||||
|
HEAR company
|
||||||
|
|
||||||
|
TALK "What's your role?"
|
||||||
|
HEAR role AS "Executive", "Manager", "Individual Contributor", "Student", "Other"
|
||||||
|
|
||||||
|
TALK "What brings you here today?"
|
||||||
|
HEAR interest AS "Product Demo", "Pricing", "Support", "Partnership", "Just Exploring"
|
||||||
|
|
||||||
|
' Score the lead
|
||||||
|
WITH lead_data
|
||||||
|
.name = name
|
||||||
|
.email = email
|
||||||
|
.company = company
|
||||||
|
.role = role
|
||||||
|
.interest = interest
|
||||||
|
.source = source
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
|
||||||
|
' Route based on qualification
|
||||||
|
IF score.status = "hot" OR interest = "Product Demo" THEN
|
||||||
|
TALK "Great! Let me schedule a demo for you."
|
||||||
|
TALK "When works best?"
|
||||||
|
HEAR preferred_time
|
||||||
|
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Hot Lead - Demo Request" BODY lead_data
|
||||||
|
CREATE TASK "Demo call with " + name DUE DATEADD(NOW(), 1, "day")
|
||||||
|
|
||||||
|
TALK "Our team will reach out within 24 hours to confirm your demo!"
|
||||||
|
|
||||||
|
ELSEIF interest = "Pricing" THEN
|
||||||
|
USE KB "pricing"
|
||||||
|
pricing_info = LLM "Provide a brief pricing overview"
|
||||||
|
TALK pricing_info
|
||||||
|
TALK "Would you like to speak with someone about your specific needs?"
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
USE KB "getting-started"
|
||||||
|
TALK "Here's what you can do to get started..."
|
||||||
|
answer = LLM "Give a brief getting started guide"
|
||||||
|
TALK answer
|
||||||
|
END IF
|
||||||
|
|
||||||
|
INSERT "leads", lead_data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Proactive Messages
|
||||||
|
|
||||||
|
**Intercom:** Outbound messages
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' proactive-engagement.bas
|
||||||
|
SET SCHEDULE "every hour"
|
||||||
|
|
||||||
|
' Find users who might need help
|
||||||
|
inactive_sessions = FIND "sessions", "last_activity < DATEADD(NOW(), -5, 'minute') AND page_views > 3 AND not contacted"
|
||||||
|
|
||||||
|
FOR EACH session IN inactive_sessions
|
||||||
|
' Send proactive message
|
||||||
|
SEND TO session.id MESSAGE "Need any help? I'm here if you have questions!"
|
||||||
|
UPDATE "sessions", "id = '" + session.id + "'", #{contacted: true}
|
||||||
|
NEXT session
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resolution Bot (AI Answers)
|
||||||
|
|
||||||
|
**Intercom Fin:** $0.99 per resolution
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' ai-resolution.bas
|
||||||
|
USE KB "help-center"
|
||||||
|
USE KB "product-docs"
|
||||||
|
USE KB "faq"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a helpful support assistant. Answer questions accurately based on the knowledge base. If you're not confident in the answer, say so and offer to connect with a human."
|
||||||
|
|
||||||
|
TALK "How can I help you today?"
|
||||||
|
HEAR question
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
|
||||||
|
' Check confidence (you can implement confidence scoring)
|
||||||
|
IF CONTAINS(answer, "I'm not sure") OR CONTAINS(answer, "I don't have") THEN
|
||||||
|
TALK answer
|
||||||
|
TALK "Would you like me to connect you with a support agent?"
|
||||||
|
HEAR wants_human AS BOOLEAN
|
||||||
|
IF wants_human THEN
|
||||||
|
CALL REQUEST_HUMAN_HANDOFF()
|
||||||
|
END IF
|
||||||
|
ELSE
|
||||||
|
TALK answer
|
||||||
|
|
||||||
|
' Track resolution
|
||||||
|
INSERT "resolutions", #{
|
||||||
|
question: question,
|
||||||
|
answer: answer,
|
||||||
|
resolved: true,
|
||||||
|
timestamp: NOW()
|
||||||
|
}
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customer Segments
|
||||||
|
|
||||||
|
**Intercom:** User segments
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' segment-customers.bas
|
||||||
|
SET SCHEDULE "every day at 6am"
|
||||||
|
|
||||||
|
customers = FIND "customers", "1=1"
|
||||||
|
|
||||||
|
FOR EACH customer IN customers
|
||||||
|
segment = "standard"
|
||||||
|
|
||||||
|
IF customer.total_spent > 10000 THEN
|
||||||
|
segment = "enterprise"
|
||||||
|
ELSEIF customer.total_spent > 1000 THEN
|
||||||
|
segment = "premium"
|
||||||
|
ELSEIF customer.signup_date > DATEADD(NOW(), -30, "day") THEN
|
||||||
|
segment = "new"
|
||||||
|
ELSEIF customer.last_activity < DATEADD(NOW(), -90, "day") THEN
|
||||||
|
segment = "at-risk"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
UPDATE "customers", "id = '" + customer.id + "'", #{segment: segment}
|
||||||
|
NEXT customer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Targeted Campaigns
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' win-back-campaign.bas
|
||||||
|
SET SCHEDULE "every monday at 10am"
|
||||||
|
|
||||||
|
' Find at-risk customers
|
||||||
|
at_risk = FIND "customers", "segment = 'at-risk' AND not win_back_sent"
|
||||||
|
|
||||||
|
FOR EACH customer IN at_risk
|
||||||
|
USE KB "product-updates"
|
||||||
|
personalized_message = LLM "Write a brief, friendly win-back message for " + customer.name + " who hasn't used our product in 3 months. Mention recent improvements."
|
||||||
|
|
||||||
|
SEND MAIL TO customer.email SUBJECT "We miss you, " + customer.name + "!" BODY personalized_message
|
||||||
|
|
||||||
|
UPDATE "customers", "id = '" + customer.id + "'", #{win_back_sent: true, win_back_date: NOW()}
|
||||||
|
NEXT customer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multi-Channel Support
|
||||||
|
|
||||||
|
### Intercom Channels
|
||||||
|
- Web Messenger
|
||||||
|
- Mobile SDK
|
||||||
|
- Email
|
||||||
|
- SMS (add-on)
|
||||||
|
|
||||||
|
### General Bots Channels
|
||||||
|
All channels use the same BASIC scripts:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Same bot works everywhere
|
||||||
|
USE KB "support"
|
||||||
|
|
||||||
|
TALK "How can I help?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
|
||||||
|
' Channel-specific handling if needed
|
||||||
|
IF channel = "whatsapp" THEN
|
||||||
|
' WhatsApp-specific features
|
||||||
|
ELSEIF channel = "email" THEN
|
||||||
|
' Email formatting
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
Supported channels:
|
||||||
|
- Web chat
|
||||||
|
- WhatsApp Business
|
||||||
|
- Teams
|
||||||
|
- Slack
|
||||||
|
- Telegram
|
||||||
|
- SMS
|
||||||
|
- Email
|
||||||
|
- Voice (LiveKit)
|
||||||
|
|
||||||
|
## Reporting and Analytics
|
||||||
|
|
||||||
|
### Conversation Metrics
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' daily-metrics.bas
|
||||||
|
SET SCHEDULE "every day at 11pm"
|
||||||
|
|
||||||
|
today = FORMAT(NOW(), "yyyy-MM-dd")
|
||||||
|
|
||||||
|
conversations = AGGREGATE "conversations", "COUNT", "id", "DATE(created_at) = '" + today + "'"
|
||||||
|
resolutions = AGGREGATE "resolutions", "COUNT", "id", "DATE(timestamp) = '" + today + "' AND resolved = true"
|
||||||
|
avg_response_time = AGGREGATE "conversations", "AVG", "first_response_seconds", "DATE(created_at) = '" + today + "'"
|
||||||
|
|
||||||
|
WITH daily_report
|
||||||
|
.date = today
|
||||||
|
.total_conversations = conversations
|
||||||
|
.ai_resolutions = resolutions
|
||||||
|
.resolution_rate = ROUND(resolutions / conversations * 100, 1)
|
||||||
|
.avg_response_time = ROUND(avg_response_time / 60, 1)
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
INSERT "daily_metrics", daily_report
|
||||||
|
|
||||||
|
SEND MAIL TO "support-lead@company.com" SUBJECT "Daily Support Metrics - " + today BODY daily_report
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export all Intercom data (conversations, contacts, articles)
|
||||||
|
- [ ] Document custom bot workflows
|
||||||
|
- [ ] List all integrations
|
||||||
|
- [ ] Note custom attributes and tags
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Convert Help Center to .gbkb structure
|
||||||
|
- [ ] Create support bot scripts
|
||||||
|
- [ ] Implement human handoff flow
|
||||||
|
- [ ] Set up notification channels
|
||||||
|
- [ ] Configure chat widget
|
||||||
|
- [ ] Import customer data
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Test all conversation flows
|
||||||
|
- [ ] Verify knowledge base accuracy
|
||||||
|
- [ ] Train support team
|
||||||
|
- [ ] Run parallel support briefly
|
||||||
|
- [ ] Redirect widget embed code
|
||||||
|
- [ ] Cancel Intercom subscription
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
**No Per-Seat Pricing:** Add unlimited agents without cost increase.
|
||||||
|
|
||||||
|
**Native AI:** Use any LLM without per-resolution fees.
|
||||||
|
|
||||||
|
**Full Customization:** Modify every aspect of the support experience.
|
||||||
|
|
||||||
|
**Data Ownership:** All conversations stay on your infrastructure.
|
||||||
|
|
||||||
|
**Automation Power:** Go beyond simple workflows with full BASIC scripting.
|
||||||
|
|
||||||
|
**Multi-Channel Native:** Same bot works across all channels without add-ons.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Projects](../chapter-11-features/projects.md) - Organizing support queues
|
||||||
|
- [HEAR Validation](../chapter-06-gbdialog/keyword-hear.md) - Input validation
|
||||||
|
- [Lead Scoring](../chapter-06-gbdialog/keywords-lead-scoring.md) - Qualification
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full feature comparison
|
||||||
361
docs/src/chapter-14-migration/n8n.md
Normal file
361
docs/src/chapter-14-migration/n8n.md
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
# n8n Migration Guide
|
||||||
|
|
||||||
|
Migrating workflows and automations from n8n to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
n8n is a workflow automation platform with a visual node-based editor. General Bots provides equivalent automation capabilities through BASIC scripting, offering more flexibility and integrated features without execution limits.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | n8n | General Bots |
|
||||||
|
|--------|-----|--------------|
|
||||||
|
| Automation | Visual workflows | BASIC scripts (more powerful) |
|
||||||
|
| Pricing | Per-execution limits | Unlimited executions |
|
||||||
|
| AI Integration | Via API nodes | Native LLM keywords |
|
||||||
|
| Chat/Bot | Not included | Full multi-channel |
|
||||||
|
| Productivity Suite | Not included | Email, calendar, files, tasks |
|
||||||
|
| Knowledge Base | Not included | Built-in RAG |
|
||||||
|
| Self-hosting | Available | Available |
|
||||||
|
|
||||||
|
## Workflow Mapping
|
||||||
|
|
||||||
|
### Triggers
|
||||||
|
|
||||||
|
| n8n Trigger | General Bots Equivalent |
|
||||||
|
|-------------|------------------------|
|
||||||
|
| Schedule Trigger | `SET SCHEDULE` |
|
||||||
|
| Webhook | `WEBHOOK` |
|
||||||
|
| Email Trigger (IMAP) | `ON "email:received"` |
|
||||||
|
| Database Trigger | `ON "table:tablename:insert"` |
|
||||||
|
| Manual Trigger | Direct script execution |
|
||||||
|
| Cron | `SET SCHEDULE "cron expression"` |
|
||||||
|
|
||||||
|
### Common Nodes
|
||||||
|
|
||||||
|
| n8n Node | General Bots Equivalent |
|
||||||
|
|----------|------------------------|
|
||||||
|
| HTTP Request | `GET`, `POST`, `PUT`, `DELETE` |
|
||||||
|
| Set | Variable assignment |
|
||||||
|
| IF | `IF/THEN/ELSE/END IF` |
|
||||||
|
| Switch | `SWITCH/CASE/END SWITCH` |
|
||||||
|
| Code (JavaScript) | BASIC script |
|
||||||
|
| Function | BASIC subroutines |
|
||||||
|
| Merge | Array operations |
|
||||||
|
| Split In Batches | `FOR EACH` |
|
||||||
|
| Wait | `WAIT` |
|
||||||
|
| Send Email | `SEND MAIL` |
|
||||||
|
| Slack | `POST` to Slack webhook |
|
||||||
|
| Discord | `POST` to Discord webhook |
|
||||||
|
| Google Sheets | `GET`/`POST` to Sheets API |
|
||||||
|
| Airtable | `GET`/`POST` to Airtable API |
|
||||||
|
| MySQL/PostgreSQL | `FIND`, `INSERT`, `UPDATE`, `DELETE` |
|
||||||
|
| MongoDB | `GET`/`POST` to MongoDB API |
|
||||||
|
|
||||||
|
## Migration Examples
|
||||||
|
|
||||||
|
### Scheduled Data Sync
|
||||||
|
|
||||||
|
**n8n workflow:**
|
||||||
|
```
|
||||||
|
Schedule Trigger → HTTP Request → IF → Google Sheets
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every hour"
|
||||||
|
|
||||||
|
data = GET "https://api.example.com/data"
|
||||||
|
|
||||||
|
IF data.status = "active" THEN
|
||||||
|
FOR EACH item IN data.items
|
||||||
|
INSERT "synced_data", #{
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
value: item.value,
|
||||||
|
synced_at: NOW()
|
||||||
|
}
|
||||||
|
NEXT item
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Synced " + LEN(data.items) + " items"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook Processing
|
||||||
|
|
||||||
|
**n8n workflow:**
|
||||||
|
```
|
||||||
|
Webhook → Set → IF → Send Email + Slack
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
WEBHOOK "order-received"
|
||||||
|
|
||||||
|
order = body
|
||||||
|
customer_name = order.customer.name
|
||||||
|
order_total = order.total
|
||||||
|
|
||||||
|
IF order_total > 1000 THEN
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Large Order" BODY "Order from " + customer_name + ": $" + order_total
|
||||||
|
|
||||||
|
POST "https://hooks.slack.com/services/xxx", #{
|
||||||
|
text: "Large order received: $" + order_total
|
||||||
|
}
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Step API Orchestration
|
||||||
|
|
||||||
|
**n8n workflow:**
|
||||||
|
```
|
||||||
|
Webhook → HTTP Request (API 1) → Code → HTTP Request (API 2) → IF → Multiple outputs
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
WEBHOOK "process-lead"
|
||||||
|
|
||||||
|
lead = body
|
||||||
|
|
||||||
|
' Step 1: Enrich lead data
|
||||||
|
enriched = POST "https://api.clearbit.com/enrich", #{email: lead.email}
|
||||||
|
|
||||||
|
' Step 2: Score the lead
|
||||||
|
WITH lead_data
|
||||||
|
.email = lead.email
|
||||||
|
.company = enriched.company.name
|
||||||
|
.industry = enriched.company.industry
|
||||||
|
.size = enriched.company.employees
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
score = SCORE LEAD lead_data
|
||||||
|
|
||||||
|
' Step 3: Route based on score
|
||||||
|
IF score.status = "hot" THEN
|
||||||
|
POST "https://api.salesforce.com/leads", lead_data
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Hot Lead" BODY lead_data
|
||||||
|
ELSEIF score.status = "warm" THEN
|
||||||
|
POST "https://api.hubspot.com/contacts", lead_data
|
||||||
|
ELSE
|
||||||
|
INSERT "cold_leads", lead_data
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
**n8n approach:** Error Trigger node
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every 5 minutes"
|
||||||
|
|
||||||
|
TRY
|
||||||
|
result = GET "https://api.example.com/health"
|
||||||
|
IF result.status <> "healthy" THEN
|
||||||
|
THROW "Service unhealthy: " + result.message
|
||||||
|
END IF
|
||||||
|
CATCH
|
||||||
|
SEND MAIL TO "ops@company.com" SUBJECT "Alert: Service Down" BODY ERROR_MESSAGE
|
||||||
|
POST "https://hooks.slack.com/services/xxx", #{text: "Service alert: " + ERROR_MESSAGE}
|
||||||
|
END TRY
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exporting n8n Workflows
|
||||||
|
|
||||||
|
### Export Process
|
||||||
|
|
||||||
|
1. In n8n, select the workflow
|
||||||
|
2. Click the three-dot menu → Download
|
||||||
|
3. Save the JSON file
|
||||||
|
4. Analyze nodes and connections
|
||||||
|
5. Translate to BASIC script
|
||||||
|
|
||||||
|
### JSON Structure Analysis
|
||||||
|
|
||||||
|
n8n exports workflows as JSON:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{"type": "n8n-nodes-base.httpRequest", "parameters": {...}},
|
||||||
|
{"type": "n8n-nodes-base.if", "parameters": {...}}
|
||||||
|
],
|
||||||
|
"connections": {...}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Map each node type to the equivalent BASIC keyword.
|
||||||
|
|
||||||
|
## Feature Comparison
|
||||||
|
|
||||||
|
### What You Gain
|
||||||
|
|
||||||
|
**Native AI integration:**
|
||||||
|
```basic
|
||||||
|
USE KB "company-docs"
|
||||||
|
response = LLM "Analyze this data and provide insights: " + data
|
||||||
|
```
|
||||||
|
|
||||||
|
**Multi-channel chat:**
|
||||||
|
```basic
|
||||||
|
TALK "How can I help you?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
**Built-in productivity:**
|
||||||
|
```basic
|
||||||
|
CREATE TASK "Follow up with " + customer_name DUE DATEADD(NOW(), 3, "day")
|
||||||
|
BOOK "Meeting with " + customer_name AT meeting_time
|
||||||
|
SEND MAIL TO customer_email SUBJECT "Confirmation" BODY message
|
||||||
|
```
|
||||||
|
|
||||||
|
**Knowledge base:**
|
||||||
|
```basic
|
||||||
|
USE KB "product-docs"
|
||||||
|
USE KB "pricing-info"
|
||||||
|
answer = LLM customer_question
|
||||||
|
```
|
||||||
|
|
||||||
|
### What Changes
|
||||||
|
|
||||||
|
| n8n Approach | General Bots Approach |
|
||||||
|
|--------------|----------------------|
|
||||||
|
| Visual drag-and-drop | Text-based BASIC scripts |
|
||||||
|
| Node connections | Sequential code flow |
|
||||||
|
| Credentials UI | config.csv settings |
|
||||||
|
| Execution history UI | Log files + monitoring |
|
||||||
|
| Community nodes | HTTP keywords + custom code |
|
||||||
|
|
||||||
|
## Credentials Migration
|
||||||
|
|
||||||
|
### n8n Credentials
|
||||||
|
|
||||||
|
n8n stores credentials separately. Export and configure in General Bots:
|
||||||
|
|
||||||
|
**config.csv:**
|
||||||
|
```csv
|
||||||
|
key,value
|
||||||
|
slack-webhook-url,https://hooks.slack.com/services/xxx
|
||||||
|
api-key-clearbit,your-api-key
|
||||||
|
salesforce-token,your-token
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage in BASIC:**
|
||||||
|
```basic
|
||||||
|
slack_url = GET CONFIG "slack-webhook-url"
|
||||||
|
POST slack_url, #{text: "Message"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export all n8n workflows as JSON
|
||||||
|
- [ ] Document active schedules and triggers
|
||||||
|
- [ ] List all credentials and API keys
|
||||||
|
- [ ] Identify critical workflows for priority migration
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Translate workflows to BASIC scripts
|
||||||
|
- [ ] Configure credentials in config.csv
|
||||||
|
- [ ] Set up webhooks with same endpoints
|
||||||
|
- [ ] Configure schedules
|
||||||
|
- [ ] Test each workflow individually
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Run parallel execution for verification
|
||||||
|
- [ ] Compare outputs between systems
|
||||||
|
- [ ] Monitor for errors
|
||||||
|
- [ ] Decommission n8n workflows
|
||||||
|
- [ ] Document new BASIC scripts
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Batch Processing
|
||||||
|
|
||||||
|
**n8n:** Split In Batches node
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
items = GET "https://api.example.com/items"
|
||||||
|
batch_size = 10
|
||||||
|
total = LEN(items)
|
||||||
|
|
||||||
|
FOR i = 0 TO total - 1 STEP batch_size
|
||||||
|
batch = SLICE(items, i, i + batch_size)
|
||||||
|
FOR EACH item IN batch
|
||||||
|
PROCESS_ITEM(item)
|
||||||
|
NEXT item
|
||||||
|
WAIT 1000 ' Rate limiting
|
||||||
|
NEXT i
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Branching
|
||||||
|
|
||||||
|
**n8n:** IF node with multiple branches
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SWITCH status
|
||||||
|
CASE "new"
|
||||||
|
HANDLE_NEW()
|
||||||
|
CASE "pending"
|
||||||
|
HANDLE_PENDING()
|
||||||
|
CASE "complete"
|
||||||
|
HANDLE_COMPLETE()
|
||||||
|
DEFAULT
|
||||||
|
HANDLE_UNKNOWN()
|
||||||
|
END SWITCH
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Transformation
|
||||||
|
|
||||||
|
**n8n:** Set node or Code node
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Transform data
|
||||||
|
WITH transformed
|
||||||
|
.full_name = data.first_name + " " + data.last_name
|
||||||
|
.email = LOWER(data.email)
|
||||||
|
.created = NOW()
|
||||||
|
.source = "api"
|
||||||
|
END WITH
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Start with simple workflows.** Migrate straightforward automations first to build familiarity with BASIC syntax.
|
||||||
|
|
||||||
|
**Use descriptive variable names.** BASIC scripts are more readable than node graphs when well-written.
|
||||||
|
|
||||||
|
**Add comments.** Document your scripts for future maintenance:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Daily sales report - sends summary to management
|
||||||
|
' Runs at 6 PM on weekdays
|
||||||
|
SET SCHEDULE "0 18 * * 1-5"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Leverage native features.** Don't just replicate n8n workflows—take advantage of General Bots' integrated AI, chat, and productivity features.
|
||||||
|
|
||||||
|
**Test incrementally.** Verify each migrated workflow before moving to the next.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [SET SCHEDULE](../chapter-06-gbdialog/keyword-set-schedule.md) - Scheduling reference
|
||||||
|
- [WEBHOOK](../chapter-06-gbdialog/keyword-webhook.md) - Webhook creation
|
||||||
|
- [HTTP Keywords](../chapter-06-gbdialog/keywords-http.md) - API integration
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full feature comparison
|
||||||
443
docs/src/chapter-14-migration/notion.md
Normal file
443
docs/src/chapter-14-migration/notion.md
Normal file
|
|
@ -0,0 +1,443 @@
|
||||||
|
# Notion Migration Guide
|
||||||
|
|
||||||
|
Migrating content and workflows from Notion to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Notion is a collaborative workspace combining notes, databases, and project management. General Bots provides equivalent functionality through its knowledge base, task management, and AI-powered conversation features—with the added benefit of self-hosting and native automation.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Notion | General Bots |
|
||||||
|
|--------|--------|--------------|
|
||||||
|
| Hosting | Cloud only | Self-hosted |
|
||||||
|
| Pricing | $10-15/user/month | No per-user fees |
|
||||||
|
| AI Features | $10/user/month add-on | Native (any LLM) |
|
||||||
|
| Automation | Limited | Full BASIC scripting |
|
||||||
|
| Chat/Bot | Not included | Multi-channel |
|
||||||
|
| API Creation | Not available | Instant webhooks |
|
||||||
|
| Data Sovereignty | Their servers | Your infrastructure |
|
||||||
|
|
||||||
|
## Content Mapping
|
||||||
|
|
||||||
|
### Notion to General Bots
|
||||||
|
|
||||||
|
| Notion Feature | General Bots Equivalent |
|
||||||
|
|----------------|------------------------|
|
||||||
|
| Pages | Knowledge base documents (.gbkb) |
|
||||||
|
| Databases | Tables (CSV/database) |
|
||||||
|
| Kanban boards | Task boards |
|
||||||
|
| Calendar | Calendar API |
|
||||||
|
| Comments | Conversation history |
|
||||||
|
| Templates | Bot templates |
|
||||||
|
| Integrations | BASIC scripts + webhooks |
|
||||||
|
| Notion AI | LLM keyword |
|
||||||
|
|
||||||
|
## Migration Process
|
||||||
|
|
||||||
|
### Step 1: Export Notion Content
|
||||||
|
|
||||||
|
1. Go to Settings & Members → Settings
|
||||||
|
2. Scroll to Export content
|
||||||
|
3. Choose Export format: Markdown & CSV
|
||||||
|
4. Download the ZIP file
|
||||||
|
|
||||||
|
The export includes:
|
||||||
|
- Pages as Markdown files
|
||||||
|
- Databases as CSV files
|
||||||
|
- Attachments in folders
|
||||||
|
|
||||||
|
### Step 2: Prepare Knowledge Base
|
||||||
|
|
||||||
|
Organize exported content for General Bots:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-bot.gbkb/
|
||||||
|
├── company-info/
|
||||||
|
│ ├── about.md
|
||||||
|
│ ├── policies.md
|
||||||
|
│ └── procedures.md
|
||||||
|
├── products/
|
||||||
|
│ ├── catalog.md
|
||||||
|
│ └── pricing.md
|
||||||
|
└── support/
|
||||||
|
├── faq.md
|
||||||
|
└── troubleshooting.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Import Documents
|
||||||
|
|
||||||
|
Place Markdown files in your `.gbkb` folder. General Bots automatically indexes them for RAG:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "company-info"
|
||||||
|
USE KB "products"
|
||||||
|
USE KB "support"
|
||||||
|
|
||||||
|
TALK "How can I help you?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Convert Databases
|
||||||
|
|
||||||
|
Transform Notion CSV exports to General Bots tables:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Import Notion database export
|
||||||
|
data = READ "notion-export/Projects.csv"
|
||||||
|
|
||||||
|
FOR EACH row IN data
|
||||||
|
INSERT "projects", #{
|
||||||
|
name: row["Name"],
|
||||||
|
status: row["Status"],
|
||||||
|
due_date: row["Due Date"],
|
||||||
|
assignee: row["Assignee"],
|
||||||
|
imported_at: NOW()
|
||||||
|
}
|
||||||
|
NEXT row
|
||||||
|
|
||||||
|
TALK "Imported " + LEN(data) + " projects"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Recreate Task Boards
|
||||||
|
|
||||||
|
Convert Notion Kanban boards to General Bots task boards:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Create project for Notion board
|
||||||
|
project_id = CREATE PROJECT "Product Roadmap" WITH DESCRIPTION "Migrated from Notion"
|
||||||
|
|
||||||
|
' Import tasks
|
||||||
|
tasks = READ "notion-export/Roadmap.csv"
|
||||||
|
|
||||||
|
FOR EACH task IN tasks
|
||||||
|
status = SWITCH task["Status"]
|
||||||
|
CASE "Not Started" : "todo"
|
||||||
|
CASE "In Progress" : "in_progress"
|
||||||
|
CASE "Done" : "done"
|
||||||
|
DEFAULT : "todo"
|
||||||
|
END SWITCH
|
||||||
|
|
||||||
|
CREATE TASK task["Name"] IN PROJECT project_id WITH STATUS status
|
||||||
|
NEXT task
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notion AI to General Bots
|
||||||
|
|
||||||
|
### Document Summarization
|
||||||
|
|
||||||
|
**Notion AI:**
|
||||||
|
- Highlight text → "Summarize"
|
||||||
|
- Limited to Notion content
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
USE KB "documents"
|
||||||
|
summary = LLM "Summarize the key points from our Q3 report"
|
||||||
|
TALK summary
|
||||||
|
```
|
||||||
|
|
||||||
|
### Content Generation
|
||||||
|
|
||||||
|
**Notion AI:**
|
||||||
|
- Type `/ai` → Generate content
|
||||||
|
- Basic prompting
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are a technical writer. Write clear, concise documentation."
|
||||||
|
|
||||||
|
TALK "What would you like me to write?"
|
||||||
|
HEAR topic
|
||||||
|
|
||||||
|
content = LLM "Write comprehensive documentation about: " + topic
|
||||||
|
WRITE "/docs/" + SLUGIFY(topic) + ".md", content
|
||||||
|
TALK "Documentation created!"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q&A on Documents
|
||||||
|
|
||||||
|
**Notion AI:**
|
||||||
|
- Ask questions about page content
|
||||||
|
- Single page context
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Load entire knowledge base
|
||||||
|
USE KB "all-docs"
|
||||||
|
USE KB "wiki"
|
||||||
|
USE KB "procedures"
|
||||||
|
|
||||||
|
' Answer questions across all content
|
||||||
|
TALK "Ask me anything about our documentation"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Automation Migration
|
||||||
|
|
||||||
|
### Notion Automations (Limited)
|
||||||
|
|
||||||
|
Notion has basic automations for:
|
||||||
|
- Status changes
|
||||||
|
- Due date reminders
|
||||||
|
- Slack notifications
|
||||||
|
|
||||||
|
### General Bots Equivalent
|
||||||
|
|
||||||
|
**Status change automation:**
|
||||||
|
```basic
|
||||||
|
ON "table:projects:update"
|
||||||
|
IF params.old_status <> params.new_status THEN
|
||||||
|
IF params.new_status = "complete" THEN
|
||||||
|
SEND MAIL TO params.owner_email SUBJECT "Project Completed" BODY "Your project " + params.name + " is now complete!"
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
**Due date reminders:**
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every day at 9am"
|
||||||
|
|
||||||
|
upcoming = FIND "tasks", "due_date = DATEADD(NOW(), 1, 'day') AND status <> 'done'"
|
||||||
|
|
||||||
|
FOR EACH task IN upcoming
|
||||||
|
SEND MAIL TO task.assignee_email SUBJECT "Task Due Tomorrow" BODY "Reminder: " + task.name + " is due tomorrow"
|
||||||
|
NEXT task
|
||||||
|
```
|
||||||
|
|
||||||
|
**Slack notifications:**
|
||||||
|
```basic
|
||||||
|
ON "table:tasks:insert"
|
||||||
|
POST "https://hooks.slack.com/services/xxx", #{
|
||||||
|
text: "New task created: " + params.name,
|
||||||
|
channel: "#tasks"
|
||||||
|
}
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Migration
|
||||||
|
|
||||||
|
### Notion Database Properties
|
||||||
|
|
||||||
|
| Notion Property | General Bots Equivalent |
|
||||||
|
|-----------------|------------------------|
|
||||||
|
| Title | TEXT column |
|
||||||
|
| Text | TEXT column |
|
||||||
|
| Number | NUMERIC column |
|
||||||
|
| Select | TEXT with validation |
|
||||||
|
| Multi-select | JSONB array |
|
||||||
|
| Date | DATE/TIMESTAMP column |
|
||||||
|
| Person | User reference |
|
||||||
|
| Files | File path references |
|
||||||
|
| Checkbox | BOOLEAN column |
|
||||||
|
| URL | TEXT column |
|
||||||
|
| Email | TEXT column |
|
||||||
|
| Phone | TEXT column |
|
||||||
|
| Formula | Computed in BASIC |
|
||||||
|
| Relation | Foreign key |
|
||||||
|
| Rollup | AGGREGATE queries |
|
||||||
|
|
||||||
|
### Formula Migration
|
||||||
|
|
||||||
|
**Notion formula:**
|
||||||
|
```
|
||||||
|
prop("Price") * prop("Quantity")
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Calculate on insert/update
|
||||||
|
total = price * quantity
|
||||||
|
INSERT "orders", #{item: item, price: price, quantity: quantity, total: total}
|
||||||
|
|
||||||
|
' Or query with calculation
|
||||||
|
SELECT "*, price * quantity as total FROM orders"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Relation Migration
|
||||||
|
|
||||||
|
**Notion relations** link databases together.
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Create related tables
|
||||||
|
CREATE TABLE "projects" (id, name, status)
|
||||||
|
CREATE TABLE "tasks" (id, project_id, name, assignee)
|
||||||
|
|
||||||
|
' Query with join
|
||||||
|
tasks = FIND "tasks", "project_id = '" + project_id + "'"
|
||||||
|
|
||||||
|
' Or use JOIN keyword
|
||||||
|
result = JOIN "projects", "tasks", "projects.id = tasks.project_id"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Template Migration
|
||||||
|
|
||||||
|
### Notion Templates
|
||||||
|
|
||||||
|
Notion templates are pre-filled pages. Convert to General Bots templates:
|
||||||
|
|
||||||
|
**Meeting notes template → BASIC script:**
|
||||||
|
```basic
|
||||||
|
' meeting-notes.bas
|
||||||
|
PARAM meeting_title AS string
|
||||||
|
PARAM attendees AS string
|
||||||
|
PARAM date AS date
|
||||||
|
|
||||||
|
DESCRIPTION "Create meeting notes document"
|
||||||
|
|
||||||
|
template = "# " + meeting_title + "
|
||||||
|
|
||||||
|
**Date:** " + FORMAT(date, "MMMM d, yyyy") + "
|
||||||
|
**Attendees:** " + attendees + "
|
||||||
|
|
||||||
|
## Agenda
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## Discussion Notes
|
||||||
|
|
||||||
|
|
||||||
|
## Action Items
|
||||||
|
- [ ]
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Next Meeting
|
||||||
|
"
|
||||||
|
|
||||||
|
WRITE "/meetings/" + FORMAT(date, "yyyy-MM-dd") + "-" + SLUGIFY(meeting_title) + ".md", template
|
||||||
|
TALK "Meeting notes created: " + meeting_title
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project Template
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' new-project.bas
|
||||||
|
PARAM project_name AS string
|
||||||
|
PARAM owner AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Create new project with standard structure"
|
||||||
|
|
||||||
|
project_id = CREATE PROJECT project_name WITH DESCRIPTION "Created by template"
|
||||||
|
ADD USER TO PROJECT project_id, owner, "owner"
|
||||||
|
|
||||||
|
' Create standard tasks
|
||||||
|
CREATE TASK "Define requirements" IN PROJECT project_id
|
||||||
|
CREATE TASK "Create timeline" IN PROJECT project_id
|
||||||
|
CREATE TASK "Assign resources" IN PROJECT project_id
|
||||||
|
CREATE TASK "Kickoff meeting" IN PROJECT project_id
|
||||||
|
CREATE TASK "First milestone review" IN PROJECT project_id
|
||||||
|
|
||||||
|
TALK "Project '" + project_name + "' created with 5 starter tasks"
|
||||||
|
```
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
### Self-Hosting
|
||||||
|
Your data stays on your infrastructure. No concerns about Notion's data practices or service availability.
|
||||||
|
|
||||||
|
### Native AI Without Extra Cost
|
||||||
|
Notion charges $10/user/month for AI features. General Bots includes AI at no additional cost—use any LLM provider.
|
||||||
|
|
||||||
|
### Full Automation
|
||||||
|
Go beyond Notion's limited automations with complete BASIC scripting:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every monday at 9am"
|
||||||
|
|
||||||
|
' Generate weekly report
|
||||||
|
projects = FIND "projects", "status = 'active'"
|
||||||
|
tasks_completed = AGGREGATE "tasks", "COUNT", "id", "completed_at > DATEADD(NOW(), -7, 'day')"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a project manager. Create a concise weekly summary."
|
||||||
|
report = LLM "Summarize: " + LEN(projects) + " active projects, " + tasks_completed + " tasks completed this week"
|
||||||
|
|
||||||
|
SEND MAIL TO "team@company.com" SUBJECT "Weekly Project Summary" BODY report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Channel Access
|
||||||
|
Access your knowledge base through any channel:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Same bot works on web, WhatsApp, Teams, Slack
|
||||||
|
TALK "How can I help you today?"
|
||||||
|
HEAR question
|
||||||
|
|
||||||
|
USE KB "company-wiki"
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom APIs
|
||||||
|
Create APIs instantly—something not possible in Notion:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
WEBHOOK "project-status"
|
||||||
|
|
||||||
|
project = FIND "projects", "id = '" + params.id + "'"
|
||||||
|
tasks = FIND "tasks", "project_id = '" + params.id + "'"
|
||||||
|
|
||||||
|
WITH response
|
||||||
|
.project = project
|
||||||
|
.task_count = LEN(tasks)
|
||||||
|
.completed = LEN(FILTER(tasks, "status = 'done'"))
|
||||||
|
END WITH
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export all Notion content (Markdown & CSV)
|
||||||
|
- [ ] Inventory databases and their properties
|
||||||
|
- [ ] Document active integrations
|
||||||
|
- [ ] Identify critical templates
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Organize Markdown files into .gbkb structure
|
||||||
|
- [ ] Import database CSVs to tables
|
||||||
|
- [ ] Convert formulas to BASIC calculations
|
||||||
|
- [ ] Recreate task boards as projects
|
||||||
|
- [ ] Migrate templates to BASIC scripts
|
||||||
|
- [ ] Set up automations
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Verify all content is searchable
|
||||||
|
- [ ] Test database queries
|
||||||
|
- [ ] Confirm automations work
|
||||||
|
- [ ] Train team on new interface
|
||||||
|
- [ ] Redirect any Notion integrations
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Organize knowledge base thoughtfully.** Group related documents in collections for better RAG results.
|
||||||
|
|
||||||
|
**Simplify database structures.** Notion encourages complex relations; General Bots works best with cleaner schemas.
|
||||||
|
|
||||||
|
**Leverage AI for migration.** Use General Bots' LLM to help transform and summarize Notion content:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
content = READ "notion-export/long-document.md"
|
||||||
|
summary = LLM "Create a concise summary of this document: " + content
|
||||||
|
WRITE "/summaries/document-summary.md", summary
|
||||||
|
```
|
||||||
|
|
||||||
|
**Keep templates as scripts.** BASIC templates are more powerful than Notion's static templates.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Knowledge Base](../chapter-03/README.md) - KB configuration
|
||||||
|
- [Projects](../chapter-11-features/projects.md) - Project management
|
||||||
|
- [Template Variables](../chapter-06-gbdialog/template-variables.md) - Dynamic content
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full feature comparison
|
||||||
406
docs/src/chapter-14-migration/perplexity.md
Normal file
406
docs/src/chapter-14-migration/perplexity.md
Normal file
|
|
@ -0,0 +1,406 @@
|
||||||
|
# Perplexity Migration Guide
|
||||||
|
|
||||||
|
Migrating from Perplexity to General Bots for AI-powered search and knowledge retrieval.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Perplexity is an AI-powered search assistant that answers questions with web citations. General Bots provides equivalent and expanded capabilities through its knowledge base, RAG system, and LLM integration—with the advantage of using your own documents, self-hosting, and full customization.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Perplexity | General Bots |
|
||||||
|
|--------|------------|--------------|
|
||||||
|
| Hosting | Cloud only | Self-hosted |
|
||||||
|
| Pricing | $20/month Pro | No subscription |
|
||||||
|
| Knowledge Source | Web search | Your documents + optional web |
|
||||||
|
| Customization | None | Full BASIC scripting |
|
||||||
|
| Data Privacy | Queries logged | Complete privacy |
|
||||||
|
| API Access | Limited | Full REST API |
|
||||||
|
| Multi-channel | Web only | Web, WhatsApp, Teams, etc. |
|
||||||
|
| Automation | None | Full workflow automation |
|
||||||
|
| Integration | None | Any system via API |
|
||||||
|
|
||||||
|
## Feature Comparison
|
||||||
|
|
||||||
|
### Search and Q&A
|
||||||
|
|
||||||
|
| Perplexity Feature | General Bots Equivalent |
|
||||||
|
|--------------------|------------------------|
|
||||||
|
| Web search | `USE WEBSITE` + `LLM` |
|
||||||
|
| Document Q&A (Pro) | `USE KB` + `LLM` |
|
||||||
|
| Citation generation | RAG with sources |
|
||||||
|
| Focus modes | `SET CONTEXT` |
|
||||||
|
| Collections (Pro) | Multiple `.gbkb` folders |
|
||||||
|
| File upload | Knowledge base indexing |
|
||||||
|
|
||||||
|
### What Perplexity Does
|
||||||
|
|
||||||
|
1. Searches the web for relevant information
|
||||||
|
2. Synthesizes answers from multiple sources
|
||||||
|
3. Provides citations and links
|
||||||
|
4. Allows follow-up questions
|
||||||
|
|
||||||
|
### What General Bots Does
|
||||||
|
|
||||||
|
1. Searches your private knowledge base
|
||||||
|
2. Optionally fetches web content
|
||||||
|
3. Synthesizes answers with full context
|
||||||
|
4. Provides source references
|
||||||
|
5. Allows conversation and follow-ups
|
||||||
|
6. Automates actions based on answers
|
||||||
|
7. Deploys to any channel
|
||||||
|
|
||||||
|
## Migration Approach
|
||||||
|
|
||||||
|
### Step 1: Build Your Knowledge Base
|
||||||
|
|
||||||
|
Instead of relying on web search, create a curated knowledge base:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-bot.gbkb/
|
||||||
|
├── company/
|
||||||
|
│ ├── policies.pdf
|
||||||
|
│ ├── procedures.md
|
||||||
|
│ └── org-chart.pdf
|
||||||
|
├── products/
|
||||||
|
│ ├── catalog.pdf
|
||||||
|
│ ├── specifications.xlsx
|
||||||
|
│ └── pricing.csv
|
||||||
|
├── support/
|
||||||
|
│ ├── faq.md
|
||||||
|
│ ├── troubleshooting.md
|
||||||
|
│ └── known-issues.md
|
||||||
|
└── industry/
|
||||||
|
├── regulations.pdf
|
||||||
|
└── best-practices.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Configure RAG
|
||||||
|
|
||||||
|
Enable retrieval-augmented generation:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Load knowledge collections
|
||||||
|
USE KB "company"
|
||||||
|
USE KB "products"
|
||||||
|
USE KB "support"
|
||||||
|
|
||||||
|
' Set assistant behavior
|
||||||
|
SET CONTEXT "You are a knowledgeable assistant. Answer questions based on the provided documents. Always cite your sources."
|
||||||
|
|
||||||
|
' Handle questions
|
||||||
|
TALK "What would you like to know?"
|
||||||
|
HEAR question
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Add Web Search (Optional)
|
||||||
|
|
||||||
|
For real-time information, add website sources:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "internal-docs"
|
||||||
|
USE WEBSITE "https://docs.example.com"
|
||||||
|
USE WEBSITE "https://industry-news.com"
|
||||||
|
|
||||||
|
answer = LLM "What are the latest updates on " + topic
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recreating Perplexity Features
|
||||||
|
|
||||||
|
### Focus Modes
|
||||||
|
|
||||||
|
**Perplexity Focus: Academic**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are an academic research assistant. Provide scholarly, well-cited responses based on peer-reviewed sources and academic literature. Be precise and thorough."
|
||||||
|
|
||||||
|
USE KB "research-papers"
|
||||||
|
USE KB "academic-journals"
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
```
|
||||||
|
|
||||||
|
**Perplexity Focus: Writing**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are a professional writing assistant. Help with content creation, editing, and improving text. Focus on clarity, style, and engagement."
|
||||||
|
|
||||||
|
answer = LLM "Help me write: " + topic
|
||||||
|
```
|
||||||
|
|
||||||
|
**Perplexity Focus: Code**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are an expert programmer. Provide accurate, well-documented code examples. Explain your reasoning and suggest best practices."
|
||||||
|
|
||||||
|
USE KB "code-documentation"
|
||||||
|
USE KB "api-references"
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
```
|
||||||
|
|
||||||
|
### Collections
|
||||||
|
|
||||||
|
**Perplexity Collections** organize related searches.
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Create specialized search contexts
|
||||||
|
WEBHOOK "search-products"
|
||||||
|
USE KB "products"
|
||||||
|
SET CONTEXT "You are a product specialist."
|
||||||
|
answer = LLM body.query
|
||||||
|
END WEBHOOK
|
||||||
|
|
||||||
|
WEBHOOK "search-support"
|
||||||
|
USE KB "support"
|
||||||
|
SET CONTEXT "You are a support technician."
|
||||||
|
answer = LLM body.query
|
||||||
|
END WEBHOOK
|
||||||
|
|
||||||
|
WEBHOOK "search-legal"
|
||||||
|
USE KB "legal"
|
||||||
|
SET CONTEXT "You are a legal advisor. Always include disclaimers."
|
||||||
|
answer = LLM body.query
|
||||||
|
END WEBHOOK
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pro Search (Deep Research)
|
||||||
|
|
||||||
|
**Perplexity Pro Search** performs multi-step research.
|
||||||
|
|
||||||
|
**General Bots equivalent:**
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Deep research workflow
|
||||||
|
PARAM topic AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Perform comprehensive research on a topic"
|
||||||
|
|
||||||
|
SET CONTEXT "You are a research analyst. Conduct thorough analysis with multiple perspectives."
|
||||||
|
|
||||||
|
USE KB "all-documents"
|
||||||
|
|
||||||
|
' Step 1: Initial analysis
|
||||||
|
initial = LLM "Provide an overview of: " + topic
|
||||||
|
|
||||||
|
' Step 2: Deep dive
|
||||||
|
details = LLM "Now provide detailed analysis with specific examples for: " + topic
|
||||||
|
|
||||||
|
' Step 3: Alternative perspectives
|
||||||
|
alternatives = LLM "What are alternative viewpoints or counterarguments regarding: " + topic
|
||||||
|
|
||||||
|
' Step 4: Synthesis
|
||||||
|
WITH research_prompt
|
||||||
|
.instruction = "Synthesize a comprehensive report"
|
||||||
|
.overview = initial
|
||||||
|
.details = details
|
||||||
|
.alternatives = alternatives
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
final_report = LLM "Create a comprehensive report combining: " + research_prompt
|
||||||
|
|
||||||
|
TALK final_report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Citation and Sources
|
||||||
|
|
||||||
|
**Perplexity** shows numbered citations with links.
|
||||||
|
|
||||||
|
**General Bots** provides source references through RAG:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "documents"
|
||||||
|
|
||||||
|
SET CONTEXT "When answering, always cite which document your information comes from. Format citations as [Source: document name]."
|
||||||
|
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
### Private Knowledge Base
|
||||||
|
|
||||||
|
Your proprietary documents stay private:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "confidential-data"
|
||||||
|
USE KB "internal-reports"
|
||||||
|
|
||||||
|
' All queries against your own data
|
||||||
|
' Nothing sent to external search engines
|
||||||
|
answer = LLM sensitive_question
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom AI Behavior
|
||||||
|
|
||||||
|
Fine-tune responses for your specific needs:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET CONTEXT "You are the customer service assistant for Acme Corp.
|
||||||
|
- Always be friendly and professional
|
||||||
|
- If you don't know something, offer to connect with a human
|
||||||
|
- Never discuss competitor products
|
||||||
|
- Emphasize our satisfaction guarantee"
|
||||||
|
|
||||||
|
answer = LLM customer_question
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Channel Deployment
|
||||||
|
|
||||||
|
Access your AI assistant anywhere:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Same knowledge base, any channel
|
||||||
|
' Web chat, WhatsApp, Teams, Slack, SMS, Email
|
||||||
|
|
||||||
|
TALK "How can I help you?"
|
||||||
|
HEAR question
|
||||||
|
USE KB "company-knowledge"
|
||||||
|
answer = LLM question
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automation Beyond Q&A
|
||||||
|
|
||||||
|
Take action based on queries:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
USE KB "products"
|
||||||
|
|
||||||
|
TALK "What are you looking for?"
|
||||||
|
HEAR query
|
||||||
|
|
||||||
|
answer = LLM query
|
||||||
|
|
||||||
|
' If user wants to order, take action
|
||||||
|
IF CONTAINS(LOWER(query), "order") OR CONTAINS(LOWER(query), "buy") THEN
|
||||||
|
TALK "Would you like me to start an order?"
|
||||||
|
HEAR confirm AS BOOLEAN
|
||||||
|
IF confirm THEN
|
||||||
|
CREATE TASK "Follow up on order inquiry" DUE DATEADD(NOW(), 1, "day")
|
||||||
|
SEND MAIL TO "sales@company.com" SUBJECT "Order Inquiry" BODY "Customer asked: " + query
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK answer
|
||||||
|
```
|
||||||
|
|
||||||
|
### API for Integration
|
||||||
|
|
||||||
|
Create search APIs for your applications:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
WEBHOOK "search"
|
||||||
|
|
||||||
|
USE KB params.collection
|
||||||
|
SET CONTEXT params.context
|
||||||
|
|
||||||
|
answer = LLM params.query
|
||||||
|
|
||||||
|
WITH response
|
||||||
|
.answer = answer
|
||||||
|
.query = params.query
|
||||||
|
.timestamp = NOW()
|
||||||
|
END WITH
|
||||||
|
```
|
||||||
|
|
||||||
|
Call from any application:
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/search
|
||||||
|
{
|
||||||
|
"collection": "products",
|
||||||
|
"context": "You are a product expert",
|
||||||
|
"query": "What's the best option for enterprise?"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Identify information sources you frequently search
|
||||||
|
- [ ] Gather documents to build knowledge base
|
||||||
|
- [ ] Determine required focus modes/contexts
|
||||||
|
- [ ] Plan deployment channels
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Organize documents into .gbkb collections
|
||||||
|
- [ ] Create context configurations
|
||||||
|
- [ ] Build specialized search endpoints
|
||||||
|
- [ ] Test with common queries
|
||||||
|
- [ ] Configure multi-channel access
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Compare answer quality
|
||||||
|
- [ ] Train team on new interface
|
||||||
|
- [ ] Monitor and refine contexts
|
||||||
|
- [ ] Add automation workflows
|
||||||
|
- [ ] Expand knowledge base as needed
|
||||||
|
|
||||||
|
## Example: Complete Search Assistant
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' search-assistant.bas
|
||||||
|
' A Perplexity-like search experience with General Bots
|
||||||
|
|
||||||
|
' Load knowledge bases
|
||||||
|
USE KB "company-docs"
|
||||||
|
USE KB "product-info"
|
||||||
|
USE KB "industry-knowledge"
|
||||||
|
|
||||||
|
' Configure AI behavior
|
||||||
|
SET CONTEXT "You are an intelligent search assistant.
|
||||||
|
Provide accurate, well-sourced answers.
|
||||||
|
When citing information, mention the source document.
|
||||||
|
If you're uncertain, acknowledge the limitations.
|
||||||
|
Be concise but comprehensive."
|
||||||
|
|
||||||
|
' Main conversation loop
|
||||||
|
TALK "Hello! I can search our knowledge base and help answer your questions. What would you like to know?"
|
||||||
|
|
||||||
|
LOOP
|
||||||
|
HEAR query
|
||||||
|
|
||||||
|
IF LOWER(query) = "exit" OR LOWER(query) = "quit" THEN
|
||||||
|
TALK "Goodbye!"
|
||||||
|
EXIT LOOP
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Generate response with sources
|
||||||
|
answer = LLM query
|
||||||
|
TALK answer
|
||||||
|
|
||||||
|
' Offer follow-up
|
||||||
|
TALK "Would you like to know more about any aspect of this?"
|
||||||
|
LOOP
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Curate your knowledge base.** Quality documents produce better answers than random web search.
|
||||||
|
|
||||||
|
**Use specific contexts.** Tailor the AI's behavior for different use cases rather than using generic settings.
|
||||||
|
|
||||||
|
**Iterate on prompts.** Refine your `SET CONTEXT` instructions based on the quality of responses.
|
||||||
|
|
||||||
|
**Combine sources strategically.** Mix internal documents with curated external sources for comprehensive coverage.
|
||||||
|
|
||||||
|
**Add automation.** Go beyond Q&A—let your assistant take actions, create tasks, and integrate with workflows.
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Knowledge Base](../chapter-03/README.md) - Building effective KBs
|
||||||
|
- [USE KB](../chapter-06-gbdialog/keyword-use-kb.md) - Knowledge base keyword
|
||||||
|
- [SET CONTEXT](../chapter-06-gbdialog/keyword-set-context.md) - AI configuration
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full feature comparison
|
||||||
290
docs/src/chapter-14-migration/resources.md
Normal file
290
docs/src/chapter-14-migration/resources.md
Normal file
|
|
@ -0,0 +1,290 @@
|
||||||
|
# Migration Resources
|
||||||
|
|
||||||
|
General Bots provides comprehensive tools and resources for organizations transitioning from cloud-based productivity platforms to self-hosted infrastructure.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Migration Toolkit
|
||||||
|
|
||||||
|
### Data Import Utilities
|
||||||
|
|
||||||
|
General Bots includes import tools for common enterprise data formats:
|
||||||
|
|
||||||
|
**Email Migration**
|
||||||
|
- IMAP sync for mailbox migration
|
||||||
|
- PST file import support
|
||||||
|
- Calendar (ICS) import
|
||||||
|
- Contact (VCF/CardDAV) import
|
||||||
|
|
||||||
|
**File Migration**
|
||||||
|
- Bulk file upload via S3 API
|
||||||
|
- Folder structure preservation
|
||||||
|
- Metadata retention
|
||||||
|
- Version history import where available
|
||||||
|
|
||||||
|
**User Migration**
|
||||||
|
- SCIM provisioning support
|
||||||
|
- LDAP directory sync
|
||||||
|
- CSV user import
|
||||||
|
- Bulk credential generation
|
||||||
|
|
||||||
|
### BASIC Migration Scripts
|
||||||
|
|
||||||
|
Template scripts for common migration tasks:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' migrate-files.bas
|
||||||
|
PARAM source_api AS string
|
||||||
|
PARAM auth_token AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Migrate files from external storage"
|
||||||
|
|
||||||
|
SET HEADER "Authorization", "Bearer " + auth_token
|
||||||
|
files = GET source_api + "/files"
|
||||||
|
|
||||||
|
FOR EACH file IN files
|
||||||
|
content = DOWNLOAD file.download_url
|
||||||
|
WRITE "/" + file.path, content
|
||||||
|
TALK "Migrated: " + file.name
|
||||||
|
NEXT file
|
||||||
|
|
||||||
|
TALK "Migration complete: " + LEN(files) + " files"
|
||||||
|
```
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' migrate-users.bas
|
||||||
|
PARAM csv_path AS string
|
||||||
|
|
||||||
|
DESCRIPTION "Import users from CSV export"
|
||||||
|
|
||||||
|
users = READ csv_path
|
||||||
|
FOR EACH row IN users
|
||||||
|
CREATE USER row.email WITH NAME row.name
|
||||||
|
NEXT row
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Compatibility
|
||||||
|
|
||||||
|
### REST API Mapping
|
||||||
|
|
||||||
|
General Bots REST APIs follow familiar patterns:
|
||||||
|
|
||||||
|
| Common Operation | General Bots Endpoint |
|
||||||
|
|-----------------|----------------------|
|
||||||
|
| List files | `GET /api/files/list` |
|
||||||
|
| Upload file | `POST /api/files/write` |
|
||||||
|
| Download file | `GET /api/files/{path}` |
|
||||||
|
| List users | `GET /api/users` |
|
||||||
|
| Create user | `POST /api/users` |
|
||||||
|
| Send email | `POST /api/email/send` |
|
||||||
|
| List calendar events | `GET /api/calendar/events` |
|
||||||
|
| Create task | `POST /api/tasks` |
|
||||||
|
|
||||||
|
### Identity Federation
|
||||||
|
|
||||||
|
Support SSO during migration with identity federation:
|
||||||
|
|
||||||
|
- OIDC provider integration
|
||||||
|
- SAML support via Zitadel
|
||||||
|
- Hybrid authentication during transition
|
||||||
|
- Gradual user migration
|
||||||
|
|
||||||
|
Configure in `config.csv`:
|
||||||
|
|
||||||
|
```csv
|
||||||
|
key,value
|
||||||
|
oidc-provider-url,https://identity.example.com
|
||||||
|
oidc-client-id,general-bots-client
|
||||||
|
oidc-client-secret,your-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
## Industry Templates
|
||||||
|
|
||||||
|
Pre-built configurations for common industries:
|
||||||
|
|
||||||
|
### Healthcare
|
||||||
|
|
||||||
|
- HIPAA-compliant configuration
|
||||||
|
- Patient communication templates
|
||||||
|
- Appointment scheduling workflows
|
||||||
|
- Secure document handling
|
||||||
|
|
||||||
|
### Financial Services
|
||||||
|
|
||||||
|
- SOC 2 aligned settings
|
||||||
|
- Secure data handling
|
||||||
|
- Audit logging enabled
|
||||||
|
- Compliance reporting
|
||||||
|
|
||||||
|
### Education
|
||||||
|
|
||||||
|
- Student enrollment flows
|
||||||
|
- Course management
|
||||||
|
- Parent communication channels
|
||||||
|
- Assignment tracking
|
||||||
|
|
||||||
|
### Professional Services
|
||||||
|
|
||||||
|
- Client onboarding templates
|
||||||
|
- Project management workflows
|
||||||
|
- Time tracking integration
|
||||||
|
- Invoice generation
|
||||||
|
|
||||||
|
## Deployment Guides
|
||||||
|
|
||||||
|
### Infrastructure Sizing
|
||||||
|
|
||||||
|
| Organization Size | CPU | RAM | Storage | Users |
|
||||||
|
|------------------|-----|-----|---------|-------|
|
||||||
|
| Small | 2 cores | 4 GB | 100 GB | 1-50 |
|
||||||
|
| Medium | 4 cores | 8 GB | 500 GB | 50-500 |
|
||||||
|
| Large | 8 cores | 16 GB | 2 TB | 500-5000 |
|
||||||
|
| Enterprise | 16+ cores | 32+ GB | 10+ TB | 5000+ |
|
||||||
|
|
||||||
|
### High Availability
|
||||||
|
|
||||||
|
For production deployments:
|
||||||
|
|
||||||
|
- PostgreSQL replication
|
||||||
|
- Load-balanced botserver instances
|
||||||
|
- Distributed SeaweedFS storage
|
||||||
|
- Redis/Valkey clustering
|
||||||
|
|
||||||
|
### Backup Strategy
|
||||||
|
|
||||||
|
Automated backup configuration:
|
||||||
|
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every day at 2am"
|
||||||
|
|
||||||
|
' Database backup
|
||||||
|
result = POST "https://backup.internal/postgres", #{database: "botserver"}
|
||||||
|
|
||||||
|
' File storage backup
|
||||||
|
result = POST "https://backup.internal/seaweedfs", #{bucket: "all"}
|
||||||
|
|
||||||
|
' Notify on completion
|
||||||
|
SEND MAIL TO "ops@company.com" SUBJECT "Backup Complete" BODY result
|
||||||
|
```
|
||||||
|
|
||||||
|
## Training Resources
|
||||||
|
|
||||||
|
### Administrator Training
|
||||||
|
|
||||||
|
- Initial setup and configuration
|
||||||
|
- User management
|
||||||
|
- Security settings
|
||||||
|
- Monitoring and maintenance
|
||||||
|
|
||||||
|
### Developer Training
|
||||||
|
|
||||||
|
- BASIC scripting fundamentals
|
||||||
|
- API integration patterns
|
||||||
|
- Custom keyword development
|
||||||
|
- Package creation
|
||||||
|
|
||||||
|
### End User Training
|
||||||
|
|
||||||
|
- Chat interface usage
|
||||||
|
- File management
|
||||||
|
- Calendar and tasks
|
||||||
|
- Mobile access
|
||||||
|
|
||||||
|
## ROI Calculator
|
||||||
|
|
||||||
|
Estimate savings with self-hosted deployment:
|
||||||
|
|
||||||
|
| Factor | Cloud (100 users) | General Bots |
|
||||||
|
|--------|------------------|--------------|
|
||||||
|
| Annual licensing | $15,000-60,000 | $0 |
|
||||||
|
| AI assistant add-on | $36,000 | $0 |
|
||||||
|
| Infrastructure | Included | $2,400-6,000 |
|
||||||
|
| LLM API costs | Included | $600-6,000 |
|
||||||
|
| **Total Annual** | **$51,000-96,000** | **$3,000-12,000** |
|
||||||
|
|
||||||
|
Typical savings: 75-95% reduction in annual costs.
|
||||||
|
|
||||||
|
## Support Resources
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- Complete keyword reference
|
||||||
|
- API documentation
|
||||||
|
- Configuration guides
|
||||||
|
- Troubleshooting guides
|
||||||
|
|
||||||
|
### Community
|
||||||
|
|
||||||
|
- GitHub discussions
|
||||||
|
- Issue tracking
|
||||||
|
- Feature requests
|
||||||
|
- Community contributions
|
||||||
|
|
||||||
|
### Professional Services
|
||||||
|
|
||||||
|
For enterprise deployments:
|
||||||
|
|
||||||
|
- Migration planning
|
||||||
|
- Custom development
|
||||||
|
- Training programs
|
||||||
|
- Support contracts
|
||||||
|
|
||||||
|
Contact: partners@pragmatismo.com.br
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Inventory current services and usage
|
||||||
|
- [ ] Identify data to migrate
|
||||||
|
- [ ] Plan user communication
|
||||||
|
- [ ] Set up test environment
|
||||||
|
- [ ] Configure identity federation
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Deploy General Bots infrastructure
|
||||||
|
- [ ] Import users and groups
|
||||||
|
- [ ] Migrate files and documents
|
||||||
|
- [ ] Transfer email (if applicable)
|
||||||
|
- [ ] Set up integrations
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Verify data integrity
|
||||||
|
- [ ] Test all workflows
|
||||||
|
- [ ] Train users
|
||||||
|
- [ ] Update DNS/routing
|
||||||
|
- [ ] Decommission old services
|
||||||
|
- [ ] Monitor and optimize
|
||||||
|
|
||||||
|
## Case Study Template
|
||||||
|
|
||||||
|
Document your migration for internal reference:
|
||||||
|
|
||||||
|
**Organization Profile**
|
||||||
|
- Size and industry
|
||||||
|
- Previous platform
|
||||||
|
- Key requirements
|
||||||
|
|
||||||
|
**Migration Scope**
|
||||||
|
- Services migrated
|
||||||
|
- Data volume
|
||||||
|
- Timeline
|
||||||
|
|
||||||
|
**Results**
|
||||||
|
- Cost savings achieved
|
||||||
|
- Performance improvements
|
||||||
|
- User feedback
|
||||||
|
|
||||||
|
**Lessons Learned**
|
||||||
|
- Challenges encountered
|
||||||
|
- Solutions implemented
|
||||||
|
- Recommendations
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Migration Overview](./overview.md) - Getting started with migration
|
||||||
|
- [Validation and Testing](./validation.md) - Verify migration success
|
||||||
|
- [Enterprise Platform Migration](../chapter-11-features/m365-comparison.md) - Feature mapping
|
||||||
|
- [Quick Start](../chapter-01/quick-start.md) - Initial deployment
|
||||||
489
docs/src/chapter-14-migration/zapier-make.md
Normal file
489
docs/src/chapter-14-migration/zapier-make.md
Normal file
|
|
@ -0,0 +1,489 @@
|
||||||
|
# Zapier and Make Migration Guide
|
||||||
|
|
||||||
|
Migrating workflows from Zapier or Make (formerly Integromat) to General Bots.
|
||||||
|
|
||||||
|
<img src="../assets/gb-decorative-header.svg" alt="General Bots" style="max-height: 100px; width: 100%; object-fit: contain;">
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Zapier and Make are visual automation platforms connecting apps through triggers and actions. General Bots provides equivalent automation through BASIC scripting, offering more power and flexibility without per-task pricing.
|
||||||
|
|
||||||
|
## Why Migrate
|
||||||
|
|
||||||
|
| Aspect | Zapier/Make | General Bots |
|
||||||
|
|--------|-------------|--------------|
|
||||||
|
| Pricing | Per-task/operation | Unlimited executions |
|
||||||
|
| Automation | Visual workflows | BASIC scripts |
|
||||||
|
| AI Integration | Via paid apps | Native LLM keywords |
|
||||||
|
| Chat/Bot | Not included | Multi-channel |
|
||||||
|
| Productivity Suite | Not included | Email, calendar, files |
|
||||||
|
| Custom Logic | Limited | Full programming |
|
||||||
|
| Self-hosting | Not available | Full control |
|
||||||
|
| API Creation | Not available | Instant webhooks |
|
||||||
|
|
||||||
|
## Cost Comparison
|
||||||
|
|
||||||
|
### Zapier Pricing
|
||||||
|
|
||||||
|
| Plan | Tasks/Month | Cost |
|
||||||
|
|------|-------------|------|
|
||||||
|
| Free | 100 | $0 |
|
||||||
|
| Starter | 750 | $19.99 |
|
||||||
|
| Professional | 2,000 | $49 |
|
||||||
|
| Team | 50,000 | $69/user |
|
||||||
|
| Company | 100,000+ | Custom |
|
||||||
|
|
||||||
|
### Make Pricing
|
||||||
|
|
||||||
|
| Plan | Operations/Month | Cost |
|
||||||
|
|------|------------------|------|
|
||||||
|
| Free | 1,000 | $0 |
|
||||||
|
| Core | 10,000 | $9 |
|
||||||
|
| Pro | 10,000 | $16 |
|
||||||
|
| Teams | 10,000 | $29/user |
|
||||||
|
| Enterprise | Custom | Custom |
|
||||||
|
|
||||||
|
### General Bots
|
||||||
|
|
||||||
|
| Plan | Operations | Cost |
|
||||||
|
|------|------------|------|
|
||||||
|
| Self-hosted | Unlimited | Infrastructure only |
|
||||||
|
|
||||||
|
## Trigger Mapping
|
||||||
|
|
||||||
|
| Zapier/Make Trigger | General Bots Equivalent |
|
||||||
|
|---------------------|------------------------|
|
||||||
|
| Schedule | `SET SCHEDULE` |
|
||||||
|
| Webhook | `WEBHOOK` |
|
||||||
|
| New Email | `ON "email:received"` |
|
||||||
|
| New Row (Sheets) | `ON "table:name:insert"` |
|
||||||
|
| Form Submission | `ON FORM SUBMIT` |
|
||||||
|
| New File | `ON "file:created"` |
|
||||||
|
| RSS Feed | Scheduled `GET` |
|
||||||
|
| App-specific | API polling or webhooks |
|
||||||
|
|
||||||
|
## Action Mapping
|
||||||
|
|
||||||
|
| Zapier/Make Action | General Bots Equivalent |
|
||||||
|
|--------------------|------------------------|
|
||||||
|
| Send Email | `SEND MAIL` |
|
||||||
|
| HTTP Request | `GET`, `POST`, `PUT`, `DELETE` |
|
||||||
|
| Create Row | `INSERT` |
|
||||||
|
| Update Row | `UPDATE` |
|
||||||
|
| Filter | `IF/THEN/ELSE` |
|
||||||
|
| Formatter | String/date functions |
|
||||||
|
| Delay | `WAIT` |
|
||||||
|
| Paths | `IF` branches |
|
||||||
|
| Loop | `FOR EACH` |
|
||||||
|
| Code (JS/Python) | BASIC script |
|
||||||
|
| Slack Message | `POST` to Slack webhook |
|
||||||
|
| Create Task | `CREATE TASK` |
|
||||||
|
| Send SMS | SMS integration |
|
||||||
|
|
||||||
|
## Migration Examples
|
||||||
|
|
||||||
|
### Simple Zap: Form to Email
|
||||||
|
|
||||||
|
**Zapier:**
|
||||||
|
```
|
||||||
|
Typeform → Gmail (Send Email)
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
ON FORM SUBMIT "contact-form"
|
||||||
|
name = fields.name
|
||||||
|
email = fields.email
|
||||||
|
message = fields.message
|
||||||
|
|
||||||
|
SEND MAIL TO "support@company.com" SUBJECT "New Contact: " + name BODY "From: " + email + "\n\nMessage:\n" + message
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Step Zap: Lead Processing
|
||||||
|
|
||||||
|
**Zapier:**
|
||||||
|
```
|
||||||
|
Webhook → Filter → Clearbit Enrich → Salesforce (Create Lead) → Slack (Send Message)
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
WEBHOOK "new-lead"
|
||||||
|
|
||||||
|
lead = body
|
||||||
|
|
||||||
|
' Filter
|
||||||
|
IF lead.email = "" OR NOT CONTAINS(lead.email, "@") THEN
|
||||||
|
RETURN #{status: "invalid", reason: "Invalid email"}
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Enrich
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "clearbit-key"
|
||||||
|
enriched = GET "https://person.clearbit.com/v2/people/find?email=" + lead.email
|
||||||
|
|
||||||
|
' Create in CRM
|
||||||
|
WITH salesforce_lead
|
||||||
|
.Email = lead.email
|
||||||
|
.FirstName = enriched.name.givenName
|
||||||
|
.LastName = enriched.name.familyName
|
||||||
|
.Company = enriched.employment.name
|
||||||
|
.Title = enriched.employment.title
|
||||||
|
END WITH
|
||||||
|
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "salesforce-token"
|
||||||
|
result = POST "https://yourinstance.salesforce.com/services/data/v52.0/sobjects/Lead", salesforce_lead
|
||||||
|
|
||||||
|
' Notify Slack
|
||||||
|
POST GET CONFIG "slack-webhook", #{
|
||||||
|
text: "New lead: " + lead.email + " from " + enriched.employment.name
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN #{status: "success", salesforce_id: result.id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scheduled Sync
|
||||||
|
|
||||||
|
**Make Scenario:**
|
||||||
|
```
|
||||||
|
Schedule → HTTP Request → Iterator → Google Sheets (Add Row)
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every hour"
|
||||||
|
|
||||||
|
data = GET "https://api.example.com/new-orders"
|
||||||
|
|
||||||
|
FOR EACH order IN data.orders
|
||||||
|
INSERT "orders", #{
|
||||||
|
order_id: order.id,
|
||||||
|
customer: order.customer_name,
|
||||||
|
total: order.total,
|
||||||
|
status: order.status,
|
||||||
|
synced_at: NOW()
|
||||||
|
}
|
||||||
|
NEXT order
|
||||||
|
|
||||||
|
TALK "Synced " + LEN(data.orders) + " orders"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
**Zapier:** Error handling path or retry
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SET SCHEDULE "every 5 minutes"
|
||||||
|
|
||||||
|
TRY
|
||||||
|
result = POST "https://api.example.com/sync", data
|
||||||
|
IF result.status <> 200 THEN
|
||||||
|
THROW "API returned " + result.status
|
||||||
|
END IF
|
||||||
|
CATCH
|
||||||
|
' Log error
|
||||||
|
INSERT "error_log", #{
|
||||||
|
error: ERROR_MESSAGE,
|
||||||
|
timestamp: NOW(),
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
|
||||||
|
' Alert
|
||||||
|
SEND MAIL TO "ops@company.com" SUBJECT "Sync Error" BODY ERROR_MESSAGE
|
||||||
|
POST GET CONFIG "slack-alerts", #{text: "Sync failed: " + ERROR_MESSAGE}
|
||||||
|
END TRY
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Paths
|
||||||
|
|
||||||
|
**Zapier Paths:**
|
||||||
|
```
|
||||||
|
Trigger → Path A (if condition) → Actions
|
||||||
|
→ Path B (else) → Actions
|
||||||
|
```
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
WEBHOOK "order-status"
|
||||||
|
|
||||||
|
order = body
|
||||||
|
|
||||||
|
IF order.total > 1000 THEN
|
||||||
|
' High-value order path
|
||||||
|
SEND MAIL TO "vip-team@company.com" SUBJECT "High-Value Order" BODY order
|
||||||
|
POST GET CONFIG "slack-vip", #{text: "VIP Order: $" + order.total}
|
||||||
|
priority = "high"
|
||||||
|
|
||||||
|
ELSEIF order.is_rush = true THEN
|
||||||
|
' Rush order path
|
||||||
|
SEND MAIL TO "fulfillment@company.com" SUBJECT "RUSH Order" BODY order
|
||||||
|
priority = "rush"
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
' Standard order path
|
||||||
|
priority = "normal"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
INSERT "orders", #{
|
||||||
|
id: order.id,
|
||||||
|
total: order.total,
|
||||||
|
priority: priority,
|
||||||
|
created: NOW()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Transformation
|
||||||
|
|
||||||
|
**Make/Zapier Formatter:**
|
||||||
|
- Split text
|
||||||
|
- Format dates
|
||||||
|
- Math operations
|
||||||
|
- Lookup tables
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' String operations
|
||||||
|
full_name = first_name + " " + last_name
|
||||||
|
email_domain = SPLIT(email, "@")[1]
|
||||||
|
slug = LOWER(REPLACE(title, " ", "-"))
|
||||||
|
|
||||||
|
' Date formatting
|
||||||
|
formatted_date = FORMAT(created_at, "MMMM d, yyyy")
|
||||||
|
due_date = DATEADD(NOW(), 7, "day")
|
||||||
|
days_ago = DATEDIFF("day", created_at, NOW())
|
||||||
|
|
||||||
|
' Math
|
||||||
|
subtotal = price * quantity
|
||||||
|
tax = subtotal * 0.08
|
||||||
|
total = subtotal + tax
|
||||||
|
discount = IIF(total > 100, total * 0.1, 0)
|
||||||
|
|
||||||
|
' Lookup
|
||||||
|
status_label = SWITCH status
|
||||||
|
CASE "new" : "New Order"
|
||||||
|
CASE "processing" : "In Progress"
|
||||||
|
CASE "shipped" : "On the Way"
|
||||||
|
CASE "delivered" : "Completed"
|
||||||
|
DEFAULT : "Unknown"
|
||||||
|
END SWITCH
|
||||||
|
```
|
||||||
|
|
||||||
|
## App-Specific Migrations
|
||||||
|
|
||||||
|
### Gmail/Email
|
||||||
|
|
||||||
|
**Zapier:** Gmail trigger/action
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Send email
|
||||||
|
SEND MAIL TO recipient SUBJECT subject BODY body
|
||||||
|
|
||||||
|
' With attachments
|
||||||
|
SEND MAIL TO recipient SUBJECT subject BODY body ATTACH "/files/report.pdf"
|
||||||
|
|
||||||
|
' Process incoming (via Stalwart webhook)
|
||||||
|
ON "email:received"
|
||||||
|
IF CONTAINS(params.subject, "Order") THEN
|
||||||
|
PROCESS_ORDER(params)
|
||||||
|
END IF
|
||||||
|
END ON
|
||||||
|
```
|
||||||
|
|
||||||
|
### Slack
|
||||||
|
|
||||||
|
**Zapier:** Slack app
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Simple message
|
||||||
|
POST "https://hooks.slack.com/services/xxx", #{text: "Hello!"}
|
||||||
|
|
||||||
|
' Rich message
|
||||||
|
WITH slack_message
|
||||||
|
.channel = "#general"
|
||||||
|
.blocks = [
|
||||||
|
#{type: "header", text: #{type: "plain_text", text: "New Order"}},
|
||||||
|
#{type: "section", text: #{type: "mrkdwn", text: "*Customer:* " + customer_name}},
|
||||||
|
#{type: "section", text: #{type: "mrkdwn", text: "*Total:* $" + total}}
|
||||||
|
]
|
||||||
|
END WITH
|
||||||
|
POST GET CONFIG "slack-webhook", slack_message
|
||||||
|
```
|
||||||
|
|
||||||
|
### Google Sheets
|
||||||
|
|
||||||
|
**Zapier:** Google Sheets app
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
' Read from sheet
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "google-token"
|
||||||
|
data = GET "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/Sheet1!A1:D100"
|
||||||
|
|
||||||
|
' Append row
|
||||||
|
POST "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/Sheet1!A1:append?valueInputOption=USER_ENTERED", #{
|
||||||
|
values: [[name, email, phone, NOW()]]
|
||||||
|
}
|
||||||
|
|
||||||
|
' Or use General Bots tables directly
|
||||||
|
INSERT "contacts", #{name: name, email: email, phone: phone}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Airtable
|
||||||
|
|
||||||
|
**Zapier:** Airtable app
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "airtable-key"
|
||||||
|
|
||||||
|
' Read records
|
||||||
|
records = GET "https://api.airtable.com/v0/{baseId}/{tableName}"
|
||||||
|
|
||||||
|
' Create record
|
||||||
|
POST "https://api.airtable.com/v0/{baseId}/{tableName}", #{
|
||||||
|
fields: #{
|
||||||
|
Name: name,
|
||||||
|
Email: email,
|
||||||
|
Status: "New"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### HubSpot
|
||||||
|
|
||||||
|
**Zapier:** HubSpot app
|
||||||
|
|
||||||
|
**General Bots:**
|
||||||
|
```basic
|
||||||
|
SET HEADER "Authorization", "Bearer " + GET CONFIG "hubspot-token"
|
||||||
|
|
||||||
|
' Create contact
|
||||||
|
POST "https://api.hubapi.com/crm/v3/objects/contacts", #{
|
||||||
|
properties: #{
|
||||||
|
email: email,
|
||||||
|
firstname: first_name,
|
||||||
|
lastname: last_name,
|
||||||
|
company: company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
' Create deal
|
||||||
|
POST "https://api.hubapi.com/crm/v3/objects/deals", #{
|
||||||
|
properties: #{
|
||||||
|
dealname: deal_name,
|
||||||
|
amount: amount,
|
||||||
|
pipeline: "default",
|
||||||
|
dealstage: "appointmentscheduled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## What You Gain
|
||||||
|
|
||||||
|
### No Operation Limits
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Process thousands of records without worrying about limits
|
||||||
|
SET SCHEDULE "every hour"
|
||||||
|
|
||||||
|
records = GET "https://api.example.com/all-records"
|
||||||
|
|
||||||
|
FOR EACH record IN records
|
||||||
|
PROCESS_RECORD(record) ' No per-operation cost
|
||||||
|
NEXT record
|
||||||
|
```
|
||||||
|
|
||||||
|
### Native AI Integration
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' AI-powered automation
|
||||||
|
USE KB "company-docs"
|
||||||
|
|
||||||
|
incoming_email = params.body
|
||||||
|
category = LLM "Categorize this email as: support, sales, billing, or other: " + incoming_email
|
||||||
|
|
||||||
|
IF category = "support" THEN
|
||||||
|
response = LLM "Draft a helpful support response to: " + incoming_email
|
||||||
|
SEND MAIL TO params.from SUBJECT "Re: " + params.subject BODY response
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Channel Chat
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Same automation works across channels
|
||||||
|
TALK "How can I help you?"
|
||||||
|
HEAR request
|
||||||
|
|
||||||
|
USE KB "help-docs"
|
||||||
|
answer = LLM request
|
||||||
|
TALK answer
|
||||||
|
|
||||||
|
' Available on Web, WhatsApp, Teams, Slack, Telegram, SMS
|
||||||
|
```
|
||||||
|
|
||||||
|
### Built-in Productivity
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' No need for separate calendar, task, email apps
|
||||||
|
CREATE TASK "Follow up with " + customer_name DUE DATEADD(NOW(), 3, "day")
|
||||||
|
BOOK "Call with " + customer_name AT meeting_time
|
||||||
|
SEND MAIL TO customer_email SUBJECT "Confirmation" BODY message
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Checklist
|
||||||
|
|
||||||
|
### Pre-Migration
|
||||||
|
|
||||||
|
- [ ] Export Zap/Scenario descriptions
|
||||||
|
- [ ] Document all triggers and schedules
|
||||||
|
- [ ] List all connected apps and credentials
|
||||||
|
- [ ] Identify critical automations
|
||||||
|
- [ ] Set up General Bots environment
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
- [ ] Create BASIC scripts for each workflow
|
||||||
|
- [ ] Configure credentials in config.csv
|
||||||
|
- [ ] Set up webhooks with same URLs
|
||||||
|
- [ ] Configure schedules
|
||||||
|
- [ ] Test each automation
|
||||||
|
|
||||||
|
### Post-Migration
|
||||||
|
|
||||||
|
- [ ] Run parallel for verification
|
||||||
|
- [ ] Compare execution results
|
||||||
|
- [ ] Monitor for errors
|
||||||
|
- [ ] Disable Zapier/Make automations
|
||||||
|
- [ ] Cancel subscriptions
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
**Start with simple Zaps.** Migrate basic workflows first to learn BASIC syntax.
|
||||||
|
|
||||||
|
**Combine multiple Zaps.** Often several Zaps can become one General Bots script.
|
||||||
|
|
||||||
|
**Use native features.** Don't replicate Zapier patterns—leverage AI, chat, and productivity features.
|
||||||
|
|
||||||
|
**Add error handling.** BASIC provides better error handling than visual builders.
|
||||||
|
|
||||||
|
**Document your scripts.** Add comments explaining what each script does.
|
||||||
|
|
||||||
|
```basic
|
||||||
|
' Daily sales report
|
||||||
|
' Runs at 6 PM on weekdays
|
||||||
|
' Aggregates daily orders and sends summary to management
|
||||||
|
SET SCHEDULE "0 18 * * 1-5"
|
||||||
|
|
||||||
|
' ... implementation
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [SET SCHEDULE](../chapter-06-gbdialog/keyword-set-schedule.md) - Scheduling
|
||||||
|
- [WEBHOOK](../chapter-06-gbdialog/keyword-webhook.md) - Webhooks
|
||||||
|
- [HTTP Keywords](../chapter-06-gbdialog/keywords-http.md) - API calls
|
||||||
|
- [Platform Comparison](./comparison-matrix.md) - Full comparison
|
||||||
Loading…
Add table
Reference in a new issue