Skip to content

Commit

Permalink
уведомления в телеграме
Browse files Browse the repository at this point in the history
  • Loading branch information
Marker-bit committed Aug 17, 2024
1 parent b0b26b5 commit 42ff040
Show file tree
Hide file tree
Showing 15 changed files with 702 additions and 26 deletions.
89 changes: 89 additions & 0 deletions alembic/versions/2fa551197c57_add_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Add notifications
Revision ID: 2fa551197c57
Revises: 387ad491f680
Create Date: 2024-08-16 20:35:22.382879
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "2fa551197c57"
down_revision: Union[str, None] = "387ad491f680"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
notificationintervaltype = sa.Enum(
"EVERY_DAY",
"OTHER_DAY",
"USER_CHOICE",
name="notificationintervaltype",
)
notificationintervaltype.create(op.get_bind(), checkfirst=True)
notificationweekdaytype = sa.Enum(
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY",
name="notificationweekdaytype",
)
notificationweekdaytype.create(op.get_bind(), checkfirst=True)
op.add_column(
"tg_users", sa.Column("notificate_at", sa.Integer(), nullable=True)
)
op.add_column(
"tg_users",
sa.Column(
"notification_interval", notificationintervaltype, nullable=True
),
)
op.add_column(
"tg_users",
sa.Column("notification_day", notificationweekdaytype, nullable=True),
)
op.add_column(
"tg_users",
sa.Column("notifications_enabled", sa.Boolean(), nullable=False, default=False),
)
op.add_column(
"vk_users", sa.Column("notificate_at", sa.Integer(), nullable=True)
)
op.add_column(
"vk_users",
sa.Column(
"notification_interval", notificationintervaltype, nullable=True
),
)
op.add_column(
"vk_users",
sa.Column("notification_day", notificationweekdaytype, nullable=True),
)
op.add_column(
"vk_users",
sa.Column("notifications_enabled", sa.Boolean(), nullable=False, default=False),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("vk_users", "notification_day")
op.drop_column("vk_users", "notification_interval")
op.drop_column("vk_users", "notificate_at")
op.drop_column("vk_users", "notifications_enabled")
op.drop_column("tg_users", "notification_day")
op.drop_column("tg_users", "notification_interval")
op.drop_column("tg_users", "notificate_at")
op.drop_column("tg_users", "notifications_enabled")
# ### end Alembic commands ###
16 changes: 16 additions & 0 deletions src/db/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,19 @@ class ButtonTypeEnum:
MAILING = "Рассылка"
ADMIN_MESSAGE = "Связь с админом"
NOTIFICATION = "Настройка уведомлений"


class NotificationInterval:
EVERY_DAY = "1"
OTHER_DAY = "2"
USER_CHOICE = "3"


class NotificationWeekDay:
MONDAY = "1"
TUESDAY = "2"
WEDNESDAY = "3"
THURSDAY = "4"
FRIDAY = "5"
SATURDAY = "6"
SUNDAY = "7"
38 changes: 36 additions & 2 deletions src/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
BigInteger,
ForeignKey,
Text,
Boolean
Boolean,
)
from sqlalchemy.ext.asyncio import (
AsyncAttrs,
Expand All @@ -22,7 +22,13 @@
from sqlalchemy.orm import sessionmaker, relationship, backref

from .config import database_url
from .constants import LinkResourseType, RoleName, ButtonTypeEnum
from .constants import (
LinkResourseType,
RoleName,
ButtonTypeEnum,
NotificationInterval,
NotificationWeekDay,
)

Base = declarative_base()

Expand Down Expand Up @@ -52,6 +58,26 @@ class ButtonType(enum.Enum):
NOTIFICATION = ButtonTypeEnum.NOTIFICATION


class NotificationIntervalType(enum.Enum):
"""Enum типов интервалов уведомлений."""

EVERY_DAY = NotificationInterval.EVERY_DAY
OTHER_DAY = NotificationInterval.OTHER_DAY
USER_CHOICE = NotificationInterval.USER_CHOICE


class NotificationWeekDayType(enum.Enum):
"""Enum типов дней недели."""

MONDAY = NotificationWeekDay.MONDAY
TUESDAY = NotificationWeekDay.TUESDAY
WEDNESDAY = NotificationWeekDay.WEDNESDAY
THURSDAY = NotificationWeekDay.THURSDAY
FRIDAY = NotificationWeekDay.FRIDAY
SATURDAY = NotificationWeekDay.SATURDAY
SUNDAY = NotificationWeekDay.SUNDAY


class TGUser(AsyncAttrs, Base):
"""Модель пользователя телеграм."""

Expand All @@ -60,6 +86,10 @@ class TGUser(AsyncAttrs, Base):
role = Column(Enum(RoleType), nullable=False)
is_admin = Column(Numeric, default=0)
created_at = Column(DateTime, default=func.now())
notificate_at = Column(Integer)
notification_interval = Column(Enum(NotificationIntervalType))
notification_day = Column(Enum(NotificationWeekDayType))
notifications_enabled = Column(Boolean(), default=False, nullable=False)
is_banned = Column(Numeric, default=0)
is_subscribed = Column(Boolean(), default=False)

Expand All @@ -72,6 +102,10 @@ class VKUser(AsyncAttrs, Base):
role = Column(Enum(RoleType), nullable=False)
is_admin = Column(Numeric, default=0)
created_at = Column(DateTime, default=func.now())
notificate_at = Column(Integer)
notification_interval = Column(Enum(NotificationIntervalType))
notification_day = Column(Enum(NotificationWeekDayType))
notifications_enabled = Column(Boolean(), default=False, nullable=False)
is_banned = Column(Numeric, default=0)
is_subscribed = Column(Boolean(), default=False)

Expand Down
13 changes: 12 additions & 1 deletion src/telegram_bot/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(parent_dir)
from db.models import ButtonType, RoleType # noqa
from db.models import ButtonType, RoleType, NotificationIntervalType, NotificationWeekDayType # noqa


class PromocodeDeleteCallback(CallbackData, prefix="promo_list_delete"):
Expand Down Expand Up @@ -85,3 +85,14 @@ class MailingButtonSettings(CallbackData, prefix="mailing_settings"):

class MailingButtonRole(CallbackData, prefix="mailing_role"):
role: Optional[RoleType]


class EnableNotifications(CallbackData, prefix="notify"):
is_enabled: bool
button_id: int


class NotificationIntervalCallback(CallbackData, prefix="notify_interval"):
interval: Optional[NotificationIntervalType]
button_id: int
day_of_week: Optional[NotificationWeekDayType] = None
1 change: 1 addition & 0 deletions src/telegram_bot/handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
from .admin_buttons_handler import router as admin_buttons_router # noqa
from .ask_admin_handler import router as ask_admin_router # noqa
from .admin_mailing_handler import router as admin_mailing_router # noqa
from .notification_handler import router as notification_router # noqa
4 changes: 2 additions & 2 deletions src/telegram_bot/handlers/admin_buttons_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,9 @@ async def button_add_type_handler(
"""Обработка выбора кнопки 'Добавить кнопку'."""
await callback.answer()

# await callback.message.delete()
await callback.message.delete()

await callback.message.edit_text(
await callback.message.answer(
"Введите текст на кнопке", reply_markup=kb.cancel
)
await state.set_state(AdminStates.waiting_on_button_text_create)
Expand Down
29 changes: 16 additions & 13 deletions src/telegram_bot/handlers/admin_mailing_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,23 @@ async def send_mailing_messages(callback: CallbackQuery, state: FSMContext):
state_data = await state.get_data()
async with async_session() as session:
async with session.begin():
stmt = select(TGUser).where(
and_(
(
TGUser.role == state_data["role"]
if state_data["role"]
else True
),
(
TGUser.is_subscribed == True
if state_data["ignore_subscribed"]
else True
),
if state_data["role"] is None and state_data["ignore_subscribed"]:
stmt = select(TGUser)
elif (
state_data["role"] is None
and not state_data["ignore_subscribed"]
):
stmt = select(TGUser).where(TGUser.is_subscribed.is_(True))
elif state_data["role"] and state_data["ignore_subscribed"]:
stmt = select(TGUser).where(TGUser.role == state_data["role"])
else:
stmt = select(TGUser).where(
and_(
TGUser.role == state_data["role"],
TGUser.is_subscribed.is_(True),
)
)
)

result = await session.execute(stmt)
tg_users: list[TGUser] = result.scalars().all()

Expand Down
Loading

0 comments on commit 42ff040

Please sign in to comment.