Laravel send mail using google smtp

In this example, we will create a simple contact form. When users submit those details instead of storing those data we will directly send it to the responsible person using Google mail.

Sending an email is an essential part of every web application and there are plenty of ways or services to send E-mail in Laravel applications. The mail function is essential for these tasks, to register or notify the users, password reset link, and much more.

The benefits of using an SMTP server cannot be over-emphasized, with an SMTP server we can send email from our local server. Thus, giving us the ability to test the email functionality on the local server itself.

In this tutorial, we will create simple contact us form and send data from that form using Gmail SMTP.

Why Use Google SMTP?

The main reason is when we use Google SMTP, it makes sure users receive mail in their inbox instead of the spam folder. In addition, it's free to use and you don't need to purchase mail service for a small project. It provides free 100 emails per day.

Nowadays, It's the perfect choice for email communication because of its server's stability and consistent performance and great user base.

For your better understanding, we have divided our application into some parts :

  • Step 1: Create New Application
  • Step 2: Database Setup
  • Step 3: Google Account Configuration
  • Step 4: Mail Configuration
  • Step 5: Create a Mailable Class
  • Step 6: Create a Controller
  • Step 7: Add Blade Views
  • Step 8: Add Route
  • Step 9: Running Application

Note: If you already have Laravel application then you can skip the first and second steps.

Create New Application

First, open terminal and create new Laravel application using below command :

composer create-project --prefer-dist laravel/laravel GmailSmtp
//If you already installed laravel globel installer
laravel new GmailSmtp

Database Setup

Let's configure a database for our application. If you don't have a database then create a new one. After creating the database open .env file from root directory of your project. if .env file is missing from project then copy content from .env.example and create file. .env file defines many common environment variables

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=**********
DB_USERNAME=*********
DB_PASSWORD=*********

Mail Configuration

First of all, let's configure our mail. For that you have to configure the mail driver, mail host, mail port, and Gmail credentials like the below example

Let's head back to the terminal at root directory of project and enter below command :

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=mail_address
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=admin@example.com
MAIL_FROM_NAME="${APP_NAME}"

In the above settings, we configured MAIL_DRIVER as SMTP, MAIL_HOST for Gmail as smtp.gmail.com, MAIL_ PORT for Gmail as 587, and MAIL_ENCRYPTION method as tls.

Since we are using Gmail SMTP, we need to change some security settings on our Google account, to give access to less secure applications.

Google Account Configure

Before starting, we need to modify/change some security settings in our Gmail account.

Log in to your Gmail account. Now Click on your profile picture and then click on "Manage Your Google Account". Then Under the Security tab, Select "Less secure app access". At last click to "Turn on access (not recommended)".

Google setting for enable less secure app

Create Mail Class

In Laravel, each type of mail your application sends is called a Mailable class. All Mailable classes are stored at the app/Mail directory in your project. Don't worry if it is not in your application, it's automatically created while creating a mailable class.

To create a mailable class with is markdown, enter the below command into your terminal :

php artisan make:mail ContactMail

This command will create app/Mail/ContactMail.php and resources/views/mail/contact-mail.blade.php files. The mailable class will handle the logic for mail. While the view will send through mail to user.

<?php

namespace App\Mail;

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

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }

    public function build()
    {
        return $this->subject('Inquiry From '.$this->data['name'].' ('.$this->data['email'].')' )
                ->markdown('mail.contact-mail')
                ->with('data', $this->data);
    }
}

In simple terms when user submits the form controller calls the mailable class and passes all user-entered data as an array to the construct method while the build method will create a mail object and generate view with the markdown() function.

Create Controller

The next thing you need is a controller which will validate user inputs and pass create a mail object and trigger mail using our google mail configuration. To create the controller, run this Artisan command:

php artisan make:controller MailController

It will create a new file called MailController.php. Now you need to modify this newly created controller as per requirement :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactMail;

class MailController extends Controller
{
    public function ContactMail(Request $request){
        $validated = $request->validate([
            'name' => 'required|max:255',
            'email' => 'required|email',
            'phone' => 'required',
        ]);
        $data = $request->input();
        Mail::to('admin@example.com')->send(new ContactMail($data));
        return back()->with('success', 'Thanks for contacting us!');
    }
}

Here, we have created ContactMail() function. First of all this function validate user input and then get those inputs into an array and then send those data through mail. Here, you need to replace receiver email address for testing.

Create Blade View

Now we have to create views to get user input as well as a mail template. We will get user input into the contact form so let's create it first.

let's navigate to the views directory and create new file contact.blade.php. In this view file, we will set a form which takes name, email, phone number, and message from a user. so let's modify it :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Contact Us - Codewolfy</title>
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <style>
        body {
            background: -webkit-linear-gradient(left, #0072ff, #00c6ff);
        }

        .contact-form {
            background: #fff;
            margin-top: 10%;
            margin-bottom: 5%;
            width: 70%;
        }

        .contact-form .form-control {
            border-radius: 1rem;
        }

        .contact-image {
            text-align: center;
        }

        .contact-image img {
            border-radius: 6rem;
            width: 11%;
            margin-top: -3%;
        }

        .contact-form form {
            padding: 14%;
        }

        .contact-form form .row {
            margin-bottom: -7%;
        }

        .contact-form h3 {
            margin-bottom: 8%;
            margin-top: -10%;
            text-align: center;
            color: #0062cc;
        }

        .contact-form .btnContact {
            width: 50%;
            border: none;
            border-radius: 1rem;
            padding: 1.5%;
            background: #dc3545;
            font-weight: 600;
            color: #fff;
            cursor: pointer;
        }

        .btnContactSubmit {
            width: 50%;
            border-radius: 1rem;
            padding: 1.5%;
            color: #fff;
            background-color: #0062cc;
            border: none;
            cursor: pointer;
        }
    </style>
</head>
<body>
    @if ($message = Session::get('success'))
        <div class="alert alert-success alert-block">
            <button type="button" class="close" data-dismiss="alert">×</button>
            <strong>{{ $message }}</strong>
        </div>
    @endif
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
    <div class="container contact-form">
        <div class="contact-image">
            <img src="https://www.codewolfy.com/assets/images/logo/logo.png" alt="codewolfy" />
        </div>
        <form method="POST" action="{{route('contact.mail')}}">
            @csrf
            <h3>Drop Us a Message</h3>
            <div class="row">
                <div class="col-md-6">
                    <div class="form-group">
                        <input type="text" name="name" class="form-control" placeholder="Your Name *" value="" />
                    </div>
                    <div class="form-group">
                        <input type="email" name="email" class="form-control" placeholder="Your Email *" value="" />
                    </div>
                    <div class="form-group">
                        <input type="number" name="phone" class="form-control" placeholder="Your Phone Number *" value="" />
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="form-group">
                        <textarea name="message" class="form-control" placeholder="Your Message *" style="width: 100%; height: 150px;"></textarea>
                    </div>
                </div>
                <div class="col-md-12">
                    <div class="form-group">
                        <input type="submit" name="btnSubmit" class="btnContact" value="Send Message" />
                    </div>
                </div>
            </div>
        </form>
    </div>
</body>
</html>

To modify markdown or mail template open resources\views\mail\contact-mail.blade.php. This file is already created with the Mailable class. Let's make some changes to the view.

@component('mail::message')
# Inquiry From {{$data['name']}}
{{$data['message']}}
Call : {{$data['phone']}}
{{ config('app.name') }}
@endcomponent

Create Route

The last thing we need to add is to create a route which will all user routing. For this application, we need to define 2 routes. The first route will display the contact form and send route will handle sending mail functionality.

<?php

use App\Http\Controllers\MailController;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});
Route::get('contact-us', function(){
    return view('contact');
});
Route::post('/contact-mail', [MailController::class, 'ContactMail'])->name('contact.mail');

Running/Testing Application

php artisan serve

open below URL into your browser :

http://127.0.0.1:8000/contact-us

Fill up the form with dummy data and hit enter. It will trigger mail from configured Gmail address to your specified address. you can change the receiver address from the controller.