Cómo enviar correo electrónico con PHP usando Twilio SendGrid y Mezzio

Publicado: 2021-03-24

El correo electrónico es una herramienta de comunicación tan importante como siempre. Para ayudarlo a aprovechar mejor el correo electrónico, le mostraré cómo enviar correo electrónico utilizando el marco Mezzio de PHP y la API de Twilio SendGrid.

Específicamente, aprenderá cómo enviar correos electrónicos con cuerpos de texto sin formato y HTML, y eso incluye un archivo adjunto en PDF. También aprenderá a usar la funcionalidad de plantillas transaccionales de Twilio SendGrid para simplificar la creación de cuerpos de correo electrónico tanto para el equipo de desarrollo como para cualquier otro equipo dentro de su organización.

¿Suena bien? Vamos a empezar.

Visión general rápida de la aplicación

Para hacer que este tutorial sea más significativo, imagine que el código que escribiremos es parte de una tienda de comercio electrónico en línea ficticia creada con Mezzio, llamada The Little PHP Shop , específicamente, la parte inmediatamente después de que un cliente realiza una compra. En ese punto del flujo de usuarios, el cliente recibe un correo electrónico agradeciéndole su compra e incluye una factura en PDF para sus registros.

Vamos a crear una clase Handler para enviar el correo electrónico posterior a la compra, que recibirá los detalles de compra de un pedido completado por el cliente. Con esa información de compra, la clase Handler utilizará varias clases en la API PHP de SendGrid para crear y enviar el correo electrónico de confirmación de compra.

De estos, los más importantes son "SendGrid\Mail\Mail" y "\SendGrid". “SendGrid\Mail\Mail” es el objeto que almacena todas las propiedades de un mensaje de correo electrónico que enviaremos a través de Twilio SendGrid. El objeto "SendGrid" forma la capa de transporte, lo que facilita el envío de correos electrónicos a través de Twilio SendGrid.

requisitos previos

Para completar este tutorial, necesitará las siguientes 4 cosas en su entorno de desarrollo local:

  1. Cuenta Twilio SendGrid
  2. PHP 7.4 con las extensiones cURL , mbstring y O pen SSL instaladas y habilitadas
  3. Composer instalado globalmente
  4. rizo

Scaffolding la aplicación Mezzio

Primero necesitamos crear la aplicación base. Para hacerlo, como siempre, usaremos el Mezzio Skeleton para que lo haga por nosotros. Una vez que construyamos la aplicación base, cambiaremos al directorio del proyecto recién creado. Luego ejecute los siguientes comandos en su terminal, siguiendo las indicaciones del primero:

Instala las dependencias requeridas

Con el proyecto estructurado, necesitamos agregar 3 dependencias adicionales para completar el proyecto. Estos son:

  • Biblioteca API de PHP de Twilio SendGrid para interactuar con la API de Twilio SendGrid
  • Cliente PHP HTTP para enviar solicitudes HTTP
  • PHP Dotenv para almacenar y recuperar variables de entorno

Para instalarlos, ejecute el siguiente comando en su terminal:

Inicializar PHP Dotenv

Con las dependencias instaladas, cargamos PHP Dotenv para que lea las variables configuradas en “.env” y las ponga a disposición de PHP como variables de entorno. Para hacer eso, inserte el siguiente código en "public/index.php", justo después de "requerir proveedor/autoload.php".

Agregue los detalles de su cuenta de Twilio SendGrid

Ahora debe proporcionar a la aplicación su clave API de SendGrid. Para hacer eso, después de iniciar sesión en Twilio SendGrid , vaya a “Configuración -> Claves API . " Una vez ahí:

  1. Haga clic en " Crear clave de API " para crear una clave de API
  2. Asigne un nombre a la nueva clave API, acepte el permiso de clave API predeterminado de " Acceso completo " y haga clic en " Crear y ver ".

Con la clave API creada, haga clic y copie la clave, luego haga clic en " Listo " .

Después de eso, agregue 2 claves más al archivo: "SENDGRID_DEFAULT_SENDER_ADDRESS" y "SENDGRID_DEFAULT_SENDER_NAME". Como indican los nombres, estos son la dirección de correo electrónico y el nombre que usaremos para cualquier correo electrónico enviado desde nuestra aplicación, a menos que se anule.

Nota: Para ello, en Autenticación de remitente , asegúrese de que dice “Verificado” en la tabla “Verificación de remitente único”.

Establecer los detalles de configuración del correo de la aplicación

Además de la clave API de Twilio SendGrid, vamos a almacenar algunas otras configuraciones de configuración de correo global. Específicamente, vamos a establecer una dirección de correo electrónico y un nombre de remitente que usaremos en cada mensaje de correo electrónico. De esa manera, no tenemos que configurarlos cada vez.

También vamos a crear 2 plantillas de cuerpo de correo electrónico: una para correos electrónicos de texto sin formato y otra para correos electrónicos HTML. Para hacer eso, en “config/autoload” cree un nuevo archivo llamado “mail.global.php” y en él, agregue el siguiente código.

Crear una clase para instanciar un objeto de correo

Con los detalles de configuración de la aplicación clave establecidos, ahora vamos a crear una clase que creará una instancia de un objeto de correo básico con las propiedades predeterminadas establecidas. Para hacer eso, en un nuevo directorio, "src/App/src/Mailer", cree un nuevo archivo llamado "SendGridMailMessageFactory.php" y agregue el código a continuación.

Cuando invocamos la clase, tiene acceso al contenedor de inyección de dependencia (DI) de la aplicación, desde el cual recuperará los detalles de configuración que almacenamos en "config/autoload/mail.global.php".

Después de eso, creará una instancia de un nuevo objeto "SendGrid\Mail\Mail" y configurará los detalles desde y responderá pasando los detalles de configuración respectivos a las llamadas a los métodos "Mail", "setFrom" y "setReplyTo", respectivamente. Después de eso, devolverá el objeto "Correo" instanciado.

Sin embargo, para usarlo, debe registrarlo con el contenedor DI. Para hacer eso, en "src/App/src/ConfigProvider", agregue la siguiente entrada al elemento "factories" en la matriz devuelta por el método "getDependencies".

Crear un controlador para enviar correo electrónico

A continuación, debemos crear una clase de controlador para redactar y enviar correos electrónicos. Para hacer eso, usaremos las herramientas CLI de Mezzio , disponibles a través de Composer, ejecutando el siguiente comando.

Ejecutar el comando anterior hace cuatro cosas por nosotros:

  1. C rea una nueva clase de controlador, “src/App/Handler/EmailSenderHandler.php”
  2. Crea una clase de fábrica para instanciar la clase de controlador, "src/App/Handler/EmailSenderHandlerFactory.php"
  3. Crea un archivo de plantilla ("src/App/templates/app/email-sender.html.<ext>"), que no necesitaremos . El nombre de archivo “<ext>” está determinado por el motor de plantillas que eligió durante la etapa de “creación de proyecto”.
  4. Registra la nueva clase Handler como un servicio en el contenedor DI agregando una entrada a "config/autoload/mezzio-tooling-factories.global.php"

Refactorizar el controlador para enviar correos electrónicos

Con "EmailSenderHandler.php" creado, ahora necesitamos refactorizarlo para que pueda enviar correos electrónicos. Para hacer eso, primero refactorizaremos el constructor "EmailSenderHandler's", reemplazando el parámetro "TemplateRendererInterface" con 3 nuevos parámetros. Estos inicializarán 3 nuevas variables miembro de clase:

  • Un objeto “\SendGrid\Mail\Mail”
  • Un objeto "\SendGrid"
  • Una matriz que contiene los detalles de configuración necesarios

Puede ver el constructor revisado en el siguiente ejemplo, junto con las variables de miembro de clase relacionadas. Reemplace la variable miembro de clase existente y el constructor con este código.

Nota: A continuación, necesitamos refactorizar el método de "manejar". Reemplace el contenido existente del método "manejar" "EmailSenderHandler" con el código a continuación, luego veamos lo que hace.

Comienza usando “$request->getParsedBody()” para recuperar los parámetros proporcionados en el cuerpo de la solicitud, que devolverá una matriz asociativa, inicializando “$detalles”. Con los parámetros disponibles, llama al método "addTo" del objeto "SendGrid\Mail\Mail" para establecer el destinatario del correo electrónico, pasando la dirección de correo electrónico y el nombre del destinatario en los primeros 2 argumentos y una serie de sustituciones en el tercer argumento.

Las sustituciones le permiten personalizar los mensajes de correo electrónico para cada destinatario. En los correos electrónicos de texto sin formato, cualquier cadena rodeada inmediatamente por guiones, por ejemplo, "-first_name-" es una sustitución. En los correos electrónicos HTML, utiliza la sintaxis de Handlebars , que rodea las cadenas con doble paréntesis, por ejemplo, "{{ first_name }}".

A continuación, establecemos el asunto del mensaje y agregamos un texto sin formato y un cuerpo de mensaje HTML. Con eso, nuestro correo electrónico está listo para enviar. Así que usamos el objeto "SendGrid", "$this->mailer", para enviarlo, inicializando una nueva variable, "$response", con la respuesta al intentar enviar el mensaje. Finalmente, devolvemos un objeto JsonResponse , que contiene el código de estado y el cuerpo de la respuesta.

Nota: Refactorizar el método __invoke de EmailSenderHandlerFactory

Ahora que hemos completado la refactorización de "EmailSenderHandler", debemos refactorizar "EmailSenderHandlerFactory". Esto creará una instancia de "EmailSenderHandler" correctamente. Para hacer eso, reemplace la definición existente de su método "__invoke`" con el siguiente código.

Esto recupera un objeto "\SendGrid\Mail\Mail" del contenedor DI, preinicializado con el remitente y responde a los detalles del correo electrónico, e inicializa un nuevo objeto llamado "$message". Luego crea una instancia de un nuevo objeto "SendGrid", llamado "$mailer" para enviar el mensaje de correo. Finalmente, recupera la configuración del correo de la configuración de la aplicación. Luego, los usa para inicializar y devolver el objeto "EmailSenderHandler".

Actualizar la tabla de enrutamiento

Con todos esos cambios, queda un último cambio antes de que podamos probar el código y enviar un correo electrónico. Tenemos que actualizar la tabla de enrutamiento para que la ruta predeterminada utilice nuestra nueva clase Handler como controlador de la ruta, en lugar de "HomePageHandler". Para hacer eso, reemplace la definición de la ruta predeterminada en “config/routes.php” con el siguiente ejemplo.

Enviar el primer correo electrónico

Ahora es el momento de enviar el primer correo electrónico. Para hacer eso, primero, inicie la aplicación ejecutando el siguiente comando en la terminal.

Luego, usando cURL, haga una solicitud GET a " http://localhost:8080 ", como en el ejemplo a continuación, reemplazando los valores entre paréntesis angulares con detalles relevantes para su correo electrónico.

Debería ver la salida “{“status”:202,“message”:””}” en el terminal, y debería recibir un correo electrónico similar a la imagen a continuación.

Nota: Use plantillas de correo electrónico transaccional en lugar de cadenas de plantillas

Si bien hemos podido enviar un correo electrónico con un cuerpo de texto sin formato y HTML, la forma en que lo hemos hecho, sin embargo, es menos que ideal. Para cada correo electrónico que enviamos, y nuestra aplicación puede terminar enviando bastantes, necesitaremos agregarles un cuerpo de texto sin formato y HTML.

Pero almacenar las definiciones del cuerpo del correo electrónico en el código coloca la mayor parte del esfuerzo en el equipo de desarrollo. Sin embargo, al menos en mi experiencia, a menudo sucede que otros equipos, a menudo de marketing, crean y mantienen plantillas de correo electrónico.

Entonces, por esa razón, y porque aceleraría el desarrollo y compartiría la carga entre varios equipos, vamos a refactorizar la aplicación para usar plantillas de correo electrónico transaccional . Puede crearlos y mantenerlos a través de la interfaz de usuario de Twilio SendGrid por miembros del equipo que pueden tener poca o ninguna experiencia técnica, en lugar de en código.

Si no ha oído hablar de ellos, el glosario Twilio SendGrid los define de la siguiente manera:

Las plantillas de correo electrónico transaccional son diseños de correo electrónico precodificados que los especialistas en marketing, diseñadores y desarrolladores pueden usar para crear campañas de correo electrónico transaccional de forma rápida y sencilla. Las plantillas de correo electrónico transaccional de Twilio SendGrid permiten a personas técnicas y no técnicas realizar cambios en tiempo real en el correo electrónico que reciben sus destinatarios.

Para este artículo, solo necesitamos uno bastante básico. Para hacerlo, siga los detalles en la documentación de Twilio SendGrid y cree uno que tenga como contenido solo un módulo de texto único. Luego, para el cuerpo del texto, use el texto a continuación.

Tenga en cuenta que hay 6 sustituciones en el correo electrónico:

  • “first_name”: el nombre del cliente
  • “last_name”: el apellido del cliente
  • “sender_name”: el nombre de la tienda de comercio electrónico (The Little PHP Shop)
  • “sender_state”: Estado de la tienda de comercio electrónico
  • “sender_country”: el país de la tienda de comercio electrónico
  • “support_email”: el correo electrónico de soporte que los clientes pueden usar para obtener soporte posventa

Dado eso, necesitamos hacer que esa información esté disponible para nuestra aplicación. El nombre y apellido del cliente ya lo tenemos. Las 4 sustituciones restantes serán globales, por lo que, como hicimos anteriormente, agregaremos la configuración a continuación a " config/autoload/mail.global.php ", después del elemento "templates".

Con el nuevo archivo de configuración creado, en el método "manejar" "EmailSenderHandler", reemplace las 2 llamadas a "$this->mail->addContent()", con el siguiente código.

Las 2 llamadas de método agregan los detalles del remitente y admiten la dirección de correo electrónico como sustituciones globales. Estas sustituciones se aplican al cuerpo del correo electrónico antes que cualquier otra sustitución, pero se anulan si hay sustituciones con la misma clave para un destinatario de correo electrónico.

A continuación, debe recuperar el ID de la plantilla de correo electrónico transaccional. Puede encontrarlo haciendo clic en el nombre de la plantilla en la lista de plantillas , como puede ver en la captura de pantalla a continuación.

Cópielo y guárdelo en "config/autoload/mail.global.php" en un nuevo elemento con la clave "template_id" y luego elimine "simple" y "HTML". Cuando termine, el elemento "correo/plantillas" de la matriz devuelta se verá como el código a continuación, donde "<la identificación de la plantilla>" reemplaza la identificación de su plantilla.

Con la configuración actualizada, ahora necesitamos agregar una llamada al método "Mail" "setTemplateId" en el método "handle" de "EmailSenderHandler", pasando la ID de plantilla que acabamos de agregar a "config/autoload/mail.global. php.” Puedes ver un ejemplo en el siguiente código.

Probemos los cambios

Como antes, usando cURL, haga una solicitud GET a " http://localhost:8080 " para probar si los cambios funcionan como se esperaba. Debería ver la salida “{“status”:202,”message”:””}” en el terminal, como en el ejemplo anterior. En la bandeja de entrada de su correo electrónico, debería ver un hermoso correo electrónico, con las sustituciones reemplazadas, como en la captura de pantalla a continuación.

Adjunte una factura en PDF

Ahora que estamos usando plantillas dinámicas, adjuntemos la factura en PDF de la que hablamos al principio del artículo. Para ahorrarle el tiempo y el esfuerzo de buscar o crear uno usted mismo, he creado una factura en PDF de muestra que puede usar para este artículo. Guárdelo en el directorio " datos" de la aplicación .

Nota: Para adjuntar una factura, debemos utilizar el método "Correo" "addAttachment", que puede ver en el siguiente código de ejemplo. El método toma 5 argumentos, pero solo proporcionamos los primeros 4. Estos son:

  1. Un objeto " Adjunto" o una cadena codificada en Base64 . Si el valor de este parámetro no está codificado en base64, el método lo hará por nosotros.
  2. El tipo MIME del archivo adjunto (ahora conocido como tipo de medio ).
  3. El nombre del archivo adjunto . Este es el nombre con el que se guardará el archivo, de forma predeterminada, a menos que el usuario lo cambie.
  4. La disposición del contenido del archivo adjunto . Si no está familiarizado con la disposición del contenido, la disposición del contenido en línea significa que el archivo adjunto debe mostrarse automáticamente cuando se muestra el mensaje, y la disposición del contenido del archivo adjunto significa que el archivo adjunto no se muestra automáticamente y requiere algún tipo de acción por parte del usuario para abrelo.

En el siguiente ejemplo de código, el método file_get_contents de PHP lee el contenido del archivo en una nueva variable llamada "$factura". Luego, el PDF se adjunta al mensaje llamando al método "addAttachment".

Aquí nosotros:

  • Pase el contenido de la factura, que estará codificado en Base64
  • Establezca el tipo MIME en "aplicación/pdf" ya que estamos adjuntando un archivo PDF
  • Establezca el nombre de archivo de la factura en un nombre ficticio que un cliente podría esperar razonablemente
  • Establezca la disposición del contenido en "archivo adjunto"

Ahora que hemos terminado esos cambios, probemos que funcionan. Ejecute la misma solicitud cURL que ejecutamos las 2 veces anteriores. Luego, en la bandeja de entrada de su correo electrónico, debería ver un hermoso correo electrónico con la factura en PDF de ejemplo visible al ver el correo electrónico.

Así es como enviar correo electrónico con PHP usando Twilio SendGrid y Mezzio

Si bien solo rascamos la superficie de lo que es posible al enviar correos electrónicos con Twilio SendGrid y Mezzio, ahora puede enviar un correo electrónico con texto sin formato y cuerpo HTML, así como con un archivo adjunto. También aprendió a usar plantillas transaccionales y sustituciones que puede configurar globalmente y por destinatario.

Le recomiendo encarecidamente que eche un vistazo a la documentación de la biblioteca de PHP para ver qué más hay disponible, como programar envíos de correo electrónico, adjuntar un archivo de Amazon S3, agregar encabezados y agregar secciones y categorías.

Matthew Setter es un editor de PHP en el equipo de Twilio Voices y, naturalmente, un desarrollador de PHP. También es el autor de Mezzio Essentials . Cuando no está escribiendo código PHP, está editando excelentes artículos de PHP aquí en Twilio. Se le puede contactar a través de:

  • Correo electrónico: [email protected]
  • Web: http://matthewsetter.com
  • Twitter: @settermjd
  • GitHub: https://github.com/settermjd