Skip to main content

Overview

System settings control the bot’s personality, behavior, and operational modes. These settings are stored in the settings table and can be configured through the admin dashboard or directly in the database.

Settings Table Schema

database/schema.sql
CREATE TABLE IF NOT EXISTS settings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    setting_key VARCHAR(100) NOT NULL UNIQUE,
    setting_type ENUM('text', 'boolean', 'json') DEFAULT 'text',
    setting_value TEXT NOT NULL,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

Bot Mode Configuration

The bot operates in two modes:
Conversational intelligence with RAG
UPDATE settings 
SET setting_value = 'ai' 
WHERE setting_key = 'bot_mode';
Features:
  • Natural language understanding
  • RAG-powered responses from knowledge base
  • GPT-based conversation
  • Audio transcription with Whisper
  • Calendar intent detection
  • Context-aware responses
webhook.php
$botModeRow = $db->fetchOne(
    "SELECT setting_value FROM settings WHERE setting_key = 'bot_mode'",
    []
);
$botMode = $botModeRow['setting_value'] ?? 'ai';

System Prompt

The system prompt defines the bot’s personality and capabilities:
database/schema.sql
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('system_prompt', 'Eres un asistente virtual inteligente y profesional especializado en atención al cliente.

CAPACIDADES PRINCIPALES:

1. Información General: Responde preguntas sobre servicios, productos y consultas generales usando tu base de conocimientos.

2. Base de Conocimientos RAG: Usa documentos cargados en el sistema para dar respuestas precisas y actualizadas.

TONO Y ESTILO:

Profesional pero cercano, respuestas concisas y directas, siempre confirma las acciones realizadas.', 'text');

Loading System Prompt

webhook.php
$systemPromptRow = $db->fetchOne(
    "SELECT setting_value FROM settings WHERE setting_key = 'system_prompt'",
    []
);
$systemPrompt = $systemPromptRow['setting_value'] ?? 'Eres un asistente virtual útil y amigable.';

Calendar Prompt Addition

When calendar is enabled, calendar capabilities are added to the system prompt:
webhook.php
$isCalendarEnabled = $calendarConfig['enabled'];

if ($isCalendarEnabled && file_exists(__DIR__ . '/prompts/calendar_prompt.txt')) {
    $calendarPrompt = file_get_contents(__DIR__ . '/prompts/calendar_prompt.txt');
    $systemPrompt .= "\n\n" . $calendarPrompt;
}
Create prompts/calendar_prompt.txt to add calendar-specific instructions to the AI.

Conversation Context

Context Messages Count

Control how many previous messages are included as context:
UPDATE settings 
SET setting_value = '5' 
WHERE setting_key = 'context_messages_count';
webhook.php
$contextCountRow = $db->fetchOne(
    "SELECT setting_value FROM settings WHERE setting_key = 'context_messages_count'",
    []
);
$contextMessagesCount = isset($contextCountRow['setting_value']) 
    ? intval($contextCountRow['setting_value']) 
    : 5;

if ($contextMessagesCount > 0) {
    $historyMessages = $db->fetchAll(
        "SELECT sender_type, message_text FROM messages 
         WHERE conversation_id = :conversation_id 
         ORDER BY created_at DESC 
         LIMIT " . intval($contextMessagesCount),
        [':conversation_id' => $conversation['id']]
    );
    
    $conversationHistory = array_map(function($msg) {
        return [
            'sender' => $msg['sender_type'],
            'message_text' => $msg['message_text']
        ];
    }, array_reverse($historyMessages));
}
More context messages improve response quality but increase OpenAI costs. Recommended: 3-7 messages.

Welcome and Fallback Messages

Bot Greeting

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('bot_greeting', 'Hola! Soy un asistente virtual. ¿En qué puedo ayudarte?', 'text')
ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value);
Alternative keys:
  • welcome_message: Alternative name for the same purpose
  • bot_name: Display name for the bot

Fallback Message

Shown when the bot can’t find relevant information:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('bot_fallback_message', 'Lo siento, no encontré información relevante. Un operador humano te atenderá pronto.', 'text'),
('fallback_message', 'Lo siento, no encontré información relevante. Un operador humano te atenderá pronto.', 'text')
ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value);
webhook.php
$fallbackMessage = 'Lo siento, no encontré información relevante sobre tu consulta. Un operador te atenderá pronto.';
$whatsapp->sendMessage($messageData['from'], $fallbackMessage);

Human Handoff Configuration

Enable Human Handoff

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('human_handoff_enabled', 'true', 'boolean')
ON DUPLICATE KEY UPDATE setting_value = 'true';

Trigger Keywords

Keywords that trigger human handoff:
webhook.php
$humanKeywords = [
    'hablar con humano', 
    'hablar con una persona', 
    'hablar con operador', 
    'quiero un humano', 
    'atención humana', 
    'operador', 
    'agente humano',
    'hablar con alguien', 
    'persona real', 
    'representante'
];

$messageLower = mb_strtolower($messageData['text']);
$isRequestingHuman = false;

foreach ($humanKeywords as $keyword) {
    if (strpos($messageLower, $keyword) !== false) {
        $isRequestingHuman = true;
        break;
    }
}

if ($isRequestingHuman) {
    $humanMessage = 'Enseguida te comunico con alguien de nuestro equipo.';
    $whatsapp->sendMessage($messageData['from'], $humanMessage);
    
    $conversationService->updateConversationStatus($conversation['id'], 'pending_human');
    $db->query(
        'UPDATE conversations SET ai_enabled = 0 WHERE id = :id',
        [':id' => $conversation['id']]
    );
}
Conversations marked as pending_human will not receive AI responses until re-enabled.

Business Information

Business Name

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('business_name', 'Mi Negocio', 'text')
ON DUPLICATE KEY UPDATE setting_value = 'Mi Negocio';

Timezone

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('timezone', 'America/Bogota', 'text')
ON DUPLICATE KEY UPDATE setting_value = 'America/Bogota';
config/config.php
'app' => [
    'base_url' => getenv('APP_BASE_URL') ?: 'http://localhost',
    'timezone' => 'America/Bogota',
    'debug' => getenv('APP_DEBUG') === 'true'
]

RAG Configuration

Confidence Threshold

Minimum similarity score for using RAG results:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('confidence_threshold', '0.7', 'text')
ON DUPLICATE KEY UPDATE setting_value = '0.7';
webhook.php
if ($result['response'] && $result['confidence'] >= Config::get('rag.similarity_threshold')) {
    $whatsapp->sendMessage($conversation['phone_number'], $result['response']);
}
Range: 0.0 to 1.0
  • 0.6-0.7: Relaxed matching (more results, less precision)
  • 0.7-0.8: Balanced (recommended)
  • 0.8-0.9: Strict matching (fewer results, higher precision)

Max Results

Number of similar chunks to retrieve:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('max_results', '5', 'text')
ON DUPLICATE KEY UPDATE setting_value = '5';

Chunk Size

Characters per document chunk:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('chunk_size', '1000', 'text')
ON DUPLICATE KEY UPDATE setting_value = '1000';

Auto-Reply Configuration

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('auto_reply', 'true', 'boolean')
ON DUPLICATE KEY UPDATE setting_value = 'true';
When disabled, the bot will receive and store messages but not send automatic responses.

OpenAI Status Tracking

The system tracks OpenAI API status:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('openai_status', 'active', 'text'),
('openai_last_error', '', 'text'),
('openai_error_timestamp', '', 'text')
ON DUPLICATE KEY UPDATE setting_key = setting_key;

Insufficient Funds Detection

webhook.php
function handleInsufficientFunds($db, $e) {
    if (strpos($e->getMessage(), 'INSUFFICIENT_FUNDS') !== false) {
        $db->query(
            "INSERT INTO settings (setting_key, setting_value) 
             VALUES ('openai_status', 'insufficient_funds') 
             ON DUPLICATE KEY UPDATE setting_value = 'insufficient_funds'",
            []
        );
        $db->query(
            "INSERT INTO settings (setting_key, setting_value) 
             VALUES ('openai_error_timestamp', NOW()) 
             ON DUPLICATE KEY UPDATE setting_value = NOW()",
            []
        );
        return true;
    }
    return false;
}

try {
    $result = $rag->generateResponse(...);
} catch (\Exception $e) {
    handleInsufficientFunds($db, $e);
}

Timeout Configuration

INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('timeout', '30', 'text')
ON DUPLICATE KEY UPDATE setting_value = '30';
Controls HTTP request timeout in seconds for external API calls.

Temperature Setting

Controls AI response creativity:
INSERT INTO settings (setting_key, setting_value, setting_type) VALUES
('temperature', '0.7', 'text')
ON DUPLICATE KEY UPDATE setting_value = '0.7';
See OpenAI Configuration for details on temperature values.

All Available Settings

Complete list of system settings:
Setting KeyTypeDefaultDescription
bot_modetextaiBot operation mode: ai or classic
bot_nametextWhatsApp BotDisplay name for the bot
bot_greetingtextHola! Soy un asistente virtual...Initial greeting message
welcome_messagetextSame as greetingAlternative welcome message
bot_fallback_messagetextLo siento, no encontré...Fallback when no answer found
fallback_messagetextSame as aboveAlternative fallback message
system_prompttextLong promptAI personality and instructions
human_handoff_enabledbooleantrueAllow human takeover
context_messages_counttext5Number of previous messages as context
business_nametextMi NegocioBusiness display name
timezonetextAmerica/BogotaSystem timezone
calendar_enabledbooleanfalseEnable/disable calendar features
confidence_thresholdtext0.7RAG similarity threshold (0.0-1.0)
max_resultstext5Max RAG results to retrieve
chunk_sizetext1000Document chunk size in characters
auto_replybooleantrueSend automatic responses
temperaturetext0.7OpenAI temperature (0.0-2.0)
timeouttext30API timeout in seconds
openai_statustextactiveOpenAI API status tracking
openai_last_errortextLast OpenAI error message
openai_error_timestamptextWhen the last error occurred

Getting Settings in Code

Using CredentialService

$credentialService = new CredentialService($db, $encryption);
$value = $credentialService->getSetting('bot_name', 'Default Bot');

Direct Database Query

$row = $db->fetchOne(
    "SELECT setting_value FROM settings WHERE setting_key = :key",
    [':key' => 'bot_mode']
);
$botMode = $row['setting_value'] ?? 'ai';

Batch Settings Retrieval

$settings = $db->fetchAll(
    "SELECT setting_key, setting_value FROM settings",
    []
);

$settingsMap = [];
foreach ($settings as $setting) {
    $settingsMap[$setting['setting_key']] = $setting['setting_value'];
}

$botMode = $settingsMap['bot_mode'] ?? 'ai';
$greeting = $settingsMap['bot_greeting'] ?? 'Hello!';

Best Practices

Important considerations
  • Test changes in a development environment first
  • Back up settings before making bulk changes
  • Document custom system prompts
  • Monitor OpenAI token usage when adjusting context count
  • Keep timezone consistent across all calendar settings
Optimization tips
  • Use lower context_messages_count (3-5) to reduce costs
  • Set appropriate confidence_threshold for your knowledge base
  • Adjust temperature based on desired response style
  • Enable auto_reply only when bot is production-ready
  • Use Classic mode for structured flows, AI mode for flexibility

Next Steps

WhatsApp Setup

Configure WhatsApp Business API

OpenAI Setup

Set up AI capabilities

Build docs developers (and LLMs) love