From 5f587980e106469c7286b641c989ac9f113247c0 Mon Sep 17 00:00:00 2001 From: vasilytray Date: Mon, 10 Mar 2025 09:45:07 +0700 Subject: [PATCH] function take url, phone, e-mail from users message --- README.md | 52 +++++++++++++++++++++++++++++++++++++++++-- bot.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3183de..b38f3e6 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,54 @@ async def cmd_hello(message: Message): ) ``` -В примере выше конструкция **content.as_kwargs() вернёт аргументы text, entities, parse_mode и подставит их в вызов answer() +В примере выше конструкция ****content.as_kwargs()** вернёт аргументы **text, entities, parse_mode** и подставит их в вызов **answer()** -Упомянутый инструмент форматирования довольно комплексный, [официальная документация](https://core.telegram.org/bots/api#formatting-options) демонстрирует удобное отображение сложных конструкций \ No newline at end of file +Упомянутый инструмент форматирования довольно комплексный, [официальная документация](https://core.telegram.org/bots/api#formatting-options) демонстрирует удобное отображение сложных конструкций + +#### Сохранение форматирования +Представим, что бот должен получить форматированный текст от пользователя и добавить туда что-то своё, например, отметку времени. + +Напишем простой код: +```py +# новый импорт! +from datetime import datetime + +@dp.message(F.text) +async def echo_with_time(message: Message): + # Получаем текущее время в часовом поясе ПК + time_now = datetime.now().strftime('%H:%M') + # Создаём подчёркнутый текст + added_text = html.underline(f"Создано в {time_now}") + # Отправляем новое сообщение с добавленным текстом + await message.answer(f"{message.text}\n\n{added_text}", parse_mode="HTML") +``` + +НО! ``message.text`` возвращает просто текст, без каких-либо оформлений. +Чтобы получить текст в нужном форматировании, воспользуемся альтернативными свойствами: ``message.html_text`` или ``message.md_text``. + +#### Работа с entities +**Telegram** сильно упрощает жизнь разработчикам, выполняя предобработку сообщений пользователей на своей стороне. Например, некоторые сущности, типа **e-mail**, **номера телефона, юзернейма** и др. можно не доставать регулярными выражениями, а извлечь напрямую из объекта **Message** и поля **entities**, содержащего массив объектов типа [MessageEntity](https://core.telegram.org/bots/api#messageentity). + +Здесь кроется важный подвох. *Telegram возвращает не сами значения, а их начало в тексте и длину*. +```py +@dp.message(F.text) +async def extract_data(message: Message): + data = { + "url": "", + "email": "", + "code": "" + } + entities = message.entities or [] + for item in entities: + if item.type in data.keys(): + # Неправильно + # data[item.type] = message.text[item.offset : item.offset+item.length] + # Правильно + data[item.type] = item.extract_from(message.text) + await message.reply( + "Вот что я нашёл:\n" + f"URL: {html.quote(data['url'])}\n" + f"E-mail: {html.quote(data['email'])}\n" + f"Пароль: {html.quote(data['code'])}" + ) +``` \ No newline at end of file diff --git a/bot.py b/bot.py index 579e975..274de91 100644 --- a/bot.py +++ b/bot.py @@ -46,6 +46,7 @@ async def cmd_start(message: types.Message): as_marked_section( Bold("Я умею:"), "/test1 - Отвечу Test1", + "/more - Еще больше возможностей!", "/answer - Просто отвечу", "/reply - Отвечу ответом", "/name - Поприветствую тебя по Имени и Фамилии", @@ -68,6 +69,36 @@ async def cmd_start(message: types.Message): **content.as_kwargs() ) +@dp.message(Command("more")) +async def cmd_more(message: types.Message): + # await message.answer("Привет! ") + content = as_list( + Text( + + Bold(message.from_user.first_name), + " Еще я могу вот что: ", + ), + as_marked_section( + Bold(""), + "Если ты напишешь в тексте ", + "адрес сайта,", + "e-mail,", + "Номер телефона,", + "Какой нибудь код или пароль", + "Я распознаю из и напишу что нашел", + "/dice - Подкину для тебя кубик, загадай число ;)", + marker="✅ ", + ), + HashTag("#еще"), + # Text( + # "Номер телефона, ", + # Bold(message.contact.phone_number) + # ) + ) + await message.answer( + **content.as_kwargs() + ) + # Хэндлер на команду /test1 @dp.message(Command("test1")) async def cmd_test1(message: types.Message): @@ -142,6 +173,41 @@ async def cmd_dice2(message: types.Message, bot: Bot): async def cmd_info(message: types.Message, started_at: str): await message.answer(f"Бот запущен {started_at}") +# сохраним формат введенного пользователем текста - после теста отключим хендлер +#@dp.message(F.text) +async def echo_with_time(message: Message): + # Получаем текущее время в часовом поясе ПК + time_now = datetime.now().strftime('%H:%M') + # Создаём подчёркнутый текст + added_text = html.underline(f"Написано в {time_now}") + not_anderstand = (message.from_user.first_name) + # Отправляем новое сообщение с добавленным текстом + await message.answer(f"{message.html_text}\n\n{not_anderstand}!!! Я не понимаю эту команду :(\nДля получения списка известных мне команд напиши /start \n{added_text}", parse_mode="HTML") + +# Извлекаем из сообщений пользователя данные url, email, телефон и код +@dp.message(F.text) +async def extract_data(message: Message): + data = { + "url": "", + "email": "", + "phone_number": "", + # "code": "" + } + entities = message.entities or [] + for item in entities: + if item.type in data.keys(): + # Неправильно + # data[item.type] = message.text[item.offset : item.offset+item.length] + # Правильно + data[item.type] = item.extract_from(message.text) + await message.reply( + "Вот что я нашёл:\n" + f"URL: {html.quote(data['url'])}\n" + f"E-mail: {html.quote(data['email'])}\n" + f"Телефон: {html.quote(data['phone_number'])}\n" + # f"Пароль: {html.quote(data['code'])}" + ) + # Запуск процесса поллинга новых апдейтов async def main(): # Регистрируем хэндлер cmd_test2 по команде /start