apiKey = getenv('GEMINI_API_KEY') ?: null; $this->baseUrl = "https://generativelanguage.googleapis.com/v1beta/models/"; } /** * Analyze market prices and generate target promotion response * * @param array $competitorPrices Array of competitor pricing information * @param float $siroBasePrice Current Siro base pricing for this region/country * @param string $regionName Name of the region/city * @param string $countryCode Country code (e.g. SY, JO, EG, IQ) * @param string $model Override AI model to use (default: gemini-1.5-flash) * @return array|null Decoded JSON response from Gemini or null on failure */ public function analyzeMarketAndDraftCampaign( array $competitorPrices, float $siroBasePrice, string $regionName, string $countryCode, string $model = 'gemini-flash-lite-latest' ): ?array { if (!$this->apiKey) { error_log("[SiroGeminiService] API Key is missing."); return null; } $dialect = match (strtoupper($countryCode)) { 'SY' => 'السورية (الشامية)', 'JO' => 'الأردنية', 'EG' => 'المصرية', 'IQ' => 'العراقية', default => 'العربية الفصحى البسيطة' }; $prompt = " أنت خبير تسويق ذكي ومحلل أسعار لتطبيق Siro لخدمات نقل الركاب. قم بتحليل أسعار المنافسين في منطقة '$regionName' وصياغة حملة تسويقية وعرض ترويجي منافس. بيانات الإدخال: 1. أسعار المنافسين الحالية: " . json_encode($competitorPrices, JSON_UNESCAPED_UNICODE) . " 2. سعر رحلة Siro الأساسي الحالي: $siroBasePrice المطلوب: 1. دراسة الأسعار وتحديد هل توجد فرصة تسويقية واضحة لجذب الركاب (opportunity_detected: true/false). 2. تحديد معامل التخفيض المقترح أو قيمة خصم مناسبة (discount_value) والنسبة المئوية (discount_percentage). 3. كتابة رسالة تسويقية إعلانية جذابة وقصيرة جداً ومقنعة لإرسالها كإشعار (Push Notification) للركاب النشطين بالهجة $dialect. 4. كتابة رسالة استعادة جذابة ومغرية وقصيرة لإرسالها عبر SMS أو WhatsApp للركاب المنقطعين بالهجة $dialect مع ذكر كود الخصم المقترح. 5. اقتراح كود خصم مناسب للحملة (promo_code) ليكون سهل الحفظ ومناسباً للحدث. الخرج المطلوب (يجب أن يكون JSON صالحاً تماماً وخالياً من أي شرح خارجي، باللغة العربية): { \"opportunity_detected\": true/false, \"recommended_price\": 12000, \"discount_percentage\": 15, \"promo_code\": \"SIROGO15\", \"push_title\": \"عنوان الإشعار (بحد أقصى 5 كلمات)\", \"push_body\": \"محتوى الإشعار القصير والمثير للاهتمام (بحد أقصى 15 كلمة)\", \"sms_body\": \"محتوى رسالة الاستعادة (بحد أقصى 20 كلمة)\" } "; return $this->callGemini($prompt, $model); } /** * يُولّد إشعاراً مخصصاً لحدث دخول الجيوفينس بناءً على بيانات أسعار حقيقية. * * @param string $zoneName اسم منطقة السياج الجغرافي * @param string $countryCode رمز الدولة (SY, JO, EG, IQ) * @param float $savingsPct نسبة التوفير (مثال: 8.5) * @param string $topCompetitor اسم أبرز منافس في المنطقة * @param string $model * @return array|null */ public function generateGeofenceMessage( string $zoneName, string $countryCode, float $savingsPct, string $topCompetitor = 'كريم', string $model = 'gemini-flash-lite-latest' ): ?array { if (!$this->apiKey) return null; $dialect = match (strtoupper($countryCode)) { 'SY' => 'السورية الشامية', 'JO' => 'الأردنية', 'EG' => 'المصرية العامية', 'IQ' => 'العراقية', default => 'العربية الفصحى' }; $savingsFormatted = number_format($savingsPct, 1); $prompt = " أنت كاتب إشعارات تسويقية ذكية لتطبيق Siro لخدمات نقل الركاب. المستخدم الآن موجود بالقرب من '$zoneName'. سعر سيرو أقل بـ $savingsFormatted% من $topCompetitor وبقية التطبيقات في هذه المنطقة. المطلوب: اكتب إشعاراً push قصيراً جداً (عنوان + جسم) باللهجة $dialect. - العنوان: لا يتجاوز 5 كلمات، مثير للاهتمام - الجسم: لا يتجاوز 12 كلمة، يذكر التوفير الفعلي ويحفّز على الطلب الآن - اجعله طبيعياً كأنه يكتبه شخص حقيقي وليس روبوت الخرج (JSON فقط، بدون أي شرح): { \"push_title\": \"...\", \"push_body\": \"...\" } "; return $this->callGemini($prompt, $model); } /** * تقرأ معادلات المنافسين المكتشفة أسبوعياً وتقدم استراتيجية تسويق (Weekly Advisor). * * @param array $formulas المصفوفة المستخرجة من competitor_secret_formulas * @param string $model * @return array|null */ public function analyzeCompetitorFormulas( array $formulas, string $model = 'gemini-flash-lite-latest' ): ?array { if (!$this->apiKey) return null; $formulasJson = json_encode($formulas, JSON_UNESCAPED_UNICODE); $prompt = " أنت المستشار التسويقي المالي لتطبيق 'سيرو' لنقل الركاب. لقد قمنا بعمل هندسة عكسية لرحلات منافسينا واكتشفنا معادلات التسعير السرية الخاصة بهم لهذا الأسبوع. البيانات المكتشفة: $formulasJson المطلوب منك (كمستشار أعمال خبير): 1. تحليل هذه الأرقام، وتوضيح أين تكمن نقاط قوة المنافسين وأين نقاط ضعفهم في التسعير (مثلاً من يركز على المسافات القصيرة برفع فتح العداد؟). 2. اقتراح 3 استراتيجيات تسويقية أو رسائل إعلانية (Push Notifications/Social Media) موجهة للركاب، تستغل نقاط ضعف المنافسين المكتشفة. قم بصياغة تقريرك بتنسيق HTML مرتب وجاهز للعرض في لوحة الإدارة (بدون علامات ```html)، واستخدم ألوان خفيفة في العناوين

. تحدث بلغة عربية احترافية ومباشرة لصناع القرار. "; // بما أن الإخراج سيكون نص HTML، سنستخدم API جيميناي العادي بدون تقييد JSON $url = $this->baseUrl . "{$model}:generateContent?key={$this->apiKey}"; $postData = [ 'contents' => [ [ 'parts' => [ ['text' => $prompt] ] ] ], 'generationConfig' => [ 'temperature' => 0.7, 'maxOutputTokens' => 2000 ] ]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); curl_setopt($ch, CURLOPT_TIMEOUT, 60); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200) { $data = json_decode($response, true); $text = $data['candidates'][0]['content']['parts'][0]['text'] ?? ''; return ['status' => 'success', 'html_report' => $text]; } else { error_log("[SiroGeminiService] HTTP $httpCode in analyzeCompetitorFormulas: $response"); return null; } } /** * Helper: يُرسل prompt لـ Gemini ويُعيد JSON مُفكَّك */ private function callGemini(string $prompt, string $model): ?array { $apiUrl = $this->baseUrl . $model . ":generateContent?key=" . $this->apiKey; $payload = [ 'contents' => [ [ 'parts' => [ ['text' => $prompt] ] ] ] ]; $ch = curl_init($apiUrl); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 5 ]); $response = curl_exec($ch); $curlErr = curl_error($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($curlErr) { error_log("[SiroGeminiService] Curl Error: $curlErr"); return null; } if ($httpCode !== 200) { error_log("[SiroGeminiService] HTTP Error $httpCode. Response: $response"); return null; } try { $responseData = json_decode($response, true); $rawText = $responseData['candidates'][0]['content']['parts'][0]['text'] ?? ''; // تنظيف أي علامات كود ماركداون محتملة من الموديل $cleanJson = trim(preg_replace('/```json|```/', '', $rawText)); $decoded = json_decode($cleanJson, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("[SiroGeminiService] JSON Decode Error: " . json_last_error_msg() . " | Raw text: $rawText"); return null; } return $decoded; } catch (Exception $e) { error_log("[SiroGeminiService] Exception: " . $e->getMessage()); return null; } } public function evaluatePostsForReporting(array $posts, string $model = 'gemini-flash-lite-latest'): ?string { if (!$this->apiKey || empty($posts)) return null; $postsJson = json_encode($posts, JSON_UNESCAPED_UNICODE); $prompt = " أنت محلل بيانات استخباراتية للسوق لتطبيق 'سيرو' لنقل الركاب. إليك مجموعة من المنشورات والتعليقات التي جمعها الروبوت الخاص بنا من مجموعات فيسبوك اليوم: $postsJson المطلوب منك: 1. قراءة جميع هذه المنشورات واستخراج أي شكاوى، أسئلة، أو نقاشات تتعلق بـ (تطبيقات النقل الذكي، أسعار المحروقات، باقات الإنترنت، مشاكل السيارات). ملاحظة هامة عن بنية البيانات: - أي نص يبدأ بـ [FEED]: هو عبارة عن المنشور الأصلي (البوست). - أي نص يبدأ بـ [COMMENT]: هو تعليق تابع للمنشور الذي يسبقه مباشرة. 2. تلخيص أهم هذه النقاشات في تقرير قصير ومفيد (News Report). يرجى التمييز بين المنشور الأصلي والتعليقات عليه لفهم السياق. 3. تجاهل المنشورات العشوائية أو الشخصية التي لا تفيد السوق. هام جداً: - يجب أن يكون التقرير باللغة العربية بالكامل. - يجب أن تغلف التقرير بالكامل بوسم
في البداية و
في النهاية لضمان القراءة من اليمين لليسار. - استخدم

للعناوين و