Fermin Perdomo

Senior Full Stack Engineer | PHP | JavaScript

How to create a call me form with Laravel to send lead to Vicidial

Fermin Perdomo
April 30, 2023

Capture Leads in Laravel and Send to Vicidial

Let’s create a simple lead capture form in PHP and send submissions to Vicidial using:

  • 🧱 Laravel (PHP framework)
  • 📦 Composer (PHP package manager)
  • 🖥️ Vicidial (one of the best contact center software in the world)


 ✅ Prerequisites

Ensure the following are installed on your system:

  • PHP (v8.0 or higher)
  • Composer (v2.5 or higher)
  • A Vicidial server (installed and accessible)

🛠️ Step 1: Create a New Laravel Project

Open your terminal and run:

laravel new callme-vicidial
cd callme-vicidial

This may take a few moments. Once it's done, you’ll be inside the new Laravel project directory.

📦 Step 2: Install the Vicidial API Wrapper

We’ll use the masterfermin02/vicidial-api-wrapper package to connect Laravel with Vicidial.

Install it using Composer:

composer require masterfermin02/vicidial-api-wrapper

✏️ Step 3: Code the Application

We'll complete the app in two steps:

  1. Configure the Vicidial API connection.
  2. Create the web form in our Laravel app.

🔐 Vicidial Configuration

We recommend creating a dedicated API user in your Vicidial server.

Make sure this user has permission to modify leads/lists.

Now, open your .env file and add your Vicidial credentials:

VICIDIAL_API_USER={your_api_user}
VICIDIAL_API_PASSWORD={your_password}
VICIDIAL_API_URL={http://your-vicidial-server/agc/api.php}

Replace values inside {} with your actual Vicidial data.

🧮 Step 4: Create the Web Form

1. Create a Controller

Run the following command:

php artisan make:controller VicidialLeadController

2. Define the Route

Open routes/web.php and add:

use App\Http\Controllers\VicidialLeadController;

Route::get('/', [VicidialLeadController::class, 'index']);
Route::post('/leads', [VicidialLeadController::class, 'store'])->name('leads.store');

3. Add Controller Logic

Open app/Http/Controllers/VicidialLeadController.php and update:

use Illuminate\Http\Request;
use masterfermin02\VicidialApiWrapper\Vicidial;

class VicidialLeadController extends Controller
{
    public function index()
    {
        return view('pages.vicidial.admin.lead');
    }

    public function store(Request $request)
    {
        $vicidial = new Vicidial();

        $vicidial->addLead([
            'phone_number' => $request->input('phone'),
            'first_name' => $request->input('name'),
            'list_id' => 999, // Change this if needed
        ]);

        return redirect('/')->with('success', 'Lead sent to Vicidial!');
    }
}

4. Create the View

Inside resources/views, create folders:

pages/vicidial/admin/

Then, inside admin, create the file: lead.blade.php

Paste the HTML from this Gist:

 <!doctype html>
<html>
<head>
    <title>Lead</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="font-sans text-gray-900 antialiased relative isolate px-6 pt-14 lg:px-8">
    <form method="post" action="{{ url('/vicidial/admin/lead')  }}">
        @csrf
        <div class="space-y-12">
            <div class="border-b border-gray-900/10 pb-12">
                <h2 class="text-base font-semibold leading-7 text-gray-900">Vicidial form</h2>
            </div>

            <div class="border-b border-gray-900/10 pb-12">
                <h2 class="text-base font-semibold leading-7 text-gray-900">Personal Information</h2>
                <p class="mt-1 text-sm leading-6 text-gray-600">Use a permanent address where you can receive mail.</p>

                <div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
                    <div class="sm:col-span-3">
                        <label for="first-name" class="block text-sm font-medium leading-6 text-gray-900">First name</label>
                        <div class="mt-2">
                            <input type="text" name="first-name" id="first-name" autocomplete="given-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-3">
                        <label for="last-name" class="block text-sm font-medium leading-6 text-gray-900">Last name</label>
                        <div class="mt-2">
                            <input type="text" name="last-name" id="last-name" autocomplete="family-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-4">
                        <label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
                        <div class="mt-2">
                            <input id="email" name="email" type="email" autocomplete="email" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-3">
                        <label for="country" class="block text-sm font-medium leading-6 text-gray-900">Country</label>
                        <div class="mt-2">
                            <select id="country" name="country" autocomplete="country-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6">
                                <option>United States</option>
                                <option>Canada</option>
                                <option>Mexico</option>
                                <option>Dominican Republic</option>
                            </select>
                        </div>
                    </div>

                    <div class="col-span-full">
                        <label for="street-address" class="block text-sm font-medium leading-6 text-gray-900">Street address</label>
                        <div class="mt-2">
                            <input type="text" name="street-address" id="street-address" autocomplete="street-address" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-2 sm:col-start-1">
                        <label for="city" class="block text-sm font-medium leading-6 text-gray-900">City</label>
                        <div class="mt-2">
                            <input type="text" name="city" id="city" autocomplete="address-level2" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-2">
                        <label for="region" class="block text-sm font-medium leading-6 text-gray-900">State / Province</label>
                        <div class="mt-2">
                            <input type="text" name="region" id="region" autocomplete="address-level1" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-2">
                        <label for="postal-code" class="block text-sm font-medium leading-6 text-gray-900">ZIP / Postal code</label>
                        <div class="mt-2">
                            <input type="text" name="postal-code" id="postal-code" autocomplete="postal-code" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>

                    <div class="sm:col-span-2">
                        <label for="phone_number" class="block text-sm font-medium leading-6 text-gray-900">Phone number</label>
                        <div class="mt-2">
                            <input type="text" name="phone_number" id="phone_number" autocomplete="tel" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="mt-6 flex items-center justify-end gap-x-6">
            <button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
            <button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
        </div>
    </form>
</div>
</body>
</html>

🌐 Test It

Visit http://your-app-url/ in your browser.

  • Fill out the form
  • Click Save
  • The lead should now appear in Vicidial list 999 (or your specified list)

📁 Full Example

You can download the complete example from GitHub:
 🔗 https://github.com/masterfermin02/callme-example-for-vicidial

🧾 Conclusion

In this guide, we learned how to:

  • Set up a Laravel app
  • Create a controller and define routes
  • Configure Vicidial API credentials
  • Use the vicidial-api-wrapper to send leads

This setup is ideal for creating lightweight landing pages or simple CRMs that sync with Vicidial in real time.


Reactions

Loading reactions...
Log in to react to this post.

Comments

Please login to leave a comment.

Newsletter