Skip to main content

Overview

This guide covers common issues you may encounter when deploying or running the WhatsApp RAG Bot, with detailed solutions.

Webhook Problems

Webhook Verification Fails

Possible causes:
  • Verify token mismatch
  • Server not responding
  • SSL certificate issues
  • Wrong callback URL
Solution:
1

Check verify token

Ensure tokens match exactly (case-sensitive):
.env
WHATSAPP_VERIFY_TOKEN=my_custom_token_123
Must match what you entered in Meta Developer Console.
2

Test verification manually

curl "https://yourdomain.com/whatsapp/webhook?hub.mode=subscribe&hub.verify_token=my_custom_token_123&hub.challenge=test_challenge"

# Should return: test_challenge
3

Check webhook.php logic

From webhook.php:84-103:
if ($mode === 'subscribe' && $token === $verifyToken) {
    echo $challenge;
    http_response_code(200);
    exit;
}
Ensure this code is reachable and not blocked.
Cause: Webhook signature verification failingFrom webhook.php:115-124:
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $appSecret);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Unauthorized');
}
Solution:
1

Verify app secret

Check .env has correct WHATSAPP_APP_SECRET from Meta Developer Console:
.env
WHATSAPP_APP_SECRET=abc123def456...
2

Check request headers

Log the incoming signature:
error_log('Received signature: ' . ($_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? 'NONE'));
error_log('Expected signature: ' . $expected);
3

Temporary: Skip validation for testing

Only for debugging, never in production!
Comment out validation temporarily:
// if (!hash_equals($expected, $signature)) {
//     http_response_code(401);
//     exit('Unauthorized');
// }
Possible causes:
  • OpenAI API issues
  • Database connection problems
  • AI disabled for conversation
  • Conversation in ‘pending_human’ status
Solution:
1

Check logs

tail -100 logs/$(date +%Y-%m-%d).log
Look for:
  • [ERROR] entries
  • OpenAI API errors
  • Database connection errors
2

Verify conversation status

SELECT phone_number, status, ai_enabled 
FROM conversations 
WHERE phone_number = '1234567890';
If status = 'pending_human' or ai_enabled = 0:
UPDATE conversations 
SET status = 'active', ai_enabled = 1 
WHERE phone_number = '1234567890';
3

Test OpenAI connection

curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

API Issues

OpenAI API Errors

Symptom: Bot stops responding, logs show INSUFFICIENT_FUNDSFrom webhook.php:22-37, the bot automatically detects and tracks this:
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'",
            []
        );
        return true;
    }
    return false;
}
Solution:
1

Check OpenAI account

  1. Log in to platform.openai.com
  2. Go to Settings > Billing
  3. Verify account has credits
  4. Add payment method if needed
2

Reset status in database

After adding credits:
UPDATE settings 
SET setting_value = 'active' 
WHERE setting_key = 'openai_status';
3

Monitor usage

Check OpenAI usage:
SELECT COUNT(*) as message_count 
FROM messages 
WHERE sender_type = 'bot' 
  AND created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
Symptom: 401 Unauthorized from OpenAISolution:
1

Verify API key format

.env
# Correct format
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxx

# NOT (old format)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxx
2

Regenerate key if needed

  1. Go to platform.openai.com/api-keys
  2. Create new secret key
  3. Update .env immediately
3

Test manually

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "test"}],
    "max_tokens": 10
  }'
Symptom: 429 Too Many RequestsSolution:
1

Check rate limits

OpenAI rate limits vary by tier:
  • Free tier: Very limited
  • Tier 1: 3,500 RPM (requests per minute)
  • Tier 2+: Higher limits
2

Implement request queuing

Add delays between requests:
// In OpenAIService.php
sleep(1); // Wait 1 second between requests
3

Use embedding cache

The bot already caches embeddings in query_embedding_cache table:
SELECT COUNT(*) FROM query_embedding_cache;
SELECT AVG(hit_count) as avg_reuse FROM query_embedding_cache;

WhatsApp API Errors

Symptom: Bot can’t send messages, 190 error from WhatsApp APISolution:
1

Regenerate access token

  1. Go to developers.facebook.com
  2. Open your WhatsApp app
  3. Go to WhatsApp > API Setup
  4. Generate new token
  5. Update .env:
WHATSAPP_ACCESS_TOKEN=EAAxxxxxxxxxxxxx
2

Check token expiration

Temporary tokens expire in 24 hours. Use system user token for permanent access.
Symptom: First message to user fails with template errorNote: This bot sends text messages, not template messages. Ensure you’re not triggering template requirements.Solution:
  • User must message you first (user-initiated conversation)
  • Or use approved message templates for business-initiated messages

Database Issues

Connection Problems

Symptom: SQLSTATE[HY000] [2002] Connection refusedSolution:
1

Verify MySQL is running

# Check status
sudo systemctl status mysql
# or
mysqladmin ping

# Start if stopped
sudo systemctl start mysql
2

Check credentials

.env
DB_HOST=localhost
DB_PORT=3306
DB_NAME=whatsapp_rag_bot
DB_USER=correct_user
DB_PASSWORD=correct_password
3

Test connection manually

mysql -h localhost -u your_user -p whatsapp_rag_bot
4

Check MySQL user permissions

SHOW GRANTS FOR 'your_user'@'localhost';

-- If needed, grant permissions:
GRANT ALL PRIVILEGES ON whatsapp_rag_bot.* TO 'your_user'@'localhost';
FLUSH PRIVILEGES;
Symptom: SQLSTATE[HY000] [1045] Access deniedSolution:
-- Create user with correct permissions
CREATE USER 'whatsapp_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON whatsapp_rag_bot.* TO 'whatsapp_user'@'localhost';
FLUSH PRIVILEGES;
Update .env with these credentials.
Symptom: Table 'whatsapp_rag_bot.documents' doesn't existSolution:
# Re-import schema
mysql -u root -p whatsapp_rag_bot < database/schema.sql

# Verify tables
mysql -u root -p whatsapp_rag_bot -e "SHOW TABLES;"

Performance Issues

Symptom: Bot responses are slow, especially with many documentsSolution:
1

Add missing indexes

-- Check existing indexes
SHOW INDEX FROM vectors;

-- Add if missing
CREATE INDEX idx_document_id ON vectors(document_id);
CREATE INDEX idx_created_at ON vectors(created_at);
2

Optimize tables

OPTIMIZE TABLE vectors;
OPTIMIZE TABLE messages;
OPTIMIZE TABLE documents;
3

Monitor query performance

-- Enable slow query log
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;

-- Check slow queries
SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;

File Upload Issues

Symptom: Can’t upload PDF/DOCX files through admin panelSolution:
1

Check file size limits

From .htaccess:
php_value upload_max_filesize 10M
php_value post_max_size 10M
Also check php.ini:
upload_max_filesize = 10M
post_max_size = 10M
2

Verify directory permissions

chmod 755 uploads/
chown www-data:www-data uploads/

# Test write access
sudo -u www-data touch uploads/test.txt
3

Check disk space

df -h /path/to/uploads
Symptom: Voice messages not transcribedFrom webhook.php:225-259, audio processing:
$audioContent = $whatsapp->downloadMedia($messageData['audio_id']);
// ... save to uploads/audios/ ...
$transcription = $openai->transcribeAudio($audioContent, 'audio.ogg');
Solution:
1

Check uploads/audios/ exists

mkdir -p uploads/audios
chmod 755 uploads/audios
2

Verify OpenAI Whisper access

curl https://api.openai.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: multipart/form-data" \
  -F model="whisper-1" \
  -F file="@test.ogg"
3

Check audio format support

WhatsApp sends OGG Opus format. Ensure OpenAI accepts it.

Logging and Debugging

Enable Debug Mode

1

Update .env

.env
APP_DEBUG=true
2

Check PHP error logs

# Find PHP error log location
php -i | grep error_log

# View errors
tail -f /var/log/php_errors.log
3

Application logs

From src/Core/Logger.php, logs are written to logs/YYYY-MM-DD.log:
# View today's log
tail -100 logs/$(date +%Y-%m-%d).log

# Follow in real-time
tail -f logs/$(date +%Y-%m-%d).log

# Search for errors
grep ERROR logs/*.log

# Count errors by date
for file in logs/*.log; do
  echo "$file: $(grep -c ERROR $file)"
done

Common Log Messages

[2026-03-06 14:30:22] [INFO] Webhook received {"type":"text","from_hash":"abc123def456"}
[2026-03-06 14:30:23] [INFO] Calendar intent detection {"intent":"schedule","confidence":0.85}
[2026-03-06 14:30:24] [INFO] RAG response generated {"confidence":0.92,"sources":3}

Add Custom Logging

use App\Core\Logger;

$logger = new Logger(__DIR__ . '/logs');

// Log levels
$logger->info('User action', ['user_id' => 123]);
$logger->warning('Unusual activity', ['ip' => $_SERVER['REMOTE_ADDR']]);
$logger->error('Critical failure', ['error' => $e->getMessage()]);
$logger->debug('Variable dump', ['data' => $someVariable]);

Permission Errors

Symptom: No log files created, or permission denied errorsSolution:
# Fix ownership
chown -R www-data:www-data logs/

# Fix permissions
chmod 755 logs/

# Verify
ls -la logs/
Symptom: Can access .env directly, or rewrites don’t workSolution:
1

Verify mod_rewrite enabled

# Apache
a2enmod rewrite
sudo systemctl restart apache2

# Check
apache2ctl -M | grep rewrite
2

Check AllowOverride

In Apache virtual host or main config:
<Directory /var/www/html>
    AllowOverride All
</Directory>

Classic Bot Mode Issues

Symptom: In classic mode, bot doesn’t follow flow nodesSolution:
1

Verify bot mode setting

SELECT setting_value FROM settings WHERE setting_key = 'bot_mode';
-- Should return: 'classic'

-- If not:
UPDATE settings SET setting_value = 'classic' WHERE setting_key = 'bot_mode';
2

Check flow nodes exist

SELECT COUNT(*) FROM flow_nodes WHERE is_active = 1;
-- Should be > 0

-- View root node:
SELECT * FROM flow_nodes WHERE is_root = 1 LIMIT 1;
3

Test flow matching

-- Check trigger keywords
SELECT name, trigger_keywords FROM flow_nodes WHERE is_active = 1;

Calendar Integration Issues

Symptom: Can’t create appointmentsSolution:
1

Verify calendar is enabled

SELECT setting_value FROM settings WHERE setting_key = 'calendar_enabled';
-- Should return: 'true'
2

Check Google OAuth credentials

SELECT access_token, refresh_token, calendar_id 
FROM google_oauth_credentials 
WHERE id = 1;
All should be non-empty.
3

Test Google Calendar API

curl "https://www.googleapis.com/calendar/v3/calendars/primary/events" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Emergency Reset

Use only as last resort. This will clear all conversations and messages.
-- Reset conversations
TRUNCATE TABLE messages;
TRUNCATE TABLE conversations;
TRUNCATE TABLE calendar_flow_state;
TRUNCATE TABLE classic_flow_sessions;

-- Reset OpenAI status
UPDATE settings SET setting_value = 'active' WHERE setting_key = 'openai_status';

-- Clear embedding cache
TRUNCATE TABLE query_embedding_cache;

Getting Help

Check Logs First

tail -100 logs/$(date +%Y-%m-%d).log

Enable Debug Mode

APP_DEBUG=true

Test Components

  • Test OpenAI API directly
  • Test WhatsApp API directly
  • Test database connection

Review Documentation

Performance Monitoring

-- Message volume
SELECT DATE(created_at) as date, COUNT(*) as count 
FROM messages 
GROUP BY DATE(created_at) 
ORDER BY date DESC 
LIMIT 7;

-- Average response confidence
SELECT AVG(confidence_score) as avg_confidence 
FROM messages 
WHERE sender_type = 'bot' AND confidence_score IS NOT NULL;

-- Active conversations
SELECT COUNT(*) FROM conversations WHERE status = 'active';

-- Embedding cache hit rate
SELECT 
  COUNT(*) as total_queries,
  SUM(hit_count) as total_hits,
  AVG(hit_count) as avg_hits_per_query
FROM query_embedding_cache;

Preventive Maintenance

1

Daily tasks

  • Monitor log files for errors
  • Check disk space
  • Verify webhook is responding
2

Weekly tasks

  • Review OpenAI usage and costs
  • Check database size and optimize if needed
  • Rotate old logs (30+ days)
3

Monthly tasks

  • Update dependencies: composer update
  • Review and update flow nodes
  • Test disaster recovery (backup restore)
  • Review security updates

Build docs developers (and LLMs) love