Deploy: 2026-05-22 23:55:19
This commit is contained in:
@@ -43,9 +43,25 @@ class ConversationFlowEngine
|
||||
$companyId = $session['company_id'];
|
||||
$text = isset($msgData['body']) ? trim($msgData['body']) : '';
|
||||
|
||||
// If incoming message is audio, transcribe it via Gemini
|
||||
// If incoming message is audio, transcribe it via Gemini (if limits permit)
|
||||
$isAudio = !empty($msgData['audio']) && !empty($msgData['mimeType']);
|
||||
if ($isAudio) {
|
||||
if ($companyId !== 1) {
|
||||
$activeSub = \App\Models\CompanySubscription::findActiveByCompany($companyId);
|
||||
if (!$activeSub) {
|
||||
error_log("[Flow Engine Warning] Company {$companyId} has no active subscription for audio transcription.");
|
||||
return false;
|
||||
}
|
||||
if (!\App\Models\CompanySubscriptionUsage::hasRemainingLimit($companyId, 'request')) {
|
||||
error_log("[Flow Engine Warning] Company {$companyId} has exceeded its request limit for audio transcription.");
|
||||
return false;
|
||||
}
|
||||
if (!\App\Models\CompanySubscriptionUsage::hasRemainingLimit($companyId, 'voice')) {
|
||||
error_log("[Flow Engine Warning] Company {$companyId} has exceeded its voice limit for audio transcription.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$rule = \App\Models\ChatbotRule::findActiveForRule($companyId);
|
||||
$configuredGeminiKey = ($rule && !empty($rule['gemini_api_key'])) ? $rule['gemini_api_key'] : null;
|
||||
$apiKey = \App\Services\GeminiService::getGeminiApiKey($configuredGeminiKey);
|
||||
@@ -54,6 +70,11 @@ class ConversationFlowEngine
|
||||
if ($transcription) {
|
||||
$text = $transcription;
|
||||
$msgData['body'] = $transcription;
|
||||
// Increment usage stats for successful transcription
|
||||
if ($companyId !== 1) {
|
||||
\App\Models\CompanySubscriptionUsage::incrementUsage($companyId, 'voice');
|
||||
\App\Models\CompanySubscriptionUsage::incrementUsage($companyId, 'request');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,6 +105,21 @@ class ConversationFlowEngine
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check subscription limits for active/starting flow
|
||||
if ($companyId !== 1) {
|
||||
$activeSub = \App\Models\CompanySubscription::findActiveByCompany($companyId);
|
||||
if (!$activeSub) {
|
||||
error_log("[Flow Engine Warning] Company {$companyId} has no active subscription.");
|
||||
self::sendReply($session, $phone, "⚠️ عذراً، لا يوجد اشتراك نشط لهذا المتجر حالياً.");
|
||||
return true;
|
||||
}
|
||||
if (!\App\Models\CompanySubscriptionUsage::hasRemainingLimit($companyId, 'request')) {
|
||||
error_log("[Flow Engine Warning] Company {$companyId} has exceeded its general request limit.");
|
||||
self::sendReply($session, $phone, "⚠️ عذراً، لقد استهلك هذا المتجر كامل الحد المسموح له من الرسائل والطلبات لهذا الشهر.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. User cancel flow option
|
||||
$normalizedCancel = strtolower(trim($text));
|
||||
if (in_array($normalizedCancel, ['إلغاء', 'خروج', 'cancel', 'exit'])) {
|
||||
|
||||
@@ -172,7 +172,7 @@ EOT
|
||||
$configuredGeminiKey = ($rule && !empty($rule['gemini_api_key'])) ? $rule['gemini_api_key'] : null;
|
||||
$apiKey = GeminiService::getGeminiApiKey($configuredGeminiKey);
|
||||
if (!empty($apiKey)) {
|
||||
$postponeData = $this->detectPostponement($text, $apiKey);
|
||||
$postponeData = $this->detectPostponement($text, $apiKey, $companyId);
|
||||
if ($postponeData !== null) {
|
||||
$hours = $postponeData['hours'];
|
||||
$postponeCount = ($context['postpone_count'] ?? 0) + 1;
|
||||
@@ -366,6 +366,15 @@ EOT
|
||||
}
|
||||
|
||||
$companyId = $context['company_id'] ?? 1;
|
||||
|
||||
// Check subscription limit for OCR
|
||||
if ($companyId !== 1) {
|
||||
if (!\App\Models\CompanySubscriptionUsage::hasRemainingLimit($companyId, 'ocr')) {
|
||||
error_log("[DriverRegistrationFlow] Company {$companyId} has exceeded its OCR limit.");
|
||||
return new FlowResult("⚠️ عذراً، لقد استهلك هذا المتجر الحد المسموح له من تحليل الصور والوصولات لهذا الشهر. يرجى إرسال استفسارك نصياً.", $step);
|
||||
}
|
||||
}
|
||||
|
||||
$rule = ChatbotRule::findActiveForRule($companyId);
|
||||
$configuredGeminiKey = ($rule && !empty($rule['gemini_api_key'])) ? $rule['gemini_api_key'] : null;
|
||||
$apiKey = GeminiService::getGeminiApiKey($configuredGeminiKey);
|
||||
@@ -389,6 +398,12 @@ EOT
|
||||
return new FlowResult($failMessage, $step);
|
||||
}
|
||||
|
||||
// Increment stats on successful OCR processing
|
||||
if ($companyId !== 1) {
|
||||
\App\Models\CompanySubscriptionUsage::incrementUsage($companyId, 'ocr');
|
||||
\App\Models\CompanySubscriptionUsage::incrementUsage($companyId, 'request');
|
||||
}
|
||||
|
||||
// Save URL and OCR JSON string in the conversation context
|
||||
$context[$step . '_url'] = $imageUrl;
|
||||
$context[$step . '_ocr'] = $ocrData;
|
||||
@@ -432,7 +447,7 @@ EOT
|
||||
/**
|
||||
* Detect if user wants to postpone, and return hours_delay if so.
|
||||
*/
|
||||
private function detectPostponement(string $text, string $apiKey): ?array
|
||||
private function detectPostponement(string $text, string $apiKey, int $companyId): ?array
|
||||
{
|
||||
if (empty($text)) {
|
||||
return null;
|
||||
@@ -471,6 +486,11 @@ EOT;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Increment request limit on successful postponement check API call
|
||||
if ($companyId !== 1) {
|
||||
\App\Models\CompanySubscriptionUsage::incrementUsage($companyId, 'request');
|
||||
}
|
||||
|
||||
// Clean markdown block if present
|
||||
$response = trim(preg_replace('/```json|```/', '', $response));
|
||||
$data = json_decode($response, true);
|
||||
|
||||
Reference in New Issue
Block a user