craftivelabs/laravel-syncraft

Laravel package for Syncraft WhatsApp Gateway API

Maintainers

Package info

github.com/getsyncraft/laravel-syncraft

pkg:composer/craftivelabs/laravel-syncraft

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-25 14:08 UTC

This package is not auto-updated.

Last update: 2026-07-26 13:31:49 UTC


README

PHP Version Laravel Version License

Laravel package for Syncraft WhatsApp Gateway API.

Compatible with PHP 7.4 through PHP 8.4+ and supports Laravel 8, 9, 10, 11, and 12+.

Features

  • Full Syncraft API support: Connections (QR & Phone Pairing), Messages (Text, Media, Group, Channel), Broadcasts, Group/Channel metadata, and Number checks.
  • 🚀 Laravel Facade & Auto-Discovery: Clean syntax via Syncraft::sendText(...).
  • 💉 Dependency Injection Ready: Auto-wired SyncraftClient singleton in Laravel's container.
  • 🔔 Event-driven Webhooks: Built-in WebhookController that automatically dispatches native Laravel events (MessageReceived, MessageSent, DeviceConnected, DeviceDisconnected).
  • 🛡️ Typed DTOs & Custom Exceptions: Strongly typed responses and exception handling.

Installation

Install the package via Composer:

composer require craftivelabs/laravel-syncraft

The package will automatically register its Service Provider (SyncraftServiceProvider) and Facade (Syncraft).

Publish Configuration

Publish the syncraft.php configuration file:

php artisan vendor:publish --tag=syncraft-config

This creates config/syncraft.php in your application:

return [
    'api_key'  => env('SYNCRAFT_API_KEY', ''),
    'base_url' => env('SYNCRAFT_BASE_URL', 'https://api.getsyncraft.com/v1/public'),
];

Environment Variables

Add your Syncraft API key to your .env file:

SYNCRAFT_API_KEY=your_api_key_here
SYNCRAFT_BASE_URL=https://api.getsyncraft.com/v1/public

Usage

💡 For full copy-pasteable examples of every single Syncraft API function, see EXAMPLES.md.

Using the Facade

use CraftiveLabs\Syncraft\Laravel\Facades\Syncraft;

// Send plain text message
$result = Syncraft::sendText('6281234567890', 'Hello from Laravel!');
echo $result->messageId;

// Send media message (file upload)
$result = Syncraft::sendMedia(
    '6281234567890',
    'image',
    'Check out this photo!',
    storage_path('app/public/photo.jpg')
);

// Send media message with custom filename
$result = Syncraft::sendMedia(
    '6281234567890',
    'document',
    'Invoice #1001',
    storage_path('app/public/invoice.pdf'),
    'invoice-1001.pdf'
);

// Send message to WhatsApp Group
$result = Syncraft::sendGroupText('1203632123456789@g.us', 'Hello group!');

// Send message to WhatsApp Newsletter Channel
$result = Syncraft::sendChannelText('12036302394829302@newsletter', 'New announcement!');

Using Dependency Injection

namespace App\Http\Controllers;

use CraftiveLabs\Syncraft\SyncraftClient;

class NotificationController extends Controller
{
    public function notify(SyncraftClient $syncraft)
    {
        $status = $syncraft->getStatus();
        
        if ($status->isConnected) {
            $syncraft->sendText('6281234567890', 'System status normal');
        }
    }
}

Connection & Session Management

use CraftiveLabs\Syncraft\Laravel\Facades\Syncraft;

// Get QR Code for scanning
$qr = Syncraft::connectQr();
echo $qr->qrCode; // base64 PNG data string

// Get 8-character pairing code
$code = Syncraft::connectPhone('6281234567890');
echo $code->pairingCode; // e.g. ABCD-1234

// Temporary disconnect
Syncraft::disconnect();

// Permanent logout
Syncraft::logout();

// Get status
$status = Syncraft::getStatus();
echo $status->isConnected ? 'Connected' : 'Disconnected';

Broadcast Campaigns

use CraftiveLabs\Syncraft\Laravel\Facades\Syncraft;

// Create broadcast campaign
$broadcast = Syncraft::createBroadcast('Promo July', 'text', 'Hello valued customer!', [
    ['phone_number' => '62812345678'],
    ['phone_number' => '62898765432', 'message' => 'Custom message for Budi!'],
]);
echo $broadcast->id; // e.g. 42

// Get campaign status
$detail = Syncraft::getBroadcast(42);
echo "Sent: {$detail->sentCount}, Failed: {$detail->failedCount}";

// Cancel broadcast campaign
Syncraft::cancelBroadcast(42);

Metadata & Number Check

use CraftiveLabs\Syncraft\Laravel\Facades\Syncraft;

// Check single WhatsApp number
$check = Syncraft::checkNumber('6281234567890');
if ($check->isRegistered) {
    echo "Registered JID: {$check->jid}";
}

// Bulk check WhatsApp numbers
$bulk = Syncraft::checkNumbers(['6281234567890', '6289876543210']);

// Get joined groups
$groups = Syncraft::getGroups();

// Get newsletter channels
$channels = Syncraft::getChannels();

Webhook Integration

Syncraft sends HTTP callbacks for events: message.received, message.sent, device.connected, and device.disconnected.

Option A: Native Laravel Webhook Controller & Events

Register the built-in route in your routes/api.php or routes/web.php:

use CraftiveLabs\Syncraft\Laravel\Controllers\WebhookController;

Route::post('/syncraft/webhook', WebhookController::class)->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);

WebhookController automatically parses incoming webhooks and fires native Laravel events:

  • CraftiveLabs\Syncraft\Laravel\Events\MessageReceived
  • CraftiveLabs\Syncraft\Laravel\Events\MessageSent
  • CraftiveLabs\Syncraft\Laravel\Events\DeviceConnected
  • CraftiveLabs\Syncraft\Laravel\Events\DeviceDisconnected
  • CraftiveLabs\Syncraft\Laravel\Events\WebhookReceived

Register Event Listener in EventServiceProvider

use CraftiveLabs\Syncraft\Laravel\Events\MessageReceived;
use App\Listeners\HandleIncomingWhatsAppMessage;

protected $listen = [
    MessageReceived::class => [
        HandleIncomingWhatsAppMessage::class,
    ],
];

Event Listener Implementation

namespace App\Listeners;

use CraftiveLabs\Syncraft\Laravel\Events\MessageReceived;
use Illuminate\Support\Facades\Log;

class HandleIncomingWhatsAppMessage
{
    public function handle(MessageReceived $event): void
    {
        $message = $event->message;
        
        Log::info("Received WhatsApp message from {$message->from}: {$message->content}");
    }
}

Option B: Custom Class with Handler Interface

If you prefer custom webhook routing without Laravel Events:

use CraftiveLabs\Syncraft\Webhook\Handler;
use CraftiveLabs\Syncraft\Webhook\WebhookTrait;

class WhatsAppWebhookHandler implements Handler
{
    use WebhookTrait;

    public function handle(array $payload): void
    {
        $event = $this->parseEvent($payload);

        if ($event->isMessageReceived()) {
            $msg = $event->toMessageData();
            // Process message...
        }
    }
}

Response DTO Reference

DTO Description Properties
QRCode Base64 QR code string qrCode
PairingCode 8-character phone pairing code pairingCode
ConnectionStatus Connection status response deviceId, isConnected, jid, status
SentMessage Sent message confirmation messageId, status, to
BroadcastResult Created broadcast campaign summary id, name, status, totalCount, createdAt
BroadcastDetail Full broadcast campaign details id, name, status, totalCount, sentCount, failedCount, recipients
GroupList List of joined groups groups (array of Group), total
Group Group metadata jid, name, topic, ownerJid, isLocked, isAnnounce, participants
ChannelList List of channels channels (array of Channel), total
Channel Channel metadata jid, name, description
NumberCheck Number registration check isRegistered, jid
BulkNumberCheck Bulk number registration check results (array of NumberCheck)
WebhookEvent Raw webhook callback event event, deviceId, timestamp, data
MessageData Webhook message payload messageId, from, messageType, content, timestamp, isGroup, isFromMe
DeviceData Webhook device state payload jid, status

Requirements

  • PHP: >= 7.4 (Compatible with PHP 7.4, 8.0, 8.1, 8.2, 8.3, 8.4+)
  • Laravel: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0
  • Guzzle: ^7.0

Testing

Run tests with PHPUnit:

vendor/bin/phpunit

License

The MIT License (MIT). See LICENSE for details.