Skip to content

Commit

Permalink
fix error with telegram form
Browse files Browse the repository at this point in the history
  • Loading branch information
Teri-anric committed Nov 29, 2024
1 parent d520124 commit 9aa9ace
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 44 deletions.
1 change: 0 additions & 1 deletion apps/web_app/.env.dev
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
DERISK_API_URL=#

ENV=dev
# PostgreSQL
DB_USER=postgres
DB_PASSWORD=password
Expand Down
2 changes: 1 addition & 1 deletion apps/web_app/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class NotificationData(Base):
email = Column(String, index=True, nullable=True)
wallet_id = Column(String, nullable=False)
telegram_id = Column(String, unique=False, nullable=False)
ip_address = Column(IPAddressType, nullable=False)
ip_address = Column(IPAddressType, nullable=True)
health_ratio_level = Column(Float, nullable=False)
protocol_id = Column(ChoiceType(ProtocolIDs, impl=String()), nullable=False)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""ip address nullable true
Revision ID: b3179b2fff8b
Revises: f4baaac5103f
Create Date: 2024-11-29 18:44:44.613470
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils


# revision identifiers, used by Alembic.
revision: str = "b3179b2fff8b"
down_revision: Union[str, None] = "f4baaac5103f"
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! ###
op.alter_column(
"notification",
"ip_address",
existing_type=sa.VARCHAR(length=50),
nullable=True,
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"notification",
"ip_address",
existing_type=sa.VARCHAR(length=50),
nullable=False,
)
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion apps/web_app/telegram/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ async def bot_start_polling():


if __name__ == "__main__":
if os.getenv("ENV") == "DEV":
if bot is not None:
loop = asyncio.get_event_loop()
loop.run_until_complete(bot_start_polling())
5 changes: 5 additions & 0 deletions apps/web_app/telegram/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,8 @@ async def get_objects_by_filter(
if limit == 1:
return await db.scalar(stmp)
return await db.scalars(stmp).all()

async def write_to_db(self, obj: ModelType) -> None:
async with self.Session() as db:
db.add(obj)
await db.commit()
109 changes: 68 additions & 41 deletions apps/web_app/telegram/handlers/create_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,131 @@
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from database.models import NotificationData
from database.schemas import NotificationForm
from telegram.crud import TelegramCrud
from utils.values import ProtocolIDs
from fastapi import status

create_notification_router = Router()


class NotificationFormStates(StatesGroup):
"""States for the notification form process."""
wallet_id = State()
health_ratio_level = State()
protocol_id = State()


@create_notification_router.callback_query(F.data == "create_subscription")
async def start_form(callback: types.CallbackQuery, state: FSMContext):
"""Initiates the notification creation form by asking for the wallet ID."""
await state.set_state(NotificationFormStates.wallet_id)
await callback.message.edit_text(
"Please enter your wallet ID:",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
])
reply_markup=types.InlineKeyboardMarkup(
inline_keyboard=[
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
]
),
)


@create_notification_router.message(NotificationFormStates.wallet_id)
async def process_wallet_id(message: types.Message, state: FSMContext):
"""Processes the wallet ID input from the user."""
await state.update_data(wallet_id=message.text)
await state.set_state(NotificationFormStates.health_ratio_level)
await message.answer(
"Please enter your health ratio level (between 0 and 10):",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
])
reply_markup=types.InlineKeyboardMarkup(
inline_keyboard=[
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
]
),
)


@create_notification_router.message(NotificationFormStates.health_ratio_level)
async def process_health_ratio(message: types.Message, state: FSMContext):
"""Processes the health ratio level input from the user."""
try:
health_ratio = float(message.text)
if not (0 <= health_ratio <= 10):
raise ValueError

await state.update_data(health_ratio_level=health_ratio)
await state.set_state(NotificationFormStates.protocol_id)

# Create protocol selection buttons
protocol_buttons = []
for protocol in ProtocolIDs:
protocol_buttons.append([
types.InlineKeyboardButton(
text=protocol.value,
callback_data=f"protocol_{protocol.value}"
)
])
protocol_buttons.append([
types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")
])

protocol_buttons.append(
[
types.InlineKeyboardButton(
text=protocol.value, callback_data=f"protocol_{protocol.value}"
)
]
)
protocol_buttons.append(
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
)

await message.answer(
"Please select your protocol:",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=protocol_buttons)
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=protocol_buttons),
)
except ValueError:
await message.answer(
"Please enter a valid number between 0 and 10.",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="Cancel", callback_data="cancel_form")]
])
reply_markup=types.InlineKeyboardMarkup(
inline_keyboard=[
[
types.InlineKeyboardButton(
text="Cancel", callback_data="cancel_form"
)
]
]
),
)


@create_notification_router.callback_query(F.data.startswith("protocol_"))
async def process_protocol(callback: types.CallbackQuery, state: FSMContext, crud: TelegramCrud):
async def process_protocol(
callback: types.CallbackQuery, state: FSMContext, crud: TelegramCrud
):
"""Processes the selected protocol and saves the subscription data."""
protocol_id = callback.data.replace("protocol_", "")
form_data = await state.get_data()
notification = NotificationForm(
wallet_id=form_data["wallet_id"],
health_ratio_level=form_data["health_ratio_level"],
data = await state.get_data()

subscription = NotificationData(
wallet_id=data["wallet_id"],
health_ratio_level=data["health_ratio_level"],
protocol_id=protocol_id,
telegram_id=str(callback.from_user.id),
email=""
email=None,
ip_address=None,
)

subscription = NotificationData(**notification.model_dump())
subscription_id = crud.write_to_db(obj=subscription)

await crud.write_to_db(subscription)

await state.clear()
await callback.message.edit_text(
"Subscription created successfully!",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="Go to menu", callback_data="go_menu")]
])
reply_markup=types.InlineKeyboardMarkup(
inline_keyboard=[
[types.InlineKeyboardButton(text="Go to menu", callback_data="go_menu")]
]
),
)


@create_notification_router.callback_query(F.data == "cancel_form")
async def cancel_form(callback: types.CallbackQuery, state: FSMContext):
"""Cancels the form and clears the state."""
await state.clear()
await callback.message.edit_text(
"Form cancelled.",
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="Go to menu", callback_data="go_menu")]
])
)
reply_markup=types.InlineKeyboardMarkup(
inline_keyboard=[
[types.InlineKeyboardButton(text="Go to menu", callback_data="go_menu")]
]
),
)

0 comments on commit 9aa9ace

Please sign in to comment.