Update: 2026-08-07 15:50:04
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* cron_sms_requests.php — شبكة الأمان لمسار الطلب بالرسائل
|
||||
* ─────────────────────────────────────────────────────────────
|
||||
* المعالجة الأصلية تتم فورياً داخل webhook_sms/webhook.php، لأن الراكب
|
||||
* واقف ينتظر رداً ودقيقة تأخير تعني أنه ظنّ الرقم معطّلاً. هذا الكرون
|
||||
* لا يعالج المسار السعيد إذن — وظيفته ما يسقط منه:
|
||||
*
|
||||
* ١. طلبات بقيت 'pending' (فشل شبكي عابر وقت الإنشاء)
|
||||
* ٢. طلبات عَلِقت في 'dispatching' (مات التنفيذ بين القفل والنتيجة)
|
||||
* ٣. رحلات لم يقبلها أحد — نخبر الراكب بدل تركه ينتظر بلا خبر
|
||||
*
|
||||
* الثالثة هي الأهم: راكب التطبيق يرى الخريطة فيعرف أن البحث جارٍ.
|
||||
* راكب الرسائل لا يرى شيئاً — صمتنا عنده يساوي عطلاً.
|
||||
*
|
||||
* جدولة: كل دقيقة.
|
||||
* *\/1 * * * * docker compose exec -T php php /var/www/backend/bot/cron_sms_requests.php
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../core/bootstrap.php';
|
||||
require_once __DIR__ . '/../sms/ride_request.php';
|
||||
|
||||
// طلب عَلِق في 'dispatching' أطول من هذا يُعتبر ميتاً ويُعاد للطابور.
|
||||
const SMS_STUCK_MINUTES = 3;
|
||||
|
||||
// بعد هذه المدة بلا سائق نخبر الراكب. أقصر من مهلة التطبيق عمداً:
|
||||
// من ينتظر بلا شاشة يفقد صبره أسرع.
|
||||
const SMS_NO_DRIVER_MINUTES = 6;
|
||||
|
||||
try {
|
||||
$con = Database::get('main');
|
||||
} catch (Exception $e) {
|
||||
fwrite(STDERR, '[sms-cron] DB unavailable: ' . $e->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// ١) تحرير العالق
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
$freed = 0;
|
||||
try {
|
||||
$st = $con->prepare("
|
||||
UPDATE sms_ride_requests
|
||||
SET status = 'pending'
|
||||
WHERE status = 'dispatching'
|
||||
AND updated_at < NOW() - INTERVAL " . SMS_STUCK_MINUTES . " MINUTE
|
||||
");
|
||||
$st->execute();
|
||||
$freed = $st->rowCount();
|
||||
} catch (PDOException $e) {
|
||||
fwrite(STDERR, '[sms-cron] تعذّر تحرير العالق: ' . $e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// ٢) إعادة محاولة المعلّق
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
$retried = 0;
|
||||
$created = 0;
|
||||
try {
|
||||
$st = $con->query("
|
||||
SELECT id, sender_norm, passenger_id, start_location, end_location,
|
||||
start_name, end_name, distance, duration, attempts
|
||||
FROM sms_ride_requests
|
||||
WHERE status = 'pending' AND passenger_id IS NOT NULL
|
||||
ORDER BY id ASC
|
||||
LIMIT 50
|
||||
");
|
||||
|
||||
foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $req) {
|
||||
$retried++;
|
||||
if (smsProcessRequest($con, $req)) $created++;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
fwrite(STDERR, '[sms-cron] فشل إعادة المحاولة: ' . $e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// ٣) إبلاغ من لم يجد سائقاً
|
||||
//
|
||||
// نعتمد على حالة الرحلة نفسها لا على مؤقّت منفصل: ما دامت 'waiting'
|
||||
// فلا سائق قَبِل. والوسم في fail_reason يمنع تكرار الإبلاغ كل دقيقة.
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
$notified = 0;
|
||||
try {
|
||||
$st = $con->prepare("
|
||||
SELECT s.id, s.sender_norm, s.ride_id
|
||||
FROM sms_ride_requests s
|
||||
JOIN ride r ON r.id = s.ride_id
|
||||
WHERE s.status = 'dispatched'
|
||||
AND (s.fail_reason IS NULL OR s.fail_reason <> 'no_driver_notified')
|
||||
AND r.status IN ('waiting', 'wait')
|
||||
AND s.updated_at < NOW() - INTERVAL " . SMS_NO_DRIVER_MINUTES . " MINUTE
|
||||
LIMIT 50
|
||||
");
|
||||
$st->execute();
|
||||
|
||||
foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
// الوسم أولاً ثم الإرسال: لو انقطع التنفيذ بينهما، أسوأ نتيجة
|
||||
// رسالة لم تصل — لا رسالة تصل كل دقيقة.
|
||||
$con->prepare("UPDATE sms_ride_requests SET fail_reason='no_driver_notified' WHERE id=?")
|
||||
->execute([$row['id']]);
|
||||
|
||||
smsEnqueue($con, $row['sender_norm'],
|
||||
'سيرو: ما زلنا نبحث عن سائق قريب منك. سنرسل لك رسالة فور قبول أحدهم،'
|
||||
. ' أو أعد إرسال طلبك بعد قليل.',
|
||||
'no_driver_yet', (string) $row['ride_id']);
|
||||
$notified++;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
fwrite(STDERR, '[sms-cron] تعذّر إبلاغ من بلا سائق: ' . $e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
echo "[sms-cron] حُرِّر {$freed}، أُعيدت محاولة {$retried}، أُنشئ {$created}،"
|
||||
. " أُبلغ {$notified}\n";
|
||||
Reference in New Issue
Block a user