87 lines
4.4 KiB
Markdown
87 lines
4.4 KiB
Markdown
# SMS Campaigns — Архитектура
|
||
|
||
## Обзор
|
||
|
||
4 сценария SMS-рассылок, каждый — systemd timer + service + Python скрипт.
|
||
Сервер: `217.114.5.8`, скрипты в `/opt/supersam/scripts/`.
|
||
|
||
## Сценарии
|
||
|
||
| Сценарий | Timer | Скрипт | Триггер |
|
||
|----------|-------|--------|---------|
|
||
| 1-я SMS | `sms-first-campaign.timer` | `sms_first_campaign.py` | `notification_status=link_ready` + `delivery_status=pending_confirmation` |
|
||
| 2-я SMS | `sms-second-campaign.timer` | `sms_second_campaign.py` | `notification_status=first_sms_sent` + время прошло |
|
||
| Ручное управление | `sms-manual-campaign.timer` | `sms_manual_campaign.py` | `second_sms_sent` + expired, или `link_ready` без SMS > 3ч, или `sms_sending` > 3ч |
|
||
| Платное хранение | `sms-paid-storage-campaign.timer` | `sms_paid_storage_campaign.py` | `notification_status=paid_storage` + `paid_storage_at` |
|
||
|
||
## Timer конфигурация
|
||
|
||
- `OnUnitActiveSec=600` — каждые 10 минут
|
||
- `sms_timer_manager.sh` — управляет `timer_active` + `run_requested` + `needs_check`
|
||
- `fcntl.flock` во всех скриптах — защита от параллельного запуска
|
||
- `send_telegram` = no-op (pass)
|
||
|
||
## Логика retry
|
||
|
||
- 2 попытки отправки SMS с интервалом ~90 мин
|
||
- Если код SMS.ru не 103 (доставлено) после 2 попыток → `manual_required`
|
||
- `effective_attempts = max(sms_attempts, total_failed)` — total_failed из всей истории `sms_campaign_log`
|
||
- Код 231 (лимит одинаковых) → `send_failed`, НЕ повторять
|
||
|
||
## Рабочие часы
|
||
|
||
| Параметр | 1/2 SMS | Manual | Paid Storage |
|
||
|----------|---------|--------|-------------|
|
||
| Часы | 8–21 | 8–21 | 8–21 |
|
||
| Дни | Пн–Пт (1-5) | Пн–Сб (1-6) | Пн–Пт |
|
||
| Проверка статусов | 24/7 | 24/7 | 24/7 |
|
||
|
||
## Настройки (БД `sms_campaign_settings`)
|
||
|
||
- `test_mode` — false (1/2 SMS), true (manual/paid_storage)
|
||
- `test_phone` — 79788382260
|
||
- `timer_active` — управляет включением systemd timer
|
||
- `send_interval_seconds` — пауза между отправками (15с)
|
||
- `work_hours_start/end` — 8/21
|
||
- `work_days` — "1,2,3,4,5" или "1,2,3,4,5,6"
|
||
- `last_run_at` — обновляется при каждом запуске скрипта
|
||
- `last_balance` — баланс sms.ru после последней отправки
|
||
|
||
## SMS.ru
|
||
|
||
- Провайдер: sms.ru
|
||
- Коды: 100 (в очереди), 102 (в пути), 103 (доставлено), 104-108 (ошибка), 231/232 (лимит)
|
||
- API ключ хранится в `sms_campaign_settings`
|
||
- Баланс отображается в UI (SmsCampaignPanel)
|
||
|
||
## UI (SmsCampaignPanel.jsx)
|
||
|
||
- `getRunnerStatus(settings)` — показывает статус последнего запуска:
|
||
- 🟢 Работает (Xм назад) — < 10 мин
|
||
- 🟡 Xм назад — < 60 мин
|
||
- 🔴 Xч назад — < 24ч
|
||
- 🔴 Xд назад — > 24ч
|
||
- `🔴 Xд назад` = `last_run_at` был более 24 часов назад
|
||
- 4 вкладки кампаний, переключатель test/боевой, таймер on/off
|
||
- Логи отправок, фильтры (дата, открытие ссылки), bulk delete
|
||
- Edge function `check-sms-status` — мгновенная проверка SMS через sms.ru API
|
||
|
||
## State Machine
|
||
|
||
```
|
||
not_started → link_ready → sms_sending → checking → first_sms_sent
|
||
→ second_sms_sending → second_sms_sent → manual_required → confirmed
|
||
→ address_required → agreed → driver_assigned → loaded → on_route → delivered/picked_up
|
||
```
|
||
|
||
## Ссылки
|
||
|
||
- SMS ссылка содержит `?src=sms` — отличает открытие клиентом от админа
|
||
- `opened_at` ставится только при `p_src='sms'` в RPC `get_delivery_invitation_by_token`
|
||
- `access_count` растёт при любом открытии
|
||
|
||
## Деплой
|
||
|
||
- Скрипты: напрямую в `/opt/supersam/scripts/` (не в Docker)
|
||
- UI: SCP → `docker compose -f docker-compose.app.yml build --no-cache && up -d`
|
||
- SW bump: `sed -i 's/construction-delivery-static-v[0-9]*/vNN/g' public/service-worker.js` |