Python Telegram бот, отправить письмо с файлом на почту

Это небольшой пост, скорее заметка, где мы разработаем асинхронного 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", "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', 'Привет
'))

Письмо успешно доставлено.
Телеграм бот
Установим библиотеку для удобного взаимодействия с 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'User ID ') asyncio.gather(asyncio.create_task(cormail)) asyncio.run(bot.polling())
Проверяем, отправив сообщение боту.

Письмо с ID пользователя доставлено.
Отправка файла
Тут все просто, немного изменим содержимое функции send_mail и добавим новый параметр url . Не забываем импортировать aiohttp , io , и MIMEApplication
. message.attach(MIMEText(f" ", "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=' 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/' cormail = smtp.send_mail('Новое сообщение', 'example@yandex.ru', f'Файл отправлен пользователем ID ', url_file) asyncio.gather(asyncio.create_task(cormail))
Запускаем и наслаждаемся.
Как отправить письмо на почту с помощью Python?
Подскажите, понадобилось на python отправлять сообщение на почту yandex.
Нашел код, но вылетает ошибка.
Почитал, написано что ошибка может вылетать, так как пароль может быть не в кодировке utf-8.
Пишу в коде для password, addr_from, addr_to это: encode(encoding=’utf-8′) — ноль эмоций.
Подскажите, как тогда исправить ошибку?
import smtplib # Импортируем библиотеку по работе с SMTP # Добавляем необходимые подклассы - MIME-типы from email.mime.multipart import MIMEMultipart # Многокомпонентный объект from email.mime.text import MIMEText # Текст/HTML addr_from = "[email protected]" addr_to = "[email protected]" password = "pass" # пароль от почты addr_from msg = MIMEMultipart() # Создаем сообщение msg['From'] = addr_from # Адресат msg['To'] = addr_to # Получатель msg['Subject'] = 'Тема сообщения' # Тема сообщения body = "Текст сообщения" msg.attach(MIMEText(body, 'plain')) # Добавляем в сообщение текст server = smtplib.SMTP_SSL('smtp.yandex.ru', 465) # Создаем объект SMTP # server.starttls() # Начинаем шифрованный обмен по TLS server.login(addr_from, password) # Получаем доступ server.send_message(msg) # Отправляем сообщение server.quit() # Выходим
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Error: authentication failed: This user does not have access rights to this service')
Отправка электронных писем с помощью Python
![]()
В этой статье посмотрим как можно отправлять электронные письма при помощи Python. Есть и более простые способы это сделать, но мне больше подошел именно следующий вариант.
Итак, вот как это выглядит: у вас есть имена и адреса электронной почты некоторой группы контактов. И вы хотите отправить каждому из них письмо, добавив в начале сообщения «Уважаемый [имя]».
Для простоты вы можете хранить всю контактную информацию просто в файле, а не в базе данных. Также вы можете сохранить в файл шаблон сообщения, которое вы хотите отправить.
Модуль smtplib в Python – это практически все, что вам понадобиться для отправки простых электронных писем без заполнения темы письма или какой-либо еще дополнительной информации. Но, конечно, для настоящих писем вам необходимо заполнить строку темы письма и другую информацию, и, возможно, даже прикрепить изображения или какие-то другие вложения.
Вот тут и приходит на помощь пакет email в Python. Имейте в виду, что нельзя отправить сообщение через электронную почту, используя только этот пакет. Вам необходимо совместить email и smtplib .
Обязательно ознакомьтесь с подробной официальной документацией для каждого из этих пакетов.
Вот четыре основных шага для отправки электронных писем с помощью Python:
- Настройте SMTP-сервер и войдите в свою учетную запись.
- Создайте объект сообщения MIMEMultipart и загрузите его с соответствующими заголовками для полей From (От), To (Кому) и Subject (Тема).
- Добавьте тело сообщения.
- Отправьте сообщение с помощью объекта SMTP-сервера.
А теперь давайте рассмотрим весь процесс.
Допустим, что у вас есть файл контактов mycontacts.txt , который выглядит вот так:
user@computer ~ $ cat mycontacts.txt john johndoe@example.com katie katie2016@example.com
Каждая строка соответствует одному контакту. В каждой строке пишется имя, а за ним следует адрес электронной почты. У меня все сохранено в нижнем регистре. Я оставлю преобразования любых полей или некоторых начальных букв в верхний регистр логике программирования, если это будет необходимо. В Python это все довольно просто.
Далее у нас есть файл с шаблоном сообщения message.txt .
user@computer ~ $ cat message.txt Dear $, This is a test message. Have a great weekend! Yours Truly
Обратили внимание на $ ? Это шаблонная строка в Python. Шаблонные строки можно легко заменить другими строками; в данном примере $ будет заменено настоящим именем человека (вы скоро это увидите).
А теперь давайте перейдем к коду Python. Для начала нам необходимо прочитать контакты из файла mycontacts.txt . Мы, кстати, можем обобщить это в отдельную функцию.
# Function to read the contacts from a given contact file and return a # list of names and email addresses def get_contacts(filename): names = [] emails = [] with open(filename, mode='r', encoding='utf-8') as contacts_file: for a_contact in contacts_file: names.append(a_contact.split()[0]) emails.append(a_contact.split()[1]) return names, emails
Функция get_contacts() в качестве аргумента принимает имя файла. Она откроет этот файл, прочитает каждую строку (то есть каждый контакт), разделит их на имя и адрес электронной почты, а затем добавит их в два отдельных списка. И, наконец, в качестве результата работы функции возвращаются эти два списка.
Также нам нужна функция для того, чтобы прочитать шаблон сообщения (такой как message.txt ) и вернуть объект типа Template , созданный из его содержимого.
from string import Template def read_template(filename): with open(filename, 'r', encoding='utf-8') as template_file: template_file_content = template_file.read() return Template(template_file_content)
Как и предыдущая функция, в качестве аргумента она принимает имя файла.
Для того, чтобы отправить письмо, вам необходимо использовать протокол SMTP (Simple Mail Transfer Protocol – протокол простого обмена электронной почтой). Как уже упоминалось ранее, у Python есть необходимые для этого библиотеки.
# import the smtplib module. It should be included in Python by default import smtplib # set up the SMTP server s = smtplib.SMTP(host='your_host_address_here', port=your_port_here) s.starttls() s.login(MY_ADDRESS, PASSWORD)
В приведенном выше фрагменте кода вы импортируете smtplib , а затем создаете экземпляр SMTP, который формирует SMTP-соединение. В качестве параметра он принимает адрес хоста и номер порта, оба эти параметра полностью зависят от настроек SMTP вашего поставщика услуг электронной почты. Например, в случае Outlook строка под номером 4 будет выглядеть вот так:
s = smtplib.SMTP(host='smtp-mail.outlook.com', port=587)
Для того, чтобы все работало, вам необходимо использовать адрес хоста и номер порта конкретно вашего поставщика услуг электронной почты.
MY_ADDRESS и PASSWORD – это две переменные, которые содержат полный адрес электронной почты и пароль от учетной записи, которую вы собираетесь использовать.
А теперь самое время получить контактную информацию и шаблон сообщения, используя функции, которые мы определили ранее.
names, emails = get_contacts('mycontacts.txt') # read contacts message_template = read_template('message.txt')
А теперь давайте отправим отдельное письмо каждому из этих контактов.
# import necessary packages from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # For each contact, send the email: for name, email in zip(names, emails): msg = MIMEMultipart() # create a message # add in the actual person name to the message template message = message_template.substitute(PERSON_NAME=name.title()) # setup the parameters of the message msg['From']=MY_ADDRESS msg['To']=email msg['Subject']="This is TEST" # add in the message body msg.attach(MIMEText(message, 'plain')) # send the message via the server set up earlier. s.send_message(msg) del msg
Для каждого name (имя) и email (адрес электронной почты) (из файла с контактами) вы создаете объект MIMEMultipart , настраиваете заголовки типов содержимого From (от), To (кому), Subject (тема) как словарь ключевых слов, а затем прикрепляете тело сообщения к объекту MIMEMultipart в виде обычного текста. Возможно, вам захочется прочитать документацию, чтобы узнать больше о других типах MIME , с которыми вы также можете поэкспериментировать.
Также обратите внимание, что в строке 10 выше я заменяю $ фактическим именем, которое было извлечено из файла с контактами с помощью механизма шаблонизации в Python.
В данном конкретном примере я каждый раз удаляю объект MIMEMultipart и создаю его заново при каждой итерации цикла.
Как только вы проделаете все это, то сможете отправить сообщение, используя простую удобную функцию send_message() объекта SMTP, который вы создали ранее.
А вот и полный код:
import smtplib from string import Template from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText MY_ADDRESS = 'my_address@example.comm' PASSWORD = 'mypassword' def get_contacts(filename): """ Return two lists names, emails containing names and email addresses read from a file specified by filename. """ names = [] emails = [] with open(filename, mode='r', encoding='utf-8') as contacts_file: for a_contact in contacts_file: names.append(a_contact.split()[0]) emails.append(a_contact.split()[1]) return names, emails def read_template(filename): """ Returns a Template object comprising the contents of the file specified by filename. """ with open(filename, 'r', encoding='utf-8') as template_file: template_file_content = template_file.read() return Template(template_file_content) def main(): names, emails = get_contacts('mycontacts.txt') # read contacts message_template = read_template('message.txt') # set up the SMTP server s = smtplib.SMTP(host='your_host_address_here', port=your_port_here) s.starttls() s.login(MY_ADDRESS, PASSWORD) # For each contact, send the email: for name, email in zip(names, emails): msg = MIMEMultipart() # create a message # add in the actual person name to the message template message = message_template.substitute(PERSON_NAME=name.title()) # Prints out the message body for our sake print(message) # setup the parameters of the message msg['From']=MY_ADDRESS msg['To']=email msg['Subject']="This is TEST" # add in the message body msg.attach(MIMEText(message, 'plain')) # send the message via the server set up earlier. s.send_message(msg) del msg # Terminate the SMTP session and close the connection s.quit() if __name__ == '__main__': main()
Как отправить электронное письмо с помощью Python: руководство для «чайников»

В нашем блоге мы много пишем о создании email-рассылок и работе с электронной почтой. В современном мире люди получают множество писем, а у некоторых даже есть несколько почтовых ящиков. Все это усложняет процесс их администрирования, что вынуждает искать пути решения проблемы. Не так давно мы рассказывали о том, как инженер из США упорядочивал свои письма с помощью нейронной сети (1, 2), а сегодня речь пойдет об автоматизации отправки писем для разных почтовых ящиков.
Редактор издания Motherboard Майкл Берн (Michael Byrne) написал материал о том, как отправлять электронные письма для различных почтовых ящиков с помощью Python. Мы представляем вашему вниманию адаптированный перевод этой заметки.
Берн пишет, что у него есть целых пять электронных ящиков: один личный, два университетских и два рабочих. Есть ещё и шестой, который он иногда использует, когда нужно быстро где-то зарегистрироваться. Немалая часть жизни журналиста состоит из быстрого просмотра и сортировки электронных писем, их удаления, добавления в избранное, и даже чтения этих писем и ответа на них. Берн говорит, что даже не хочет задумываться о том, сколько на все это уходит времени каждый день.
Журналист признается, что однажды в шутку подумал, что ему надо нанять помощника для управления своей электронной почтой. Это, в свою очередь, привело к размышлениям о том, какие указания такому сотруднику надо было бы давать: «Если в письме есть то-то и то-то, сделай одно, или если вот это так, сделай кое-что другое». Это был бы определённый набор правил, применённый к письмам.
Но когда я вижу словосочетание «набор правил», я сразу думаю о написании компьютерных программ. Пролистывая свои письма, я понимаю, что было бы разумно воплотить моего помощника в компьютерном коде.
Тем не менее, чтобы сделать это, необходимо каким-то образом связать электронные ящики с программой для чтения писем. Это делается довольно просто. На самом деле, электронные письма – это набор текстовых протоколов для передачи информации между сетями; как и весь остальной интернет, в общем. Всё это лишь несколько уровней протоколов. То, как мы представляем себе электронную почту, отображает лишь ее интерфейс.
Даже если вы не хотите создавать сортирующую письма программу, управлять электронными письмами как набором данных довольно интересно. Берн решил использовать для решения задачи Python, так как этот язык действительно хорош для лёгкого и интуитивного создания подобных вещей, и подходит даже для не-программистов. Последующие инструкции частично основаны на главе про автоматизацию электронной почты из книги Эла Свейгарта (Al Sweigart) «Automate the Boring Stuff with Python», которую журналист очень рекомендую и как введение в программирование, и как справочное руководство для тех, кто хочет повеселиться с автоматизацией. Эта книга доступна бесплатно под лицензией Creative Commons на automatetheboringstuff.com.
Для начала потребуется скачать Python (если он еще не установлен). Также потребуется любой простой текстовый редактор. Отлично подойдет Sublime Text — его можно скачать здесь. ST не бесплатный, но в тестовом режиме им можно пользоваться бесконечно, хоть иногда и будет появляться предложение о покупке. Но своих денег он стоит.
Python можно использовать в двух режимах. Первый – это командный интерпретатор, где пользователь вводит команды или сниппеты на Python в консоль, и они сразу же выполняются (например, print(«Hello, World!»)). Второй режим – это скрипты на Python. По сути, это просто набор команд на Python в одном или нескольких файлах, которые могут быть вызваны одновременно из консоли. Фактически, эти файлы – это программы: иногда маленькие и простые (как то, что мы рассмотрим дальше), они могут разрастаться до больших проектов.
Если вы только что скачали Python, вам нужно сделать ещё две вещи перед тем, как начать. Первое: прочтите краткое руководство про написание «Hello, World!» на Python. Второе: уделите пять минут прочтению руководства по использованию модулей в Python. Установка и импорт расширений Python производятся предельно просто.
0) Протоколы для получения почты: краткое руководство
Существуют три основных протокола для работы с электронной почтой. Самый старый из них называется POP (Post Office Protocol). Его суть в том, что программное обеспечение для работы с электронной почтой (не браузер) подключается к удалённому серверу, скачивает письма на компьютер пользователя, и они становятся доступны без подключения к интернету. Это было хорошей идеей в те времена, когда к интернету подключались нечасто, и было нормальным не иметь выхода в Сеть, но в настоящее время такого почти не бывает.
Текущим стандартом доступа к электронным ящикам является протокол IMAP (Internet Message Access Protocol). Он намного быстрее и больше соответствует тому, как интернет используется в наши дни. Он позволяет нескольким пользователям подключаться к одному ящику и поддерживает их соединение в течение всей сессии.
Веб-браузеры получают доступ к электронной почте с помощью дополнительного протокола – HTTP, но в основе лежат всё те же POP и IMAP.
В основном для получения писем с сервера используются POP (актуальная версия POP3) и IMAP. Но для того чтобы отправить письмо, нужен другой протокол – SMTP (Simple Mail Transfer Protocol). Всё потому, что нельзя просто отправить письмо получателю. Его нужно отправить на сервер, с которого получатель это письмо скачает, используя IMAP и POP3.
1) Подключение SMTP-модуля Python
Для начала нам нужен подходящий модуль Python. Smtplib поставляется вместе с Python, поэтому не нужно предпринимать дополнительных действий, достаточно просто ввести эту строку в консоль:
import smtplib
Для получения справки по модулю (и чтобы удостовериться, что он подключился), можно использовать функцию help:
help(smtplib)
Следует отметить, что эта функция работает с любым модулем.
2) Подключение к серверу электронной почты
Прежде всего, нужно создать объект smtplib, который можно рассматривать как некий портал, дающий доступ к подключению и различным инструментам работы с ним из модуля smtplib.
В данном случае функция, возвращающая необходимый объект, принимает два параметра или аргумента. Первый аргумент содержит доменное имя, то есть адрес электронной почты, начинающийся с «smtp», как показано ниже. Второй аргумент – это номер порта, к которому будет осуществляться подключение на сервере электронной почты. Он почти всегда принимает значение 587 в соответствии со стандартом шифрования TLS. Очень редко встречаются сервисы, использующие порт 465.
Итак, нужно написать следующее:
smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
Получается, что переменная smtpObj является объектом типа SMTP. В этом можно убедиться, если ввести имя переменной в консоль и подтвердить ввод. На экране появятся адрес её ячейки памяти и тип (при условии, что вы ввели предыдущую команду правильно). Переменную smtpObj можно назвать, как угодно, лишь бы это было допустимое в Python имя переменной.
3) Шифрование
Следующее, что нужно сделать для установления соединения, это «сказать» SMTP-объекту, что сообщение должно быть зашифровано. Для этого следует ввести в консоль эту строку и нажать Enter:
smtpObj.starttls()
Вот что мы сделали: мы сообщили Gmail, что хотим, чтобы наше соединение шифровалось с помощью протокола TLS (Transport Layer Security), который на сегодняшний день является стандартом для интернет-коммуникаций. Сам по себе TLS не является криптографическим алгоритмом, он скорее сообщает, что необходимо использовать шифрование или соединение не должно быть установлено.
В ответ вы должны получить подтверждение:
2.0.0 Ready to start TLS
Важный момент — если пропустить этот шаг и сразу перейти к авторизации, то на экране появятся сообщения об ошибках. Всё потому, что Gmail применяет шифрование с использованием протокола HTTPS, то есть всё тот же НТТР, «обёрнутый» в дополнительный TLS-протокол.
5) Авторизация
Для того чтобы авторизоваться, нужно всего лишь написать
smtpObj.login('justkiddingboat@gmail.com','just123kidding')
На данном этапе пароль от электронной почты, так сказать, улетает в неизвестность, что довольно опасно. Это не проблема на локальном компьютере, но если вы действительно автоматизируете работу с электронной почтой с помощью скрипта на Python, то нужно проявить осторожность и дважды подумать, прежде чем публиковать код скрипта где-либо или загружать файл с ним на сторонние площадки.
5) Отправка сообщения
Плюс использования сред с командным интерпретатором заключается в том, что даже при отсутствии какой-либо информации — например, описания отправки письма — можно спросить об этом сам интерпретатор. Для этого нужно просто ввести следующую команду:
help(smtpObj)
Немного поскроллив страницу можно увидеть нужный метод:

Интерпретатор даже выведет пример его использования:

Заметьте, что в примере выше отсутствует команда авторизации. Это связано с тем, что программа подключалась к компьютеру пользователя, а не к удалённому серверу электронной почты. Для нашего случая напишем следующее:
smtpObj.sendmail("justkiddingboat@gmail.com","michael.byrne@vice.com","go to bed!")

6) Завершение соединения
Для завершения соединения достаточно использовать такую команду:
smtpObj.quit()
Естественно, отправка сообщений – это всего лишь малая часть того, что можно делать с электронной почтой с помощью Python. Берн советует продолжить обучение с книгой Свейгарта, чтобы узнать, как работать с электронной почтой, используя IMAP.
Предупреждаю: кода будет всё так же немного. К утру вы сможете делать с вашей почтой всё, что захотите с помощью скриптов на Python.
И, конечно, нужно понимать, что такая автоматизация должна быть использована лишь для облегчения работы с электронной почтой, а не для заваливания людей ненужным спамом.
- программирование
- Python
- электронная почта
- автоматизация
- Блог компании Pechkin.com
- Программирование
- Верстка писем