Envíos de Emails en Laravel

Video thumbnail

Conociendo como podemos limitar la cantidad de peticiones del usuario, resulta buena idea aprener a enviar correos para notificar a estos usuarios. Podemos configurar el envío de correos muy fácilmente en Laravel, si ya tienes un servicio que provee tu hosting o similar, lo único que debes de hacer es crear una dirección de correo con su contraseña.

A partir de aquí, debes de configurar algunos parámetros, si no los conoces porque el servidor de correos que estás empleando es de un servicio, debes de preguntar a tus proveedores de servicio; en el caso de Hostinger serían los siguientes:

config/mail.php

'smtp' => [
       'transport' => 'smtp',
       'host' => env('MAIL_HOST', 'smtp.hostinger.com'),
       'port' => env('MAIL_PORT', 465),
       'encryption' => env('MAIL_ENCRYPTION', 'ssl'),
       'username' => env('MAIL_USERNAME','<EMAIL>'),
       'password' => env('MAIL_PASSWORD',"<PASSWORD>"),
       'timeout' => null,
       'auth_mode' => null,
],

O puedes emplear un servicio de pruebas en caso de que no tengas acceso a un servidor de correos real como mailtrap:

https://mailtrap.io

En el cual, debes de ir a la página anterior, crearte una cuenta que es completamente gratuita, crear un inbox y configurar en tu proyecto.

.env

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=ec5cbede982042
MAIL_PASSWORD=********0be7

Clase Mailable

Para enviar cualquier correo, debemos de emplear una clase, al igual que ocurre cuando definimos un modelo, controlador o request, debemos de crear una clase con una estructura específica:

app\Mail\OrderShipped.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{

    public $email;
    public $title;
    public $content;

    use Queueable, SerializesModels;

    public function __construct($email, $title, $content)
    {
        $this->email = $email;
        $this->title = $title;
        $this->content = $content;
    }

 
    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Order Shipped',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'emails.subscribe',
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }
}

Para ello, usamos el comando de:

$ php artisan make:mail OrderShipped

El método de envelope() lo empleamos para definir el asunto, el de content() para el cuerpo del mensaje, allí especificamos la vista y el de attachments() para archivos adjuntos, el constructor es básico en las clases de PHP y se emplea para inicializar propiedades u otras tareas al momento de crear el objeto o instancia de la clase.

También definimos algunas propiedades de ejemplo como lo son el título, contenido e email, puedes crear otros o modificar los definidos según tus necesidades.

También podemos emplear un solo método para definir el asunto y contenido:

app\Mail\SubscribeEmail.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class SubscribeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $email;
    public $title;
    public $content;

    public function __construct($email, $title, $content)
    {
        $this->email = $email;
        $this->title = $title;
        $this->content = $content;
    }

    public function build()
    {
        return $this->subject($this->title)->view('subscribe');
    }
}

Desde la misma, podemos personalizar los argumentos a recibir, como email asunto o contenido del correo y retornar una vista de blade que corresponde al cuerpo del correo; por ejemplo:

Creamos la vista que puede tener cualquier formato:

resources\views\emails\subscribe.blade.php

<p>Hi<br>
{!! $content !!}

Enviar correos de forma individual

Para enviar los correos, creamos una instancia de la siguiente manera:

Mail::to('no-reply@example.net.com')->send(new SubscribeEmail('contact@gmail.com', $title, $content));

Parámetros

No está limitado a especificar simplemente los destinatarios "to" al enviar un mensaje. Eres libre de configurar destinatarios "to", "cc" y "bcc" empleando sus respectivos métodos:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new SubscribeEmail(contact@gmail.com', $title, $content));

CC y BCC/CCO

Un CC es una forma de enviar copias adicionales de un correo electrónico a otras personas "copia de carbono", mientras que BCC es lo mismo que el CC pero esta lista de destinatarios o personas permanecen ocultas, es decir, no aparecen en la firma del correo electrónico.

Enviar correos en masa

Una de las formas en las cuales podemos enviar múltiples correos en masa o lote, es la de enviar en un mismo contacto a múltiples correos, usualmente este es un caso delicado ya que, si hacemos algo como lo siguiente:

Mail::to('no-reply@example.net.com')
   ->cc(['hideemail1@gmail.com','hideemail2@gmail.com','hideemail3@gmail.com'])->send(new SubscribeEmail(contact@gmail.com', $title, $content));

El correo va a exponer todos los emails de los usuarios, situación que usualmente es un problema por la exposición de todos los correos a todos los destinatarios; en vez de emplear la opción de cc podemos emplear la opción de bcc la cual permite ocultar los destinatarios:

Mail::to('no-reply@example.net.com')
   ->bcc(['hideemail1@gmail.com','hideemail2@gmail.com','hideemail3@gmail.com'])->send(new SubscribeEmail(contact@gmail.com', $title, $content));

Ahora veremos que los emails definidos en BBC aparecen ocultos:

 

Cabecera de emails

 

Y no presentes como en la imagen anterior.

Enviar mensajes de verificación de email del usuario en Laravel

Los mensajes de confirmación son correos que se envían a un cliente al completar una acción para confirmar la operación realizada, por ejemplo, el cambio de una contraseña, recuperar un usuario, la compra de un producto, etc, esto en cualquier sistema web que incluye alguna interacción con el usuario, es una tarea fundamental, por lo tanto, aprenderemos a enviar correos desde Laravel.

En Laravel, tenemos acceso a una función que podemos utilizar para confirmar el registro de un usuario.

Mandar mensajes de confirmación de manera programática

Desde una instancia del usuario, tenemos acceso a una función que envía el email de confirmación para verificar un usuario por el email:

$user->sendEmailVerificationNotification();

Por supuesto, para esto debes de tener configurado tu servidor SMTP para el envio de correos.

Y recuerda implementar en tu modelo de usuarios la clase MustVerifyEmail:

use Illuminate\Contracts\Auth\MustVerifyEmail;
***
class User extends Authenticatable implements MustVerifyEmail

Ya con esto, puedes hacer uso de la función anterior; al usarla, llegará un correo como el siguiente:

Email confirmación
Confirmar email

Extra: Rest Api para los usuarios a verificar

Por aquí te dejo un uso común de esta función sobre una Rest Api para registrar usuarios y verificar los mismos; tenemos una función exclusiva para mandar los emails de verificación de los usuarios:

class UserController extends Controller
{
    /**
     * Register
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), StoreUser::myRules());
        if ($validator->fails())
            return $this->errorResponse($validator->errors(), 422);
        try {
            $user = new User();
            $user->name = $request->name;
            $user->email = $request->email;
            $user->password = Hash::make($request->password);
            $user->save();
            if ($request->subscribed) {
                Subscribe::create(['email' => $request->email]);
            }
            $success = true;
            $message = 'User register successfully';
        } catch (\Illuminate\Database\QueryException $ex) {
            $success = false;
            $message = $ex->getMessage();
        }
        // response
        $response = [
            'success' => $success,
            'message' => $message,
        ];
        $credentials = [
            'email' => $request->email,
            'password' => $request->password,
        ];
        Auth::attempt($credentials);
        $user->sendEmailVerificationNotification();
        return $this->successResponse($response);
    }
    public function verifie()
    {
        $user = Auth::user() ?? auth('sanctum')->user();
        $userModel = User::find($user->id);
        $userModel->sendEmailVerificationNotification();
        return $this->successResponse("ok");
    }

Como ves, tenemos una función de registrarse, en la cual obtenemos los datos del usuario y una vez registrado, iniciamos sesión con sendEmailVerificationNotification y enviamos el correo con la función explicada en esta entrada.

Y una función de verificar para que la ejecutes de manera programática; en este ejemplo, estamos empleando una Rest Api en Laravel con Laravel Sanctum con tokens, pero puedes emplear cualquier tipo para verificar cuentas de usuario.

El siguiente paso es que conozcas como puedes extender Laravel con funcionalidades claves como lo son, detectar si la navegación es mobile o por PC.

Acepto recibir anuncios de interes sobre este Blog.

Hablaremos sobre como enviar emails en Laravel, configuración y tipos, crearemos una clase Mail en Laravel que personalizaremos y luego enviaremos un email a partir de la misma.

| 👤 Andrés Cruz

🇺🇸 In english