-
Автор темы
- #1
Всем привет. Попала в тупик, хотелось бы услышать ваши мысли по идее и коду)
Задумка: телеграмм бот игра по типу тамагочи. Кормить нужно шагами за день (один раз в день можно вводить число).
Сначала бот предлагает выбрать питомца, потом спрашивает сколько шагов за день пользователь прошел. Далее через 24 можно будет ввести шаги. Каждые 10 000 шагов переходит на новый уровень. Хочу потом картинки вставить (Midjourney ван лав). Все переменные, все данные должны храниться в базе.
Логика довольно простая, но технически я не так подкована, возникли проблемы. Далее напишу весь код. По-идее хоть что-то должно работать, но, к сожалению, даже после старта ничего не выводит. Я реально не понимаю, почему ничего не работает... Задумка как по мне интересная. Буду очень благодарна за ваши мысли и помощь!!!
Задумка: телеграмм бот игра по типу тамагочи. Кормить нужно шагами за день (один раз в день можно вводить число).
Сначала бот предлагает выбрать питомца, потом спрашивает сколько шагов за день пользователь прошел. Далее через 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()