Мне нужно написать скрипт авторега аккаунтов для одного популярного сервиса. для регистрации аккаунтов нужна электронная почта. логичным решением было использовать временные почты.
Ранее (~1.5 года назад) я уже использовал для таких задач python-библиотеку tempmail, но она перестала работать.
В моей issue к tempmail предложили альтернативу.
Но в связи с устаревшими решениями по коду я решил форкнуть либу. оказалось, что механизм библиотеки достаточно прост - она использует открытые api mail.tm.
Проведя небольшой ресёрч в интернете я нашел mail.gw, который выглядит/работает также, как mail.tm и с которым, как оказалось, уже может работать мой форк.
Но, есть проблема: при регистрации аккаунта сервис легко обнаруживает временные почты (предположительно, по черному списку доменов, но у меня есть решение, расскажу в конце).
Значит нам предстоит развернуть собственный сервер временной электронной почты на собственном домене.
Исходный код сервера mail.tm и mail.gw (предположительно) был опубликован на GitHub. по крайней мере так было с документацией, но с 2022 года или ранее недоступен (определил по архивным копиям).
Запрос на почты поддержки (support@mail.tm, support@mail.qw), в дс/тг не дал результатов (мне не ответили).
Из этого можно сделать вывод: исходный код серверной части можно считать закрытым, а значит нам нужно написать свой.
Проводя ресёрч решений по поднятию собственной python-совместимой почты, я наткнулся на старенькую статью на habr о библиотеке inbox.py, которая позиционирует себя как простой почтовый smtp-сервер для людей.
Интересный факт: в контрибьюторах библиотеки числится создатель requests (популярной библиотеки для парсинга).
Когда я попытался развернуть сервер на inbox.py, оказалось, что она давно не поддерживается и не может работать с python версии 3.12 и выше.
Логичным решением было форкнуть библиотеку, обновив зависимости (переписал на aiosmtpd).
Теперь она работает в современном python (и называется inboxium).
Поднял почту на VDS.
Ради интереса решил отправить письмо, просто, по ip (admin@0.0.0.0) - работает. Ни разу не видел чтобы так делали.
После успешной покупки домена и проброса MX записей в DNS мы имеем рабочую почту.
Но проблемы начались с другой стороны:
Для подтверждения почты сервис отправляет сообщение, в формате, который библиотека считает пустым текстом.
Это значит, что нам придётся переписать механизм препарирования сообщений (чтобы пользователь мог получить сырые данные).
И ещё я давно хотел сделать структуру работы с сообщениями как в aiogram, чтобы был единый класс Message и разработчик мог получить из него всё остальное:
by: str | получатель (-и).
sender: str | отправитель.
subject: str | тема письма.
text: str | текст письма.
raw: str | сырой текст письма (для таких случаев как наш).
Вот пример кода на обновлённом inboxium:
@inbox.message
async def handle(message: InboxMessage) -> None:
"""Handle any messages."""
if message.sender == TARGET_SENDER:
print("!!! Верно обнаружен отправитель !!!")
urls = re.findall(FIND_CONFIDER_URL, message.raw)
if urls:
r = requests.get(urls[0])
print(f"!!! Почта подтверждена {urls[0]} !!!")
Кстати, заметил, что в стандартных классах современного python, связанных с email отвратительное оформление кода. так что даже в питоне есть еще что форкать))
Для удобства работы, систему было решено сделать автономной: на VDS с белым IP поднят скрипт, который сверяет отправителя и тему письма и автоматически переходит по ссылкам для подтверждения почты.
Обещал способ нивелировать обнаружения временных почт:
Большинство систем, для обнаружения временных почт грубо сверяют домен. поэтому, для минимизации обнаружения нужно поднимать временную почту на домене третьего уровня (user@example.example.com).