Главная » Хабрахабр » [Из песочницы] Своя временная почта: телеграм бот

[Из песочницы] Своя временная почта: телеграм бот

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

Небольшая предыстория

В обоих случаях у меня был самый дешёвый тарифный план и Ubuntu 16. Не так давно я переехал с обычного хостинга на VPS и так получилось, что спустя месяц или чуть больше мне снова пришлось переезжать уже на другой VPS. Так как последний раз на тот момент с терминалом я сталкивался в университете, что было равносильно полному отсутствию опыта, для настройки своего VPS я использовал прекрасные пошаговые инструкции от DigitalOcean (часть из них переведена на русский язык для тех, кто, как и я, недостаточно знает английский). 04. Повторив пару раз процедуру настройки LAMP, я немного привык к терминалу VPS и в рамках его дальнейшего освоения решил перейти к необычным экспериментам – к созданию своего сервиса временной почты например.
И да, мой первый VPS был на DO, а переехать снова пришлось в основном потому, что часть его IP адресов попала под раздачу РКН.

Опыт в бэкенде, в частности в создании телеграм ботов на PHP MySQL у меня уже был, но получать электронную почту «самому» — это казалось далёким и непонятным. Открыв несколько вкладок с различными статьями по теме, я понял, что ничего не понял. Везде предлагалось использовать тонну различных инструментов, что на мой взгляд больше подходило для полноценного почтового сервиса, чем для задачи получения входящих email сообщений на VPS.

Получение входящей почты

Для первого шага мне очень помогла статья из песочницы: habr.com/ru/post/260429. Я обратил внимание на её отрицательный рейтинг, однако в ней описано ровно то, что меня интересовало. Я хотел как можно быстрее получить результат, который можно «пощупать», и с мыслями «в будущем я сделаю как надо» пошёл настраивать sendmail.

DNS записи: Затем я настроил домен.

XX. example.com IN MX 5 mail.example.com
mail.example.com IN A XXX. XXX (ip адрес VPS) XXX.

На сервере в файл /etc/mail/virtusertable добавил строку @example.com vasya, тем самым определив, что вся почта, предназначенная для любых адресов на ****@example.com адресована пользователю Васе.

Чтобы обрабатывать входящую почту php-скриптом, в файл /etc/aliases добавил строку vasya: "|php -q /home/vasya/mail.php".

Проведя несколько тестов и убедившись, что входящая почта передаётся в php скрипт, я мог заняться её обработкой.

Получение сырой входящей почты, направленной в php выше описанным способом, реализуется в коде крайне просто:

$msg = file_get_contents("php://stdin");

Совсем другое дело это разбор почтового формата и представление данных в понятном и доступном виде. Гугл предложил мне несколько вариантов, как можно разобрать почтовый формат средствами PHP. Все найденные мной библиотеки тянули за собой установку дополнительных компонентов, однако одна из них мне показалась менее громоздкой: github.com/zbateson/mail-mime-parser. Единственное, что мне нужно было установить дополнительно, это популярный пакетный менеджер для PHP – Composer. Конечно, на обычном хостинге я с ним и не сталкивался, но его установка и дальнейшее подключение библиотеки для разбора почты не оказалось сколько-нибудь сложным.

Начало php скрипта для обработки входящей почты с использованием библиотеки zbateson/mail-mime-parser выглядит так:

<?php
require("vendor/autoload.php"); use ZBateson\MailMimeParser\MailMimeParser;
use ZBateson\MailMimeParser\Message; $msg = file_get_contents("php://stdin");
$parser = new MailMimeParser();
$message = Message::from($msg);

Так как временная почта на мой взгляд не предполагает несколько получателей, достаточно взять только первого из возможных:

$to = $message->getHeader('To');
$email = $to->getAddresses()[0]->getEmail();

В переменной $email у нас оказывается адрес получателя вида vasyaorpetya@example.com.

Для получения контента входящих писем в библиотеке есть соответствующие методы:

$from = $message->getHeader('From')->getEmail();
$subject = $message->getHeaderValue('Subject'); $msg_text = $message->getTextContent();
$msg_html = $message->getHtmlContent();

Телеграм бот

Что должен уметь телеграм бот временной почты в первую очередь?

  1. Выдавать новый временный email адрес по запросу
  2. Присылать в чат входящие письма для этого email, пока почтовый адрес действителен
  3. Продлевать действие email-адреса

Вполне подходящий в данном и множестве других случаев способ получения обновлений от Телеграма – это использование Webhook. Нужен только адрес скрипта с https. Использование Certbot для настройки ssl сертификата домена подробно описано в инструкциях DO.

Кто-то предпочитает использовать популярные библиотеки. Для взаимодействия с Telegram Bot API я использую собственные наработки. Отправка сообщений с кнопками в телеграм уже давно стала привычным делом, о чём написано не мало статей.

Я создал таблицу для email адресов в базе данных, где id типа int с автоинкрементом однозначно определяет получателя. Генерация временных email адресов по сути является выдачей следующего адреса по порядку. 26 букв по сравнению с цифрами дают неплохое сокращение длины идентификатора. Превращение числового id в строковый адрес осуществляется как перевод числа в другую систему счисления, где в качестве «цифр» доступен весь латинский алфавит. Наверное, я мог бы использовать также большие буквы, цифры и некоторые символы без проблем для ещё большего сокращения длины выдаваемых адресов, но я оставил лишь маленькие латинские буквы.

Функции перевода числового id в строковый и обратно:

$alphabet = explode(",", "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"); function num2str($n, $a) return strrev($x);
} function str2num($s, $a) { $n = 0; $b = count($a); $s = strrev($s); for ($i = 0; $i < strlen($s); $i++) { $n += array_search($s[$i], $a) * pow($b, $i); } return $n;
}

Одно из ключевых преимуществ использования сервиса временной почты — отсутствие спама. Но если адреса идут по порядку, можно составить список ближайших адресов, которые будут выданы и успешно делать рассылку. Для решения этой проблемы я добавил некоторую случайную строку к идентификатору получателя. Для различия id и случайной составляющей в адресе я решил всегда начинать случайную компоненту с цифры.

Случайную строку выдаваемого email адреса записываем в БД вместе с id получателя, id пользователя в телеграме и временем выдачи почтового ящика.

Но как быть с html письмами? Казалось бы, можно даже не хранить входящую почту — отправили в телеграм и всё. Остаётся записывать входящие html сообщения в БД и показывать их на сайте, а пользователю отправлять ссылку, включающую в себя id сообщения и очередной сгенерированный пароль. Их невозможно отобразить в сообщении в чате. Для очистки БД кроном по расписанию запускается php скрипт, удаляющий входящие html сообщения, которые были получены более часа назад.

Позже в телеграм бота я добавил кнопки, продлевающие срок действия почтового ящика на 10 или 60 минут, а также кнопку, позволяющую узнать сколько, всё-таки, осталось ему жить до того, как будет прекращён приём входящих сообщений.

Выданный почтовый ящик «принимает» входящие только когда это необходимо пользователю, всё остальное время возможный спам игнорируется. Так как в телеграме мы имеем дело с зарегистрированными пользователями, можно предоставить возможность активировать свои старые почтовые ящики например с целью восстановить забытый пароль на веб-сайте или для любых других операций, требующих подтверждение с помощью email.

Хотелки на будущее:

  • Создать веб-версию [сделано]
  • Настроить быструю смену почтового домена в пару кликов/команд (как?)

Ссылки

Телеграм бот: @tmpmailbot

Статья, где описана настройка sendmail

PHP библиотека для разбора электронной почты


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Из песочницы] ВИЧ – методы лечения от первых лекарств до сегодняшнего дня

Прежде, чем приступить к изложению материала, хотелось бы сказать несколько слов о себе: участник сообществ по борьбе с отрицанием ВИЧ („ВИЧ/СПИД диссидентством“): в 2016-2018 годах „ВИЧ/СПИД диссиденты и их дети“, с 2018 года – „ВИЧ/СПИД отрицание и альтернативная медицина“. Это ...

Изюминки прошедшей Moscow Python Conf++ 2019: трансформация в площадку для общения

Самыми горячими темами Moscow Python Conf++ оказались асинхронная разработка, а также сопоставление Python, его лучших практик и инструментария с аналогами из других языков, и его место в ландшафте современной разработки. Плюс мы пригласили выступить Бенджамина Петерсона, одного из разработчиков CPython, ...