Умные напоминания
Экран объединяет три автоматики удержания: лестницу напоминаний об истечении подписки, воронку возврата ушедших и календарь праздничных акций. Всё рассылает воркер по расписанию — фоновая задача просыпается каждые 5 минут и проверяет, чьё время пришло.
Лестница напоминаний об истечении
Основной механизм продления. Лестница состоит из ступеней: каждая ступень срабатывает за hours_before часов до истечения подписки (от 0 до 8760; 0 — в момент истечения). Ступени добавляются, редактируются и выключаются по отдельности; два шага с одинаковым смещением создать нельзя.
При первом запуске магазина лестница уже засеяна:
| За сколько | Текст по умолчанию |
|---|---|
| 24 часа | Подписка истекает через 24 часа. Продлите, чтобы не потерять доступ. |
| 12 часов | Подписка истекает через 12 часов — успейте продлить. |
| 1 час | Подписка истекает через час! Продлите сейчас, чтобы не остаться без VPN. |
| В момент истечения | Подписка закончилась. Продлите — и доступ вернётся сразу. |
Как это работает:
- Ступени с
hours_before > 0получают владельцы подписок ACTIVE и TRIAL; ступень «в момент истечения» — также LIMITED и EXPIRED. - Каждая ступень отправляется один раз на подписку на срок истечения (дедупликация в Redis на 7 дней). После продления срок меняется — лестница взводится заново.
- Задача ходит каждые 5 минут с 15-минутным окном назад, так что ступень не пропустится и не продублируется.
В тексте работают плейсхолдеры:
| Плейсхолдер | Подставляется |
|---|---|
{hours} | Число часов: 24 |
{time} | Число со склонением: «24 часа», «1 час», «12 часов» |
{plan} | Название тарифа из снапшота подписки |
У каждой ступени есть переключатель кнопки: под сообщением появится «Продлить», открывающая миниаппу. Кнопка показывается, только если в настройках задан https-адрес миниаппы (SUBSCRIPTION_MINI_APP_URL) — см. Миниаппа.
Дневное напоминание — legacy
Старый экран «умного напоминания» (дни в CSV + время отправки по МСК, плейсхолдер {days}) в кабинете остался, но самостоятельно больше не срабатывает — его заменила часовая лестница выше.
Возврат ушедших (win-back)
Воронка для «спящих»: через N дней после истечения подписки пользователь получает сообщение и одноразовую скидку на следующую покупку.
| Параметр ступени | Значение |
|---|---|
offset_days | Дней после истечения, 1–365, уникально на ступень |
text | Сообщение, плейсхолдер {discount}; по умолчанию «Мы скучаем! Вернитесь со скидкой {discount}% на любой тариф.» |
discount_pct | Одноразовая скидка на покупку, % |
send_time | Время отправки по МСК, по умолчанию 12:00 |
enabled | Вкл/выкл ступени |
Ступень срабатывает по пользователям, чья подписка истекла ровно offset_days МСК-дней назад — так пользователь проходит воронку ступень за ступенью. Скидка записывается на пользователя как одноразовая и списывается при следующей покупке; если у него уже есть скидка больше — остаётся большая. Не больше одного win-back-сообщения пользователю в день. Под сообщением — кнопка «Вернуться» в миниаппу.
Праздничный календарь
Календарь акций по датам. При первом открытии засевается набором дат РФ (Новый год, Рождество, 23 февраля, 8 марта, 1 мая, День Победы, День России, 1 сентября, День народного единства, Чёрная пятница, Новогодняя ночь) — все выключены, включаете нужные.
У каждого праздника настраиваются:
| Параметр | Значение |
|---|---|
enabled | По умолчанию выключен |
reward_type | discount (скидка %), days (бонусные дни) или balance (бонус на баланс, в копейках) |
value | Размер награды |
send_time | Время отправки по МСК, по умолчанию 10:00 |
В день праздника в заданное время все активные пользователи бота получают сообщение — текст собирается по типу награды, например: «🎉 Новый год! Скидка -20% на продление — только сегодня!». Отправка идёт с паузой 40 мс (~25 сообщений/с) и выполняется один раз в год на праздник. Число доставленных сообщений сохраняется по годам и видно в кабинете рядом с праздником.
МСК везде
Время отправки win-back и праздничных акций задаётся по московскому времени и срабатывает в 5-минутном окне после указанного значения.
