πŸš€ WAHA PHP Client

PHP client modern untuk WAHA (WhatsApp HTTP API) dengan fitur anti-banned flow otomatis dan database logging

⚑ PHP 8.1+ 🎯 Laravel Support πŸ—„οΈ Database Logging πŸ”’ Anti-Banned

✨ Fitur Utama

πŸ›‘οΈ Anti-Banned Flow

Otomatis handle sendSeen β†’ startTyping β†’ delay β†’ stopTyping β†’ sendText untuk menghindari banned

πŸ“¦ Bulk Messaging

Kirim pesan massal dengan delay otomatis dan batch processing yang aman

πŸ—„οΈ Database Logging

Setiap request tercatat otomatis di database (MySQL/PostgreSQL)

🎯 Laravel Integration

Facade, Service Provider, dan Artisan command untuk Laravel

⚑ Easy Setup

Instalasi mudah via Composer dengan konfigurasi minimal

πŸ”§ Flexible

Bisa digunakan dengan atau tanpa framework PHP

πŸ“₯ Installation

Requirements: PHP 8.1+, Guzzle 7+, WAHA instance running (Docker)

Install via Composer

composer require orlinkzz/waha-php

Atau Tambahkan ke composer.json

{
    "require": {
        "orlinkzz/waha-php": "^1.0"
    }
}

βš™οΈ Setup

Tanpa Framework (Pure PHP)

use Orlinkzz\Waha\WahaClient;
use Orlinkzz\Waha\WahaConfig;

$config = new WahaConfig(
    baseUrl: 'http://localhost:3000',
    apiKey:  'your-api-key',
    session: 'default',
);

$waha = new WahaClient($config);

Laravel

1. Publish config file:

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

2. Tambahkan ke .env:

WAHA_BASE_URL=https://waha.yourdomain.com
WAHA_API_KEY=your-secret-key
WAHA_SESSION=default

3. Gunakan via Facade:

use Orlinkzz\Waha\Laravel\WahaFacade as Waha;

Waha::sendText('628123456789@c.us', 'Halo!');

πŸ’¬ Usage

Reply ke Pesan Masuk (Anti-Banned Flow Otomatis)

// Otomatis: sendSeen β†’ startTyping β†’ delay β†’ stopTyping β†’ sendText
$waha->reply('628123456789@c.us', 'Halo! Ada yang bisa kami bantu?');

Kirim via OutgoingMessage DTO

use Orlinkzz\Waha\Message\OutgoingMessage;

$message = OutgoingMessage::to('+628123456789', 'Halo {name}!')
    ->personalize('Budi');  // replace {name} + variasi spasi

$waha->send($message);

Kirim Gambar

$waha->sendImage('628123456789@c.us', 'https://example.com/banner.jpg', 'Promo spesial!');

Kirim File

$waha->sendFile('628123456789@c.us', 'https://example.com/invoice.pdf', 'invoice.pdf');

Session Management

// Start session (scan QR di dashboard WAHA)
$waha->startSession();

// Cek status
$status = $waha->getSessionStatus();

// List semua session
$sessions = $waha->listSessions();

// Stop session
$waha->stopSession();

πŸ“¨ Bulk / Broadcast Messaging

Fitur Anti-Banned Otomatis:
  • Delay acak 30–60 detik antar pesan
  • Pause antar batch (60–120 detik setiap 4 pesan)
  • Typing simulation per pesan
  • Error per-pesan tidak stop keseluruhan
use Orlinkzz\Waha\Message\OutgoingMessage;

$contacts = [
    ['phone' => '628111111111', 'name' => 'Budi'],
    ['phone' => '628222222222', 'name' => 'Siti'],
    ['phone' => '628333333333', 'name' => 'Andi'],
];

$messages = array_map(fn($c) =>
    OutgoingMessage::to($c['phone'], 'Halo {name}, ada promo spesial!')
        ->personalize($c['name']),
    $contacts
);

$result = $waha->sendBulk(
    messages: $messages,
    onEach: function ($message, $response, $index) {
        echo "βœ… Sent to {$message->chatId} ({$index})\n";
    },
    onBatchPause: function ($batchNumber, $pauseSeconds) {
        echo "⏸️  Batch {$batchNumber} selesai, pause {$pauseSeconds} detik...\n";
    }
);

echo "Sukses: {$result->successCount()} / {$result->total}\n";

if ($result->hasFailures()) {
    foreach ($result->failures() as $fail) {
        echo "❌ {$fail['chatId']}: {$fail['error']}\n";
    }
}

Di Laravel β€” Pakai Queue untuk Bulk

// app/Jobs/SendWhatsappBlast.php

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Orlinkzz\Waha\Laravel\WahaFacade as Waha;
use Orlinkzz\Waha\Message\OutgoingMessage;

class SendWhatsappBlast implements ShouldQueue
{
    use Queueable;

    public int $timeout = 3600; // 1 jam

    public function __construct(private array $contacts, private string $template) {}

    public function handle(): void
    {
        $messages = array_map(fn($c) =>
            OutgoingMessage::to($c['phone'], $this->template)
                ->personalize($c['name']),
            $this->contacts
        );

        $result = Waha::sendBulk($messages);
        // Log result...
    }
}

// Dispatch:
SendWhatsappBlast::dispatch($contacts, 'Halo {name}, ada info penting!');

πŸ—„οΈ Database Logging

Setiap request ke WAHA API otomatis tercatat di database. Support MySQL dan PostgreSQL.

Quick Start

  1. Buat database dan import schema
  2. Konfigurasi di .env
  3. Jalankan migration (Laravel)
  4. Selesai! Semua request otomatis tercatat

1. Import SQL Schema

# MySQL
mysql -u root -p waha < database/sql/mysql_schema.sql

# PostgreSQL
psql -U postgres -d waha -f database/sql/postgres_schema.sql

2. Konfigurasi di .env

WAHA_DB_DRIVER=mysql
WAHA_DB_HOST=127.0.0.1
WAHA_DB_PORT=3306
WAHA_DB_DATABASE=waha
WAHA_DB_USERNAME=root
WAHA_DB_PASSWORD=

3. Jalankan Migration (Laravel)

php artisan waha:migrate --force
php artisan waha:migrate --rollback --force   # rollback

Tabel Database

Tabel Fungsi
waha_sessions Info session (nama, status, QR, waktu connect/disconnect)
waha_contacts Data kontak (phone, nama, blocked, business)
waha_messages Riwayat pesan masuk & keluar
waha_message_logs Log pengiriman (status: pending β†’ sent/failed)

Apa yang Tercatat

Method Tercatat di
startSession() / stopSession() waha_sessions
sendText(), sendImage(), sendFile() waha_message_logs + waha_contacts
reply() waha_message_logs + waha_contacts
sendBulk() waha_message_logs (per pesan)
getMessages() waha_messages

Query Data

// Log pesan
$pending = $waha->getMessageLogs('pending');
$sent    = $waha->getMessageLogs('sent');
$failed  = $waha->getMessageLogs('failed');

// Sessions
$sessions = $waha->getSessions();

// Contacts
$contacts = $waha->getContacts();
$contacts = $waha->getContacts('default'); // per session

Webhook Integration

public function handleWebhook(Request $request)
{
    app('waha')->handleIncomingMessage($request->all());
    return response()->json(['status' => 'ok']);
}

πŸ”§ Configuration

WAHA API Configuration

Key Default Keterangan
base_url http://localhost:3000 URL WAHA instance
api_key β€” API key WAHA
session default Nama session WhatsApp
typing_delay_min 1000 ms Min delay simulate typing
typing_delay_max 3000 ms Max delay simulate typing
bulk_delay_min 30000 ms Min delay antar pesan bulk
bulk_delay_max 60000 ms Max delay antar pesan bulk
bulk_batch_size 4 Jumlah pesan per batch

Database Configuration

Key Default Keterangan
WAHA_DB_DRIVER mysql mysql atau pgsql
WAHA_DB_HOST 127.0.0.1 Database host
WAHA_DB_PORT 3306 3306 (MySQL) atau 5432 (PostgreSQL)
WAHA_DB_DATABASE waha Database name
WAHA_DB_USERNAME root Database username
WAHA_DB_PASSWORD β€” Database password

πŸ“š Examples

Complete Example: Send Message with Database Logging

<?php

require 'vendor/autoload.php';

use Orlinkzz\Waha\WahaClient;
use Orlinkzz\Waha\WahaConfig;

// Configure WAHA client with database
$config = new WahaConfig(
    baseUrl: 'http://localhost:3000',
    apiKey: 'your-api-key',
    session: 'default',
    database: [
        'driver' => 'mysql',
        'host' => '127.0.0.1',
        'port' => '3306',
        'database' => 'waha',
        'username' => 'root',
        'password' => '',
    ]
);

$waha = new WahaClient($config);

// Send message - automatically logged to database
try {
    $result = $waha->sendText('628123456789@c.us', 'Halo! Pesan otomatis tercatat di database.');
    echo "βœ… Message sent successfully!\n";

    // Query logs
    $logs = $waha->getMessageLogs('sent');
    echo "Total sent messages: " . count($logs) . "\n";

} catch (Exception $e) {
    echo "❌ Error: " . $e->getMessage() . "\n";
}

Laravel Example: Webhook Handler

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Orlinkzz\Waha\Laravel\WahaFacade as Waha;

class WhatsAppController extends Controller
{
    // Handle incoming messages
    public function webhook(Request $request)
    {
        // Automatically log to database
        Waha::handleIncomingMessage($request->all());

        // Auto-reply with anti-banned flow
        if (isset($request->from)) {
            Waha::reply($request->from, 'Terima kasih! Pesan Anda telah diterima.');
        }

        return response()->json(['status' => 'ok']);
    }

    // Send bulk messages
    public function broadcast()
    {
        $contacts = [
            ['phone' => '628111111111', 'name' => 'Budi'],
            ['phone' => '628222222222', 'name' => 'Siti'],
        ];

        $messages = array_map(fn($c) =>
            \Orlinkzz\Waha\Message\OutgoingMessage::to($c['phone'], 'Halo {name}!')
                ->personalize($c['name']),
            $contacts
        );

        $result = Waha::sendBulk($messages);

        return response()->json([
            'success' => $result->successCount(),
            'failed' => $result->failureCount(),
            'total' => $result->total
        ]);
    }
}

πŸ” Troubleshooting

Database Connection Failed

SQLSTATE[HY000] [2002] Connection refused

Solution: Pastikan database credentials benar dan database server berjalan

Table Not Found

SQLSTATE[42S02]: Base table or view 1146: Table 'waha.waha_sessions' doesn't exist

Solution: Jalankan migration terlebih dahulu

Laravel Migration Not Working

Solution:

php artisan config:clear
php artisan waha:migrate --force

πŸ“„ License

MIT License - Copyright (c) 2026 Orlinkzz

Lihat file LICENSE untuk detail lengkap.

↑