Symfony Mailer. Una nueva forma de enviar emails
Introducción al componente Mailer, candidato a sustituir Swiftmailer desde Symfony 4.3
Desde la versión 1.2 de Symfony el envío de emails se ha realizado a través de la librería Swiftmailer. Esta librería nos simplificaba el envío de emails tanto en texto plano como empleando HTML’s. Además, su integración con sistemas como Gmail o servidores SMTP era prácticamente inmediata por lo que probablemente casi todos los proyectos basados en Symfony la empleen para gestionar el envío de emails.
Sin embargo, y como veremos a continuación, tenía una serie de limitaciones que en palabras de su propio creador hacía muy difícil tanto su mantenimiento como su integración con otras características de Symfony que están apareciendo, por lo que Fabien Potencier, líder del proyecto de Symfony, ha desarrollado un nuevo componente con el fin de reemplazarla en el medio plazo: bienvenidos al componente Mailer.
Limitaciones de Swiftmailer
Pero antes de adentrarnos en el funcionamiento de este nuevo componente me gustaría comentar los motivos que ha dado el equipo de Symfony para proponerlo como remplazo de Swiftmailer. Creo que resulta interesante saberlo de cara a entender cómo funciona el ecosistema de Symfony y hacia dónde quieren orientarlo.
En primer lugar, uno de los problemas que apunta Fabien es que Swiftmailer no está escrito basado en el estándar que sigue Symfony, lo cual provoca que mantenerlo sea una tarea bastante complicada.
Entre sus principales inconvenientes se encuentran los siguientes:
- no tiene definidos namespaces,
- su inicialización es bastante pesada,
- tiene su propio contenedor de dependencias,

- no emplea el autoloader de composer,
- la jerarquía de clases es bastante enrevesada,
- y las instancias de los mensajes no son DTO’s, lo cual dificulta su serialización.
Todo esto provoca que pese a tener grandes características como un gran conjunto de plugins, su integración con distintos sistemas de autenticación o la posibilidad de emplear la extensión SMTP Pipelining para acelerar las comunicaciones el equipo de Symfony haya planteado una alternativa más solida. Es aquí donde aparece el componente Mailer de Symfony.
Symfony Mailer
De cara a afrontar las limitaciones que hemos mencionado sobre Swiftmailer el equipo de Symfony con Fabien a la cabeza ha desarrollado el componente Mailer.
Este componente tiene como objetivo facilitarnos el envío de emails transaccionales como por ejemplo una confirmación de registro o la factura de un pedido. En el caso de que queramos enviar otro tipo de emails como newsletters el propio equipo de Symfony recomienda recurrir a soluciones especializadas.
Su uso básico es realmente sencillo:

Como veis, el envío de un email es realmente sencillo. Lo más reseñable del código anterior es el concepto de Transport
, que permite abstraer la forma de envío. A nuestra disposición tendremos diferentes Transports como por ejemplo GmailTransport
o SendgridTransport
los cuales podremos instanciar de un modo tan sencillo como:
new GmailTransport('user', 'password');
Todos ellos se encuentran dentro del namespace Symfony\Component\Mailer\Transport
.
Gracias a estos Transports podremos unificar el comportamiento asociado al envío de emails sin importar el proveedor que estemos empleando:
- Dispondremos de un sistema unificado para declarar DSN’s.
- Al implementar todos la misma interfaz es muy sencillo declarar diferentes proveedores para el envío de emails en función del entorno que estemos empleando.
- Y, una de las cosas más importantes, los mensajes que enviamos implementan todos la misma interfaz y son serializables.
Integración con Twig
Otro de los inconvenientes que tenía Swiftmailer era que no disponía de integración directa con Twig, por lo que era necesario primero renderear la plantilla y de cara a pasar el HTML generado.

Por el contrario, el componente Mailer incorpora un nuevo tipo de mensaje: TemplatedEmail
el cual se encargará de unificar el proceso de renderear la plantilla Twig para definir el cuerpo HTML del email.
Su uso es bastante sencillo:

Dentro de la plantilla podremos sobreescribir 3 bloques:
subject
, para el asunto del mensajetext
, para texto sin formato.html
, para el cuerpo HTML del email

En el caso de que queramos emplear variables podremos hacerlo definiendo un contexto que pasaremos también también al objeto de la clase TemplatedEmail
. Desde la plantilla Twig podremos acceder a dicho contexto y a las variables que en él hayamos definido:


Plantillas predefinidas
Sin embargo, el componente Mailer no se queda aquí sino que además nos proporciona una solución para enviar emails con HTML que sean compatible con los gestores de correo habituales gracias a una serie de plantillas predefinidas cortesía de Postmark.
La idea de estas plantillas es la siguiente: emplear Webpack Encore para gestionar las hojas de estilo e incrustarlos en las plantillas mediante el componente Symfony CSS selector.
Para emplear este tipo de plantillas tendremos a nuestra disposición otra clase similar a TemplatedEmail
: ThemedEmail
.
Su uso es prácticamente idéntico a la anterior:

Pero a la hora de elaborar la plantilla dispondremos de nuevos bloques que podremos sobrescribir para obtener un email “bonito” y, lo más importante, responsive. Esto lo lograremos extendiendo del template devuelto por la directiva email_layout
:

Gracias a los ThemedEmail
obtendremos un email similar al siguiente:

La potencia de ThemedEmail
es mucho más, pues nos proporciona de una serie de directivas en Twig para mejorar aún más el estilo de nuestro email como por ejemplo:
email_button
, para generar botones como el de la imagen anterioremail_container
para añadir “jumbos” a nuestro emailemail_box
para añadir cajas con contenido
Creando nuestras propias clases
Otra de las ventajas de la que nos provee este nuevo componente es la posibilidad de crear nuestras propias clases para representar emails, de modo que podamos agrupar toda la información relativa a un email dentro de ellas.
Por ejemplo, podemos crear una clase que represente un código de descuento:

Al poder encapsular toda la información de un tipo de email en una clase podremos crearlos y enviarlos de forma aún más rápida:

Además, no será necesario acceder al contexto para obtener las variables que queramos pasar a la plantilla, sino que podremos hacerlo directamente a través de la variable email
dentro de Twig.
Integración con Messenger
Una de las cosas en las que el equipo de Symfony ha puesto especial atención cuando ha desarrollado el componente Mailer ha sido en su integración con Messenger del cual os hablé en los siguientes artículos:
Este componente nos permite implementar colas de mensajes e integrarlas con servicios como RabbitMQ de cara a realizar tareas de forma asíncrona.
Uno de los problemas de SwiftMailer era que los mensajes no eran fácilmente serializables, por lo que era necesario añadir una capa extra si queríamos realizar esta tarea empleando Messenger.
Sin embargo, gracias al componente Mailer esta tarea es tan sencilla como realizar lo siguiente:

gracias a que la clase Email
es serializable sin mayor esfuerzo.
Conclusiones
En definitiva, el componente Mailer representa una gran novedad para el ecosistema de Symfony eliminando algunas de las limitaciones de Swiftmailer. Probablemente de aquí a pocos meses comencemos a ver como su uso se va extendiendo por lo que espero que este artículo os haya servido para conocer sus principales características.
Si queréis seguir profundizando os animo a ver la charla completa que dio el año pasado Fabien Potencier para presentar este componente. No tiene desperdicio y se hace realmente amena:
¿Quieres recibir más artículos como este?
Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇