Найти в Дзене
Записки сисадмина

Python. Email. Принимаем сообщения

Есть мнение, что любой администратор рано или поздно должен начать программировать. И не важно, что именно ты выберешь - python, perl, golang, или что-то еще. Ведь никогда не угадаешь, в какие дебри тебя заведет автоматизация, какие проекты и задачи тебе придется реализовывать. Иногда, приходится самому писать то, что поставляется из коробки во многих системах, но конкретно в твоей этого почему-то не предусмотрено. В одной довольно старой статье я показывал скрипт отправки сообщений по почте. Сегодня будем разбираться с получением входящих. Как обычно, чтобы не показывать свои авторизационные данные, мы создадим отдельный файл config.py с логином и паролем от почты, на которую будут приходить сообщения. Для работы нам понадобятся библиотеки email и imaplib, которые входят в стандартную поставку python3. import email
import imaplib
from config import email_login, email_pass Также, нам понадобятся авторизационные данные imap сервера. IMAP - imap.gmail.com port - 993 SSL IMAP - imap.yande

Есть мнение, что любой администратор рано или поздно должен начать программировать. И не важно, что именно ты выберешь - python, perl, golang, или что-то еще.

Ведь никогда не угадаешь, в какие дебри тебя заведет автоматизация, какие проекты и задачи тебе придется реализовывать. Иногда, приходится самому писать то, что поставляется из коробки во многих системах, но конкретно в твоей этого почему-то не предусмотрено.

В одной довольно старой статье я показывал скрипт отправки сообщений по почте. Сегодня будем разбираться с получением входящих.

Как обычно, чтобы не показывать свои авторизационные данные, мы создадим отдельный файл config.py с логином и паролем от почты, на которую будут приходить сообщения.

Для работы нам понадобятся библиотеки email и imaplib, которые входят в стандартную поставку python3.

import email
import imaplib
from config import email_login, email_pass

Также, нам понадобятся авторизационные данные imap сервера.

  • Для google:
IMAP - imap.gmail.com
port - 993 SSL
  • Для яндекс:
IMAP - imap.yandex.ru
port - 993 SSL
  • Для mail.ru
IMAP - imap.mail.ru
port - 993 SSL

  • Подключаемся к нашему почтовому ящику:

mail = imaplib.IMAP4_SSL(host=imap_addr, port=imap_port) - Создает объект подключения к почтовому серверу.
mail.login(EMAIL_ACCOUNT, PASSWORD) - Через метод login() мы авторизуемся в своем почтовом ящике.
mail.list() - Выдаст список всех папок в почтовом ящике.

Если мы выведем список папок, получим список формата:

[b'(\\HasNoChildren \\Marked \\Sent)', b'(\\HasNoChildren \\Unmarked \\Junk)',]

В данном списке нас интересует папка входящих, поэтому ищем "Inbox".

  • Открываем папку "Входящие" и получаем список непрочитанных сообщений:
-2

mail.select('inbox') - Провалится в папку "Входящие"
result, data = mail.uid('search', None, "UNSEEN") - Найдет в папке все непрочитанные сообщения, в result поместит "ОК", а в data - список UID сообщений.

Список будет с единственной строкой в бинарном формате:

[b'2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23']

Поэтому разбиваем эту строку на отдельные элементы:

data = data[0].split()
[b'2', b'3', b'4', b'5', b'7', b'8', b'9', b'10', b'11', b'12', b'13', b'14', b'15', b'16', b'17', b'18', b'19', b'20', b'21', b'22', b'23']

  • Далее мы будем разбирать все на примере одного письма:
-3

result, email_data = mail.uid('fetch', b'2', '(RFC822)') - Мы напрямую указали, что нужно искать письмо с UID 2

В email_data попадет

[(b'2 (UID 2 RFC822 {8495}', b'Received: from postback9a.mail.yandex.net (postback9a.mail.yandex.net [2a02:6b8:c0e:500:1:45:d181:da09])\r\n\tby mail-notsolitesrv-production-main-31.vla.yp-c.yandex.net (notsolitesrv/Yandex))]

raw_email_string = email_data[0][1].decode('utf-8') - Из этого списка мы берем все данные письма и записываем в строку. Вывод будет:

-4

email_message = email.message_from_string(raw_email_string) - Из строки мы собираем объект письма. Это полезно для получения конкретных данных по ключу напрямую, без парсинга строки.

Например, email_message['Date'] выдаст время получения письма.

  • Обернем всю нашу логику в две функции:
-5

get_unread_messages() Будет получать список UID непрочитанных сообщений.

parse_messages() Будет обрабатывать полученные сообщения.

Код из статьи выложил здесь