in

Прикручиваем скрипт для отправки почты на Python (SSL/TLS)

Гайд для начинающих джуниор-чайников

Эйчары большие любители устраивать регулярное ревью позиции, как они это объясняют «в корреляции с твоими целями». Представь их удивление, когда ты скажешь, что теперь твоя цель — написать почтовый скрипт для отправки почты на Python

Для отправки электронной почты используется протокол SMTP. Python в данном случае — не панацея. Поднять почтовый сервер можно и на node.js, а чтобы не пропустить все лайфхаки по программированию на фрейморках рекомендуем занести в закладки блог Babacoding.

Матчасть

Электронную почту в Python можно отправлять двумя способами: поднять собственный SMTP-сервер (с помощью модуля smtpd), либо написать скрипт с помощью библиотеки smtplib, являющейся клиентом этого протокола

Во втором случае для отправки нам нужно подключиться к какому-либо SMTP-серверу, например smtp.yandex.ru, поэтому для примера мы возьмем свой электронный ящик на Яндексе, но можно использовать абсолютно любую, даже доменную почту.

Если вдруг у вас нет библиотеки smtplib, её можно установить через менеджер пакетов PIP, командой C:\Python>python -m pip install smtplib через CMD (переместитесь с помощью команды CD в каталог, где у вас установлен Python)

Подключение

Подключаться к серверу мы будем через конструктор класса SMTP  — именно он инкапсулирует SMTP-соединение

class smtplib.SMTP(host=», port=0, local_hostname=None, [timeout, ]source_address=None)

  • Host — указывается IP-адрес или домен SMTP-сервера
  • Port —  указывается порт подключения. Тут всё зависит от того, используется ли на сервере шифрование. Как правило, порт без шифрования — 25, с TLS — 587, c SSL — 465)
  • Local_hostname — если SMTP-сервер расположен на локальном ПК, то необходимо указать localhost.
  • Source_address — необязательный параметр, который позволяет выполнять привязку к определенному исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определенному исходному TCP-порту

Отправка

Отправка самого сообщения происходит за счет метода SMTP.sendmail —

SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())

  • From_addr — адрес отправителя.
  • To_addrs —  адрес получателя
  • Msg — отправляемое сообщение (формат этого параметра должен быть строкой)

Настройка ящика

Так как мы тестируем отправку через ящик Яндекса, перед тем как начать необходимо проверить настройки — скрипт работает как обычный почтовый клиент.

Первым делом, необходимо проверить, включен ли в ящике IMAP (без него SMTP работать не будет по соображениям безопасности)

Если у вас активны пароли приложений — не забудьте получить дополнительный пароль для своего скрипта:

Пишем код

Импортируем нужные для работы библиотеки:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

Далее создаём сообщение с помощью класса MIMEMultipart — нужно указать все заголовки (части) составного сообщения. MIMEText предназначен для текста (например, text/plain или text/html), если все сообщение находится в текстовом формате или его часть.

msg = MIMEMultipart()
msg['From'] = '****@yandex.ru'
msg['To'] = '****@gmail.com'
msg['Subject'] = 'Тест скрипта SMTP'
message = 'Это тестовое сообщение и отвечать на него не нужно'
msg.attach(MIMEText(message))

Если нужно написать сообщение в несколько строк используйте символ переноса строки \n

message = ‘Это тестовое сообщение и отвечать на него не нужно \n Но если очень хочется, то можно’ 

Создаём экземпляр (объект) класса SMTP. Обратите внимание на строчку mailserver.set_debuglevel(True) — так мы включаем режим отладки, чтобы в случае проблем можно было посмотреть логи

mailserver = smtplib.SMTP('smtp.yandex.ru',587)
mailserver.set_debuglevel(True)

Дальше нам нужно инициировать рукопожатие TLS. Отправляем команду ehlo() — сервер должен ответить на него. Затем запускаем сам протокол. После запуска вы должны снова вызвать ehlo() перед аутентификацией.

# Определяем, поддерживает ли сервер TLS
    mailserver.ehlo()
# Защищаем соединение с помощью шифрования tls
    mailserver.starttls()
# Повторно идентифицируем себя как зашифрованное соединение перед аутентификацией.
    mailserver.ehlo()

Подключаемся к серверу, отправляем письмо. Используем as_string (), чтобы превратить MIMEText в строку

mailserver.login('*****@yandex.ru', 'здесь_пароль')
mailserver.sendmail('*****@yandex.ru','****@gmail.com',msg.as_string())

Финальный вариант кода. В нём мы добавили простую обработку исключений (try/except) для удобства вывода

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

msg = MIMEMultipart()
msg['From'] = '******@yandex.ru'
msg['To'] = '*****@gmail.com'
msg['Subject'] = 'Тест скрипта SMTP'
message = 'Это тестовое сообщение и отвечать на него не нужно'
msg.attach(MIMEText(message))
try:
    mailserver = smtplib.SMTP('smtp.yandex.ru',587)
    mailserver.set_debuglevel(True)
# Определяем, поддерживает ли сервер TLS
    mailserver.ehlo()
# Защищаем соединение с помощью шифрования tls
    mailserver.starttls()
# Повторно идентифицируем себя как зашифрованное соединение перед аутентификацией.
    mailserver.ehlo()
    mailserver.login('******@yandex.ru', 'здесь_пароль')

    mailserver.sendmail('******@yandex.ru','******@gmail.com',msg.as_string())

    mailserver.quit()
    print("Письмо успешно отправлено")
except smtplib.SMTPException:
    print("Ошибка: Невозможно отправить сообщение")

Результат:

Письмо успешно дошло адресату:

Для отправки нескольким получателям добавьте конструкцию

recipients = [‘1@mail.com’, ‘2@mail.com’]

msg[‘To’] = «, «.join(recipients)

В строчке mailserver.sendmail исправьте код

mailserver.sendmail (*****@yandex.ru, recipients, msg.as_string())

Вариант для SSL

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

msg = MIMEMultipart()
msg['From'] = '*******@yandex.ru'
msg['To'] = '******@gmail.com'
msg['Subject'] = 'Тест скрипта SMTP'
message = 'Это тестовое сообщение и отвечать на него не нужно'
msg.attach(MIMEText(message))
try:
    mailserver = smtplib.SMTP_SSL('smtp.yandex.ru',465)
    mailserver.set_debuglevel(True)
    mailserver.login('*****@yandex.ru', 'здесь_пароль')
    mailserver.sendmail('*****@yandex.ru','******@gmail.com',msg.as_string())
    mailserver.quit()
    print("Письмо успешно отправлено")
except smtplib.SMTPException:
    print("Ошибка: Невозможно отправить сообщение")

Результат:

Добавить комментарий

Ваш адрес email не будет опубликован.