chengkangzai / laravel-waha-saloon-sdk
WAHA SDK that is generated from WAHA postman collection that is wrapped in SaloonPHP
Fund package maintenance!
CCK
Installs: 2 101
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 2
pkg:composer/chengkangzai/laravel-waha-saloon-sdk
Requires
- php: ^8.3
- illuminate/contracts: ^10.0||^11.0||^12.0
- saloonphp/saloon: ^3.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0||^9.6
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
This package is auto-updated.
Last update: 2025-12-07 11:55:18 UTC
README
A comprehensive Laravel package that provides a PHP SDK for the WAHA (WhatsApp HTTP API) service. This SDK is auto-generated from the WAHA Postman collection and wrapped with SaloonPHP for elegant HTTP client functionality.
What is WAHA?
WAHA (WhatsApp HTTP API) is a service that provides HTTP RESTful API access to WhatsApp. It allows you to:
- Send and receive WhatsApp messages programmatically
- Manage WhatsApp sessions and authentication
- Handle contacts, groups, and channels
- Implement WhatsApp business features in your application
This SDK makes it easy to integrate WAHA with your Laravel application, providing a fluent, type-safe interface to all WAHA API endpoints.
Features
- ๐ Auto-generated from WAHA Postman collection
- ๐ Elegant HTTP client powered by SaloonPHP
- ๐ฆ Laravel integration with service provider and facade
- ๐ ๏ธ Comprehensive API coverage with 23 resources and 134 request types
- ๐ Built-in API key authentication support
- ๐งช Built with testing in mind using Pest PHP
- ๐ฏ Type-safe request and response handling
- ๐ Support for Laravel 10.x, 11.x, and 12.x
Installation
You can install the package via composer:
composer require chengkangzai/laravel-waha-saloon-sdk
You can publish the config file with:
php artisan vendor:publish --tag="waha-saloon-sdk-config"
This is the contents of the published config file:
return [ 'default' => env('WAHA_CONNECTION', 'default'), 'connections' => [ 'default' => [ 'base_url' => env('WAHA_BASE_URL', ''), 'api_key' => env('WAHA_API_KEY', ''), ], ], // Legacy keys for backward compatibility 'base_url' => env('WAHA_BASE_URL', ''), 'api_key' => env('WAHA_API_KEY', ''), ];
Configuration
Set your WAHA instance URL and API key in your .env file:
WAHA_BASE_URL=https://your-waha-instance.com WAHA_API_KEY=your-api-key-here
The API key is optional but required for most WAHA endpoints (approximately 50% of endpoints require authentication). If not provided, requests will be sent without authentication headers.
Multiple WAHA Hosts
The SDK supports connecting to multiple WAHA instances. This is useful when you have separate WAHA servers for different purposes (production, staging, different WhatsApp accounts, etc.).
Configuring Multiple Hosts
Update your config/waha-saloon-sdk.php to define multiple connections:
return [ 'default' => env('WAHA_CONNECTION', 'default'), 'connections' => [ 'default' => [ 'base_url' => env('WAHA_BASE_URL', ''), 'api_key' => env('WAHA_API_KEY', ''), ], 'production' => [ 'base_url' => env('WAHA_PRODUCTION_URL', ''), 'api_key' => env('WAHA_PRODUCTION_KEY', ''), ], 'staging' => [ 'base_url' => env('WAHA_STAGING_URL', ''), 'api_key' => env('WAHA_STAGING_KEY', ''), ], ], ];
Using the Waha Facade (Recommended)
use CCK\LaravelWahaSaloonSdk\Facades\Waha; // Use default connection $response = Waha::sessions()->listAllSessions(); // Use a specific connection $response = Waha::connection('production')->sessions()->listAllSessions(); // Chain resource methods $response = Waha::connection('staging') ->chats() ->getsMessagesInTheChat('default', '1234567890@c.us');
Using Dependency Injection
use CCK\LaravelWahaSaloonSdk\WahaManager; class WhatsAppController extends Controller { public function __construct( private WahaManager $waha, ) {} public function send(Request $request) { // Use default connection $this->waha->sendText()->sendTextMessage(...); // Use specific connection $this->waha->connection('production')->sendText()->sendTextMessage(...); } }
Direct Instantiation
Direct instantiation still works and ignores the configuration:
use CCK\LaravelWahaSaloonSdk\Waha\Waha; $waha = new Waha( baseUrl: 'https://custom-instance.com', apiKey: 'custom-api-key' );
Usage
Quick Start Example
Here's a complete example showing how to send your first WhatsApp message:
<?php use CCK\LaravelWahaSaloonSdk\Waha\Waha; // 1. Create a WAHA client instance $waha = new Waha(); // 2. Start a WhatsApp session (you'll need to scan QR code first time) $sessionResponse = $waha->sessions()->startTheSession('default'); // 3. Send a text message $messageResponse = $waha->sendText()->sendTextMessage( chatId: '1234567890@c.us', // WhatsApp number with @c.us suffix text: 'Hello from Laravel WAHA SDK!', session: 'default', replyTo: null, linkPreview: null, linkPreviewHighQuality: null ); // 4. Check if message was sent successfully if ($messageResponse->successful()) { $messageData = $messageResponse->json(); echo "Message sent! ID: " . $messageData['id']; } else { echo "Failed to send message: " . $messageResponse->body(); }
Basic Usage Patterns
use CCK\LaravelWahaSaloonSdk\Waha\Waha; // Create a new WAHA client with default config (uses env vars) $waha = new Waha(); // Or with a custom base URL and API key (overrides config) $waha = new Waha( baseUrl: 'https://your-waha-instance.com', apiKey: 'your-api-key' ); // Access different resources - each resource groups related API endpoints $sessions = $waha->sessions(); // Session management $chats = $waha->chats(); // Limited chat operations $messages = $waha->sendText(); // Send text messages $misc = $waha->misc(); // Most functionality (files, media, groups, etc.) $contacts = $waha->contacts(); // Contact management $overview = $waha->overview(); // Chat overview
Working with Sessions
Sessions are the foundation of WhatsApp communication. Each session represents a WhatsApp connection.
// Get all active sessions (using misc resource) $response = $waha->misc()->listAllSessions(null); $sessions = $response->json(); foreach ($sessions as $session) { echo "Session: {$session['name']}, Status: {$session['status']}\n"; } // Get detailed information about a specific session $response = $waha->sessions()->getSessionInformation('default'); if ($response->successful()) { $session = $response->json(); echo "Session Status: {$session['status']}\n"; echo "Session Config: " . json_encode($session['config']) . "\n"; } // Start a new session (first time requires QR code scanning) $response = $waha->sessions()->startTheSession('default'); if ($response->successful()) { echo "Session started successfully\n"; // You may need to scan QR code if this is the first time } // Stop an active session $response = $waha->sessions()->stopTheSession('default'); if ($response->successful()) { echo "Session stopped successfully\n"; } // Get QR code for authentication $response = $waha->auth()->getQrCodeForPairingWhatsAppApi('default'); if ($response->successful()) { $qr = $response->json(); echo "QR Code: {$qr['qr']}\n"; }
Sending Messages
The SDK provides specialized resources for different message types. Here are comprehensive examples:
// Send a simple text message $response = $waha->sendText()->sendTextMessage( chatId: '1234567890@c.us', // Individual chat text: 'Hello from Laravel WAHA SDK!', session: 'default', replyTo: null, linkPreview: null, linkPreviewHighQuality: null ); // Send an image with caption (using misc resource) $response = $waha->misc()->sendImage( chatId: '1234567890@c.us', file: 'https://example.com/image.jpg', // URL or base64 session: 'default', replyTo: null, caption: 'Check out this amazing image! ๐ธ' ); // Send an image from local file (base64) $imageBase64 = base64_encode(file_get_contents('/path/to/image.jpg')); $response = $waha->misc()->sendImage( chatId: '1234567890@c.us', file: $imageBase64, session: 'default', replyTo: null, caption: 'Image from server storage' ); // Send a document/file $response = $waha->misc()->sendFile( chatId: '1234567890@c.us', file: 'https://example.com/document.pdf', // URL or base64 session: 'default', replyTo: null, caption: 'Important document' ); // Send a video with caption $response = $waha->misc()->sendVideo( chatId: '1234567890@c.us', file: 'https://example.com/video.mp4', session: 'default', replyTo: null, asNote: false, caption: 'Watch this tutorial video!' ); // Send voice message $response = $waha->misc()->sendVoiceMessage( chatId: '1234567890@c.us', file: 'https://example.com/audio.ogg', // URL or base64 session: 'default', replyTo: null ); // Send location $response = $waha->misc()->chattingControllerSendLocation( chatId: '1234567890@c.us', latitude: 37.7749, longitude: -122.4194, title: 'San Francisco Office', session: 'default', replyTo: null ); // Send a poll $pollData = [ 'name' => 'What\'s your favorite programming language?', 'options' => ['PHP', 'JavaScript', 'Python', 'Java'], 'selectableCount' => 1 // 1 for single choice, >1 for multiple ]; $response = $waha->misc()->sendPollWithOptions( chatId: '1234567890@c.us', poll: $pollData, session: 'default', replyTo: null ); // Check message delivery status if ($response->successful()) { $messageData = $response->json(); echo "Message sent successfully!\n"; echo "Message ID: {$messageData['id']}\n"; echo "Timestamp: {$messageData['timestamp']}\n"; } else { echo "Failed to send message: {$response->status()}\n"; echo "Error: {$response->body()}\n"; }
Working with Chats
Chats represent conversations with individuals or groups. Here's how to manage them:
// Get overview of all chats (includes last message, unread count, etc.) $response = $waha->overview()->getChatsOverviewIncludesAllNecessaryThingsToBuildUiYourChatsOverviewPageChatIdNamePictureLastMessageSortingByLastMessageTimestamp( session: 'default', limit: null, offset: null, ids: null ); $chats = $response->json(); foreach ($chats as $chat) { echo "Chat: {$chat['id']}\n"; echo "Name: {$chat['name']}\n"; echo "Last Message: {$chat['lastMessage']['body']}\n"; echo "Unread Count: {$chat['unreadCount']}\n"; echo "---\n"; } // Get basic chat list $response = $waha->misc()->getChats( session: 'default', sortBy: 'lastMessageTimestamp', sortOrder: 'desc', limit: '50', offset: '0' ); $chatList = $response->json(); // Get messages from a specific chat with pagination $response = $waha->chats()->getsMessagesInTheChat( session: 'default', chatId: '1234567890@c.us', downloadMedia: 'true', limit: '50', offset: null, filterTimestampLte: null, filterTimestampGte: null, filterFromMe: null, filterAck: null ); $messages = $response->json(); foreach ($messages as $message) { echo "From: {$message['from']}\n"; echo "Text: {$message['body']}\n"; echo "Time: {$message['timestamp']}\n"; echo "Type: {$message['type']}\n"; // text, image, video, etc. echo "---\n"; } // Mark chat as read $response = $waha->chats()->readUnreadMessagesInTheChat( session: 'default', chatId: '1234567890@c.us', messages: null, days: null ); // Delete a specific message $response = $waha->messages()->deletesMessageFromTheChat( session: 'default', chatId: '1234567890@c.us', messageId: 'message_id_here' ); // Clear all messages in a chat $response = $waha->chats()->clearsAllMessagesFromTheChat( session: 'default', chatId: '1234567890@c.us' ); // Archive/unarchive a chat $response = $waha->api()->archiveTheChat( session: 'default', chatId: '1234567890@c.us' ); $response = $waha->api()->unarchiveTheChat( session: 'default', chatId: '1234567890@c.us' );
Working with Contacts
Manage your WhatsApp contacts and verify phone numbers:
// Get all contacts from the session $response = $waha->contacts()->getAllContacts('default'); $contacts = $response->json(); foreach ($contacts as $contact) { echo "Name: {$contact['name']}\n"; echo "Number: {$contact['id']}\n"; echo "Is Business: " . ($contact['isBusiness'] ? 'Yes' : 'No') . "\n"; echo "---\n"; } // Get detailed information about a specific contact $response = $waha->contacts()->getContactBasicInfo( session: 'default', contactId: '1234567890@c.us' ); $contact = $response->json(); echo "Contact Name: {$contact['name']}\n"; echo "Push Name: {$contact['pushname']}\n"; // Get contact's about info $response = $waha->contacts()->getsTheContactAboutInfo( session: 'default', contactId: '1234567890@c.us' ); $about = $response->json(); // Check if a phone number exists on WhatsApp $response = $waha->contacts()->checkPhoneNumberIsRegisteredInWhatsApp( session: 'default', phone: '1234567890' ); $result = $response->json(); if ($result['numberExists']) { echo "Number exists on WhatsApp\n"; echo "WhatsApp ID: {$result['numberExists']}\n"; } else { echo "Number does not exist on WhatsApp\n"; } // You can also use misc resource to check number status $response = $waha->misc()->checkNumberStatus( phone: '1234567890', session: 'default' ); // Get contact's profile picture $response = $waha->contacts()->getContactProfilePictureUrl( session: 'default', contactId: '1234567890@c.us' ); $profilePic = $response->json(); // Block a contact $response = $waha->contacts()->blockContact( session: 'default', contactId: '1234567890@c.us' ); // Unblock a contact $response = $waha->contacts()->unblockContact( session: 'default', contactId: '1234567890@c.us' );
Working with Groups
Manage WhatsApp groups and their participants:
// Get all groups you're part of $response = $waha->misc()->getAllGroups( session: 'default', sortBy: null, sortOrder: null, limit: null, offset: null, exclude: null ); $groups = $response->json(); foreach ($groups as $group) { echo "Group: {$group['name']}\n"; echo "ID: {$group['id']}\n"; echo "Participants: " . count($group['participants']) . "\n"; echo "Description: {$group['description']}\n"; echo "---\n"; } // Create a new group $response = $waha->misc()->createNewGroup( session: 'default', name: 'Laravel Developers', participants: ['1234567890@c.us', '0987654321@c.us'] ); if ($response->successful()) { $group = $response->json(); echo "Group created: {$group['id']}\n"; } // Get detailed group information $response = $waha->groups()->getTheGroup( session: 'default', groupId: 'group_id@g.us' ); $groupDetails = $response->json(); // Add participants to a group (admin only) $response = $waha->participants()->addParticipants( session: 'default', groupId: 'group_id@g.us', participants: ['1234567890@c.us', '5555555555@c.us'] ); // Remove participants from a group (admin only) $response = $waha->participants()->removeParticipants( session: 'default', groupId: 'group_id@g.us', participants: ['1234567890@c.us'] ); // Promote participants to admin $response = $waha->admin()->promoteParticipantsToAdminUsers( session: 'default', groupId: 'group_id@g.us', participants: ['1234567890@c.us'] ); // Demote admins to regular participants $response = $waha->admin()->demotesParticipantsToRegularUsers( session: 'default', groupId: 'group_id@g.us', participants: ['1234567890@c.us'] ); // Update group settings $response = $waha->groups()->updatesTheGroupSubject( session: 'default', groupId: 'group_id@g.us', subject: 'New Group Name' ); $response = $waha->groups()->updatesTheGroupDescription( session: 'default', groupId: 'group_id@g.us', description: 'This is our updated group description' ); // Leave a group $response = $waha->groups()->leaveTheGroup( session: 'default', groupId: 'group_id@g.us' ); // Get group invitation link (admin only) $response = $waha->inviteCode()->getsTheInviteCodeForTheGroup( session: 'default', groupId: 'group_id@g.us' ); $inviteCode = $response->json(); echo "Invite link: https://chat.whatsapp.com/{$inviteCode['code']}\n"; // Revoke group invitation link (admin only) $response = $waha->inviteCode()->invalidatesTheCurrentGroupInviteCodeAndGeneratesNewOne( session: 'default', groupId: 'group_id@g.us' );
Advanced Message Operations
// React to a message with emoji $response = $waha->misc()->reactToMessageWithEmoji( messageId: 'message_id_here', reaction: '๐', session: 'default' ); // Forward a message $response = $waha->misc()->chattingControllerForwardMessage( chatId: '1234567890@c.us', messageId: 'message_id_to_forward', session: 'default' ); // Send contact vCard $contacts = [ [ 'id' => '1234567890@c.us', 'name' => 'John Doe' ] ]; $response = $waha->misc()->chattingControllerSendContactVcard( chatId: '1234567890@c.us', contacts: $contacts, session: 'default', replyTo: null ); // Set typing indicator $response = $waha->misc()->chattingControllerStartTyping( chatId: '1234567890@c.us', session: 'default' ); // Stop typing indicator $response = $waha->misc()->chattingControllerStopTyping( chatId: '1234567890@c.us', session: 'default' ); // Mark messages as seen $response = $waha->misc()->chattingControllerSendSeen( chatId: '1234567890@c.us', session: 'default', messageId: 'message_id_here', messageIds: null, participant: null ); // Send interactive buttons message $response = $waha->misc()->sendButtonsInteractiveMessage( chatId: '1234567890@c.us', header: 'Choose an option', body: 'Please select one of the following:', footer: 'Powered by WAHA', buttons: [ ['id' => 'btn1', 'title' => 'Option 1'], ['id' => 'btn2', 'title' => 'Option 2'] ], session: 'default', headerImage: null );
Advanced Features
// Take a screenshot of the WhatsApp web interface $response = $waha->misc()->screenshotControllerScreenshot('default'); $screenshot = $response->json(); echo "Screenshot saved\n"; // Set presence status (online, offline, typing, recording) $response = $waha->misc()->setSessionPresence( session: 'default', chatId: '1234567890@c.us', presence: 'typing' // online, offline, typing, recording ); // Get presence status of a contact $response = $waha->presence()->getThePresenceForTheChatIdIfItHasntBeenSubscribedItAlsoSubscribesToIt( session: 'default', chatId: '1234567890@c.us' ); $presence = $response->json(); // Subscribe to presence events $response = $waha->presence()->subscribeToPresenceEventsForTheChat( session: 'default', chatId: '1234567890@c.us' ); // Health check $response = $waha->misc()->checkTheHealthOfTheServer(); $health = $response->json(); echo "Service status: healthy\n"; // Ping the server $response = $waha->misc()->pingTheServer(); echo "Server is responding\n"; // Get WAHA version $response = $waha->misc()->getTheServerVersion(); $version = $response->json(); echo "WAHA Version: {$version['version']}\n"; // Get server environment $response = $waha->server()->getTheServerEnvironment(); $env = $response->json(); echo "Environment: {$env['env']}\n"; // Get server status $response = $waha->server()->getTheServerStatus(); $status = $response->json();
Error Handling and Best Practices
use CCK\LaravelWahaSaloonSdk\Waha\Waha; use Saloon\Exceptions\Request\RequestException; try { $waha = new Waha(); // Always check session status before sending messages $sessionResponse = $waha->sessions()->getSessionInformation('default'); $sessionData = $sessionResponse->json(); if ($sessionData['status'] !== 'WORKING') { throw new Exception("Session not ready. Status: {$sessionData['status']}"); } // Send message with error handling $response = $waha->sendText()->sendTextMessage( chatId: '1234567890@c.us', text: 'Hello from Laravel!', session: 'default', replyTo: null, linkPreview: null, linkPreviewHighQuality: null ); if (!$response->successful()) { throw new Exception("Failed to send message: {$response->body()}"); } $messageData = $response->json(); echo "Message sent successfully! ID: {$messageData['id']}\n"; } catch (RequestException $e) { // Handle HTTP request errors echo "Request failed: {$e->getMessage()}\n"; echo "Response: {$e->getResponse()->body()}\n"; } catch (Exception $e) { // Handle other errors echo "Error: {$e->getMessage()}\n"; }
Available Resources
The SDK provides access to all WAHA API endpoints through these resources:
- Admin (
$waha->admin()) - Admin operations (promote/demote participants) - Api (
$waha->api()) - Basic API operations (archive/unarchive chats) - Auth (
$waha->auth()) - Authentication and QR codes - Channels (
$waha->channels()) - Channel management - Chats (
$waha->chats()) - Limited chat operations (get messages, clear, mark read) - Contacts (
$waha->contacts()) - Contact management - Groups (
$waha->groups()) - Group information and settings - InfoAdminOnly (
$waha->infoAdminOnly()) - Admin-only group settings - InviteCode (
$waha->inviteCode()) - Group invitation codes - Labels (
$waha->labels()) - Label management - Lids (
$waha->lids()) - LID (LinkedIn ID) management - Messages (
$waha->messages()) - Message operations (delete, edit, pin) - MessagesAdminOnly (
$waha->messagesAdminOnly()) - Admin-only message settings - Misc (
$waha->misc()) - Main resource with most functionality (send files, media, groups, sessions, health checks, etc.) - Overview (
$waha->overview()) - Chat overview and summaries - Participants (
$waha->participants()) - Group participant management - Picture (
$waha->picture()) - Profile and group picture management - Presence (
$waha->presence()) - Online/offline status - Profile (
$waha->profile()) - Profile management - Search (
$waha->search()) - Channel search functionality - Send (
$waha->sending()) - Advanced sending (link previews, button replies) - SendText (
$waha->sendText()) - Text message sending - Server (
$waha->server()) - Server information and control - Sessions (
$waha->sessions()) - Session management - Status (
$waha->status()) - WhatsApp status updates
Note: Most of the core functionality (sending media, files, managing groups, health checks, etc.) is in the misc() resource.
Understanding WhatsApp IDs and Important Notes
WhatsApp uses specific ID formats:
- Individual chats:
1234567890@c.us(phone number + @c.us) - Group chats:
1234567890-1234567890@g.us(group ID + @g.us) - Channels:
1234567890@newsletter(channel ID + @newsletter)
Phone numbers should include country code without '+' symbol.
SDK Structure Notes
Important: This SDK is auto-generated from a Postman collection, which results in some unique characteristics:
-
Very descriptive method names: Methods have extremely long, descriptive names that match the API functionality exactly (e.g.,
getChatsOverviewIncludesAllNecessaryThingsToBuildUiYourChatsOverviewPageChatIdNamePictureLastMessageSortingByLastMessageTimestamp) -
Most functionality is in
misc()resource: Unlike typical SDKs where functionality is spread across logical resources, most operations (sending files, media, groups, health checks) are located in themisc()resource. -
Parameter order: Pay close attention to parameter order in method calls, as it may not always be intuitive.
-
Auto-generated code: The SDK is regenerated from the Postman collection, so method signatures are exactly as defined in the WAHA API.
For the most up-to-date method signatures and parameters, always refer to the actual class files in src/Waha/Resource/ or use your IDE's autocomplete functionality.
Upgrading
From v0.0.x to v0.1.0
Step 1: Update the package
composer update chengkangzai/laravel-waha-saloon-sdk
Step 2: Publish the new config (optional but recommended)
php artisan vendor:publish --tag="waha-saloon-sdk-config" --force
Step 3: Clear config cache
php artisan config:clear
No code changes required - your existing code will continue to work without modifications.
Optional: You can migrate to the new Waha facade for cleaner syntax:
// Before (still works) $waha = new \CCK\LaravelWahaSaloonSdk\Waha\Waha(); $waha->sessions()->listAllSessions(); // After (new option) use CCK\LaravelWahaSaloonSdk\Facades\Waha; Waha::sessions()->listAllSessions();
Note: The
LaravelWahaSaloonSdkfacade is deprecated in favor of the newWahafacade.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Development
Regenerating the SDK
The SDK is auto-generated from the WAHA Postman collection. To regenerate:
composer build-from-postman
Code Quality
# Format code composer format # Run static analysis composer analyse
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.