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

@@ -16,6 +16,7 @@ class ConversationFlowEngine
*/
private static array $flows = [
'test_flow' => TestFlow::class,
'driver_registration_flow' => DriverRegistrationFlow::class,
];
/**
@@ -24,6 +25,9 @@ class ConversationFlowEngine
private static array $startTriggers = [
'test' => 'test_flow',
'اختبار' => 'test_flow',
'سجل' => 'driver_registration_flow',
'تسجيل' => 'driver_registration_flow',
'register' => 'driver_registration_flow',
];
/**
@@ -39,6 +43,20 @@ class ConversationFlowEngine
$companyId = $session['company_id'];
$text = isset($msgData['body']) ? trim($msgData['body']) : '';
// If incoming message is audio, transcribe it via Gemini
$isAudio = !empty($msgData['audio']) && !empty($msgData['mimeType']);
if ($isAudio) {
$rule = \App\Models\ChatbotRule::findActiveForRule($companyId);
$apiKey = ($rule && !empty($rule['gemini_api_key'])) ? $rule['gemini_api_key'] : getenv('GEMINI_API_KEY');
if (!empty($apiKey)) {
$transcription = \App\Services\GeminiService::transcribeAudio($apiKey, $msgData['audio'], $msgData['mimeType']);
if ($transcription) {
$text = $transcription;
$msgData['body'] = $transcription;
}
}
}
// 2. Lookup existing active flow
$state = ConversationState::findActive($companyId, $phone);
@@ -84,6 +102,7 @@ class ConversationFlowEngine
$flowInstance = new $flowClass();
try {
$context['company_id'] = $companyId;
$result = $flowInstance->handleStep($currentStep, $msgData, $context);
if ($result->isFinished()) {
@@ -104,8 +123,8 @@ class ConversationFlowEngine
}
// 5. Send reply if one is provided
if ($result->getReplyText() !== '') {
self::sendReply($session, $phone, $result->getReplyText());
if ($result->getReplyText() !== '' || $result->getMediaUrl() !== null) {
self::sendReply($session, $phone, $result->getReplyText(), $result->getMediaUrl());
}
return true;
@@ -118,8 +137,14 @@ class ConversationFlowEngine
/**
* Send outbound message reply via the Baileys Gateway
*/
private static function sendReply(array $session, string $phone, string $message): void
{
public static function sendReply(
array $session,
string $phone,
string $message,
?string $mediaUrl = null,
?string $audioBase64 = null,
?string $mimetype = null
): void {
$gatewayUrl = rtrim(getenv('WHATSAPP_GATEWAY_URL') ?: 'http://localhost:3722', '/');
if (substr($gatewayUrl, -4) === '/api') {
$sendUrl = $gatewayUrl . '/messages/send';
@@ -127,11 +152,25 @@ class ConversationFlowEngine
$sendUrl = $gatewayUrl . '/api/messages/send';
}
$payload = json_encode([
$payloadData = [
'session_key' => $session['session_key'],
'phone' => $phone,
'message' => $message
]);
'phone' => $phone
];
if ($message !== '') {
$payloadData['message'] = $message;
}
if ($mediaUrl !== null) {
$payloadData['media_url'] = $mediaUrl;
}
if ($audioBase64 !== null) {
$payloadData['audio'] = $audioBase64;
}
if ($mimetype !== null) {
$payloadData['mimetype'] = $mimetype;
}
$payload = json_encode($payloadData);
$ch = curl_init($sendUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -161,14 +200,17 @@ class ConversationFlowEngine
error_log("[Flow Engine Gateway Error] Failed to send: " . $errorMsg);
}
$msgType = ($audioBase64 !== null || $mediaUrl !== null) ? 'audio' : 'text';
// Log the outbound auto-reply message
MessageLog::logMessage([
'company_id' => $session['company_id'],
'session_id' => $session['id'],
'contact_phone' => $phone,
'direction' => 'outbound',
'message_type' => 'text',
'message_type' => $msgType,
'message_body' => $message,
'media_url' => $mediaUrl,
'whatsapp_message_id' => $waMsgId,
'status' => $status,
'error_message' => $errorMsg