feat(notifications): scheduled campaigns are actually sent
Campaigns saved as 'scheduled' were never looked at again: nothing in either
app processed them. CampaignService::processDue() sends every due campaign
into the game's bell (notifications with title_ar/body_ar, as the game's
notifications.php reads them) and records recipients, claiming each one with
a conditional scheduled -> sending update so overlapping runs never send
twice. It runs from GET/POST /api/cron/notifications (X-Service-Key, or
X-Cron-Secret / ?secret= when CRON_SECRET is set, the same credentials as
the game's api/cron.php) for a scheduler, and as a fallback at most once a
minute after any staff page load.
Scheduling now stores the typed Cairo time as UTC (the raw datetime-local
value was saved as UTC, 2-3 hours late) and refuses past times; filters
are stored as jsonb, not a JSON string; cancelling only cancels a campaign
that has not started; send-now shares the same delivery code.
Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
Showing
api/cron-notifications.php
0 → 100644
This diff is collapsed.
Please register or sign in to comment