Питомец, который питается шагами бот в телеграмм

Начинающий
Статус
Оффлайн
Регистрация
14 Фев 2023
Сообщения
3
Реакции[?]
1
Поинты[?]
0
Всем привет. Попала в тупик, хотелось бы услышать ваши мысли по идее и коду)
Задумка: телеграмм бот игра по типу тамагочи. Кормить нужно шагами за день (один раз в день можно вводить число).
Сначала бот предлагает выбрать питомца, потом спрашивает сколько шагов за день пользователь прошел. Далее через 24 можно будет ввести шаги. Каждые 10 000 шагов переходит на новый уровень. Хочу потом картинки вставить (Midjourney ван лав). Все переменные, все данные должны храниться в базе.
Логика довольно простая, но технически я не так подкована, возникли проблемы. Далее напишу весь код. По-идее хоть что-то должно работать, но, к сожалению, даже после старта ничего не выводит. Я реально не понимаю, почему ничего не работает... Задумка как по мне интересная. Буду очень благодарна за ваши мысли и помощь!!!
my code:
import logging
import sqlite3
import asyncio
import re

from datetime import datetime, timedelta
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode
from aiogram.utils import executor

logging.basicConfig(level=logging.INFO)

bot_token = 'token'

bot = Bot(token=bot_token)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)

db = sqlite3.connect('main3.db')

class Pet(StatesGroup):
    waiting_for_pet_choice = State()
    waiting_for_steps_number = State()
    waiting_for_next_action = State()
    waiting_for_steps_choice = State()
    waiting_for_reminder_time = State()
    waiting_for_new_steps_number = State()

class PetAction(StatesGroup):
    waiting_for_action_choice = State()
    waiting_for_walk_time = State()

@dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
    await message.answer('Welcome to our pet tracker bot!\n'
                         'Please choose a pet to track:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Dog'), types.KeyboardButton(text='Cat')],
            [types.KeyboardButton(text='Rabbit'), types.KeyboardButton(text='Parrot')],
            [types.KeyboardButton(text='Myself')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()

@dp.message_handler(Text(equals=['Dog', 'Cat', 'Rabbit', 'Parrot']), state=Pet.waiting_for_pet_choice)
async def choose_pet(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = message.text
    await message.answer(f"You have chosen a {message.text}!\n"
                         "Please enter the number of steps your pet has taken today:")
    await Pet.waiting_for_steps_number.set()

@dp.message_handler(Text(equals=['Myself']), state=Pet.waiting_for_pet_choice)
async def choose_myself(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = 'Myself'
    await message.answer("You have chosen to track yourself!\n"
                         "Please enter the number of steps you have taken today:")
    await Pet.waiting_for_steps_number.set()

@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps_invalid(message: types.Message):
    await message.answer("Please enter a number.")

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['steps'] = int(message.text)
        data['username'] = message.from_user.username
        data['date'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    pet = data['pet']
    steps = data['steps']
    username = data['username']
    date = data['date']
    cursor = db.cursor()
    cursor.execute("INSERT INTO pet_tracker (pet, steps, username, date) VALUES (?, ?, ?, ?)", (pet, steps, username, date))
    db.commit()
    await message.answer(f"Great! Your {pet} has taken {steps} steps today.\n"
                         "What would you like to do next?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Check progress'), types.KeyboardButton(text='Set reminder')],
            [types.KeyboardButton(text='Change pet'), types.KeyboardButton(text='Exit')]
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_next_action.set()


@dp.message_handler(Text(equals=['Check progress']), state=Pet.waiting_for_next_action)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        result = cursor.fetchone()[0]
    if result is not None:
        await message.answer(f"Your {pet} has taken {result} steps in total.")
    else:
        await message.answer("You haven't logged any steps for your pet yet.")


@dp.message_handler(Text(equals=['Set reminder']), state=Pet.waiting_for_next_action)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        reminder_time = datetime.now() + timedelta(hours=24)
        reminder_text = f"Don't forget to log your {pet}'s steps today!"
    await bot.send_message(chat_id=message.chat.id, text=reminder_text, parse_mode=ParseMode.MARKDOWN)
    await message.answer(f"A reminder has been set for you to log your {pet}'s steps tomorrow.")
    await state.finish()


@dp.message_handler(Text(equals=['Change pet']), state=Pet.waiting_for_next_action)
async def change_pet(message: types.Message, state: FSMContext):
    await message.answer('Please choose a pet to track:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Dog'), types.KeyboardButton(text='Cat')],
            [types.KeyboardButton(text='Rabbit'), types.KeyboardButton(text='Parrot')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()


@dp.message_handler(Text(equals=['Exit']), state=Pet.waiting_for_next_action)
async def exit(message: types.Message, state: FSMContext):
    await message.answer('Goodbye!')
    await state.finish()
    await message.answer("What would you like to do next?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Log steps'), types.KeyboardButton(text='Check progress')],
            [types.KeyboardButton(text='Set reminder'), types.KeyboardButton(text='Change pet')],
            [types.KeyboardButton(text='Exit')],
            [types.KeyboardButton(text='Edit entry'), types.KeyboardButton(text='Delete entry')],
        ],
        resize_keyboard=True
    ))
    await Pet.next()


@dp.message_handler(Text(equals=['Check progress']), state=Pet.waiting_for_steps_choice)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        total_steps = cursor.fetchone()[0]
        await message.answer(f"Your {pet} has taken {total_steps} steps in total.")


@dp.message_handler(Text(equals=['Set reminder']), state=Pet.waiting_for_steps_choice)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        await message.answer(f"When would you like to receive a reminder to update your {pet}'s steps count?")
        await Pet.waiting_for_reminder_time.set()


@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder_invalid(message: types.Message):
    await message.answer("Please enter a number.")

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = int(message.text)
        pet = data['pet']
        reminder_time = data['reminder_time']
        reminder_datetime = datetime.now() + timedelta(hours=reminder_time)
        reminder_text = f"Don't forget to update your {pet}'s steps count!"
        await bot.send_message(chat_id=message.chat.id, text=reminder_text, reply_at=reminder_datetime)
        await message.answer(f"A reminder has been set to {reminder_time} hours from now.")
    await state.finish()


@dp.message_handler(Text(equals=['Edit entry']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("You haven't logged any steps for your pet yet.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Your {pet} has taken {current_steps} steps today.\n"
                              "Please enter the new number of steps:")
        await Pet.waiting_for_new_steps_number.set()


@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps_invalid(message: types.Message):
    await message.answer("Please enter a number.")

@dp.message_handler(Text(equals=['Edit entry']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("You haven't logged any steps for your pet yet.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Your {pet} has taken {current_steps} steps today.\n"
                             "Please enter the new number of steps:")
        await Pet.waiting_for_new_steps_number.set()

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['new_steps'] = int(message.text)
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("UPDATE pet_tracker SET steps=? WHERE pet=? AND username=?",
                       (data['new_steps'], pet, message.from_user.username))
        db.commit()
        await message.answer(f"Your {pet}'s steps count has been updated to {data['new_steps']}.\n"
                             "What would you like to do next?",
                             reply_markup=types.ReplyKeyboardMarkup(
                                 keyboard=[
                                     [types.KeyboardButton(text='Change pet'), types.KeyboardButton(text='Done')],
                                 ],
                                 resize_keyboard=True
                             ))
        await Pet.waiting_for_next_action.set()


@dp.message_handler(Text(equals=['Check progress', 'Set reminder', 'Change pet']), state=Pet.waiting_for_next_action)
async def process_next_action(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['next_action'] = message.text
        next_action = data['next_action']
        if next_action == 'Check progress':
            cursor = db.cursor()
            cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (data['pet'],))
            result = cursor.fetchone()
            total_steps = result[0] if result[0] is not None else 0
            await message.answer(f"You have recorded {total_steps} steps for your {data['pet']} so far.")
        elif next_action == 'Set reminder':
            await message.answer("What time do you want to receive the reminder? (Please enter in HH:MM format, 24-hour clock)")
            await Pet.waiting_for_reminder_time.set()
        elif next_action == 'Change pet':
            await message.answer('Please choose a pet to track:', reply_markup=types.ReplyKeyboardMarkup(
                keyboard=[
                    [types.KeyboardButton(text='Dog'), types.KeyboardButton(text='Cat')],
                    [types.KeyboardButton(text='Rabbit'), types.KeyboardButton(text='Parrot')],
                ],
                resize_keyboard=True
            ))
            await Pet.waiting_for_pet_choice.set()


@dp.message_handler(lambda message: not re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time_invalid(message: types.Message):
    await message.answer("Invalid format. Please enter time in HH:MM format, 24-hour clock.")

@dp.message_handler(lambda message: re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = message.text
        reminder_time = data['reminder_time']
        await message.answer(f"You will receive a reminder at {reminder_time} every day.")
        await state.finish()

async def send_reminder():
    while True:
        await asyncio.sleep(60)
        cursor = db.cursor()
        cursor.execute("SELECT DISTINCT username FROM pet_tracker")
        result = cursor.fetchall()
        for row in result:
            username = row[0]
            cursor.execute("SELECT pet, sum(steps) FROM pet_tracker WHERE username=? GROUP BY pet", (username,))
            result = cursor.fetchall()
            for row in result:
                pet = row[0]
                total_steps = row[1]
                if total_steps == 0:
                    continue
                cursor.execute("SELECT reminder_time FROM user_settings WHERE username=? AND pet=?", (username, pet))
                result = cursor.fetchone()
                if result is None or result[0] is None:
                    continue
                reminder_time = result[0]
                now = datetime.now()
                if now.strftime('%H:%M') == reminder_time:
                    await bot.send_message(chat_id=username, text=f"Don't forget to update the steps for your {pet} today!")


if __name__ == 'main':
    db.execute("CREATE TABLE IF NOT EXISTS pet_tracker (pet text, steps integer, username text, date text)")
    db.execute("CREATE TABLE IF NOT EXISTS user_settings (username text, pet text, reminder_time text)")
    db.commit()
    loop = asyncio.get_event_loop()
 
EFI_COMPROMISED_DATA
лучший в мире
Статус
Оффлайн
Регистрация
26 Янв 2018
Сообщения
920
Реакции[?]
1,632
Поинты[?]
85K
ты забыл(а) сам лонгполл стартануть, добавь в самом конце во внутрь if'а
executor.start_polling(dp, skip_updates=True)
 
Начинающий
Статус
Оффлайн
Регистрация
14 Фев 2023
Сообщения
3
Реакции[?]
1
Поинты[?]
0
ты забыл(а) сам лонгполл стартануть, добавь в самом конце во внутрь if'а
executor.start_polling(dp, skip_updates=True)
Действительно :fearscream: Спасибо за вашу внимательность! Код запустился
 
Начинающий
Статус
Оффлайн
Регистрация
14 Фев 2023
Сообщения
3
Реакции[?]
1
Поинты[?]
0
Хоть код запустился, но всё равно не полностью работает. Сначала просит (как надо) выбрать питомца, потом спрашивает количество шагов, а вот после второе меню вообще не активно, кнопки не нажимаются, и другие кнопки не активны почему-то.
А еще данные должны сохраняться в базе на компе, но они не сохраняются. В коде ошибки?((
У меня реально голова пухнет, взгляд замылился. Посмотрите, пожалуйста, код еще раз. Может вы найдете и подскажите, что нужно исправить. Буду очень благодарна, спасибо заранее!

my code 2:
import logging
import sqlite3
import asyncio
import re

from datetime import datetime, timedelta
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode
from aiogram.utils import executor

logging.basicConfig(level=logging.INFO)

bot_token = 'token'

bot = Bot(token=bot_token)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)

db = sqlite3.connect('main3.db')

class Pet(StatesGroup):
    waiting_for_pet_choice = State()
    waiting_for_steps_number = State()
    waiting_for_next_action = State()
    waiting_for_steps_choice = State()
    waiting_for_reminder_time = State()
    waiting_for_new_steps_number = State()

class PetAction(StatesGroup):
    waiting_for_action_choice = State()
    waiting_for_walk_time = State()

@dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
    await message.answer('Добро пожаловать на наш бот!\n'
                         'Пожалуйста, выберите животное для отслеживания:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
            [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Попугай')],
            [types.KeyboardButton(text='Myself')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()

@dp.message_handler(Text(equals=['Собака', 'Кот', 'Кролик', 'Попугай']), state=Pet.waiting_for_pet_choice)
async def choose_pet(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = message.text
    await message.answer(f"Вы выбрали {message.text}!\n"
                         "Пожалуйста, введите количество шагов, которые вы сделали сегодня:")
    await Pet.waiting_for_steps_number.set()

@dp.message_handler(Text(equals=['Myself']), state=Pet.waiting_for_pet_choice)
async def choose_myself(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['pet'] = 'Myself'
    await message.answer("You have chosen to track yourself!\n"
                         "Пожалуйста, введите количество шагов, которые вы сделали сегодня:")
    await Pet.waiting_for_steps_number.set()

@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps_invalid(message: types.Message):
    await message.answer("Напишите количество шагов числом.")

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_steps_number)
async def process_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['steps'] = int(message.text)
        data['username'] = message.from_user.username
        data['date'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    pet = data['pet']
    steps = data['steps']
    username = data['username']
    date = data['date']
    cursor = db.cursor()
    cursor.execute("INSERT INTO pet_tracker (pet, steps, username, date) VALUES (?, ?, ?, ?)", (pet, steps, username, date))
    db.commit()
    await message.answer(f"Отлично! Вы покормили {pet} {steps} шагами.\n"
                         "Что бы вы хотели сделать дальше?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Проверить прогресс'), types.KeyboardButton(text='Установить напоминание')],
            [types.KeyboardButton(text='Поменять питомца'), types.KeyboardButton(text='Выйти')]
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_next_action.set()


@dp.message_handler(Text(equals=['Проверить прогресс']), state=Pet.waiting_for_next_action)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        result = cursor.fetchone()[0]
    if result is not None:
        await message.answer(f"Вы прошли {result} шагов.")
    else:
        await message.answer("Вы еще не зарегистрировали ни одного шага для своего питомца.")


@dp.message_handler(Text(equals=['Установить напоминание']), state=Pet.waiting_for_next_action)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        reminder_time = datetime.now() + timedelta(hours=24)
        reminder_text = f"Не забудьте сегодня покормить {pet}!"
    await bot.send_message(chat_id=message.chat.id, text=reminder_text, parse_mode=ParseMode.MARKDOWN)
    await message.answer(f"Для вас было установлено напоминание о необходимости зарегистрировать шаги завтра.")
    await state.finish()


@dp.message_handler(Text(equals=['Поменять питомца']), state=Pet.waiting_for_next_action)
async def change_pet(message: types.Message, state: FSMContext):
    await message.answer('Пожалуйста, выберите животное:', reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
            [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Попугай')],
        ],
        resize_keyboard=True
    ))
    await Pet.waiting_for_pet_choice.set()


@dp.message_handler(Text(equals=['Выйти']), state=Pet.waiting_for_next_action)
async def exit(message: types.Message, state: FSMContext):
    await message.answer('Прощайте!')
    await state.finish()
    await message.answer("Что бы вы хотели сделать дальше?", reply_markup=types.ReplyKeyboardMarkup(
        keyboard=[
            [types.KeyboardButton(text='Шаги в журнале'), types.KeyboardButton(text='Проверить прогресс')],
            [types.KeyboardButton(text='Отправить напоминание'), types.KeyboardButton(text='Поменять питомца')],
            [types.KeyboardButton(text='Выйти')],
            [types.KeyboardButton(text='Редактировать запись'), types.KeyboardButton(text='Удалить запись')],
        ],
        resize_keyboard=True
    ))
    await Pet.next()


@dp.message_handler(Text(equals=['Проверить прогресс']), state=Pet.waiting_for_steps_choice)
async def check_progress(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (pet,))
        total_steps = cursor.fetchone()[0]
        await message.answer(f"У вас всего {total_steps} шагов.")


@dp.message_handler(Text(equals=['Отправить напоминание']), state=Pet.waiting_for_steps_choice)
async def set_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        await message.answer(f"Когда вы хотите получать напоминание о необходимости обновить количество шагов?")
        await Pet.waiting_for_reminder_time.set()


@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder_invalid(message: types.Message):
    await message.answer("Введите число.")

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_reminder_time)
async def process_reminder(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = int(message.text)
        pet = data['pet']
        reminder_time = data['reminder_time']
        reminder_datetime = datetime.now() + timedelta(hours=reminder_time)
        reminder_text = f"Не забудьте покормить своего питомца шагами!"
        await bot.send_message(chat_id=message.chat.id, text=reminder_text, reply_at=reminder_datetime)
        await message.answer(f"Мы напомним вам через {reminder_time} часов.")
    await state.finish()


@dp.message_handler(Text(equals=['Редактировать запись']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("Вы еще не зарегистрировали ни одного шага.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Вы сделали {current_steps} шагов сегодня.\n"
                              "Пожалуйста, введите новое уоличество шагов:")
        await Pet.waiting_for_new_steps_number.set()


@dp.message_handler(lambda message: not message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps_invalid(message: types.Message):
    await message.answer("Введите число.")

@dp.message_handler(Text(equals=['Редактировать запись']), state=Pet.waiting_for_steps_choice)
async def edit_entry(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("SELECT steps FROM pet_tracker WHERE pet=? AND username=?", (pet, message.from_user.username))
        row = cursor.fetchone()
        if not row:
            await message.answer("Вы еще не зарегистрировали шаги.")
            await state.finish()
            return
        current_steps = row[0]
        await message.answer(f"Вы сделали {current_steps} шагов сегодня.\n"
                             "Пожалуйста, введите новое количество шагов:")
        await Pet.waiting_for_new_steps_number.set()

@dp.message_handler(lambda message: message.text.isdigit(), state=Pet.waiting_for_new_steps_number)
async def process_new_steps(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['new_steps'] = int(message.text)
        pet = data['pet']
        cursor = db.cursor()
        cursor.execute("UPDATE pet_tracker SET steps=? WHERE pet=? AND username=?",
                       (data['new_steps'], pet, message.from_user.username))
        db.commit()
        await message.answer(f"Количество шагов было обновлено: {data['new_steps']}.\n"
                             "Что бы вы хотели сделать дальше?",
                             reply_markup=types.ReplyKeyboardMarkup(
                                 keyboard=[
                                     [types.KeyboardButton(text='Поменять питомца'), types.KeyboardButton(text='Готово')],
                                 ],
                                 resize_keyboard=True
                             ))
        await Pet.waiting_for_next_action.set()


@dp.message_handler(Text(equals=['Проверить прогресс', 'Отправить напоминание', 'Поменять питомца']), state=Pet.waiting_for_next_action)
async def process_next_action(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['next_action'] = message.text
        next_action = data['next_action']
        if next_action == 'Проверить прогресс':
            cursor = db.cursor()
            cursor.execute("SELECT sum(steps) FROM pet_tracker WHERE pet=?", (data['pet'],))
            result = cursor.fetchone()
            total_steps = result[0] if result[0] is not None else 0
            await message.answer(f"Вы зарегистрировали {total_steps} шагов.")
        elif next_action == 'Отправить напоминание':
            await message.answer("В какое время вы хотите получать напоминание? (Пожалуйста, введите в формате ЧЧ:ММ, 24-часовые часы)")
            await Pet.waiting_for_reminder_time.set()
        elif next_action == 'Поменять питомца':
            await message.answer('Выберите питомца:', reply_markup=types.ReplyKeyboardMarkup(
                keyboard=[
                    [types.KeyboardButton(text='Собака'), types.KeyboardButton(text='Кот')],
                    [types.KeyboardButton(text='Кролик'), types.KeyboardButton(text='Кролик')],
                ],
                resize_keyboard=True
            ))
            await Pet.waiting_for_pet_choice.set()


@dp.message_handler(lambda message: not re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time_invalid(message: types.Message):
    await message.answer("Invalid format. Please enter time in HH:MM format, 24-hour clock.")

@dp.message_handler(lambda message: re.match(r'^\d{2}:\d{2}$', message.text), state=Pet.waiting_for_reminder_time)
async def process_reminder_time(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['reminder_time'] = message.text
        reminder_time = data['reminder_time']
        await message.answer(f"Мы будем напоминать в {reminder_time} каждый день.")
        await state.finish()

async def send_reminder():
    while True:
        await asyncio.sleep(60)
        cursor = db.cursor()
        cursor.execute("SELECT DISTINCT username FROM pet_tracker")
        result = cursor.fetchall()
        for row in result:
            username = row[0]
            cursor.execute("SELECT pet, sum(steps) FROM pet_tracker WHERE username=? GROUP BY pet", (username,))
            result = cursor.fetchall()
            for row in result:
                pet = row[0]
                total_steps = row[1]
                if total_steps == 0:
                    continue
                cursor.execute("SELECT reminder_time FROM user_settings WHERE username=? AND pet=?", (username, pet))
                result = cursor.fetchone()
                if result is None or result[0] is None:
                    continue
                reminder_time = result[0]
                now = datetime.now()
                if now.strftime('%H:%M') == reminder_time:
                    await bot.send_message(chat_id=username, text=f"Не забульте написать количество шагов за сегодня!")


if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
    db.execute("CREATE TABLE IF NOT EXISTS pet_tracker (pet text, steps integer, username text, date text)")
    db.execute("CREATE TABLE IF NOT EXISTS user_settings (username text, pet text, reminder_time text)")
    db.commit()
    loop = asyncio.get_event_loop()
 
Сверху Снизу