Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion telegram_bot_project/.example.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
# General Configs
BOT_TOKEN=TELEGRAM_BOT_TOKEN
DATABASE_URL=db_driver+asyncpg://username:password@host:port/db_username
DATABASE_URL=db_driver+asyncpg://username:password@host:port/db_username

# SMTP (Simple Mail Transfer Protocol) Configuration
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=user@example.com
SMTP_PASSWORD=Password
SMTP_USE_TLS=True
SMTP_SLL=False
SMTP_MESSAGE_SUBJECT=SUBJECT
SMTP_FROM_EMAIL=user@example.com
SMTP_MESSAGE_RECEIVER=receiver@example.com
12 changes: 12 additions & 0 deletions telegram_bot_project/bot/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,15 @@ async def show_evening_routines(message: types.Message):
)

await message.answer(formatted_morning_routine, reply_markup=evening_routine_keyboard())

# Send feedback message command
async def send_feedback_command(message: types.Message, state: FSMContext):
user_id: int = message.from_user.id
user_find: Any = await UserService.get_user_by_id(user_id)
language: str = await UserService.get_user_language(user_id)

if not user_find:
await message.answer(MESSAGES['ENGLISH']['AUTHORIZATION_PROBLEM'])
else:
await message.answer(MESSAGES[language]['SMTP_MESSAGE_TEXT'])
await state.set_state(DialogStates.feedback_message)
25 changes: 24 additions & 1 deletion telegram_bot_project/bot/handlers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, message

from service.smtp import SmtpService
from bot.buttons import *
from messages import MESSAGES
from service.idea import IdeaService
Expand Down Expand Up @@ -470,4 +471,26 @@ async def process_save_updated_morning_routine(message: Message, state: FSMConte
await message.answer(MESSAGES[language]['ROUTINE_NAME_SET'].format(routine_title), reply_markup=routine_keyboard)
await state.clear()
except:
await message.answer(MESSAGES[language]['ROUTINE_EXISTS'], reply_markup=routine_keyboard)
await message.answer(MESSAGES[language]['ROUTINE_EXISTS'], reply_markup=routine_keyboard)


async def process_feedback_message(message: Message, state: FSMContext):
user_id = message.from_user.id
user_find = await UserService.get_user_by_id(user_id)
user_name = message.from_user.username
language = await UserService.get_user_language(user_id) or "ENGLISH"

if not user_find:
await message.answer(MESSAGES["ENGLISH"]['AUTHORIZATION_PROBLEM'])
return

feedback_message = message.text.strip()
if not feedback_message:
await message.answer(MESSAGES["ENGLISH"]['INVALID_MESSAGE'])
return

print("-- [INFO] - Feedback message from user with id: {user_id} is: {feedback_message}")
await SmtpService.send_feedback_message(feedback_message, user_id, user_name)
await message.answer(MESSAGES[language]['SMTP_MESSAGE_SENT'], reply_markup=settings_menu_keyboard())
await state.clear()

16 changes: 16 additions & 0 deletions telegram_bot_project/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from contextlib import asynccontextmanager
from dataclasses import dataclass

load_dotenv()

Expand All @@ -27,3 +28,18 @@ def get_token() -> str:
async def get_session() -> AsyncSession:
async with async_session() as session:
yield session

@dataclass
class SmtpData:
smtp_user: str = os.getenv("SMTP_USER")
smtp_password: str = os.getenv("SMTP_PASSWORD")
smtp_host: str = os.getenv("SMTP_HOST")
smtp_port: int = int(os.getenv("SMTP_PORT"))
smtp_ssl: bool = os.getenv("SMTP_SSL") == "True"
smtp_tsl: bool = os.getenv("SMTP_TLS") == "True"
smtp_from: str = os.getenv("SMTP_USER")
smtp_receiver: str = os.getenv("SMTP_MESSAGE_RECEIVER")
smtp_subject: str = os.getenv("SMTP_MESSAGE_SUBJECT")

def get_smtp_data() -> SmtpData:
return SmtpData()
10 changes: 10 additions & 0 deletions telegram_bot_project/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ async def evening_routines_show(message: types.Message):
async def morning_routines(message: Message):
await show_evening_routines(message)

@dp.message(Command("feedback"))
async def feedback(message: Message, state: FSMContext):
await send_feedback_command(message, state)

@dp.message(lambda m: m.text == SETTINGS_BUTTON_FEEDBACK)
async def feedback(message: Message, state: FSMContext):
await send_feedback_command(message, state)

@dp.message(lambda m: m.text == ROUTINE_EVENING_VIEW)
async def evening_routines_view(message: types.Message):
await show_evening_routines(message)
Expand Down Expand Up @@ -269,6 +277,8 @@ async def process_fallback(message: Message, state: FSMContext):
data = await state.get_data()
routine_type = data.get("routine_type", "morning")
await process_update_morning_routine(message, state, type=routine_type)
elif current_state == DialogStates.feedback_message:
await process_feedback_message(message, state)

# Main Function
async def main():
Expand Down
22 changes: 22 additions & 0 deletions telegram_bot_project/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@
"ROUTINE_DELETED": "Розпорядок видалено",
"NEW_ROUTINE_NAME": "Будь ласка, введи нову назву розпорядку:",
"ROUTINE_NAME_SET": "Нову назву розпорядку успішно змінено на «{}».",
"SMTP_MESSAGE_TEXT": "Будь ласка, залиш свій відгук нижче:",
"SMTP_MESSAGE_SENT": "Дякуємо за твій відгук, наша команда перевірить це повідомлення",
"INVALID_MESSAGE": "Будь ласка, введи коректний текст.",
"LANGUAGE_ASK": (
"🌐 **Оберіть мову інтерфейсу:**\n"
"Натисніть кнопку нижче ⬇️"
Expand Down Expand Up @@ -157,6 +160,9 @@
"ROUTINE_DELETED": "Routine deleted",
"NEW_ROUTINE_NAME": "Please enter the new routine name:",
"ROUTINE_NAME_SET": "New routine name successfully set to {}.",
"INVALID_MESSAGE": "Please enter valid text.",
"SMTP_MESSAGE_TEXT": "Please provide your feedback below:",
"SMTP_MESSAGE_SENT": "Thank for your feedback our team will check this message",
"ROUTINE_TIME": (
"⏰ Your routine:\n"
"• Wake-up time: {}\n"
Expand Down Expand Up @@ -222,4 +228,20 @@
EVENING_ROUTINE_EDIT_BTN = "✏️ Edit Evening"
MY_EVENING_ROUTINE_BTN = "🌙 My Evening Routine"

USER_FEEDBACK_MAIL_TEXT = """
📬 New User Feedback Received!

Here’s what the user had to say:

------------------------
{feedback}
------------------------

🧑‍💻 User Info:
- Username: {username}
- User ID: {user_id}
- Date: {date}

Please review it and take action if needed.
"""

42 changes: 42 additions & 0 deletions telegram_bot_project/service/smtp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import aiosmtplib
from datetime import datetime
from email.mime.text import MIMEText
from bot.utills import validate_text
from config import SmtpData, get_smtp_data
from messages import USER_FEEDBACK_MAIL_TEXT

smtp_data: SmtpData = get_smtp_data()
if not smtp_data:
raise Exception("-- [ERROR] - SMTP data not found.")

class SmtpService:
@staticmethod
async def send_feedback_message(user_message: str, user_id: int, user_name: str):
if not validate_text(user_message):
print("-- [ERROR] - Invalid message.")
return

email_body: str = USER_FEEDBACK_MAIL_TEXT.format(
feedback=user_message,
username=user_name,
user_id=user_id,
date=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)

email_message = MIMEText(email_body, "plain")
email_message['Subject'] = smtp_data.smtp_subject
email_message['From'] = smtp_data.smtp_from
email_message['To'] = smtp_data.smtp_receiver

try:
await aiosmtplib.send(
email_message,
hostname=smtp_data.smtp_host,
port=smtp_data.smtp_port,
start_tls=True,
username=smtp_data.smtp_user,
password=smtp_data.smtp_password,
)
print("-- [INFO] - Feedback message sent successfully.")
except Exception as e:
print(f"-- [ERROR] - Failed to send feedback message: {e}")
3 changes: 2 additions & 1 deletion telegram_bot_project/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ class DialogStates(StatesGroup):
add_morning_routine = State()
delete_morning_routine = State()
update_morning_routine = State()
update_morning_routine_id = State()
update_morning_routine_id = State()
feedback_message = State()