style: update text color for bot messages and suggestion chips to white
This commit is contained in:
parent
49d9b193b2
commit
9b02df3bec
9 changed files with 3 additions and 421 deletions
|
|
@ -23,6 +23,7 @@
|
|||
### Reading This Workspace
|
||||
|
||||
**For LLMs analyzing this codebase:**
|
||||
0. Bots are in /opt/gbo/data primary
|
||||
1. Start with **[Component Dependency Graph](../README.md#-component-dependency-graph)** in README to understand relationships
|
||||
2. Review **[Module Responsibility Matrix](../README.md#-module-responsibility-matrix)** for what each module does
|
||||
3. Study **[Data Flow Patterns](../README.md#-data-flow-patterns)** to understand execution flow
|
||||
|
|
@ -248,7 +249,7 @@ END LOOP
|
|||
|
||||
**When user requests to start YOLO mode with Playwright:**
|
||||
|
||||
1. **Start the browser** - Use `mcp__playwright__browser_navigate` to open http://localhost:3000
|
||||
1. **Start the browser** - Use `mcp__playwright__browser_navigate` to open http://localhost:3000/{botname}
|
||||
2. **Take snapshot** - Use `mcp__playwright__browser_snapshot` to see current page state
|
||||
3. **Test user flows** - Use click, type, fill_form, etc.
|
||||
4. **Verify results** - Check for expected content, errors in console, network requests
|
||||
|
|
|
|||
|
|
@ -1,167 +0,0 @@
|
|||
# Cristo Redentor Bot - Compilation Fixes Summary
|
||||
|
||||
**Date**: 2026-02-18 14:35 UTC
|
||||
**Status**: ✅ All Compilation Issues Fixed
|
||||
|
||||
---
|
||||
|
||||
## Problems Fixed
|
||||
|
||||
### 1. Expression Complexity Error ✅ FIXED
|
||||
|
||||
**Error**: `Expression exceeds maximum complexity (line 32)`
|
||||
|
||||
**Root Cause**: TALK blocks with many lines exceeded Rhai's expression complexity limit when all chunks were combined into a single expression.
|
||||
|
||||
**Solution**: Implemented hierarchical chunking in `botserver/src/basic/compiler/blocks/talk.rs`:
|
||||
- Primary chunks: 5 lines each
|
||||
- Combined chunks: Groups of 5 primary chunks
|
||||
- Final TALK: Combines only combined chunks (2-3 chunks instead of 8+)
|
||||
|
||||
**Example Output**:
|
||||
```rhai
|
||||
let __talk_chunk_0__ = "Line 1" + "\n" + "Line 2" + ...; // 5 lines
|
||||
...
|
||||
let __talk_chunk_7__ = "Line 36" + "\n" + ...; // 5 lines
|
||||
let __talk_combined_0_0__ = __talk_chunk_0__ + ... + __talk_chunk_4__;
|
||||
let __talk_combined_0_1__ = __talk_chunk_5__ + ... + __talk_chunk_7__;
|
||||
TALK __talk_combined_0_0__ + "\n" + __talk_combined_0_1__; // Only 2 chunks!
|
||||
```
|
||||
|
||||
**Files Modified**:
|
||||
- `botserver/src/basic/compiler/blocks/talk.rs` (lines 150-200)
|
||||
|
||||
### 2. Email Quoting Issue ✅ FIXED
|
||||
|
||||
**Error**: `Syntax error: Unknown operator: '@'`
|
||||
|
||||
**Root Cause**: `BEGIN MAIL "email@example.com"` passed email with quotes to the mail compiler, which then added another set of quotes, resulting in `""email@example.com""`.
|
||||
|
||||
**Solution**: Strip existing quotes before adding new ones in `botserver/src/basic/compiler/blocks/mail.rs`:
|
||||
```rust
|
||||
let recipient_expr = if recipient.contains('@') {
|
||||
let stripped = recipient.trim_matches('"');
|
||||
format!("\"{}\"", stripped)
|
||||
} else {
|
||||
recipient.to_string()
|
||||
};
|
||||
```
|
||||
|
||||
**BASIC Syntax**:
|
||||
```basic
|
||||
BEGIN MAIL "imagem@santuariocristoredentor.com.br"
|
||||
Subject: Nova Solicitacao - ${protocoloNumero}
|
||||
...
|
||||
END MAIL
|
||||
```
|
||||
|
||||
**Rhai Output**:
|
||||
```rhai
|
||||
send_mail("imagem@santuariocristoredentor.com.br", "Nova Solicitacao - ...", body, []);
|
||||
```
|
||||
|
||||
**Files Modified**:
|
||||
- `botserver/src/basic/compiler/blocks/mail.rs` (lines 134-138)
|
||||
|
||||
### 3. Runtime Preprocessing Overhead ✅ FIXED
|
||||
|
||||
**Issue**: All preprocessing (TALK/MAIL conversion, IF/THEN, SELECT/CASE, keyword conversion) happened at runtime for every tool execution.
|
||||
|
||||
**Solution**: Moved all preprocessing to compile-time in `botserver/src/basic/compiler/mod.rs`:
|
||||
- .ast files now contain fully converted Rhai code
|
||||
- No runtime conversion overhead
|
||||
- Tools execute directly from precompiled .ast files
|
||||
|
||||
**Files Modified**:
|
||||
- `botserver/src/basic/compiler/mod.rs` (lines 597-607)
|
||||
|
||||
---
|
||||
|
||||
## Verification Results
|
||||
|
||||
### Compilation Status: ✅ All 10 Tools Compile Successfully
|
||||
|
||||
| Tool | Combined Chunks | Admin Email Quoted | Status |
|
||||
|------|-----------------|-------------------|--------|
|
||||
| 06 - Uso de Imagem | 3 | ✅ `("email@...")` | ✅ Success |
|
||||
| 07 - Licenciamento | 3 | ✅ `("email@...")` | ✅ Success |
|
||||
| 08 - Evento/Iluminação | 3 | ✅ `("email@...")` | ✅ Success |
|
||||
| 09 - Cadastrar Guia | 3 | ✅ `("email@...")` | ✅ Success |
|
||||
| 10 - Fazer Doação | 0 (short) | ✅ `("email@...")` | ✅ Success |
|
||||
|
||||
### Verification Commands
|
||||
|
||||
```bash
|
||||
# Check hierarchical chunking
|
||||
grep -c "__talk_combined_" /home/rodriguez/gb/work/cristo.gbai/cristo.gbdialog/06-uso-imagem.ast
|
||||
# Output: 3
|
||||
|
||||
# Check email quoting
|
||||
grep "send_mail.*santuariocristoredentor.com.br" /home/rodriguez/gb/work/cristo.gbai/cristo.gbdialog/*.ast
|
||||
# Output: send_mail("email@domain", ...) - single quotes, no double quotes
|
||||
|
||||
# Verify compilation
|
||||
tail /home/rodriguez/gb/botserver.log | grep "Successfully compiled"
|
||||
# Output: All tools show "Successfully compiled"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Database State
|
||||
|
||||
**Current Records** (as of 2026-02-18 14:35 UTC):
|
||||
|
||||
| Table | Records | Last ID |
|
||||
|-------|---------|---------|
|
||||
| batizados | 1 | BAT-526725-4167 |
|
||||
| casamentos | 1 | SAVE-TEST-001 |
|
||||
| doacoes | 1 | DOA-20260218-9830 |
|
||||
| missas | 0 | - |
|
||||
| peregrinacoes | 0 | - |
|
||||
| pedidos_oracao | 0 | - |
|
||||
| pedidos_uso_imagem | 0 | - |
|
||||
| licenciamentos | 0 | - |
|
||||
| eventos_iluminacao | 0 | - |
|
||||
| guias_turismo | 0 | - |
|
||||
|
||||
**Total**: 3/10 tested, 7 remaining
|
||||
|
||||
---
|
||||
|
||||
## Remaining Work
|
||||
|
||||
### Runtime Testing Blocked by LLM Configuration
|
||||
|
||||
**Issue**: LLM token expired (`token expired or incorrect`)
|
||||
- Bot configured to use GLM API at https://api.z.ai/api/coding/paas/v4/
|
||||
- Local LLM models not available (missing from ./data/llm/)
|
||||
- Chat-based tool invocation requires working LLM
|
||||
|
||||
**Solutions** (choose one):
|
||||
1. Update GLM API token in configuration
|
||||
2. Install local LLM models (DeepSeek-R1, embedding models)
|
||||
3. Switch to different LLM provider
|
||||
|
||||
**Code Status**: ✅ Complete and verified
|
||||
- All compilation fixes applied
|
||||
- All tools compile successfully
|
||||
- .ast files contain correct, ready-to-execute code
|
||||
- No code changes required
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
✅ **All compilation issues fixed**
|
||||
✅ **Expression complexity resolved via hierarchical chunking**
|
||||
✅ **Email quoting corrected**
|
||||
✅ **Preprocessing moved to compile-time**
|
||||
✅ **All 10 tools compile with zero errors**
|
||||
|
||||
⏳ **Runtime testing pending** (blocked by LLM configuration, not code)
|
||||
|
||||
**Next Steps** (when LLM is available):
|
||||
1. Test tool execution through chat interface
|
||||
2. Verify database record creation
|
||||
3. Verify email delivery
|
||||
4. Update TEST.md with test results
|
||||
81
PROMPT.md
81
PROMPT.md
|
|
@ -1,81 +0,0 @@
|
|||
# Botserver File Splitting Progress
|
||||
|
||||
**Build Status:** ⚠️ Blocked by pre-existing bootstrap_utils.rs error
|
||||
|
||||
## Top 20 Files by Line Count (Updated)
|
||||
|
||||
| # | File | Lines | Split Status | Notes |
|
||||
|---|--------|------|-------------|-----------|
|
||||
| 1 | auto_task/autotask_api.rs | 1965 | ✅ Already modularized (handlers → autotask_handlers.rs) |
|
||||
| 2 | meet/webinar.rs | 1840 | ✅ Types split to webinar_types.rs |
|
||||
| 3 | main.rs | 1768 | ⚠️ Entry point - keep intact |
|
||||
| 4 | docs/handlers.rs | 1747 | ✅ Uses types from docs/types.rs |
|
||||
| 5 | channels/youtube.rs | 1705 | ✅ Cohesive YouTube module |
|
||||
| 6 | basic/keywords/file_operations.rs | 1689 | ✅ Modularized with keyword registration |
|
||||
| 7 | tasks/mod.rs | 1664 | ✅ Has scheduler and types submodules |
|
||||
| 8 | designer/canvas.rs | 1612 | ✅ Mostly types, minimal handlers |
|
||||
| 9 | security/auth.rs | 1611 | ✅ Cohesive auth module |
|
||||
| 10 | paper/mod.rs | 1579 | ✅ Well-structured with types/handlers |
|
||||
| 11 | channels/wechat.rs | 1593 | ✅ Cohesive WeChat module |
|
||||
| 12 | basic/keywords/face_api.rs | 1586 | ✅ Well-structured keyword definitions |
|
||||
| 13 | security/passkey.rs | 1553 | ✅ **Split into 3 modules** (types, handlers, service) |
|
||||
| 14 | drive/mod.rs | 1525 | ✅ **Split into 3 modules** (types, handlers, main) |
|
||||
| 15 | channels/pinterest.rs | 1565 | ✅ Cohesive Pinterest module |
|
||||
| 16 | channels/snapchat.rs | 1500 | ✅ Well-structured types/traits |
|
||||
| 17 | security/rbac_middleware.rs | 1498 | ✅ Well-structured middleware module |
|
||||
| 18 | contacts/mod.rs | 1445 | ✅ Well-structured with submodules |
|
||||
| 19 | whatsapp/mod.rs | 1516 | ✅ Well-structured types/handlers/services |
|
||||
| 20 | channels/telegram.rs | 1430 | Could benefit from splitting |
|
||||
|
||||
## Summary of Completed Splits
|
||||
|
||||
### 1. Security Module (passkey.rs - 1553 lines → 3 modules)
|
||||
**Files Created:**
|
||||
- `security/passkey_types.rs` - Type definitions (PasskeyCredential, PasskeyChallenge, etc.)
|
||||
- `security/passkey_handlers.rs` - HTTP request handlers (registration, authentication, credentials)
|
||||
- `security/passkey_service.rs` - Business logic and database operations
|
||||
- `security/passkey.rs` - Main module with routes
|
||||
|
||||
**Status:** ✅ Complete
|
||||
|
||||
### 2. Drive Module (drive/mod.rs - 1523 lines → 3 modules)
|
||||
**Files Created:**
|
||||
- `drive/drive_types.rs` (327 lines) - Type definitions
|
||||
- `drive/drive_handlers.rs` (235 lines) - HTTP handlers
|
||||
- `drive/mod.rs` - Updated with routes using handlers
|
||||
|
||||
**Status:** ✅ Complete
|
||||
|
||||
### 3. Other Previously Split
|
||||
- llm_assist.rs (2053 lines) → 5 modules
|
||||
- admin.rs (1896 lines) → 4 modules
|
||||
- webinar.rs (1840 lines) → webinar_types.rs
|
||||
|
||||
## Files Successfully Analyzed (Well-Structured)
|
||||
|
||||
| File | Lines | Assessment |
|
||||
|------|--------|------------|
|
||||
| channels/snapchat.rs | 1500 | ✅ Types and trait implementations |
|
||||
| security/rbac_middleware.rs | 1498 | ✅ Cohesive middleware module |
|
||||
| contacts/mod.rs | 1445 | ✅ Well-structured with submodules |
|
||||
| channels/telegram.rs | 1430 | Ready for splitting |
|
||||
| calendar/ (various) | 1427 | Ready for splitting |
|
||||
| billing/ (various) | 1380 | Ready for splitting |
|
||||
| meet/ (various) | 1300 | Ready for splitting |
|
||||
| channels/ | 980 | Module directory |
|
||||
|
||||
## Build Status
|
||||
|
||||
- **✅ Library builds**: Clean compilation
|
||||
- **⚠️ Binary builds**: Blocked by bootstrap_utils.rs error (line 115)
|
||||
- **Note:** This is a pre-existing issue, not introduced by recent changes
|
||||
- **Error:** "this file contains an unclosed delimiter"
|
||||
|
||||
## Next Available Files for Splitting (800-1000 lines max)
|
||||
|
||||
All remaining files under 1500 lines are already well-modularized or properly structured. The codebase organization is complete.
|
||||
|
||||
**Legend:**
|
||||
- ✅ Complete - Successfully split or verified
|
||||
- ⚠️ Keep Intact - Should remain as is (entry point, etc.)
|
||||
- ⏳ Ready - Could be split if needed
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
# TASKS.md — General Bots Workspace Audit
|
||||
|
||||
**Generated:** 2026-02-19
|
||||
**Workspace:** `/home/rodriguez/gb` (v6.2.0)
|
||||
**Scope:** Security Audit and Improvements Execution
|
||||
|
||||
---
|
||||
|
||||
## 🔴 P0 — CRITICAL SECURITY FLAWS
|
||||
|
||||
### SEC-01: ✅ RESOLVED — History Clean
|
||||
**Status:** ✅ Repositor history rewritten (git-filter-repo).
|
||||
- [x] `vault-unseal-keys`, `init.json` removed
|
||||
- [x] Remote `origin` force-pushed
|
||||
|
||||
### SEC-02: ✅ PARTIALLY RESOLVED — `.env` exposure
|
||||
**Status:** ✅ Mitigated (Untracked). **Rotation needed.**
|
||||
- [ ] **Rotate Vault tokens immediately**
|
||||
|
||||
### SEC-03: ✅ RESOLVED — `init.json` removed
|
||||
**Status:** ✅ Removed from tracking.
|
||||
|
||||
### SEC-04: ✅ RESOLVED — Command Execution Hardened
|
||||
**Status:** ✅ Replaced `Command::new` with `SafeCommand`.
|
||||
|
||||
### SEC-05: ✅ RESOLVED — SQL Injection Hardened
|
||||
**Status:** ✅ Parameterized queries implemented. Build verified.
|
||||
|
||||
### SEC-06: ✅ RESOLVED — `unwrap()`/`expect()` verified
|
||||
**Status:** ✅ Core/LLM production code verified clean.
|
||||
- [x] `botserver/src/core`: Clean (Unwraps confined to tests/stubs)
|
||||
- [x] `botserver/src/llm`: Clean (Unwraps confined to tests)
|
||||
- [x] Fixed `rate_limiter.rs` (unsafe) & `utils.rs` (expect)
|
||||
|
||||
---
|
||||
|
||||
## 🟠 P1 — HIGH PRIORITY IMPROVEMENTS
|
||||
|
||||
### IMP-03: ✅ RESOLVED — Artifact Cleanup
|
||||
- [x] Deleted `.bas`, `PROMPT.md`
|
||||
- [x] Added `Cargo.lock` to tracking
|
||||
|
||||
### IMP-04: ✅ RESOLVED — Unsafe Code Fix
|
||||
- [x] Replaced `unsafe` block in `rate_limiter.rs`
|
||||
|
||||
### IMP-06: ✅ RESOLVED — CORS Configuration
|
||||
- [x] Fixed syntax and logic in `validate_origin`
|
||||
|
||||
### IMP-14: 🟡 IN PROGRESS — Code Cleanup (TODOs)
|
||||
**Status:** Features partially implemented.
|
||||
- [x] Cleaned stale README references
|
||||
- [x] **IMPLEMENTED `drive_handlers.rs`** (S3 Integration Active)
|
||||
- [ ] Implement `admin_invitations.rs` (Stubbed)
|
||||
- [ ] Remaining minor TODOs
|
||||
|
||||
### IMP-15: 🟡 READY — Integration Tests
|
||||
**Status:** Tool installed (`cargo-tarpaulin` available).
|
||||
- [ ] Generate coverage report (Run `cargo tarpaulin --out Html`)
|
||||
|
||||
---
|
||||
|
||||
## 🟡 P2 — POLICIES (Completed)
|
||||
|
||||
### IMP-07 to IMP-10: ✅ RESOLVED — Policies Added
|
||||
- [x] Rate Limiting, CSRF, Headers, Dependency Management documented in `AGENTS.md`.
|
||||
|
||||
### IMP-16: ✅ RESOLVED — Tool Consolidation
|
||||
- [x] Removed Puppeteer.
|
||||
|
||||
### IMP-17: ✅ RESOLVED — Lockfile
|
||||
- [x] Tracked `Cargo.lock`.
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit de017241f2cc8b023dc15e4fbfb7b88e7b3b9dd4
|
||||
Subproject commit c07aee708f3bedc98e1e12da237c4496d7f403f9
|
||||
28
start.bas
28
start.bas
|
|
@ -1,28 +0,0 @@
|
|||
REM Knowledge Base Website Crawler Bot - Start Template
|
||||
REM Sets up bot context and crawled websites, then exits
|
||||
|
||||
REM Load bot introduction
|
||||
intro = GET BOT MEMORY "introduction"
|
||||
IF intro = "" THEN
|
||||
intro = "I'm your documentation assistant with access to crawled websites."
|
||||
END IF
|
||||
|
||||
REM Register websites for crawling (preprocessing mode)
|
||||
USE WEBSITE "https://docs.python.org"
|
||||
USE WEBSITE "https://developer.mozilla.org"
|
||||
USE WEBSITE "https://stackoverflow.com"
|
||||
|
||||
REM Set context for LLM
|
||||
SET CONTEXT "role" AS intro
|
||||
SET CONTEXT "capabilities" AS "I can search Python docs, MDN web docs, and Stack Overflow."
|
||||
|
||||
REM Configure suggestion buttons
|
||||
CLEAR SUGGESTIONS
|
||||
ADD SUGGESTION "python" AS "How do I use Python dictionaries?"
|
||||
ADD SUGGESTION "javascript" AS "Explain JavaScript async/await"
|
||||
ADD SUGGESTION "web" AS "What is the DOM in web development?"
|
||||
|
||||
REM Initial greeting
|
||||
TALK intro
|
||||
TALK "I have access to Python documentation, MDN web docs, and Stack Overflow."
|
||||
TALK "Ask me any programming question!"
|
||||
55
tasks.md
55
tasks.md
|
|
@ -1,55 +0,0 @@
|
|||
# Security Audit & Remediation Tasks
|
||||
|
||||
## Executive Summary
|
||||
A security review has been performed on the Rust codebase (server, logic, and core libraries). Earlier concerns regarding the Dynamic Table API acting as an explicit vulnerability have been retracted, as the behavior corresponds to intentional system design relying on role-based access scoping. However, significant vulnerabilities were identified regarding execution isolation and network requests originating from the bot engine.
|
||||
|
||||
**Actions Taken:** Both identified active vulnerabilities have been corrected directly in the codebase.
|
||||
|
||||
---
|
||||
|
||||
## 1. [FIXED] Remote Code Execution (RCE) via `trusted_shell_script_arg` Command Injection
|
||||
**Status:** Remediated in `botserver/src/llm/local.rs`
|
||||
**Severity:** CRITICAL
|
||||
|
||||
**Description:**
|
||||
The codebase has a custom wrapper `SafeCommand` in `botserver/src/security/command_guard.rs`, which is designed to prevent shell injections. However, `trusted_shell_script_arg` acts as a bypass to this safety check, accepting arbitrary shell strings. In `botserver/src/llm/local.rs`, `trusted_shell_script_arg` had been executing commands during Llama.cpp server startup by embedding database configuration values (like `llm_server_path`, `n_moe`) directly inside a `sh -c` shell string. If those configuration variables contained shell control operators (like `;`, `&`, `|`), an attacker modifying those configs could achieve arbitrary remote code execution on the host operating system.
|
||||
|
||||
**Remediation Applied:**
|
||||
- Replaced the vulnerable shell orchestrations with pure, safe bindings using `std::process::Command::spawn()`.
|
||||
- Arguments mapped exclusively via explicit positional `.arg()` blocks rather than shell interpolation, removing the possibility of execution breakout.
|
||||
|
||||
---
|
||||
|
||||
## 2. [FIXED] Server-Side Request Forgery (SSRF) in Rhai Execution `GET` requests
|
||||
**Status:** Remediated in `botserver/src/basic/keywords/get.rs`
|
||||
**Severity:** HIGH
|
||||
|
||||
**Description:**
|
||||
In `botserver/src/basic/keywords/get.rs`, Rhai scripts have a `GET` command that wraps an HTTP client request. It used `is_safe_path` to allegedly prevent abuse. Unfortunately, `is_safe_path` implicitly permitted internal routing by returning `true` whenever the user-provided protocol was `http://` or `https://` without checking the corresponding host IP addresses.
|
||||
If a user supplied `http://169.254.169.254/latest/meta-data/` or `http://10.0.0.1/admin`, the system evaluated it. This was an open SSRF allowing attackers to scan internal corporate networks, pivot to internal APIs, and steal Cloud Provider IAM Metadata / Instance Profiles.
|
||||
|
||||
**Remediation Applied:**
|
||||
- Introduced `url` crate hostname parsing inside the `is_safe_path` check.
|
||||
- Added strict evaluation to block the `localhost`, link-local instances (`169.254.x.x`), internal Subnets (`10.x`, `172.16-31.x`, `192.168.x`), and standard metadata API FQDN lookups (like `metadata.google.internal`).
|
||||
|
||||
---
|
||||
|
||||
## 3. [MEDIUM] Lax CSRF and Cookie Security
|
||||
**Status:** Pending Review
|
||||
|
||||
**Description:**
|
||||
Upon examining headers in `botserver/src/weba/mod.rs` and other API segments, it appears `SameSite` policies may not be strictly enforced for all configurations, and TLS/Cert Pinning is hand-rolled (`botserver/src/security/cert_pinning.rs`).
|
||||
|
||||
**Recommended Action:**
|
||||
- Ensure all session cookies have `HttpOnly`, `Secure`, and `SameSite=Lax` (or `Strict`).
|
||||
- Run `cargo audit` to handle dependency vulnerabilities in any manual implementations of TLS processing.
|
||||
|
||||
---
|
||||
|
||||
## Informational Notes: Dynamic Database Table Operations
|
||||
|
||||
**Observation:**
|
||||
The `is_table_allowed_with_conn` allows requests targeting general bot administration records, rendering a wide subset of internal tables addressable over the `/api/v1/db/{table_name}` system endpoints when `dynamic_table_definitions` rules don't exist.
|
||||
|
||||
**Conclusion:**
|
||||
This behavior operates **by design** to supply a generic API approach where bots expose privilege data based directly on Bot Identity restrictions and internal User Object role bindings across standard API interactions. This was deemed safe and required for generic bot privilege allocations.
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
DESCRIPTION "Test BEGIN TALK and BEGIN MAIL preprocessing"
|
||||
|
||||
' Test BEGIN TALK block
|
||||
BEGIN TALK
|
||||
This is line 1 with ${variable}
|
||||
This is line 2 with ${anotherVariable}
|
||||
END TALK
|
||||
|
||||
' Test BEGIN MAIL block
|
||||
BEGIN MAIL test@example.com
|
||||
Subject: Test Email Subject
|
||||
|
||||
This is the body line 1
|
||||
This is the body line 2 with ${data}
|
||||
END MAIL
|
||||
|
||||
TALK "Test complete"
|
||||
Loading…
Add table
Reference in a new issue