How to Send WhatsApp Messages in Laravel 11?

Hi, Guys

In this blog, I'll demonstrate how to send WhatsApp messages using the Twilio API in a Laravel 11 application.

Twilio is a cloud communications platform that provides a flexible API, allowing developers to integrate voice, messaging, and video capabilities into their applications. Renowned for its simplicity and scalability, Twilio supports multiple programming languages. Its API facilitates seamless incorporation of features like sending SMS, making voice calls, and implementing two-factor authentication. Twilio's services enable businesses to improve customer engagement and communication, offering a powerful solution for creating innovative and interactive applications across various industries.

In this example, we will use third-party package "twilio/sdk" for send whatsapp message to users. Twilio provides a WhatsApp API that allows you to send messages and media to WhatsApp users programmatically. here, we will create simple form with phone number and message box. then we will send WhatsApp message to given number. so, let's follow the following steps to done this example.

Step for Laravel WhatsApp API Integration

Step 1: Install Laravel 11

Step 2: Set up a Twilio Account

Step 3: Install twilio/sdk Package

Step 4: Create Route

Step 5: Create Controller

Step 6: Create Blade File

Run Laravel App

let's follow bellow steps:

Step 1: Install Laravel 11

This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the below command:

composer create-project laravel/laravel example-app
Step 2: Set up a Twilio Account

First you need to create and add phone number. then you can easily get account SID, Token and Number.

Create Account from here: www.twilio.com.

Next add Twilio Phone Number

Next you can get account SID, Token and Number and add on .env file as like bellow:

.env
TWILIO_SID=your_twilio_account_sid
TWILIO_AUTH_TOKEN=your_twilio_auth_token
TWILIO_WHATSAPP_NUMBER=your_twilio_whatsapp_number
Step 3: Install twilio/sdk Package

In this step, we need to install twilio/sdk composer package to use twilio api. so let's run bellow command:

composer require twilio/sdk
Step 4: Create Route

now we will create one route for calling our example, so let's add new route to web.php file as bellow:

routes/web.php
<?php
  
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\WhatsAppController;
  
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
  
Route::get('whatsapp', [WhatsAppController::class, 'index']);
Route::post('whatsapp', [WhatsAppController::class, 'store'])->name('whatsapp.post');
Step 5: Create Controller

in this step, we will create WhatsAppController and write send sms logic, so let's add new route to web.php file as bellow:

app/Http/Controllers/WhatsAppController.php
<?php
  
namespace App\Http\Controllers;
   
use Illuminate\Http\Request;
use Twilio\Rest\Client;
use Exception;
  
class WhatsAppController extends Controller
{
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function index()
    {
        return view('whatsapp');
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function store(Request $request)
    {
        $twilioSid = env('TWILIO_SID');
        $twilioToken = env('TWILIO_AUTH_TOKEN');
        $twilioWhatsAppNumber = env('TWILIO_WHATSAPP_NUMBER');
        $recipientNumber = $request->phone;
        $message = $request->message;
  
        try {
            $twilio = new Client($twilioSid, $twilioToken);

            $twilio->messages->create(
                $recipientNumber,
                [
                    "from" => "whatsapp:+". $twilioWhatsAppNumber,
                    "body" => $message,
                ]
            );
  
            return back()->with(['success' => 'WhatsApp message sent successfully!']);
        } catch (Exception $e) {
            return back()->with(['error' => $e->getMessage()]);
        }
    }
}
Step 6: Create Blade File

Here, we will create "whatsapp.blade.php" file with following code:

resources/views/whatsapp.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>How to Send WhatsApp Messages in Laravel 11? - Itwebtuts.com</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
  
        <div class="row">
            <div class="col-md-9">
  
                <div class="card">
                  <div class="card-header">
                    <h2>How to Send WhatsApp Messages in Laravel 11? - Itwebtuts.com</h2>
                  </div>
                  <div class="card-body">
                    <form method="POST" action="{{ route('whatsapp.post') }}">
                
                        {{ csrf_field() }}
  
                        @if ($message = Session::get('success'))
                            <div class="alert alert-success alert-block">
                                <strong>{{ $message }}</strong>
                            </div>
                        @endif
  
                        @if ($message = Session::get('error'))
                            <div class="alert alert-danger alert-block">
                                <strong>{{ $message }}</strong>
                            </div>
                        @endif
                    
                        <div class="mb-3">
                            <label class="form-label" for="inputName">Phone:</label>
                            <input 
                                type="text" 
                                name="phone" 
                                id="inputName"
                                class="form-control @error('phone') is-invalid @enderror" 
                                placeholder="Phone Number">
              
                            @error('phone')
                                <span class="text-danger">{{ $message }}</span>
                            @enderror
                        </div>
  
                        <div class="mb-3">
                            <label class="form-label" for="inputName">Message:</label>
                            <textarea 
                                name="message" 
                                id="inputName"
                                class="form-control @error('message') is-invalid @enderror" 
                                placeholder="Enter Message"></textarea>
              
                            @error('message')
                                <span class="text-danger">{{ $message }}</span>
                            @enderror
                        </div>
                   
                        <div class="mb-3">
                            <button class="btn btn-success btn-submit">Send Message</button>
                        </div>
                    </form>
                  </div>
                </div>
                  
            </div>
        </div>
      
        
    </div>
</body>
</html>
Run Laravel App:

All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:

php artisan serve

Now, Go to your web browser, type the given URL and view the app output:

http://localhost:8000/whatsapp
Output:

Now you can run and check.

I hope it can help you...

Laravel 11 Like Dislike System Example

Hi, Dev

In this blog, I will guide you through creating a like and dislike system in a Laravel 11 application.

In this example, we will build a like-dislike system for posts without relying on any special packages. We'll start by setting up user accounts using Laravel UI. After that, we'll create a posts table and populate it with some sample posts. We'll then create a page displaying a list of posts, each with a title and description. On this page, we'll include thumbs-up and thumbs-down icons to allow users to like or dislike the posts. We'll use AJAX to manage these like and dislike interactions seamlessly.

You can create your example by following a few steps:

Step for Laravel 11 Create Like Dislike System Example

Step 1: Install Laravel 11

Step 2: Create Posts and Likes Tables

Step 3: Create and Update Models

Step 4: Create Dummy Posts

Step 5: Create Auth using Scaffold

Step 6: Create Routes

Step 7: Create Controller

Step 8: Create and Update Blade Files

Run Laravel App Step 1: Install Laravel 11

This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the below command:

composer create-project laravel/laravel example-app
Step 2: Create Posts and Likes Tables

Here, we will create posts and likes table with model. so, let's run the following command:

php artisan make:migration create_posts_table
php artisan make:migration create_likes_table

now, let's update the following migrations:

database/migrations/2024_06_11_035146_create_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
database/migrations/2024_06_13_175106_create_likes_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('likes', function (Blueprint $table) {
            $table->id();
            $table->foreignId('post_id')->constrained()->onDelete('cascade');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->boolean('like'); // true for like, false for dislike
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('likes');
    }
};

now, Let's run the migration command:

php artisan migrate
Step 3: Create and Update Models

Here, we will create Post and Like model using the following command. we also need to update User model here. we will write relationship and some model function for like and dislike.

php artisan make:model Post
php artisan make:model Like

now, update the model file with hasMany() relationship:

app/Models/Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'body'];

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function likes()
    {
        return $this->hasMany(Like::class)->where('like', true);
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function dislikes()
    {
        return $this->hasMany(Like::class)->where('like', false);
    }
}
app/Models/Like.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Like extends Model
{
    use HasFactory;

    protected $fillable = ['post_id', 'user_id', 'like'];

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function post()
    {
        return $this->belongsTo(Post::class);
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function likes()
    {
        return $this->hasMany(Like::class);
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function hasLiked($postId)
    {
        return $this->likes()->where('post_id', $postId)->where('like', true)->exists();
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function hasDisliked($postId)
    {
        return $this->likes()->where('post_id', $postId)->where('like', false)->exists();
    }

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function toggleLikeDislike($postId, $like)
    {
        // Check if the like/dislike already exists
        $existingLike = $this->likes()->where('post_id', $postId)->first();

        if ($existingLike) {
            if ($existingLike->like == $like) {
                $existingLike->delete();

                return [
                    'hasLiked' => false,
                    'hasDisliked' => false
                ];
            } else {
                $existingLike->update(['like' => $like]);
            }
        } else {
            $this->likes()->create([
                'post_id' => $postId,
                'like' => $like,
            ]);
        }

        return [
            'hasLiked' => $this->hasLiked($postId),
            'hasDisliked' => $this->hasDisliked($postId)
        ];
    }
}
Step 4: Create Dummy Posts

In this step, we need to run the migration command to create the seeder to create dummy records in posts table

Let's run the migration command:

php artisan make:seeder CreateDummyPost

noww, we need to update CreateDummyPost seeder.

database/seeders/CreateDummyPost.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Post;

class CreateDummyPost extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $posts = [
            [
                'title' => 'Laravel Product CRUD Tutorial',
                'body' => 'Step by Step Laravel Product CRUD Tutorial'
            ],
            [
                'title' => 'Laravel Image Upload Example',
                'body' => 'Step by Step Laravel Image Upload Example'
            ],
            [
                'title' => 'Laravel File Upload Example',
                'body' => 'Step by Step Laravel File Upload Example'
            ],
            [
                'title' => 'Laravel Cron Job Example',
                'body' => 'Step by Step Laravel Cron Job Example'
            ],
            [
                'title' => 'Laravel Send Email Example',
                'body' => 'Step by Step Laravel Send Email Example'
            ],
            [
                'title' => 'Laravel CRUD with Image Upload',
                'body' => 'Step by Step Laravel CRUD with Image Upload'
            ],
            [
                'title' => 'Laravel Ajax CRUD with Image Upload',
                'body' => 'Step by Step Laravel Ajax CRUD with Image Upload'
            ],
            [
                'title' => 'Laravel Ajax CRUD with Image Upload',
                'body' => 'Step by Step Laravel Ajax CRUD with Image Upload'
            ]
        ];

        foreach ($posts as $key => $value) {
            Post::create([
                'title' => $value['title'],
                'body' => $value['body'],
            ]);
        }
    }
}

now, the run seeder using the following command:

php artisan db:seed --class=CreateDummyPost
Step 5: Create Auth using Scaffold

Now, in this step, we will create an auth scaffold command to generate login, register, and dashboard functionalities. So, run the following commands:

Laravel 11 UI Package:
composer require laravel/ui 
Generate Auth:
php artisan ui bootstrap --auth
npm install
npm run build
Step 6: Create Routes

In this step, we will create routes for like unlike system. So we require to create following route in web.php file.

routes/web.php
<?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PostController;

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

Route::middleware('auth')->group(function () {
    Route::get('posts', [PostController::class, 'index'])->name('posts.index');
    Route::post('posts/ajax-like-dislike', [PostController::class, 'ajaxLike'])->name('posts.ajax.like.dislike');
});
Step 7: Create Controller

now in PostController, we will add two new method posts() and ajaxLike(). so let's see PostController like as bellow:

app/Http/PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;

class PostController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::get();
        return view('posts', compact('posts'));
    }


    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function ajaxLike(Request $request)
    {
        $post = Post::find($request->id);
        $response = auth()->user()->toggleLikeDislike($post->id, $request->like);

        return response()->json(['success' => $response]);
    }
}
Step 8: Create and Update Blade Files

In this step, we will update app.blade.php file and create posts.blade file. so, let's update it.

resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">

    <!-- Scripts -->
    @vite(['resources/sass/app.scss', 'resources/js/app.js'])

    @yield('style')
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    Laravel Like DisLike System Example
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav me-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ms-auto">
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('posts.index') }}">{{ __('Posts') }}</a>
                            </li>
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>

@yield('script')

</html>
resources/views/posts.blade.php
@extends('layouts.app')

@section('style')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style type="text/css">
    i{
        cursor: pointer;
    }
</style>
@endsection

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">{{ __('Posts List') }}</div>

                <div class="card-body">
                    
                    <div class="row">
                        @foreach($posts as $post)
                        <div class="col-md-3">
                            <div class="card mt-2" style="width: 18rem;">
                              <img src="https://picsum.photos/id/0/367/267" class="card-img-top" alt="...">
                              <div class="card-body">
                                <h5 class="card-title">{{ $post->title }}</h5>
                                <p class="card-text">Some quick example text to build on the card title and make up the bulk of the cards content.</p>
                                <div class="like-box">
                                    <i id="like-{{ $post->id }}" 
                                        data-post-id="{{ $post->id }}"
                                        class="like fa-thumbs-up {{ auth()->user()->hasLiked($post->id) ? 'fa-solid' : 'fa-regular' }}"></i> 
                                    <span class="like-count">{{ $post->likes->count() }}</span>
                                    <i id="like-{{ $post->id }}" 
                                        data-post-id="{{ $post->id }}"
                                        class="dislike fa-thumbs-down {{ auth()->user()->hasDisliked($post->id) ? 'fa-solid' : 'fa-regular' }}"></i> 
                                    <span class="dislike-count">{{ $post->dislikes->count() }}</span>
                                </div>
                              </div>
                            </div>
                        </div>
                        @endforeach
                    </div>

                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@section('script')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" referrerpolicy="no-referrer"></script>
<script type="text/javascript">
    $(document).ready(function() {     

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $('.like-box i').click(function(){    
            var id = $(this).attr('data-post-id');
            var boxObj = $(this).parent('div');
            var c = $(this).parent('div').find('span').text();
            var like = $(this).hasClass('like') ? 1 : 0;

            $.ajax({
               type:'POST',
               url: "{{ route('posts.ajax.like.dislike') }}",
               data:{ id:id, like:like },
               success:function(data){

                    if (data.success.hasLiked == true) {

                        if($(boxObj).find(".dislike").hasClass("fa-solid")){
                            var dislikes = $(boxObj).find(".dislike-count").text();
                            $(boxObj).find(".dislike-count").text(parseInt(dislikes)-1);
                        }

                        $(boxObj).find(".like").removeClass("fa-regular");
                        $(boxObj).find(".like").addClass("fa-solid");

                        $(boxObj).find(".dislike").removeClass("fa-solid");
                        $(boxObj).find(".dislike").addClass("fa-regular");

                        var likes = $(boxObj).find(".like-count").text();
                        $(boxObj).find(".like-count").text(parseInt(likes)+1);

                    } else if(data.success.hasDisliked == true){

                        if($(boxObj).find(".like").hasClass("fa-solid")){
                            var likes = $(boxObj).find(".like-count").text();
                            $(boxObj).find(".like-count").text(parseInt(likes)-1);
                        }

                        $(boxObj).find(".like").removeClass("fa-solid");
                        $(boxObj).find(".like").addClass("fa-regular");

                        $(boxObj).find(".dislike").removeClass("fa-regular");
                        $(boxObj).find(".dislike").addClass("fa-solid");

                        var dislike = $(boxObj).find(".dislike-count").text();
                        $(boxObj).find(".dislike-count").text(parseInt(dislike)+1);
                    } else {
                        if($(boxObj).find(".dislike").hasClass("fa-solid")){
                            var dislikes = $(boxObj).find(".dislike-count").text();
                            $(boxObj).find(".dislike-count").text(parseInt(dislikes)-1);
                        } 

                        if($(boxObj).find(".like").hasClass("fa-solid")){
                            var likes = $(boxObj).find(".like-count").text();
                            $(boxObj).find(".like-count").text(parseInt(likes)-1);
                        }

                        $(boxObj).find(".like").removeClass("fa-solid");
                        $(boxObj).find(".like").addClass("fa-regular");

                        $(boxObj).find(".dislike").removeClass("fa-solid");
                        $(boxObj).find(".dislike").addClass("fa-regular");

                    }
               }
            });

        });   

    }); 
</script>
@endsection
Run Laravel App:

All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:

php artisan serve

Now, Go to your web browser, type the given URL and view the app output:

http://localhost:8000/

I hope it can help you...

Laravel 11 Send Email Via Notification Example

Hi, Guys

In this blog, we will explore how to create and send email notifications in a Laravel 11 application.

Laravel notifications are a robust feature of the Laravel PHP framework, enabling you to send notifications to your users. In this article, we'll focus on sending email notifications in a Laravel 11 application.

Notifications in Laravel are managed using a notification class that extends the `Illuminate\Notifications\Notification` class. Within this class, you can define the content and format of the notification, as well as specify the channels through which it should be sent.

Laravel offers a variety of built-in channels for sending notifications, including `mail` for email notifications, `database` for storing notifications in a database, and `broadcast` for broadcasting notifications over web sockets. Additionally, you can create custom channels to send notifications through other mediums.

In this example, we will create a simple `BirthdayWish` notification to be sent to users on their birthdays. Follow the steps below to implement this example.

Step for Laravel 11 Send Email Via Notification Example

Step 1: Install Laravel 11

Step 2: Create Migration

Step 3: Update Model

Step 4: Create Notification

Step 5: Create Route

Step 6: Create Controller

Run Laravel App Step 1: Install Laravel 11

This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the below command:

composer create-project laravel/laravel example-app
Step 2: Create Migration

Here, we will create a new migration to add a new column birthdate to the users table. So let's run the following command:

php artisan make:migration add_birthdate_column

After this command, you will find one file in the following path: "database/migrations". You have to put the below code in your migration file to create the products table.

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->date('birthdate')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        
    }
};

Now you have to run this migration by the following command:

php artisan migrate
Step 3: Update Model

In this step, we will add "birthdate" column in $fillable array.

Make sure you use Notifiable class form Illuminate\Notifications\Notifiable.

let's copy below code and paste it.

app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'birthdate'
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}
Step 4: Create Notification

In this step, we need to create "Notification" by using the Laravel artisan command, so let's run the command below. We will create the BirthdayWish notification class.

php artisan make:notification BirthdayWish

Now you can see a new folder created as "Notifications" in the app folder. You need to make the following changes as shown in the class below.

app/Notifications/BirthdayWish.php
<?php
  
namespace App\Notifications;
  
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
  
class BirthdayWish extends Notification
{
    use Queueable;
  
    private $messages;
  
    /**
     * Create a new notification instance.
     */
    public function __construct($messages)
    {
        $this->messages = $messages;
    }
  
    /**
     * Get the notification's delivery channels.
     *
     * @return array
     */
    public function via(object $notifiable): array
    {
        return ['mail'];
    }
  
    /**
     * Get the mail representation of the notification.
     */
    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
                    ->line($this->messages['hi'])
                    ->line($this->messages['wish'])
                    ->line('Thank you for using our application!');
    }
  
    /**
     * Get the array representation of the notification.
     *
     * @return array
     */
    public function toArray(object $notifiable): array
    {
        return [
              
        ];
    }
}

Next, you have to add the send mail configuration with mail driver, mail host, mail port, mail username, and mail password so Laravel will use those sender configurations for sending email. You can simply add it as follows:

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_USERNAME=mygoogle@gmail.com
MAIL_PASSWORD=rrnnucvnqlbsl
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=mygoogle@gmail.com
MAIL_FROM_NAME="${APP_NAME}"
Step 5: Create Route

In this step, we need to create routes for sending notifications to one user. So open your "routes/web.php" file and add the following route.

routes/web.php
<?php
  
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\UserController;
    
Route::get('user-notify', [UserController::class, 'index']);
Step 6: Create Controller

Here, we require the creation of a new controller, UserController, with an index method to send a notification route. So let's put the code below.

app/Http/Controllers/UserController.php
<?php
   
namespace App\Http\Controllers;
    
use Illuminate\Http\Request;
use App\Models\User;
use App\Notifications\BirthdayWish;
    
class UserController extends Controller
{   
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = User::find(1);
  
        $messages["hi"] = "Hey, Happy Birthday {$user->name}";
        $messages["wish"] = "On behalf of the entire company I wish you a very happy birthday and send you my best wishes for much happiness in your life.";
          
        $user->notify(new BirthdayWish($messages));
  
        dd('Done');
    }
}
Run Laravel App:

All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:

php artisan serve

Now, Go to your web browser, type the given URL and view the app output:

http://localhost:8000/user-notify
Output: You Email Look Like This

I hope it can help you...