Initial commit with updated Auth and media ignored
This commit is contained in:
171
ride/firebase/send_fcm.php
Executable file
171
ride/firebase/send_fcm.php
Executable file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
// send_fcm.php - FCM HTTP v1 Sender
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
$serviceAccountFile = __DIR__ . '/service-account.json';
|
||||
|
||||
// السماح فقط بـ POST
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Only POST allowed.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// استقبال البيانات
|
||||
$json_input = file_get_contents('php://input');
|
||||
$requestData = json_decode($json_input, true);
|
||||
|
||||
$target = $requestData['target'] ?? null;
|
||||
$title = $requestData['title'] ?? null;
|
||||
$body = $requestData['body'] ?? null;
|
||||
$isTopic = $requestData['isTopic'] ?? false;
|
||||
$tone = $requestData['tone'] ?? 'default';
|
||||
$customData = $requestData['data'] ?? [];
|
||||
|
||||
if (!$target) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Missing: target, title, or body.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// دالة Base64 URL-Safe Encoding (ضرورية للـ JWT)
|
||||
// ============================================================================
|
||||
function base64UrlEncode($data) {
|
||||
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// دالة المصادقة (Google OAuth2)
|
||||
// ============================================================================
|
||||
function getAccessToken($credentialsPath) {
|
||||
if (!file_exists($credentialsPath)) return null;
|
||||
|
||||
$credentials = json_decode(file_get_contents($credentialsPath), true);
|
||||
$clientEmail = $credentials['client_email'];
|
||||
$privateKey = $credentials['private_key'];
|
||||
|
||||
$now = time();
|
||||
$header = base64UrlEncode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
|
||||
$claim = base64UrlEncode(json_encode([
|
||||
'iss' => $clientEmail,
|
||||
'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
|
||||
'aud' => 'https://oauth2.googleapis.com/token',
|
||||
'exp' => $now + 3600,
|
||||
'iat' => $now
|
||||
]));
|
||||
|
||||
$signature = '';
|
||||
openssl_sign("$header.$claim", $signature, $privateKey, 'SHA256');
|
||||
$jwt = "$header.$claim." . base64UrlEncode($signature);
|
||||
|
||||
$ch = curl_init("https://oauth2.googleapis.com/token");
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
|
||||
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
'assertion' => $jwt
|
||||
]));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return json_decode($res, true)['access_token'] ?? null;
|
||||
}
|
||||
|
||||
// الحصول على Access Token
|
||||
$accessToken = getAccessToken($serviceAccountFile);
|
||||
if (!$accessToken) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to get Access Token.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// جلب Project ID
|
||||
$creds = json_decode(file_get_contents($serviceAccountFile), true);
|
||||
$projectId = $creds['project_id'];
|
||||
$fcmUrl = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send";
|
||||
|
||||
// ============================================================================
|
||||
// بناء هيكل الرسالة
|
||||
// ============================================================================
|
||||
$messagePayload = [
|
||||
'message' => [
|
||||
'notification' => [
|
||||
'title' => $title,
|
||||
'body' => $body
|
||||
],
|
||||
'android' => [
|
||||
'priority' => 'HIGH',
|
||||
'notification' => [
|
||||
'sound' => $tone,
|
||||
'channel_id' => 'high_importance_channel' // تأكد من تطابقه مع Android
|
||||
]
|
||||
],
|
||||
'apns' => [
|
||||
'headers' => ['apns-priority' => '10'],
|
||||
'payload' => [
|
||||
'aps' => [
|
||||
'sound' => $tone . '.caf',
|
||||
'content-available' => 1
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// تحديد الهدف (Topic أو Token)
|
||||
if ($isTopic) {
|
||||
$messagePayload['message']['topic'] = $target;
|
||||
} else {
|
||||
$messagePayload['message']['token'] = $target;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 🔥 معالجة Data Payload (يجب أن تكون String: String فقط)
|
||||
// ============================================================================
|
||||
if (!empty($customData)) {
|
||||
$processedData = [];
|
||||
foreach ($customData as $key => $val) {
|
||||
if (is_array($val) || is_object($val)) {
|
||||
// تحويل المصفوفات/الكائنات إلى JSON String
|
||||
$processedData[$key] = json_encode($val, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
} else {
|
||||
// تحويل أي قيمة أخرى إلى String
|
||||
$processedData[$key] = (string)$val;
|
||||
}
|
||||
}
|
||||
$messagePayload['message']['data'] = $processedData;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// الإرسال الفعلي إلى FCM
|
||||
// ============================================================================
|
||||
$ch = curl_init($fcmUrl);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Content-Type: application/json; charset=UTF-8'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload, JSON_UNESCAPED_UNICODE));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$result = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
// الرد
|
||||
if ($httpCode == 200) {
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'message' => 'Notification sent successfully',
|
||||
'fcm_response' => json_decode($result)
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
http_response_code($httpCode);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => 'FCM request failed',
|
||||
'fcm_response' => json_decode($result)
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user