239 lines
8.8 KiB
Python
239 lines
8.8 KiB
Python
from random import randint
|
||
import re
|
||
import asyncio
|
||
import logging
|
||
from datetime import datetime
|
||
from aiogram import F
|
||
from aiogram.types import Message
|
||
from aiogram.filters import Command, CommandObject, CommandStart
|
||
from aiogram import Bot, Dispatcher, types
|
||
from aiogram.client.default import DefaultBotProperties
|
||
from aiogram.enums import ParseMode
|
||
# новый импорт!
|
||
from aiogram.utils.keyboard import ReplyKeyboardBuilder
|
||
# Новые импорты!
|
||
from contextlib import suppress
|
||
from aiogram.exceptions import TelegramBadRequest
|
||
|
||
|
||
from config_reader import config
|
||
|
||
# Включаем логирование, чтобы не пропустить важные сообщения
|
||
logging.basicConfig(level=logging.INFO)
|
||
|
||
# Для записей с типом Secret* необходимо
|
||
# вызывать метод get_secret_value(),
|
||
# чтобы получить настоящее содержимое вместо '*******'
|
||
bot = Bot(
|
||
token=config.bot_token.get_secret_value(),
|
||
default=DefaultBotProperties(
|
||
parse_mode=ParseMode.HTML
|
||
# тут ещё много других интересных настроек
|
||
))
|
||
|
||
# Объект бота напрямую из .env
|
||
# bot = Bot(token=os.getenv("BOT_TOKEN"))
|
||
|
||
# Диспетчер
|
||
dp = Dispatcher()
|
||
dp["started_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||
|
||
# @dp.message(Command("start"))
|
||
async def cmd_start(message: types.Message):
|
||
kb = [
|
||
[
|
||
types.KeyboardButton(text="С пюрешкой"),
|
||
types.KeyboardButton(text="Без пюрешки")
|
||
],
|
||
]
|
||
keyboard = types.ReplyKeyboardMarkup(
|
||
keyboard=kb,
|
||
resize_keyboard=True,
|
||
input_field_placeholder="Выберите способ подачи"
|
||
)
|
||
await message.answer("Как подавать котлеты?", reply_markup=keyboard)
|
||
|
||
@dp.message(F.text.lower() == "с пюрешкой")
|
||
async def with_puree(message: types.Message):
|
||
await message.reply("Отличный выбор!", reply_markup=types.ReplyKeyboardRemove()) #удалим клавиатуру после ответа
|
||
|
||
@dp.message(F.text.lower() == "без пюрешки")
|
||
async def without_puree(message: types.Message):
|
||
await message.reply("Так невкусно!")
|
||
|
||
|
||
@dp.message(Command("reply_builder"))
|
||
async def reply_builder(message: types.Message):
|
||
builder = ReplyKeyboardBuilder()
|
||
for i in range(1, 17):
|
||
builder.add(types.KeyboardButton(text=str(i)))
|
||
builder.adjust(4)
|
||
await message.answer(
|
||
"Выберите число:",
|
||
reply_markup=builder.as_markup(resize_keyboard=True),
|
||
)
|
||
|
||
@dp.message(F.text.lower() == "10")
|
||
async def with_puree(message: types.Message):
|
||
await message.reply("Отличный выбор!", reply_markup=types.ReplyKeyboardRemove()) #удалим клавиатуру после ответа
|
||
|
||
@dp.message(Command("help"))
|
||
@dp.message(CommandStart(
|
||
deep_link=True, magic=F.args == "help"
|
||
))
|
||
async def cmd_start_help(message: Message):
|
||
await message.answer("Это сообщение со справкой")
|
||
|
||
|
||
@dp.message(CommandStart(
|
||
deep_link=True,
|
||
magic=F.args.regexp(re.compile(r'book_(\d+)'))
|
||
))
|
||
async def cmd_start_book(
|
||
message: Message,
|
||
command: CommandObject
|
||
):
|
||
book_number = command.args.split("_")[1]
|
||
await message.answer(f"Sending book №{book_number}")
|
||
|
||
@dp.message(Command("vfy"))
|
||
@dp.message(CommandStart(
|
||
deep_link=True, magic=F.args == "vfy"
|
||
))
|
||
async def cmd_start_vfy(message: types.Message):
|
||
builder = ReplyKeyboardBuilder()
|
||
builder.row(
|
||
types.KeyboardButton(
|
||
text="Подтвердить контакт",
|
||
request_contact=True
|
||
)
|
||
)
|
||
# Отправляем сообщение с клавиатурой
|
||
await message.answer(
|
||
"Для подтверждения номера телефона нажмите кнопку ниже:",
|
||
reply_markup=builder.as_markup(
|
||
resize_keyboard=True, # Опционально: автоматический размер
|
||
one_time_keyboard=True # Опционально: скрыть после нажатия
|
||
)
|
||
)
|
||
|
||
# Хэндлер для обработки полученного контакта
|
||
@dp.message(lambda message: message.contact is not None)
|
||
async def handle_contact(message: types.Message):
|
||
# Проверяем, что контакт принадлежит отправителю
|
||
if message.from_user.id == message.contact.user_id:
|
||
await message.answer(
|
||
f"Спасибо за контакт, {message.contact.first_name}!\n"
|
||
f"Номер телефона: {message.contact.phone_number}",
|
||
reply_markup=types.ReplyKeyboardRemove() # Убираем клавиатуру
|
||
)
|
||
else:
|
||
await message.answer("Это не ваш контакт!")
|
||
|
||
# новый импорт
|
||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||
# Запускаем Callback - кнопка
|
||
@dp.message(Command("random"))
|
||
async def cmd_random(message: types.Message):
|
||
builder = InlineKeyboardBuilder()
|
||
builder.add(types.InlineKeyboardButton(
|
||
text="Нажми меня",
|
||
callback_data="random_value")
|
||
)
|
||
await message.answer(
|
||
"Нажмите на кнопку, чтобы бот отправил число от 1 до 10",
|
||
reply_markup=builder.as_markup()
|
||
)
|
||
# хэндлер обработки callback кнопки
|
||
@dp.callback_query(F.data == "random_value")
|
||
async def send_random_value(callback: types.CallbackQuery):
|
||
await callback.message.answer(str(randint(1, 10)))
|
||
# отправим всплывающее окно после результата
|
||
await callback.answer(
|
||
text="Спасибо, что воспользовались ботом!",
|
||
show_alert=True
|
||
)
|
||
# или просто await callback.answer()
|
||
|
||
# Продолжим с колбэками
|
||
# Здесь хранятся пользовательские данные.
|
||
# Т.к. это словарь в памяти, то при перезапуске он очистится
|
||
user_data = {}
|
||
#сформируем инлайн-клавиатуру
|
||
def get_keyboard():
|
||
buttons = [
|
||
[
|
||
types.InlineKeyboardButton(text="-1", callback_data="num_decr"),
|
||
types.InlineKeyboardButton(text="+1", callback_data="num_incr")
|
||
],
|
||
[types.InlineKeyboardButton(text="Подтвердить", callback_data="num_finish")]
|
||
]
|
||
keyboard = types.InlineKeyboardMarkup(inline_keyboard=buttons)
|
||
return keyboard
|
||
|
||
# формируем сообщение с переменным аргументом
|
||
async def update_num_text(message: types.Message, new_value: int):
|
||
with suppress(TelegramBadRequest):
|
||
await message.edit_text(
|
||
f"Укажите число: {new_value}",
|
||
reply_markup=get_keyboard()
|
||
)
|
||
|
||
# запуск клавиатуры по команде /numbers
|
||
@dp.message(Command("numbers"))
|
||
async def cmd_numbers(message: types.Message):
|
||
user_data[message.from_user.id] = 0
|
||
await message.answer("Укажите число: 0", reply_markup=get_keyboard())
|
||
|
||
|
||
@dp.callback_query(F.data.startswith("num_"))
|
||
async def callbacks_num(callback: types.CallbackQuery):
|
||
user_value = user_data.get(callback.from_user.id, 0)
|
||
action = callback.data.split("_")[1]
|
||
|
||
if action == "incr":
|
||
user_data[callback.from_user.id] = user_value+1
|
||
await update_num_text(callback.message, user_value+1)
|
||
elif action == "decr":
|
||
user_data[callback.from_user.id] = user_value-1
|
||
await update_num_text(callback.message, user_value-1)
|
||
elif action == "finish":
|
||
await callback.message.edit_text(f"Итого: {user_value}")
|
||
|
||
await callback.answer()
|
||
|
||
@dp.message(Command("inline_url"))
|
||
async def cmd_inline_url(message: types.Message, bot: Bot):
|
||
builder = InlineKeyboardBuilder()
|
||
builder.row(types.InlineKeyboardButton(
|
||
text="GitHub", url="https://github.com")
|
||
)
|
||
builder.row(types.InlineKeyboardButton(
|
||
text="Оф. канал Telegram",
|
||
url="tg://resolve?domain=telegram")
|
||
)
|
||
|
||
# Чтобы иметь возможность показать ID-кнопку,
|
||
# У юзера должен быть False флаг has_private_forwards
|
||
user_id = message.from_user.id
|
||
chat_info = await bot.get_chat(user_id)
|
||
if not chat_info.has_private_forwards:
|
||
builder.row(types.InlineKeyboardButton(
|
||
text="Какой-то пользователь",
|
||
url=f"tg://user?id={user_id}")
|
||
)
|
||
|
||
await message.answer(
|
||
'Выберите ссылку',
|
||
reply_markup=builder.as_markup(),
|
||
)
|
||
|
||
# Запуск процесса поллинга новых апдейтов
|
||
async def main():
|
||
|
||
# Запускаем бота
|
||
await dp.start_polling(bot)
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|