Бот-напоминалка
Соберём всё вместе — команды, проверку ввода, списки и, главное, само срабатывание напоминаний.
Время и полночь
Пользователь пишет «напомни в 07:00». Если сейчас 23:00, это завтра. Удобно считать время в минутах от полуночи и брать разность по модулю суток:
diff = ((h * 60 + m) - (now_h * 60 + now_m)) % 1440 # 0 … 1439
return diff or 1440 # совпадение — через сутки
В Python остаток от деления на положительное число всегда неотрицательный: -30 % 1440 == 1410.
Данные каждого пользователя
Напоминания хранят отдельно для каждого человека — по message.from_user.id:
REMINDERS = {} # id → список (время, текст)
items = REMINDERS.setdefault(message.from_user.id, [])
setdefault возвращает список пользователя, создавая пустой при первом обращении. Для настоящего бота данные кладут в базу (например, SQLite через aiosqlite) — иначе они пропадут при перезапуске.
Фоновые задачи
Обработчик должен ответить сразу. Ожидание до напоминания запускают отдельной задачей:
tasks = set()
async def fire(bot, chat_id, delay, text):
await asyncio.sleep(delay)
await bot.send_message(chat_id, "⏰ " + text)
@router.message(Command("in"))
async def remind_in(message: Message, command: CommandObject, bot: Bot):
task = asyncio.create_task(fire(bot, message.chat.id, delay, text))
tasks.add(task) # держим ссылку, чтобы задачу не удалил сборщик мусора
task.add_done_callback(tasks.discard)
await message.answer("Запомнил")
asyncio.create_taskзапускает корутину в фоне и сразу возвращается;- пока задача спит, бот обрабатывает другие сообщения — тысячи напоминаний живут одновременно;
bot.send_message(chat_id, текст)— бот пишет сам, не в ответ на сообщение. Объектbotaiogram передаст в обработчик, если добавить параметрbot: Bot.
Если await fire(...) написать прямо в обработчике, он «зависнет» до срабатывания напоминания, и пользователь не получит даже «Запомнил».
Для серьёзного расписания (повторы, напоминания после перезапуска) используют библиотеки вроде APScheduler.
Запуск по-настоящему
- В Telegram откройте @BotFather, команда
/newbot, придумайте имя — получите токен. - Задайте переменную окружения: в PowerShell
$env:BOT_TOKEN = "123456:ABC…", в терминале macOS/Linuxexport BOT_TOKEN=123456:ABC…. - Запустите программу и напишите своему боту в Telegram.
Чтобы бот работал круглосуточно, его запускают на сервере (VPS) или в облаке.
Итог
- время до напоминания — по модулю 1440, совпадение — через сутки;
- данные — по
from_user.id,setdefault; asyncio.create_taskдля ожидания,bot.send_messageдля отправки;- токен — только из переменной окружения.