Новое в Symfony 6.3 — Интеграция Webhook с Mailer и Notifier
В Symfony 6.3 мы представили два новых компонента под названием Webhook и RemoteEvent. Веб-хук — это уведомление от одной системы (например, обработчик платежей) к другой системе (например, вашему приложению) о каком-то изменении состояния (например, какой-то заказ был оплачен).
Многие сторонние почтовые службы предоставляют поддержку веб-хуков, чтобы уведомлять вас о различных событиях, связанных с электронными письмами (отправлено, открыто, возвращено и т.д.). То же самое для служб уведомлений, таких как SMS, которые предоставляют веб-хуки для уведомления о таких событиях, как отправка, сбой отправки и т.д.
Большинство веб-хуков использую стандартные HTTP и JSON для отправки информации. Однако они не стандартизированы: безопасность зависит от провайдера, а полезная нагрузка имеет произвольную форму. Вот почему в Symfony 6.3 мы стандартизировали веб-хуки наиболее распространённых почтовых сервисов и сервисов уведомлений, чтобы вашему приложению не приходилось иметь дело с этими внутренними деталями.
В остальной части статьи показан пример, ориентированный на интеграцию с Mailer, но то же самое относится и к интеграции с Notifier. Представьте, что вам нужно регистрировать, когда ваши электронные письма отскакивают
(не доходят до места назначения) и когда люди отписываются от ваших электронных писем.
Если вы используете, например, Mailgun, сначала настраиваете веб-хук в этом сервисе, указывающей на URL-адрес вашего сайта (например, https://example.com/webhook/emails
). Затем добавляете следующую конфигурацию в Symfony проект:
framework:
webhook:
routing:
emails:
service: '...'
secret: '%env(MAILGUN_WEBHOOK_SECRET)%'
Наконец, создаёте потребителя этого веб-хука:
use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer;
// ...
#[AsRemoteEventConsumer(name: 'emails')]
class MailerEventConsumer implements ConsumerInterface
{
public function consume(Event $event): void
{
$email = $event->getRecipientEmail();
error_log(match ($event->getName()) {
MailerDeliveryEvent::BOUNCE => sprintf('Email to %s bounced (%s)', $email, $event->getReason()),
MailerEngagementEvent::UNSUBSCRIBE => sprintf('Unsubscribe from %s', $email),
default => sprintf('Receive unhandled email event %s', $event->getName()),
});
}
}
И это всё. Если вы измените поставщика почтовых услуг (в этом или другом проекте), вы можете повторно использовать тот же самый код потребителя; нужно будет только обновить конфигурацию. Это возможно, потому что Symfony делает следующее:
- Запускает некие
парсеры запросов
проверяющие, что входящая полезная нагрузка не искажена, содержит все необходимые данные, проверяет подписи и т.д. - Запускает некие
преобразователи полезной нагрузки
, поэтому полезная нагрузка каждой службы отображается в стандартный формат полезной нагрузки.
Ключевой момент — стандартизация. Symfony отображает входящие полезные нагрузки и события в общие структуры, которые вы можете использовать в приложении для абстрагирования от деталей поставщика.
Например, независимо от того, как каждый провайдер называет свои события. При использовании этой функции вам нужно иметь дело только со следующими общими именами событий:
namespace Symfony\Component\RemoteEvent\Event\Mailer;
final class MailerDeliveryEvent extends AbstractMailerEvent
{
public const RECEIVED = 'received';
public const DROPPED = 'dropped';
public const DELIVERED = 'delivered';
public const DEFERRED = 'deferred';
public const BOUNCE = 'bounce';
}
final class MailerEngagementEvent extends AbstractMailerEvent
{
public const OPEN = 'open';
public const CLICK = 'click';
public const SPAM = 'spam';
public const UNSUBSCRIBE = 'unsubscribe';
}
Symfony 6.3 предоставляет встроенную поддержку веб-хуков для Mailgun, Postmark и Twilio. Теперь нам нужно, чтобы вы, сообщество Symfony, нам обеспечить интеграцию с остальными почтовыми сервисами и сервисами уведомлений. Кроме того, подумайте о том, чтобы поговорить с вашей компанией о спонсировании Symfony компонентов и спонсировании сторонних интеграций Symfony.