Поделиться

Регистрация

Войти

phpmailer проверка доставки письма и его прочтения возможно получить ?

PHPMailer не предоставляет встроенных инструментов для прямой проверки доставки письма или его прочтения, так как эти функции зависят от почтовых серверов и клиентов. Однако есть несколько подходов, которые можно использовать для получения информации о доставке и прочтении писем. Рассмотрим их:

1. Проверка доставки письма

PHPMailer может сообщить, было ли письмо успешно принято SMTP-сервером для отправки, но это не гарантирует, что письмо достигло получателя или попало в его почтовый ящик. Для проверки статуса доставки можно использовать следующие методы:

a) Проверка возврата ошибки от SMTP

PHPMailer возвращает true, если письмо было успешно передано SMTP-серверу, и false в случае ошибки. Вы можете включить отладку SMTP, чтобы получить больше информации:

php

СвернутьПеренос
Копировать

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->SMTPDebug = 2; // Включить отладку

$mail->setFrom([email-masked]', 'Sender Name');

$mail->addAddress([email-masked]', 'Recipient Name');

$mail->Subject = 'Test Email';

$mail->Body = 'This is a test email.';

if ($mail->send()) {

echo 'Письмо успешно отправлено SMTP-серверу.';

}

} catch (Exception $e) {

echo "Ошибка отправки: {$mail->ErrorInfo}";

}

Если SMTP-сервер отклоняет письмо (например, из-за несуществующего адреса), вы получите ошибку в $mail->ErrorInfo. Однако, если сервер принимает письмо, это не означает, что оно доставлено в почтовый ящик получателя.

b) Обработка возвратов (Bounce Handling)

Для проверки доставки можно настроить обработку "возвратных писем" (bounced emails). Это письма, которые возвращаются отправителю, если адрес получателя недействителен или доставка невозможна. Для этого:

Настройте специальный почтовый ящик для обработки возвратов (например, [email-masked]).

Укажите его в заголовке Return-Path в PHPMailer:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Path: [email-masked]');

Используйте IMAP или POP3 для чтения писем в ящике [email-masked] и анализа уведомлений о недоставке (DSN — Delivery Status Notification). Это требует дополнительной логики для обработки таких писем, например, с использованием библиотеки IMAP в PHP.

c) Использование сторонних сервисов

Сторонние SMTP-сервисы, такие как SendGrid, Mailgun или SendLayer, предоставляют API для отслеживания статуса доставки. Например, в SendLayer вы можете проверить статус в панели управления (Logs → Event column). Для этого нужно:

Настроить PHPMailer для работы с API сервиса.

Использовать их документацию для получения логов доставки.

Пример интеграции с SendGrid:

php

СвернутьПеренос
Копировать

$mail->Host = 'smtp.sendgrid.net';

$mail->Username = 'apikey';

$mail->Password = 'ваш_api_ключ';

$mail->Port = 587;

$mail->SMTPSecure = 'tls';

После отправки проверяйте статус через API или панель управления сервиса.

d) Поддержка DSN (Delivery Status Notification)

PHPMailer не поддерживает DSN (уведомления о статусе доставки) напрямую, но вы можете модифицировать файл class.smtp.php для добавления команды NOTIFY=SUCCESS,FAILURE в SMTP-протокол после RCPT TO. Это требует ручного редактирования исходного кода, что не рекомендуется, так как обновления PHPMailer могут перезаписать изменения.

Альтернативно, настройте сервер SMTP (например, Postfix) для отправки DSN и указания адреса для уведомлений:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Receipt-To: [email-masked]');

Однако DSN работает только с серверами, поддерживающими эту функцию, и не всегда надежно.

2. Проверка прочтения письма

Проверка прочтения письма (read receipt) — это более сложная задача, так как она зависит от почтового клиента получателя. Большинство современных клиентов (например, Gmail, Outlook) позволяют пользователю отключить отправку уведомлений о прочтении. Вот несколько подходов:

a) Запрос уведомления о прочтении

Вы можете запросить уведомление о прочтении, добавив соответствующие заголовки в PHPMailer:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

$mail->addCustomHeader('X-Confirm-Reading-To: [email-masked]');

$mail->ConfirmReadingTo = [email-masked]';

Однако:

Получатель должен вручную подтвердить отправку уведомления.

Многие клиенты игнорируют такие запросы или отключают их по умолчанию.

b) Использование трекингового пикселя

Трекинговый пиксель — это небольшой (обычно 1x1 пиксель) изображение, встраиваемое в HTML-письмо, которое загружается с вашего сервера, когда получатель открывает письмо. Это позволяет зарегистрировать факт открытия письма.

Пример:

php

СвернутьПеренос
Копировать

$mail->isHTML(true);

$body = '<html><body>';

$body .= 'Ваше сообщение здесь';

$body .= '<img src="https://yourdomain.com/tracker.php?email=[email-masked]" width="1" height="1" alt="" />';

$body .= '</body></html>';

$mail->Body = $body;

На сервере создайте файл tracker.php:

php

СвернутьПеренос
Копировать

<?php

if (isset($_GET['email'])) {

$email = $_GET['email'];

// Записать в базу данных или лог, что письмо открыто

file_put_contents('log.txt', "Email opened: $email at " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);

// Отправить изображение 1x1 пиксель

header('Content-Type: image/png');

echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/wcAAgAB/w9N0AAAAABJRU5ErkJggg==');

}

Ограничения:

Многие почтовые клиенты блокируют автоматическую загрузку изображений.

Если получатель откроет письмо в текстовом режиме, пиксель не загрузится.

c) Сторонние сервисы для трекинга

Сервисы, такие как Mailgun или SendGrid, предоставляют встроенные функции отслеживания прочтения через трекинговые пиксели или API. Они автоматически добавляют пиксель в письмо и предоставляют статистику в панели управления. Это более надежный и удобный способ, чем ручная реализация.

Ограничения и рекомендации

Доставка: PHPMailer не может гарантировать доставку в почтовый ящик, так как это зависит от множества факторов (фильтры спама, настройки сервера получателя и т.д.). Используйте сторонние сервисы для точного отслеживания.

Прочтение: Уведомления о прочтении ненадежны из-за настроек почтовых клиентов. Трекинговые пиксели работают лучше, но их эффективность ограничена блокировкой изображений.

Юридические аспекты: В некоторых странах отслеживание прочтения без согласия получателя может нарушать законы о конфиденциальности (например, GDPR в Европе). Убедитесь, что вы соблюдаете местное законодательство.

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

Пример полного кода с трекингом

php

СвернутьПеренос
Копировать

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->setFrom([email-masked]', 'Sender Name');

$mail->addAddress([email-masked]', 'Recipient Name');

$mail->addCustomHeader('Return-Path: [email-masked]');

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

$mail->isHTML(true);

$mail->Subject = 'Test Email with Tracking';

$mail->Body = '<html><body>Ваше сообщение здесь<br><img src="https://yourdomain.com/tracker.php?email=[email-masked]" width="1" height="1" alt="" /></body></html>';

if ($mail->send()) {

echo 'Письмо успешно отправлено SMTP-серверу.';

}

} catch (Exception $e) {

echo "Ошибка отправки: {$mail->ErrorInfo}";

}

Заключение

Для проверки доставки лучше использовать сторонние сервисы (SendGrid, Mailgun, SendLayer) или настроить обработку возвратов через Return-Path и IMAP.

Для проверки прочтения трекинговый пиксель — наиболее распространенный метод, но он не гарантирует 100% точности.

Всегда тестируйте отправку писем и соблюдайте законодательство.

Если у вас есть конкретный SMTP-сервер или сервис, напишите, и я помогу настроить более точное решение!

25 веб-страниц

5,6s

Давай более подробно и больше информации про команды

Хорошо, давайте разберемся более подробно с командами и подходами для проверки доставки и прочтения писем с использованием PHPMailer, а также углубимся в технические аспекты, включая команды SMTP, заголовки и дополнительные инструменты. Я постараюсь объяснить всё максимально понятно и с примерами, чтобы вы могли применить это на практике.

1. Проверка доставки письма

Проверка доставки письма — это процесс определения, было ли письмо успешно доставлено в почтовый ящик получателя. PHPMailer взаимодействует с SMTP-сервером, и вы можете получить информацию о том, принят ли запрос на отправку, но дальнейшая судьба письма зависит от почтовых серверов и их настроек. Рассмотрим ключевые команды и методы.

a) SMTP-команды и отладка в PHPMailer

PHPMailer использует SMTP-протокол для отправки писем. Основные команды SMTP, которые задействуются при отправке:

HELO/EHLO: Инициирует соединение с SMTP-сервером. PHPMailer автоматически отправляет EHLO для использования расширенных функций.

MAIL FROM: Указывает адрес отправителя ($mail->setFrom()).

RCPT TO: Указывает адрес получателя ($mail->addAddress()).

DATA: Передает тело письма, включая заголовки и содержимое.

QUIT: Завершает соединение.

Для проверки, принят ли сервером запрос на отправку, включите отладку SMTP с помощью свойства SMTPDebug:

php

СвернутьПеренос
Копировать

$mail->SMTPDebug = 2; // Уровень отладки: 2 для подробного вывода

Пример кода с отладкой:

php

СвернутьПеренос
Копировать

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->SMTPDebug = 2; // Включить отладку

$mail->setFrom([email-masked]', 'Sender Name');

$mail->addAddress([email-masked]', 'Recipient Name');

$mail->Subject = 'Test Email';

$mail->Body = 'This is a test email.';

if ($mail->send()) {

echo 'Письмо успешно отправлено SMTP-серверу.';

}

} catch (Exception $e) {

echo "Ошибка отправки: {$mail->ErrorInfo}";

}

Вывод отладки (пример):

text

СвернутьПеренос
Копировать

2025-07-09 13:14:32 SERVER -> CLIENT: 220 smtp.example.com ESMTP

2025-07-09 13:14:32 CLIENT -> SERVER: EHLO yourdomain.com

2025-07-09 13:14:32 SERVER -> CLIENT: 250-smtp.example.com

2025-07-09 13:14:32 CLIENT -> SERVER: AUTH LOGIN

2025-07-09 13:14:32 SERVER -> CLIENT: 334 VXNlcm5hbWU6

2025-07-09 13:14:32 CLIENT -> SERVER: your_username

2025-07-09 13:14:32 SERVER -> CLIENT: 334 UGFzc3dvcmQ6

2025-07-09 13:14:32 CLIENT -> SERVER: your_password

2025-07-09 13:14:32 SERVER -> CLIENT: 235 Authentication successful

2025-07-09 13:14:32 CLIENT -> SERVER: MAIL FROM:<[email-masked]>

2025-07-09 13:14:32 SERVER -> CLIENT: 250 OK

2025-07-09 13:14:32 CLIENT -> SERVER: RCPT TO:<[email-masked]>

2025-07-09 13:14:32 SERVER -> CLIENT: 250 Accepted

2025-07-09 13:14:32 CLIENT -> SERVER: DATA

2025-07-09 13:14:32 SERVER -> CLIENT: 354 Enter mail

2025-07-09 13:14:32 CLIENT -> SERVER: Subject: Test Email

...

2025-07-09 13:14:32 SERVER -> CLIENT: 250 OK id=1.23456

2025-07-09 13:14:32 CLIENT -> SERVER: QUIT

2025-07-09 13:14:32 SERVER -> CLIENT: 221 Bye

Если сервер возвращает код 250 OK после команды RCPT TO, это означает, что он принял письмо для обработки. Однако это не гарантирует доставку в ящик получателя, так как письмо может быть отклонено позже (например, из-за спам-фильтров).

b) Настройка заголовка Return-Path для обработки возвратов

Чтобы получать уведомления о недоставке (bounced emails), настройте заголовок Return-Path. Это адрес, на который почтовый сервер отправляет уведомления о сбоях доставки (например, если адрес получателя не существует).

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Path: [email-masked]');

Как обрабатывать возвраты:

Создайте отдельный почтовый ящик, например, [email-masked].

Используйте библиотеку PHP IMAP для чтения писем из этого ящика.

Анализируйте письма, ищущие заголовки Diagnostic-Code или Status, которые указывают причину недоставки.

Пример обработки возвратов с IMAP:

php

СвернутьПеренос
Копировать

$mailbox = imap_open('{imap.example.com:993/imap/ssl}INBOX', [email-masked]', 'password');

if ($mailbox) {

$emails = imap_search($mailbox, 'ALL');

foreach ($emails as $email_number) {

$header = imap_headerinfo($mailbox, $email_number);

$body = imap_fetchbody($mailbox, $email_number, 1);

if (strpos($body, 'Diagnostic-Code')) {

// Логика обработки возврата

echo "Недоставленное письмо: " . $header->subject . "\n";

}

}

imap_close($mailbox);

}

Ограничения:

Формат уведомлений о недоставке (DSN) варьируется между серверами.

Некоторые серверы могут не отправлять уведомления.

c) Использование DSN (Delivery Status Notification)

Некоторые SMTP-серверы поддерживают команду NOTIFY в рамках RCPT TO, которая запрашивает уведомления о статусе доставки (SUCCESS, FAILURE, DELAY). PHPMailer по умолчанию не добавляет эту команду, но вы можете модифицировать метод send в class.smtp.php или использовать сторонние SMTP-серверы, поддерживающие DSN.

Пример модификации команды RCPT TO (не рекомендуется для стандартного использования, так как требует изменения исходного кода PHPMailer):

php

СвернутьПеренос
Копировать

// В class.smtp.php, метод rcptTo()

$this->sendCommand('RCPT', "RCPT TO:<$address> NOTIFY=SUCCESS,FAILURE,DELAY", 250, 251);

Вместо этого лучше использовать сторонние сервисы, такие как Postfix, настроенные для отправки DSN, и указать адрес для уведомлений:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Receipt-To: [email-masked]');

d) Сторонние сервисы для проверки доставки

Сторонние сервисы, такие как SendGrid, Mailgun, Amazon SES или SendLayer, предоставляют API для получения статуса доставки. Они возвращают такие события, как delivered, bounced, dropped, или spam.

Пример с SendGrid API (через их PHP библиотеку):

php

СвернутьПеренос
Копировать

require 'vendor/autoload.php';

use SendGrid\Mail\Mail;

$email = new Mail();

$email->setFrom("[email-masked]", "Sender Name");

$email->setSubject("Test Email");

$email->addTo("[email-masked]", "Recipient Name");

$email->addContent("text/html", "This is a test email.");

$sendgrid = new \SendGrid('YOUR_API_KEY');

try {

$response = $sendgrid->send($email);

echo "Статус: " . $response->statusCode();

} catch (Exception $e) {

echo 'Ошибка: ' . $e->getMessage();

}

После отправки вы можете использовать Webhook или API SendGrid для получения логов доставки:

php

СвернутьПеренос
Копировать

// Пример запроса к API для проверки статуса

$sendgrid = new \SendGrid('YOUR_API_KEY');

$query_params = ['query' => 'msg_id=your_message_id'];

$response = $sendgrid->client->get('/v3/messages', null, $query_params);

echo $response->body();

Преимущества сторонних сервисов:

Точные логи доставки.

Возможность отслеживать события, такие как delivered, bounced, dropped.

Интеграция с вебхуками для автоматической обработки.

2. Проверка прочтения письма

Проверка прочтения письма сложнее, так как зависит от действий получателя и настроек его почтового клиента. PHPMailer не имеет встроенных функций для этого, но вы можете использовать заголовки или трекинговые пиксели.

a) Запрос уведомления о прочтении

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

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

$mail->addCustomHeader('X-Confirm-Reading-To: [email-masked]');

$mail->ConfirmReadingTo = [email-masked]';

Как это работает:

Почтовый клиент (например, Outlook) может предложить получателю отправить уведомление о прочтении.

Если получатель соглашается, на адрес [email-masked] приходит письмо с подтверждением.

Ограничения:

Большинство клиентов (Gmail, Yahoo) игнорируют такие заголовки.

Пользователь может отказаться отправлять уведомление.

b) Трекинговый пиксель

Трекинговый пиксель — это наиболее распространенный способ отслеживания открытия писем. Вы добавляете в HTML-письмо ссылку на изображение, которое загружается с вашего сервера, и фиксируете запрос.

Пример кода PHPMailer с трекинговым пикселем:

php

СвернутьПеренос
Копировать

$mail->isHTML(true);

$tracking_url = 'https://yourdomain.com/tracker.php?email=' . urlencode([email-masked]') . '&id=' . uniqid();

$mail->Body = '<html><body>Ваше сообщение здесь<br><img src="' . $tracking_url . '" width="1" height="1" alt="" /></body></html>';

Серверный скрипт (tracker.php):

php

СвернутьПеренос
Копировать

<?php

if (isset($_GET['email']) && isset($_GET['id'])) {

$email = $_GET['email'];

$id = $_GET['id'];

// Записать в лог или базу данных

$log_entry = "Email opened: $email, ID: $id at " . date('Y-m-d H:i:s') . "\n";

file_put_contents('tracking_log.txt', $log_entry, FILE_APPEND);

// Отправить прозрачное изображение 1x1

header('Content-Type: image/png');

echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/wcAAgAB/w9N0AAAAABJRU5ErkJggg==');

}

Как это работает:

Когда получатель открывает письмо, его почтовый клиент загружает изображение по URL.

Сервер фиксирует запрос, записывая информацию в лог или базу данных.

Ограничения:

Если изображения отключены в почтовом клиенте, трекинг не сработает.

Некоторые клиенты (например, Gmail) кэшируют изображения, что может искажать статистику.

Использование трекинга без согласия может нарушать законы (например, GDPR).

c) Сторонние сервисы для трекинга прочтения

Сервисы, такие как SendGrid, Mailgun или Postmark, автоматически добавляют трекинговые пиксели и предоставляют статистику через API или вебхуки.

Пример с Mailgun:

php

СвернутьПеренос
Копировать

require 'vendor/autoload.php';

use Mailgun\Mailgun;

$mg = Mailgun::create('YOUR_API_KEY');

$domain = 'yourdomain.com';

$mg->messages()->send($domain, [

'from' => [email-masked]',

'to' => [email-masked]',

'subject' => 'Test Email',

'html' => '<html><body>Test email</body></html>',

'o:tracking' => true, // Включить отслеживание открытия

'o:tracking-opens' => true // Включить трекинг открытия

]);

Получение данных через вебхук:

Настройте вебхук в панели Mailgun для события opened.

Создайте скрипт для обработки вебхука:

php

СвернутьПеренос
Копировать

<?php

// webhook.php

$input = file_get_contents('php://input');

$data = json_decode($input, true);

if (isset($data['event-data']['event']) && $data['event-data']['event'] === 'opened') {

$email = $data['event-data']['recipient'];

$timestamp = $data['event-data']['timestamp'];

file_put_contents('open_log.txt', "Opened: $email at " . date('Y-m-d H:i:s', $timestamp) . "\n", FILE_APPEND);

}

Преимущества:

Надежнее, чем самописные решения.

Поддержка вебхуков для автоматического обновления.

Статистика в панели управления.

3. Дополнительные команды и настройки PHPMailer

PHPMailer предоставляет несколько методов и свойств, которые можно использовать для настройки отправки и обработки писем:

addCustomHeader($name, $value): Добавляет пользовательский заголовок, например, Return-Path или Disposition-Notification-To.

ConfirmReadingTo: Упрощает добавление заголовка для запроса уведомления о прочтении.

SMTPKeepAlive: Позволяет держать SMTP-соединение открытым для отправки нескольких писем (полезно для массовых рассылок).

addReplyTo($address, $name): Указывает адрес для ответов, что может быть полезно для обработки возвратов.

PreSend() и PostSend(): Методы для выполнения действий до и после отправки письма (например, логирование).

Пример массовой рассылки с отслеживанием:

php

СвернутьПеренос
Копировать

$mail = new PHPMailer(true);

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->SMTPKeepAlive = true; // Держать соединение открытым

$recipients = [[email-masked]', [email-masked]'];

foreach ($recipients as $recipient) {

try {

$mail->addAddress($recipient);

$mail->isHTML(true);

$tracking_url = 'https://yourdomain.com/tracker.php?email=' . urlencode($recipient) . '&id=' . uniqid();

$mail->Body = '<html><body>Hello, ' . $recipient . '<br><img src="' . $tracking_url . '" width="1" height="1" alt="" /></body></html>';

$mail->Subject = 'Test Email';

$mail->send();

echo "Письмо отправлено: $recipient\n";

$mail->clearAddresses(); // Очистить получателей для следующей итерации

} catch (Exception $e) {

echo "Ошибка для $recipient: {$mail->ErrorInfo}\n";

}

}

$mail->smtpClose(); // Закрыть соединение

4. Юридические и этические аспекты

GDPR и конфиденциальность: В ЕС и других регионах трекинг писем (особенно с помощью пикселей) требует согласия получателя. Убедитесь, что вы уведомляете пользователей о сборе данных.

CAN-SPAM (США): Требует возможности отписки и точного указания отправителя.

Антиспам-фильтры: Чрезмерное использование трекинга или некорректные заголовки могут привести к попаданию писем в спам.

5. Рекомендации по тестированию

Используйте сервисы, такие как Mailtrap или MailHog, для тестирования отправки и отображения писем.

Проверьте письма в разных клиентах (Gmail, Outlook, Yahoo) с помощью сервисов, таких как Litmus или Email on Acid.

Проверьте репутацию домена с помощью Postmark или SenderScore, чтобы избежать попадания в спам.

6. Итоговый пример кода

Полный пример с доставкой, трекингом и обработкой ошибок:

php

СвернутьПеренос
Копировать

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {

// Настройки SMTP

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->SMTPDebug = 2;

// Настройки письма

$mail->setFrom([email-masked]', 'Sender Name');

$mail->addAddress([email-masked]', 'Recipient Name');

$mail->addCustomHeader('Return-Path: [email-masked]');

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

// Трекинговый пиксель

$tracking_url = 'https://yourdomain.com/tracker.php?email=' . urlencode([email-masked]') . '&id=' . uniqid();

$mail->isHTML(true);

$mail->Subject = 'Test Email with Tracking';

$mail->Body = '<html><body>Ваше сообщение здесь<br><img src="' . $tracking_url . '" width="1" height="1" alt="" /></body></html>';

// Отправка

if ($mail->send()) {

echo 'Письмо успешно отправлено SMTP-серверу.';

}

} catch (Exception $e) {

echo "Ошибка отправки: {$mail->ErrorInfo}";

}

Заключение

Доставка: Используйте Return-Path и IMAP для обработки возвратов или сторонние сервисы (SendGrid, Mailgun) для точных логов.

Прочтение: Трекинговые пиксели — лучший способ, но их эффективность ограничена. Сторонние сервисы упрощают задачу.

Команды SMTP: PHPMailer автоматически обрабатывает основные команды (EHLO, MAIL FROM, RCPT TO, DATA), но для DSN требуется настройка сервера или модификация кода.

Тестирование и законы: Тестируйте письма и соблюдайте законодательство о конфиденциальности.

Если у вас есть конкретные вопросы или вы используете определенный SMTP-сервер, напишите, и я помогу настроить команды или интеграцию!

4,1s

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]'); $mail->addCustomHeader('X-Confirm-Reading-To: [email-masked]'); $mail->ConfirmReadingTo = [email-masked]';
mail->addCustomHeader('Return-Receipt-To: [email-masked]');
$mail->addCustomHeader('Return-Path: [email-masked]'); Давай более подробно и больше информации про команды

Хорошо, давайте разберем указанные команды PHPMailer, связанные с добавлением пользовательских заголовков (addCustomHeader, ConfirmReadingTo, Return-Path, Disposition-Notification-To, X-Confirm-Reading-To, Return-Receipt-To), их назначение, работу на уровне протокола, ограничения и лучшие практики. Я также добавлю больше контекста о том, как эти заголовки взаимодействуют с почтовыми серверами и клиентами, и дам рекомендации по их использованию.

1. Общее понимание заголовков в PHPMailer

PHPMailer позволяет добавлять пользовательские заголовки в письма с помощью метода addCustomHeader($name, $value). Заголовки — это метаданные, которые включаются в MIME-сообщение и передаются через SMTP-протокол. Они содержат инструкции для почтовых серверов и клиентов, например, о том, куда отправлять уведомления о прочтении или возвратах. Однако их обработка зависит от серверов и клиентов получателя, что делает некоторые заголовки ненадежными.

Метод addCustomHeader:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Header-Name: value');

Назначение: Добавляет произвольный заголовок в письмо.

Формат: Пара имя: значение, соответствующая стандарту RFC 2822.

Пример: $mail->addCustomHeader('X-My-Custom-Header: some-value');

Метод ConfirmReadingTo:

php

СвернутьПеренос
Копировать

$mail->ConfirmReadingTo = [email-masked]';

Назначение: Упрощенный способ добавления заголовка Disposition-Notification-To для запроса уведомления о прочтении.

Эквивалент: Выполняет то же, что $mail->addCustomHeader('Disposition-Notification-To: [email-masked]');.

Теперь разберем каждую из указанных команд подробно.

2. Подробный разбор указанных заголовков

a) Disposition-Notification-To: [email-masked]

Назначение:

Запрашивает у почтового клиента получателя отправку уведомления о прочтении (read receipt).

Этот заголовок стандартизирован в RFC 3798 (Message Disposition Notification, MDN).

Как работает:

Когда получатель открывает письмо в почтовом клиенте (например, Microsoft Outlook), клиент может показать всплывающее окно с запросом: «Отправить уведомление о прочтении?». Если пользователь соглашается, на адрес, указанный в Disposition-Notification-To, отправляется письмо с подтверждением.

Формат уведомления — это MIME-сообщение с типом multipart/report и report-type=disposition-notification.

Пример кода:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

Или эквивалент:

php

СвернутьПеренос
Копировать

$mail->ConfirmReadingTo = [email-masked]';

Технические детали:

Заголовок добавляется в секцию header MIME-сообщения.

Пример MIME-структуры письма:

text

СвернутьПеренос
Копировать

To: [email-masked]

From: [email-masked]

Subject: Test Email

Disposition-Notification-To: [email-masked]

MIME-Version: 1.0

Content-Type: text/plain; charset=utf-8

This is a test email.

Когда клиент отправляет уведомление, оно выглядит примерно так:

text

СвернутьПеренос
Копировать

From: [email-masked]

To: [email-masked]

Subject: Read: Test Email

Content-Type: multipart/report; report-type=disposition-notification

--boundary

Content-Type: message/disposition-notification

Final-Recipient: rfc822; [email-masked]

Disposition: manual-action/MDN-sent-manually; displayed

Ограничения:

Поддерживается не всеми клиентами. Например, Gmail и многие веб-клиенты игнорируют этот заголовок.

Пользователь должен вручную согласиться отправить уведомление.

Некоторые клиенты (например, Outlook) могут отправлять уведомления только в корпоративных сетях (Exchange Server).

Использование без согласия получателя может нарушать законы о конфиденциальности (например, GDPR).

Рекомендации:

Используйте только для деловой переписки, где получатель ожидает такого запроса.

Комбинируйте с трекинговыми пикселями для большей надежности (см. ниже).

Убедитесь, что адрес в Disposition-Notification-To существует и отслеживается.

b) X-Confirm-Reading-To: [email-masked]

Назначение:

Нестандартизированный заголовок, используемый некоторыми почтовыми клиентами (например, старыми версиями Outlook или Lotus Notes) для запроса уведомления о прочтении.

Аналогичен Disposition-Notification-To, но менее распространен.

Как работает:

Работает так же, как Disposition-Notification-To, но зависит от специфичных реализаций в почтовых клиентах.

Добавляется как пользовательский заголовок с префиксом X-, что указывает на его нестандартный характер (RFC 822).

Пример кода:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('X-Confirm-Reading-To: [email-masked]');

Технические детали:

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

Совместимость ограничена, так как большинство современных клиентов игнорируют заголовки с префиксом X-.

Ограничения:

Устаревший и редко поддерживается.

Используйте только для совместимости со старыми системами.

Лучше полагаться на Disposition-Notification-To или трекинговые пиксели.

Рекомендации:

Добавляйте этот заголовок только в случае, если вы отправляете письма в системы, где он может быть обработан (например, старые корпоративные почтовые серверы).

Считайте его запасным вариантом к Disposition-Notification-To.

c) ConfirmReadingTo

Назначение:

Свойство PHPMailer, которое автоматически добавляет заголовок Disposition-Notification-To.

Упрощает процесс, так как не требует вызова addCustomHeader.

Пример кода:

php

СвернутьПеренос
Копировать

$mail->ConfirmReadingTo = [email-masked]';

Технические детали:

Эквивалентно:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Disposition-Notification-To: [email-masked]');

PHPMailer автоматически форматирует адрес в соответствии со стандартами RFC.

Если вы укажете оба (ConfirmReadingTo и addCustomHeader('Disposition-Notification-To')), заголовок не будет дублироваться, так как PHPMailer обрабатывает это внутренне.

Ограничения:

Те же, что и у Disposition-Notification-To (см. выше).

Не добавляет дополнительных возможностей по сравнению с прямым использованием заголовка.

Рекомендации:

Используйте ConfirmReadingTo для удобства, если вы не добавляете другие связанные заголовки.

Убедитесь, что адрес для уведомлений активен и проверяется.

d) Return-Receipt-To: [email-masked]

Назначение:

Нестандартизированный заголовок, иногда используемый для запроса уведомления о доставке (не прочтении).

Может быть обработан некоторыми SMTP-серверами или клиентами для отправки уведомления о том, что письмо достигло почтового ящика.

Как работает:

Аналогичен DSN (Delivery Status Notification), но не стандартизирован и редко поддерживается.

Может использоваться в сочетании с Return-Path для обработки уведомлений о доставке или недоставке.

Пример кода:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Receipt-To: [email-masked]');

Технические детали:

Добавляется как пользовательский заголовок.

Некоторые почтовые серверы (например, Microsoft Exchange) могут интерпретировать его как запрос DSN, но это не гарантировано.

Формат уведомления зависит от сервера (может быть обычным письмом или DSN).

Ограничения:

Нестандартизированный, поэтому поддержка ограничена.

Современные SMTP-серверы предпочитают DSN с командой NOTIFY (см. ниже).

Не путать с Disposition-Notification-To, который относится к прочтению, а не доставке.

Рекомендации:

Используйте только для совместимости со старыми системами.

Для надежной проверки доставки лучше настроить DSN или использовать сторонние сервисы.

e) Return-Path: [email-masked]

Назначение:

Указывает адрес, на который будут отправляться уведомления о недоставке (bounced emails).

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

Как работает:

Когда почтовый сервер не может доставить письмо, он отправляет уведомление о недоставке (DSN или bounce message) на адрес, указанный в Return-Path.

Этот заголовок обычно автоматически устанавливается SMTP-сервером на основе адреса MAIL FROM в SMTP-сессии, но вы можете переопределить его.

Пример кода:

php

СвернутьПеренос
Копировать

$mail->addCustomHeader('Return-Path: [email-masked]');

Технические детали:

Return-Path добавляется в заголовки письма, но SMTP-сервер может перезаписать его, если вы явно не укажете его в команде MAIL FROM.

Пример SMTP-сессии:

text

СвернутьПеренос
Копировать

MAIL FROM:<[email-masked]>

250 OK

RCPT TO:<[email-masked]>

250 Accepted

Уведомление о недоставке (bounce) обычно имеет тип multipart/report с полем report-type=delivery-status:

text

СвернутьПеренос
Копировать

From: [email-masked]

To: [email-masked]

Subject: Undelivered Mail Returned to Sender

Content-Type: multipart/report; report-type=delivery-status

--boundary

Content-Type: message/delivery-status

Final-Recipient: rfc822; [email-masked]

Diagnostic-Code: smtp; 550 5.1.1 User unknown

Ограничения:

Не все серверы отправляют уведомления о недоставке.

Формат bounce-сообщений варьируется, что затрудняет автоматическую обработку.

Если вы используете сторонний SMTP-сервер (например, Gmail), он может игнорировать ваш Return-Path и использовать собственный адрес.

Рекомендации:

Создайте отдельный ящик (например, [email-masked]) для обработки возвратов.

Используйте библиотеку IMAP для анализа bounce-сообщений (пример ниже).

Для большей надежности используйте сторонние сервисы (SendGrid, Mailgun), которые предоставляют структурированные логи.

Пример обработки bounce-сообщений:

php

СвернутьПеренос
Копировать

$mailbox = imap_open('{imap.example.com:993/imap/ssl}INBOX', [email-masked]', 'password');

if ($mailbox) {

$emails = imap_search($mailbox, 'FROM "postmaster"');

foreach ($emails as $email_number) {

$header = imap_headerinfo($mailbox, $email_number);

$body = imap_fetchbody($mailbox, $email_number, 1);

if (strpos($body, 'Diagnostic-Code')) {

// Извлечь информацию о недоставке

preg_match('/Diagnostic-Code: smtp; (.+)/', $body, $matches);

$error = $matches[1] ?? 'Unknown error';

echo "Bounce: {$header->subject}, Error: $error\n";

}

}

imap_close($mailbox);

}

3. Взаимодействие заголовков с SMTP-протоколом

Каждый из этих заголовков взаимодействует с почтовыми серверами и клиентами по-разному. Вот как они соотносятся с SMTP-командами:

Disposition-Notification-To и X-Confirm-Reading-To:

Не влияют на SMTP-сессию напрямую. Эти заголовки обрабатываются почтовым клиентом получателя.

SMTP-сервер просто передает их как часть тела письма (команда DATA).

Return-Receipt-To:

Может быть интерпретирован SMTP-сервером как запрос DSN, если сервер поддерживает команду NOTIFY (RFC 3461).

PHPMailer не добавляет NOTIFY автоматически, но вы можете модифицировать class.smtp.php:

php

СвернутьПеренос
Копировать

// В методе rcptTo()

$this->sendCommand('RCPT', "RCPT TO:<$address> NOTIFY=SUCCESS,FAILURE,DELAY", [250, 251]);

Это требует кастомизации и не рекомендуется для стандартного использования.

Return-Path:

Соответствует команде MAIL FROM в SMTP-сессии.

PHPMailer автоматически устанавливает MAIL FROM на основе $mail->setFrom(), но вы можете переопределить его с помощью $mail->Sender:

php

СвернутьПеренос
Копировать

$mail->Sender = [email-masked]';

Это предпочтительнее, чем использование addCustomHeader('Return-Path'), так как Sender напрямую влияет на SMTP-команду.

Пример SMTP-сессии с Return-Path:

text

СвернутьПеренос
Копировать

EHLO yourdomain.com

250 OK

MAIL FROM:<[email-masked]>

250 OK

RCPT TO:<[email-masked]>

250 Accepted

DATA

354 Enter mail

From: [email-masked]

To: [email-masked]

Subject: Test Email

Return-Path: [email-masked]

This is a test email.

.

250 OK id=1.23456

QUIT

221 Bye

4. Практические рекомендации по использованию

Комбинирование заголовков:

Используйте Disposition-Notification-To (или ConfirmReadingTo) и трекинговый пиксель вместе для повышения шансов отслеживания прочтения.

Пример:

php

СвернутьПеренос
Копировать

$mail->ConfirmReadingTo = [email-masked]';

$tracking_url = 'https://yourdomain.com/tracker.php?email=' . urlencode([email-masked]') . '&id=' . uniqid();

$mail->isHTML(true);

$mail->Body = '<html><body>Test email<br><img src="' . $tracking_url . '" width="1" height="1" alt="" /></body></html>';

Обработка возвратов:

Настройте Return-Path и отдельный ящик для bounce-сообщений.

Используйте IMAP или сторонние сервисы для автоматизации анализа.

Сторонние сервисы:

Для надежного отслеживания доставки и прочтения используйте SendGrid, Mailgun или Amazon SES. Они предоставляют API и вебхуки для событий delivered, opened, bounced.

Пример настройки вебхука в SendGrid:

php

СвернутьПеренос
Копировать

$sendgrid = new \SendGrid('YOUR_API_KEY');

$email = new \SendGrid\Mail\Mail();

$email->setFrom([email-masked]');

$email->addTo([email-masked]');

$email->setSubject('Test Email');

$email->addContent('text/html', 'Test email');

$email->setTrackingSettings(['open_tracking' => ['enable' => true]]);

$sendgrid->send($email);

Тестирование:

Используйте Mailtrap или MailHog для проверки, как заголовки отображаются в письмах.

Проверьте, как клиенты (Gmail, Outlook) обрабатывают Disposition-Notification-To.

Юридические аспекты:

Уведомляйте получателей о трекинге (например, в политике конфиденциальности).

Соблюдайте GDPR, CAN-SPAM и другие законы.

5. Полный пример кода

php

СвернутьПеренос
Копировать

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {

// Настройки SMTP

$mail->isSMTP();

$mail->Host = 'smtp.example.com';

$mail->SMTPAuth = true;

$mail->Username = 'your_username';

$mail->Password = 'your_password';

$mail->SMTPSecure = 'tls';

$mail->Port = 587;

$mail->SMTPDebug = 2;

// Настройки отправителя и получателя

$mail->setFrom([email-masked]', 'Sender Name');

$mail->Sender = [email-masked]'; // Для Return-Path

$mail->addAddress([email-masked]', 'Recipient Name');

// Заголовки для уведомлений

$mail->ConfirmReadingTo = [email-masked]'; // Disposition-Notification-To

$mail->addCustomHeader('X-Confirm-Reading-To: [email-masked]');

$mail->addCustomHeader('Return-Receipt-To: [email-masked]');

$mail->addCustomHeader('Return-Path: [email-masked]');

// Трекинговый пиксель

$tracking_url = 'https://yourdomain.com/tracker.php?email=' . urlencode([email-masked]') . '&id=' . uniqid();

$mail->isHTML(true);

$mail->Subject = 'Test Email with Tracking';

$mail->Body = '<html><body>Test email<br><img src="' . $tracking_url . '" width="1" height="1" alt="" /></body></html>';

// Отправка

if ($mail->send()) {

echo 'Письмо успешно отправлено SMTP-серверу.';

}

} catch (Exception $e) {

echo "Ошибка отправки: {$mail->ErrorInfo}";

}

Сервер трекинга (tracker.php):

php

СвернутьПеренос
Копировать

<?php

if (isset($_GET['email']) && isset($_GET['id'])) {

$email = $_GET['email'];

$id = $_GET['id'];

file_put_contents('tracking_log.txt', "Opened: $email, ID: $id at " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);

header('Content-Type: image/png');

echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/wcAAgAB/w9N0AAAAABJRU5ErkJggg==');

}

6. Заключение

Disposition-Notification-To и ConfirmReadingTo: Запрашивают уведомления о прочтении, но ненадежны из-за ограниченной поддержки клиентами.

X-Confirm-Reading-To: Устаревший, используйте только для старых систем.

Return-Receipt-To: Нестандартизированный, редко поддерживается, лучше использовать DSN или сторонние сервисы.

Return-Path: Эффективен для обработки bounce-сообщений, но требует настройки ящика и анализа.

Лучшая практика: Комбинируйте заголовки с трекинговыми пикселями и используйте сторонние сервисы (SendGrid, Mailgun) для надежного отслеживания.

Если у вас есть конкретный SMTP-сервер, клиент или сервис, с которым вы работаете, напишите, и я помогу адаптировать код или настройки!

4,8s

Как Grok может помочь?

DeepSearch

Think

Grok 3