dzly / dzly-api
Laravel package for Dzly API integration - Contacts, Contact Groups, and Messaging
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/dzly/dzly-api
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-12-15 14:29:12 UTC
README
A modern, type-safe PHP SDK for the Dzly WhatsApp Business API. Build powerful messaging integrations with clean, expressive syntax.
โจ Features
| Feature | Description |
|---|---|
| Contacts | Create and manage your contact database |
| Contact Groups | Organize contacts into groups |
| Messaging | Send text and media messages |
| Templates | Use pre-approved WhatsApp templates |
| Canned Replies | Automate responses with triggers |
| Type Safety | Full DTO support for all operations |
| Error Handling | Structured ApiResponse for all requests |
| Laravel Ready | Service provider, facade, and config included |
๐ Requirements
- PHP 8.1+
- Laravel 10.x / 11.x (optional)
- Guzzle HTTP 7.x
๐ฆ Installation
composer require dzly/dzly-api
Laravel Setup
Publish the configuration:
php artisan vendor:publish --tag=dzly-config
Add credentials to .env:
DZLY_BASE_URL=https://app.dzly.ai DZLY_API_TOKEN=your-bearer-token
๐ Quick Start
Standalone PHP
use Dzly\Dzly; $dzly = new Dzly('https://app.dzly.ai', 'your-token'); // List contacts $response = $dzly->contacts()->list(); if ($response->successful()) { foreach ($response->data() as $contact) { echo $contact['full_name'] . "\n"; } } // Send a message $response = $dzly->messages()->send([ 'phone' => '+1234567890', 'message' => 'Hello from Dzly!', ]);
Laravel Facade
use Dzly\Facades\Dzly; $response = Dzly::contacts()->list();
Dependency Injection
use Dzly\Dzly; class ContactController { public function __construct(private Dzly $dzly) {} public function index() { return $this->dzly->contacts()->list()->data(); } }
๐ API Reference
ApiResponse
All API calls return an ApiResponse object with consistent methods:
$response = $dzly->contacts()->list(); // Status $response->successful(); // true if 2xx $response->failed(); // true if error $response->statusCode(); // HTTP status code $response->message(); // Response message // Data Access $response->data(); // Array of items $response->id(); // Resource ID (for create/update) $response->get('key'); // Get specific field $response->toArray(); // Raw response array // Pagination $response->total(); // Total items $response->currentPage(); // Current page number $response->lastPage(); // Last page number $response->perPage(); // Items per page $response->hasMorePages(); // Has more pages? $response->nextPageUrl(); // Next page URL $response->previousPageUrl(); // Previous page URL // Collection $response->isEmpty(); // No data? $response->isNotEmpty(); // Has data? $response->count(); // Number of items // Errors $response->hasErrors(); // Has validation errors? $response->errors(); // All errors array $response->getFieldErrors('phone'); // Errors for specific field $response->getFirstError('phone'); // First error for field
๐ฅ Contacts
List Contacts
$response = $dzly->contacts()->list(); // With pagination $response = $dzly->contacts()->list([ 'page' => 1, 'per_page' => 25, ]); foreach ($response->data() as $contact) { echo $contact['first_name'] . ' ' . $contact['last_name']; }
Create Contact
// Using array $response = $dzly->contacts()->create([ 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john@example.com', 'phone' => '+1234567890', ]); if ($response->successful()) { echo "Created contact: " . $response->id(); } // Using DTO use Dzly\DataTransferObjects\ContactData; $response = $dzly->contacts()->create(new ContactData( firstName: 'John', lastName: 'Doe', email: 'john@example.com', phone: '+1234567890', ));
Delete Contact
$response = $dzly->contacts()->delete('contact-uuid'); if ($response->successful()) { echo $response->message(); // "Contact deleted successfully" }
๐ Contact Groups
List Groups
$response = $dzly->contactGroups()->list();
Create Group
// Using array $response = $dzly->contactGroups()->create([ 'name' => 'VIP Customers', ]); // Using DTO use Dzly\DataTransferObjects\ContactGroupData; $response = $dzly->contactGroups()->create(new ContactGroupData( name: 'VIP Customers', ));
Update Group
$response = $dzly->contactGroups()->update('group-uuid', [ 'name' => 'Premium Customers', ]);
Delete Group
$response = $dzly->contactGroups()->delete('group-uuid');
๐ฌ Messages
Send Text Message
// Using array $response = $dzly->messages()->send([ 'phone' => '+1234567890', 'message' => 'Hello, how are you?', ]); // Using DTO use Dzly\DataTransferObjects\MessageData; $response = $dzly->messages()->send(new MessageData( phone: '+1234567890', message: 'Hello, how are you?', ));
Send Media Message
// Using array $response = $dzly->messages()->sendMedia([ 'phone' => '+1234567890', 'media_type' => 'image', 'media_url' => 'https://example.com/photo.jpg', 'caption' => 'Check this out!', 'file_name' => 'photo.jpg', ]); // Using DTO use Dzly\DataTransferObjects\MediaMessageData; $response = $dzly->messages()->sendMedia(new MediaMessageData( phone: '+1234567890', mediaType: 'image', mediaUrl: 'https://example.com/photo.jpg', caption: 'Check this out!', fileName: 'photo.jpg', ));
Media Helper Methods
// Image $dzly->messages()->sendImage('+1234567890', 'https://example.com/photo.jpg', 'Caption'); // Video $dzly->messages()->sendVideo('+1234567890', 'https://example.com/video.mp4', 'Caption'); // Document $dzly->messages()->sendDocument('+1234567890', 'https://example.com/doc.pdf', 'Invoice', 'invoice.pdf'); // Audio $dzly->messages()->sendAudio('+1234567890', 'https://example.com/audio.mp3', 'audio.mp3');
Send Template Message
// Simple template $dzly->messages()->sendTemplateByName( phone: '+1234567890', templateName: 'welcome_message', languageCode: 'en', ); // With components $components = [ [ 'type' => 'body', 'parameters' => [ ['type' => 'text', 'text' => 'John Doe'], ], ], ]; $dzly->messages()->sendTemplateByName( phone: '+1234567890', templateName: 'order_confirmation', languageCode: 'en', components: $components, );
๐ Templates
List Templates
$response = $dzly->templates()->list(); foreach ($response->data() as $template) { echo $template['name'] . ' - ' . $template['status']; }
๐ค Canned Replies
List Canned Replies
$response = $dzly->cannedReplies()->list();
Create Canned Reply
// Using array $response = $dzly->cannedReplies()->create([ 'name' => 'About Us', 'trigger' => 'what do you do?', 'match_criteria' => 'contains', 'response_type' => 'text', 'response' => 'We sell shoes and clothes', ]); // Using DTO use Dzly\DataTransferObjects\CannedReplyData; $response = $dzly->cannedReplies()->create(new CannedReplyData( name: 'About Us', trigger: 'what do you do?', matchCriteria: 'contains', responseType: 'text', response: 'We sell shoes and clothes', ));
Update Canned Reply
$response = $dzly->cannedReplies()->update('reply-uuid', [ 'response' => 'Updated response text', ]);
Delete Canned Reply
$response = $dzly->cannedReplies()->delete('reply-uuid');
โ ๏ธ Error Handling
The SDK returns ApiResponse for all requests, including errors:
$response = $dzly->contacts()->create([ 'phone' => 'invalid-phone', ]); if ($response->failed()) { echo "Error: " . $response->message(); echo "Status: " . $response->statusCode(); // Validation errors if ($response->hasErrors()) { foreach ($response->errors() as $field => $messages) { echo "$field: " . implode(', ', $messages); } } // Get specific field error $phoneError = $response->getFirstError('phone'); }
Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Validation Error |
| 401 | Authentication Error |
| 404 | Not Found |
| 500 | Server Error |
๐งช Testing
Run the test suite:
composer test
Or directly with PHPUnit:
./vendor/bin/phpunit
Mocking in Tests
use Dzly\Contracts\HttpClientInterface; use Dzly\Http\ApiResponse; use Dzly\Dzly; use Mockery; $mockClient = Mockery::mock(HttpClientInterface::class); $mockClient->shouldReceive('get') ->with('/api/contacts', []) ->andReturn(ApiResponse::success([ 'data' => [['id' => 1, 'first_name' => 'John']], 'meta' => ['total' => 1], ])); $dzly = Dzly::withClient($mockClient); $response = $dzly->contacts()->list();
๐ License
The MIT License (MIT). See LICENSE for details.
Made with โค๏ธ by Dzly