Deploy: 2026-05-22 21:52:51

This commit is contained in:
Hamza-Ayed
2026-05-22 21:52:51 +03:00
parent 5269789b51
commit 8acca92bba
12 changed files with 1938 additions and 285 deletions

View File

@@ -0,0 +1,139 @@
<?php
/**
* Driver Registration & Postponement Flow Simulation Script
* Run this on the server: php backend/public/test_simulation.php
*/
require_once dirname(__DIR__) . '/app/bootstrap.php';
use App\Core\Database;
use App\Models\ConversationState;
use App\Models\DriverReminder;
use App\Core\Flows\ConversationFlowEngine;
use App\Models\WhatsAppSession;
echo "=== Starting Driver Registration & Reminder Flow Simulation ===\n\n";
$companyId = 1;
$phone = "963999999999"; // Test Phone Number
// Setup mock session
$session = WhatsAppSession::findOrCreate($companyId);
// Ensure session is marked connected for simulation to go through sendReply
WhatsAppSession::updateState($session['id'], [
'phone' => $phone,
'status' => 'connected'
]);
// Refresh session data
$session = WhatsAppSession::findByCompany($companyId);
echo "1. Cleaning up existing test states/reminders...\n";
Database::execute("DELETE FROM conversation_states WHERE contact_phone = ?", [$phone]);
Database::execute("DELETE FROM driver_registration_reminders WHERE phone = ?", [$phone]);
Database::execute("DELETE FROM driver_ocr_data WHERE phone = ?", [$phone]);
echo "2. Initializing conversation to 'id_front' state...\n";
ConversationState::saveState([
'company_id' => $companyId,
'contact_phone' => $phone,
'flow_name' => 'driver_registration_flow',
'current_step' => 'id_front',
'context_data' => json_encode(['name' => 'جميل الشام'], JSON_UNESCAPED_UNICODE),
'expires_at' => date('Y-m-d H:i:s', strtotime('+1 hour'))
]);
echo "3. Simulating user postponement request: 'بكرة المسا ببعتلك الهوية الشخصية'...\n";
$msgData = [
'phone' => $phone,
'body' => 'بكرة المسا ببعتلك الهوية الشخصية'
];
$handled = ConversationFlowEngine::processMessage($session, $msgData);
echo " Message processed by flow engine: " . ($handled ? "YES" : "NO") . "\n";
// Fetch the new state and scheduled reminders
$state = ConversationState::findActive($companyId, $phone);
echo " New Flow Step: " . ($state ? $state['current_step'] : 'None (finished)') . "\n";
echo " Context: " . ($state ? $state['context_data'] : 'None') . "\n";
$reminders = Database::select("SELECT * FROM driver_registration_reminders WHERE phone = ?", [$phone]);
echo " Scheduled Reminders Count: " . count($reminders) . "\n";
if (!empty($reminders)) {
foreach ($reminders as $r) {
echo " - ID: {$r['id']}, Scheduled At: {$r['scheduled_at']}, Postpone Count: {$r['postpone_count']}, Status: {$r['status']}\n";
}
}
echo "\n4. Testing Cron Scheduler (Simulate reminder execution by setting scheduled_at to the past)...\n";
if (!empty($reminders)) {
Database::execute("UPDATE driver_registration_reminders SET scheduled_at = ? WHERE id = ?", [
date('Y-m-d H:i:s', strtotime('-1 minute')),
$reminders[0]['id']
]);
echo " Triggering cron process via internal endpoint request simulation...\n";
// We call the main cron logic directly by querying and executing the reminder
$dueReminders = Database::select(
"SELECT * FROM driver_registration_reminders WHERE status = 'pending' AND scheduled_at <= ?",
[date('Y-m-d H:i:s')]
);
echo " Due Reminders found: " . count($dueReminders) . "\n";
foreach ($dueReminders as $reminder) {
$rule = \App\Models\ChatbotRule::findActiveForRule($companyId);
$geminiKey = ($rule && !empty($rule['gemini_api_key'])) ? $rule['gemini_api_key'] : getenv('GEMINI_API_KEY');
$elApiKey = ($rule && !empty($rule['elevenlabs_api_key'])) ? $rule['elevenlabs_api_key'] : getenv('ELEVENLABS_API_KEY');
$elVoiceId = ($rule && !empty($rule['elevenlabs_voice_id'])) ? $rule['elevenlabs_voice_id'] : getenv('ELEVENLABS_VOICE_ID');
$driverName = 'جميل الشام';
$nameStr = $driverName ? " كابتن " . $driverName : " كابتن";
$reminderMsg = "أهلاً بك{$nameStr}، حابين نذكرك تكمل خطوات تسجيلك لتنضم لعائلة انطلق 🚖. بقية الأوراق كتير مهمة لنفعل حسابك ونبدأ سوا. بانتظار إرسالها!";
echo " Generating reminder Audio via TTS...\n";
$audioData = null;
if (!empty($geminiKey)) {
$audioData = \App\Services\GeminiService::generateAudioResponse(
$geminiKey,
"أنت روبوت خدمة العملاء لشركة انطلق، تتحدث باللهجة السورية الودودة.",
$reminderMsg,
'Puck',
$elApiKey ?: null,
$elVoiceId ?: null
);
}
echo " Sending outbound simulated message...\n";
ConversationFlowEngine::sendReply($session, $phone, $reminderMsg);
if ($audioData && !empty($audioData['audio'])) {
echo " Audio voice note generated successfully (Length: " . strlen($audioData['audio']) . " bytes). Sending...\n";
ConversationFlowEngine::sendReply(
$session,
$phone,
'',
null,
$audioData['audio'],
$audioData['mimeType'] ?? 'audio/mp4'
);
} else {
echo " Audio voice note generation skipped or failed (Gemini Key may be missing or empty).\n";
}
DriverReminder::update($reminder['id'], ['status' => 'sent']);
echo " Reminder ID {$reminder['id']} status set to 'sent'.\n";
}
}
echo "\n5. Simulating user resuming registration (sending message 'هلا يا كابتن')...\n";
$msgData = [
'phone' => $phone,
'body' => 'هلا يا كابتن'
];
$handled = ConversationFlowEngine::processMessage($session, $msgData);
echo " Resumed Message handled: " . ($handled ? "YES" : "NO") . "\n";
$state = ConversationState::findActive($companyId, $phone);
echo " Resumed Flow Step: " . ($state ? $state['current_step'] : 'None') . "\n";
echo "\n=== Simulation Finished ===\n";