Это небольшой пост, скорее заметка, где мы разработаем асинхронного Telegram бота на Python, и научим его отправлять сообщения на электронную почту и перенаправлять прикрепленный, вложенный файл.
Старт
Прежде всего нужно разрешить внешним приложением использовать почтовый ящик для отправки электронных писем. (Для демонстрации использовал почту Яндекс) Для этого на странице управление аккаунтом переходим во вкладку безопасность и создаем пароль для внешнего приложения.
Отправка письма
Установим библиотеку, с помощью который будем асинхронно передавать письма.
pip install aiosmtplib
Создадим файл smtp.py
. Укажем адрес электронной почты и пароль, что создали ранее, и попробуем отправить письмо с текстом "Привет" самим себе.
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from aiosmtplib import SMTP
import asyncio
EMAIL = 'example@yandex.ru'
PWD = 'password'
async def send_mail(subject, to, msg):
message = MIMEMultipart()
message["From"] = EMAIL
message["To"] = to
message["Subject"] = subject
message.attach(MIMEText(f"<html><body>{msg}</body></html>", "html", "utf-8"))
smtp_client = SMTP(hostname="smtp.yandex.ru", port=465, use_tls=True)
async with smtp_client:
await smtp_client.login(EMAIL, PWD)
await smtp_client.send_message(message)
if __name__ == '__main__':
asyncio.run(send_mail('Тема письма', 'example@yandex.ru', '<h1>Привет</h1>'))
Запускам.
Письмо успешно доставлено.
Телеграм бот
Установим библиотеку для удобного взаимодействия с Telegram Bot API.
pip install pyTelegramBotAPI
Создадим файл main.py
, и напишем простого бота, который на сообщение с текстом “Письмо” будет отправлять на почту id пользователя.
Для этого импортируем ранее созданный smtp.py
и добавляем функцию send_mail
к обработчику сообщений.
from telebot.async_telebot import AsyncTeleBot
import asyncio
import smtp
TOKEN = 'TOKEN'
bot = AsyncTeleBot(TOKEN)
@bot.message_handler(commands=['start'])
async def send_welcome(message):
await bot.send_message(message.chat.id, "Привет")
@bot.message_handler(func=lambda message: message.text.lower() == 'письмо')
async def send_mail_text(message):
await bot.send_message(message.chat.id, 'Письмо отправлено')
cormail = smtp.send_mail('Новое сообщение','example@yandex.ru', f'<p>User ID {message.from_user.id}</p>')
asyncio.gather(asyncio.create_task(cormail))
asyncio.run(bot.polling())
Проверяем, отправив сообщение боту.
Письмо с ID пользователя доставлено.
Отправка файла
Тут все просто, немного изменим содержимое функции send_mail
и добавим новый параметр url
. Не забываем импортировать aiohttp
, io
, и MIMEApplication
...
message.attach(MIMEText(f"<html><body>{msg}</body></html>", "html", "utf-8"))
if url:
async with aiohttp.ClientSession() as session:
async with session.get(url) as responce:
buffer = io.BytesIO(await responce.read())
part = MIMEApplication(buffer.read(), Name=url.split('/')[-1])
part['Content-Disposition'] = f'attachment; filename={url.split("/")[-1]}'
message.attach(part)
smtp_client = SMTP(hostname="smtp.yandex.ru", port=465, use_tls=True)
...
Так же в боте добавим новую функцию, и сам обработчик для перенаправления полученного файла на почту.
@bot.message_handler(content_types=['document'])
async def send_mail_document(message):
await bot.send_message(message.chat.id, 'Файл отправлен')
document_id = message.document.file_id
file_info = await bot.get_file(document_id)
url_file = f'http://api.telegram.org/file/bot{TOKEN}/{file_info.file_path}'
cormail = smtp.send_mail('Новое сообщение',
'example@yandex.ru',
f'<p>Файл отправлен пользователем ID{message.from_user.id}</p>',
url_file)
asyncio.gather(asyncio.create_task(cormail))
Запускаем и наслаждаемся.