Update: 2026-07-23 16:56:57
This commit is contained in:
@@ -552,7 +552,7 @@ Therefore, do NOT assume a specific field is on the front or the back of a card.
|
|||||||
|
|
||||||
/* ================== 11) Notification ================== */
|
/* ================== 11) Notification ================== */
|
||||||
try {
|
try {
|
||||||
$fcmSendUrl = 'https://api.intaleq.xyz/siro/ride/firebase/send_fcm.php';
|
$fcmSendUrl = getenv('FCM_ENDPOINT_URL') ?: 'http://nginx/backend/ride/firebase/send_fcm.php';
|
||||||
|
|
||||||
$driverFullName = $raw_first_name . ' ' . $raw_last_name;
|
$driverFullName = $raw_first_name . ' ' . $raw_last_name;
|
||||||
$notificationTitle = 'تسجيل سائق جديد';
|
$notificationTitle = 'تسجيل سائق جديد';
|
||||||
|
|||||||
@@ -62,36 +62,13 @@ echo "Silent Push triggered for $sentCount inactive users.\n";
|
|||||||
* Helper to send Silent FCM
|
* Helper to send Silent FCM
|
||||||
*/
|
*/
|
||||||
function sendSilentFcmNotification($token, $data) {
|
function sendSilentFcmNotification($token, $data) {
|
||||||
// Basic curl request to FCM API for silent push
|
if (function_exists('sendFCM_Internal')) {
|
||||||
$url = 'https://fcm.googleapis.com/fcm/send';
|
return sendFCM_Internal($token, '', '', $data, 'SilentPush', false, 'silent');
|
||||||
|
}
|
||||||
// Replace with your actual server key
|
if (!class_exists('FcmService')) {
|
||||||
$serverKey = getenv('FCM_SERVER_KEY') ?: 'YOUR_LEGACY_SERVER_KEY';
|
require_once __DIR__ . '/../core/Services/FcmService.php';
|
||||||
|
}
|
||||||
$fields = [
|
$fcm = new FcmService();
|
||||||
'to' => $token,
|
return $fcm->send($token, '', '', $data, 'SilentPush', 'silent');
|
||||||
'data' => $data,
|
|
||||||
'content_available' => true, // Required for iOS to wake up in background
|
|
||||||
'priority' => 'high' // Sometimes required to wake up Android
|
|
||||||
];
|
|
||||||
|
|
||||||
$headers = [
|
|
||||||
'Authorization: key=' . $serverKey,
|
|
||||||
'Content-Type: application/json'
|
|
||||||
];
|
|
||||||
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
|
|
||||||
|
|
||||||
$result = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -12,8 +12,14 @@ class FcmService
|
|||||||
public function __construct(?Redis $redis = null)
|
public function __construct(?Redis $redis = null)
|
||||||
{
|
{
|
||||||
$this->redis = $redis;
|
$this->redis = $redis;
|
||||||
// المسار بناء على بنية المشروع
|
$envPath = getenv('FIREBASE_SERVICE_ACCOUNT_PATH') ?: '';
|
||||||
$this->serviceAccountFile = getenv('FIREBASE_SERVICE_ACCOUNT_PATH');
|
if (!empty($envPath) && file_exists($envPath)) {
|
||||||
|
$this->serviceAccountFile = $envPath;
|
||||||
|
} elseif (file_exists('/keys/firebase_service_account.json')) {
|
||||||
|
$this->serviceAccountFile = '/keys/firebase_service_account.json';
|
||||||
|
} else {
|
||||||
|
$this->serviceAccountFile = __DIR__ . '/../../keys/firebase_service_account.json';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── إرسال إشعار ────────────────────────────────────────
|
// ── إرسال إشعار ────────────────────────────────────────
|
||||||
|
|||||||
@@ -12,10 +12,22 @@ function base64UrlEncode($data) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// دالة الحصول على Access Token من Google OAuth2
|
// دالة الحصول على Access Token من Google OAuth2
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
function getFCMAccessToken($serviceAccountPath = null) {
|
function resolveFCMServiceAccountPath($serviceAccountPath = null) {
|
||||||
if (!$serviceAccountPath) {
|
if (!empty($serviceAccountPath) && file_exists($serviceAccountPath)) {
|
||||||
$serviceAccountPath = __DIR__ . '/service-account.json';
|
return $serviceAccountPath;
|
||||||
}
|
}
|
||||||
|
$envPath = getenv('FIREBASE_SERVICE_ACCOUNT_PATH') ?: '';
|
||||||
|
if (!empty($envPath) && file_exists($envPath)) {
|
||||||
|
return $envPath;
|
||||||
|
}
|
||||||
|
if (file_exists('/keys/firebase_service_account.json')) {
|
||||||
|
return '/keys/firebase_service_account.json';
|
||||||
|
}
|
||||||
|
return __DIR__ . '/service-account.json';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFCMAccessToken($serviceAccountPath = null) {
|
||||||
|
$serviceAccountPath = resolveFCMServiceAccountPath($serviceAccountPath);
|
||||||
|
|
||||||
if (!file_exists($serviceAccountPath)) {
|
if (!file_exists($serviceAccountPath)) {
|
||||||
error_log("❌ FCM: service-account.json not found at: $serviceAccountPath");
|
error_log("❌ FCM: service-account.json not found at: $serviceAccountPath");
|
||||||
@@ -73,7 +85,7 @@ function sendFCMNotification($params) {
|
|||||||
$data = $params['data'] ?? [];
|
$data = $params['data'] ?? [];
|
||||||
$tone = $params['tone'] ?? 'default';
|
$tone = $params['tone'] ?? 'default';
|
||||||
$isTopic = $params['isTopic'] ?? false;
|
$isTopic = $params['isTopic'] ?? false;
|
||||||
$serviceAccountPath = $params['service_account_path'] ?? __DIR__ . '/service-account.json';
|
$serviceAccountPath = resolveFCMServiceAccountPath($params['service_account_path'] ?? null);
|
||||||
|
|
||||||
// التحقق من البيانات الأساسية
|
// التحقق من البيانات الأساسية
|
||||||
if (empty($token) || empty($title) || empty($body)) {
|
if (empty($token) || empty($title) || empty($body)) {
|
||||||
|
|||||||
@@ -2,16 +2,27 @@
|
|||||||
// send_fcm.php - FCM HTTP v1 Sender (Internal use only)
|
// send_fcm.php - FCM HTTP v1 Sender (Internal use only)
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
// 🔐 Require internal API key for authentication
|
// 🔐 Require internal API key for authentication if set
|
||||||
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
||||||
$expectedKey = getenv('FCM_INTERNAL_API_KEY');
|
$expectedKey = getenv('FCM_INTERNAL_API_KEY');
|
||||||
if (empty($expectedKey) || !hash_equals($expectedKey, $apiKey)) {
|
if (!empty($expectedKey) && !hash_equals($expectedKey, $apiKey)) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
|
echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$serviceAccountFile = __DIR__ . '/service-account.json';
|
function resolveServiceAccountPath(): string {
|
||||||
|
$envPath = getenv('FIREBASE_SERVICE_ACCOUNT_PATH') ?: '';
|
||||||
|
if (!empty($envPath) && file_exists($envPath)) {
|
||||||
|
return $envPath;
|
||||||
|
}
|
||||||
|
if (file_exists('/keys/firebase_service_account.json')) {
|
||||||
|
return '/keys/firebase_service_account.json';
|
||||||
|
}
|
||||||
|
return __DIR__ . '/service-account.json';
|
||||||
|
}
|
||||||
|
|
||||||
|
$serviceAccountFile = resolveServiceAccountPath();
|
||||||
|
|
||||||
// السماح فقط بـ POST
|
// السماح فقط بـ POST
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ try {
|
|||||||
FROM ride
|
FROM ride
|
||||||
WHERE passenger_id = ?
|
WHERE passenger_id = ?
|
||||||
AND (
|
AND (
|
||||||
status IN ('Apply', 'Applied', 'accepted', 'arrived', 'Arrived', 'Begin') AND created_at >= NOW() - INTERVAL 24 HOUR
|
status IN ('Apply', 'Applied', 'accepted', 'arrived', 'Arrived', 'Begin') AND created_at >= NOW() - INTERVAL 1 HOUR
|
||||||
OR (status = 'Finished' AND created_at >= NOW() - INTERVAL 24 HOUR)
|
OR (status = 'Finished' AND created_at >= NOW() - INTERVAL 1 HOUR)
|
||||||
)
|
)
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ function sendFCM_Async(string $token, string $title, string $body, array $rideDa
|
|||||||
|
|
||||||
$http = new AsyncHttp();
|
$http = new AsyncHttp();
|
||||||
$http->request(
|
$http->request(
|
||||||
'https://api.intaleq.xyz/intaleq/ride/firebase/send_fcm.php',
|
getenv('FCM_ENDPOINT_URL') ?: 'http://nginx/backend/ride/firebase/send_fcm.php',
|
||||||
[
|
[
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'data' => json_encode([
|
'data' => json_encode([
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ class AppLink {
|
|||||||
case 'Egypt':
|
case 'Egypt':
|
||||||
return 'https://location-egypt.siromove.com';
|
return 'https://location-egypt.siromove.com';
|
||||||
case 'Jordan':
|
case 'Jordan':
|
||||||
return 'https://jordan-siro.intaleqapp.com';
|
return 'https://jordan-siro.intaleqapp.com:2020';
|
||||||
default:
|
default:
|
||||||
return 'https://location-jordan.siromove.com';
|
return 'https://jordan-siro.intaleqapp.com:2020';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,9 +152,9 @@ class AppLink {
|
|||||||
case 'Egypt':
|
case 'Egypt':
|
||||||
return 'https://api-egypt.siromove.com';
|
return 'https://api-egypt.siromove.com';
|
||||||
case 'Jordan':
|
case 'Jordan':
|
||||||
return 'https://jordan-siro.intaleqapp.com';
|
return 'https://jordan-siro.intaleqapp.com:3030';
|
||||||
default:
|
default:
|
||||||
return 'https://api.siromove.com';
|
return 'https://jordan-siro.intaleqapp.com:3030';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user