dzly/dzly-api
Composer 安装命令:
composer require dzly/dzly-api
包简介
Laravel package for Dzly API integration - Contacts, Contact Groups, and Messaging
README 文档
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
dzly/dzly-api 适用场景与选型建议
dzly/dzly-api 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 27 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 12 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「api」 「messaging」 「laravel」 「contacts」 「whatsapp」 「dzly」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 dzly/dzly-api 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 dzly/dzly-api 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 dzly/dzly-api 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A PSR-7 compatible library for making CRUD API endpoints
PHP SDK for Mobile Message SMS API
Azure service bus Transport
Official PHP client for NATS messaging system
Alfabank REST API integration
Laravel / Lumen package for Firebase Cloud Messaging
统计信息
- 总下载量: 27
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 14
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-15