Пересылка почты в телеграм на PHP


Завершил небольшой проект по забору почты с рамблера, фильтрации её и пересылке в телеграм с помощью бота. С небольшими изменениями может использоваться и для майл с яндексом. Подразумевается, что вы уже зарегистрировали и настроили бота для телеграм.

Итак, для начала надо включить доступ к ящику сторонних предложений в рамблере. Иными словами, чтобы забирать почту не через браузер, необходимо разрешить это сделать. Это несложно:



Отлично, теперь нам требуется подключиться. Делается это так:

$email = "ваш_емайл@rambler.ru";
$password = "ваш пароль";
$folder = "INBOX";
$ref = "{imap.rambler.ru:993/novalidate-cert/ssl}$folder";
$connect_imap = imap_open($ref, $email, $password) or die("Error:" . imap_last_error());
$mails = imap_search($connect_imap, 'UNSEEN');
Здесь в первых трех строчках мы задаем параметры подключения (логин, пароль и папку), в четвертой строка подключения, в пятой непосредственно подключение через imap, а в шестой уже получаем массив писем.

Остановимся немного подробнее на строке подключения. Адрес imap берем из скрина выше (у яндекса будут уже другой), порт у всех стандартный, но самое интересное тут – это «novalidate-cert» - без этого у вас будет выбивать ошибку на некоторых хостингах. Imap уже обычно установлен на шаред хостингах, если у вас сервер – то придется ставить самостоятельно.

Функция imap_search() как можно догадаться по названию ищет по некоторым параметрам письма. В данном случае мы используем 'UNSEEN' – непрочитанные. Папка - "INBOX", если вам в другой надо искать, то смотрите как она у вас называется; регистр тут важен.

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

foreach($mails as $single_mail){
	$header = imap_header($connect_imap, $single_mail);

	$mail_from = $header->sender[0]->mailbox . "@" . $header->sender[0]->host;
	$subject =  imap_utf8($header->subject);
А дальше немного сложнее. Если письмо содержит обычный текст, то

$text_mail_text = base64_decode(imap_fetchbody($connect_imap, $single_mail, 1));
if (!$text_mail_text){
	$text_mail_text = imap_fetchbody($connect_imap, $single_mail, 1);
}
Зависит от кодировки – либо просто достаем, либо расшифровываем base64. Кодировка в даннном случае зависит от того, с какой почты пришло письмо. С html-письмом вот так поступим:

$body = getBody( imap_uid($connect_imap, $num_mail), $connect_imap);
Дополнительные функции:

function getBody($uid, $imap)
{
    $body = get_part($imap, $uid, "TEXT/HTML");
    if ($body == "") {
        $body = get_part($imap, $uid, "TEXT/PLAIN");
    }
    return $body;
}

function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false)
{
    if (!$structure) {
        $structure = imap_fetchstructure($imap, $uid, FT_UID);
    }
    if ($structure) {
        if ($mimetype == get_mime_type($structure)) {
            if (!$partNumber) {
                $partNumber = 1;
            }
            $text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
            switch ($structure->encoding) {
                case 3:
                    return imap_base64($text);
                case 4:
                    return imap_qprint($text);
                default:
                    return $text;
            }
        }
        if ($structure->type == 1) {
            foreach ($structure->parts as $index => $subStruct) {
                $prefix = "";
                if ($partNumber) {
                    $prefix = $partNumber . ".";
                }
                $data = get_part($imap, $uid, $mimetype, $subStruct, $prefix . ($index + 1));
                if ($data) {
                    return $data;
                }
            }
        }
    }
    return false;
}

function get_mime_type($structure)
{
    $primaryMimetype = ["TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"];

    if ($structure->subtype) {
        return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
    }
    return "TEXT/PLAIN";
}
Но и это еще не все. После получения тела письма для отправки в телеграм его необходимо превратить в обычный текст – иначе бот не сможет отправить. Это сделать можно, например, вот так. Сначала подключаем simple html dom

include_once "simple_html_dom.php"; 
Разбираем:

$html = str_get_html($body);
foreach($html->find('div') as $element) {
	$text = $element->plaintext;
	$text_mail .= $text.'. ';
}
И убираем все лишние знаки:

$text_mail = str_replace(PHP_EOL, '', $text_mail);
$text_mail = str_replace("\r\n", "", $text_mail);
$text_mail = str_replace(array("\r","\n","\t"), '', $text_mail);
$text_mail = preg_replace('/[^ a-zа-яё\d]/ui', '',$text_mail );
Сама отправка:

$txt = "В ящик $email пришло письмо от $mail_from с темой '$subject' и текстом '$text_mail'";	
sendMessage($tg_chat_id, $txt);
Функцию sendMessage() я уже разбирал здесь. Дальше этот наш файлик php кидаем на хостинг и дергаем по крону, скажем, раз в две минуты.

Как видите, большой сложности в заборе писем нет, основное – это борьба с кодировками и спецсимволами.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, php, telegram, бот, mail




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Урок 11. Директивы v-text, v-once, v-pre и v-html Vue 3
Курс валют и котировки акций онлайн на PHP
BrowseForFolder и MTP-устройства