Update: 2026-06-21 18:58:05
This commit is contained in:
129
backend/core/Services/SiroGeminiService.php
Normal file
129
backend/core/Services/SiroGeminiService.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// core/Services/SiroGeminiService.php
|
||||
// Siro AI Market Analysis & Marketing Content Generation Service
|
||||
// ============================================================
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class SiroGeminiService {
|
||||
private ?string $apiKey;
|
||||
private string $baseUrl;
|
||||
|
||||
public function __construct() {
|
||||
$this->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-1.5-flash'
|
||||
): ?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\": \"عنوان الإشعار\",
|
||||
\"push_body\": \"محتوى الإشعار القصير والمثير للاهتمام\",
|
||||
\"sms_body\": \"محتوى رسالة الاستعادة القصير والمقنع للـ SMS أو الواتساب\"
|
||||
}
|
||||
";
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user