From 36cd544a6693f85ae7fe2a4cc29dfbef2480ea7f Mon Sep 17 00:00:00 2001 From: Mohammed Elhaouari Date: Sun, 22 Feb 2026 17:57:53 +0100 Subject: [PATCH 1/2] Add laravel service provider --- README.md | 44 +++++++++++++++++++++++++++++ composer.json | 10 ++++++- phpstan.neon | 1 + phpunit.xml | 3 ++ src/Api/Dto/Contact.php | 18 ++++++------ src/Laravel/WatiServiceProvider.php | 24 ++++++++++++++++ src/helpers.php | 2 +- tests/helpersTest.php | 32 ++++++++++----------- 8 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 src/Laravel/WatiServiceProvider.php diff --git a/README.md b/README.md index adb9564..e1a5c69 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,50 @@ try { } ``` +## Usage with Laravel + +The SDK includes a Laravel service provider for easy integration. + +### Configuration + +Add the following to your `config/services.php`: + +```php +'wati' => [ + 'endpoint' => env('WATI_ENDPOINT'), + 'token' => env('WATI_TOKEN'), +], +``` + +Add to your `.env` file: + +```env +WATI_ENDPOINT=https://your-instance.wati.io/123456 +WATI_TOKEN=your-bearer-token +``` + +### Usage + +The service provider is auto-discovered. Simply inject or resolve `WatiClient`: + +```php +use Wati\Http\WatiClient; +use Wati\Api\GetContacts; + +class ContactController +{ + public function __construct( + private readonly WatiClient $wati + ) {} + + public function index() + { + $response = $this->wati->send(new GetContacts()); + return json_decode($response->getBody()->getContents(), true); + } +} +``` + ## API Reference For full API documentation, visit [Wati API Docs](https://docs.wati.io/reference/introduction). diff --git a/composer.json b/composer.json index 5afe3a9..cd45a80 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "require": { "php": "^8.3 || ^8.4", "ext-json": "*", - "phpjuice/wati-http-client": "^1.0" + "phpjuice/wati-http-client": "^1.0", + "illuminate/support": "^10.0|^11.0|^12.0" }, "require-dev": { "laravel/pint": "^1.27", @@ -74,5 +75,12 @@ "allow-plugins": { "pestphp/pest-plugin": true } + }, + "extra": { + "laravel": { + "providers": [ + "Wati\\Laravel\\WatiServiceProvider" + ] + } } } diff --git a/phpstan.neon b/phpstan.neon index 12fd0aa..96296b7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,3 +5,4 @@ parameters: - tests excludePaths: - tests/*/data/* + - src/Laravel diff --git a/phpunit.xml b/phpunit.xml index 1ec04a3..6dd4f98 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -14,5 +14,8 @@ src + + src/Laravel + diff --git a/src/Api/Dto/Contact.php b/src/Api/Dto/Contact.php index 204920f..d8130d2 100644 --- a/src/Api/Dto/Contact.php +++ b/src/Api/Dto/Contact.php @@ -24,15 +24,15 @@ public function __construct( public static function fromArray(array $data): self { return new self( - id: data_get($data, 'id', ''), - phone: data_get($data, 'phone', ''), - fullName: data_get($data, 'fullName', ''), - wAid: is_string($v = data_get($data, 'wAid')) ? $v : null, - firstName: is_string($v = data_get($data, 'firstName')) ? $v : null, - email: is_string($v = data_get($data, 'email')) ? $v : null, - contactStatus: is_string($v = data_get($data, 'contactStatus')) ? $v : null, - created: is_string($v = data_get($data, 'created')) ? $v : null, - lastUpdated: is_string($v = data_get($data, 'lastUpdated')) ? $v : null, + id: data_get_str($data, 'id', ''), + phone: data_get_str($data, 'phone', ''), + fullName: data_get_str($data, 'fullName', ''), + wAid: is_string($v = data_get_str($data, 'wAid')) ? $v : null, + firstName: is_string($v = data_get_str($data, 'firstName')) ? $v : null, + email: is_string($v = data_get_str($data, 'email')) ? $v : null, + contactStatus: is_string($v = data_get_str($data, 'contactStatus')) ? $v : null, + created: is_string($v = data_get_str($data, 'created')) ? $v : null, + lastUpdated: is_string($v = data_get_str($data, 'lastUpdated')) ? $v : null, ); } } diff --git a/src/Laravel/WatiServiceProvider.php b/src/Laravel/WatiServiceProvider.php new file mode 100644 index 0000000..7285219 --- /dev/null +++ b/src/Laravel/WatiServiceProvider.php @@ -0,0 +1,24 @@ +app->singleton(WatiClient::class, fn (): WatiClient => new WatiClient( + new WatiEnvironment( + endpoint: config('services.wati.endpoint'), + bearerToken: config('services.wati.token'), + ) + )); + } +} diff --git a/src/helpers.php b/src/helpers.php index 985fef4..2fa18ec 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -9,7 +9,7 @@ * @param TDefault $default * @return string|TDefault */ -function data_get(array $data, string $key, mixed $default = null): mixed +function data_get_str(array $data, string $key, mixed $default = null): mixed { if (! array_key_exists($key, $data)) { return $default; diff --git a/tests/helpersTest.php b/tests/helpersTest.php index b03a4ca..4ee96c6 100644 --- a/tests/helpersTest.php +++ b/tests/helpersTest.php @@ -5,42 +5,42 @@ it('returns value when key exists', function (): void { $data = ['name' => 'John', 'email' => 'john@example.com']; - expect(data_get($data, 'name'))->toBe('John') - ->and(data_get($data, 'email'))->toBe('john@example.com'); + expect(data_get_str($data, 'name'))->toBe('John') + ->and(data_get_str($data, 'email'))->toBe('john@example.com'); }); it('returns default when key does not exist', function (): void { $data = ['name' => 'John']; - expect(data_get($data, 'email'))->toBeNull() - ->and(data_get($data, 'email', 'default'))->toBe('default'); + expect(data_get_str($data, 'email'))->toBeNull() + ->and(data_get_str($data, 'email', 'default'))->toBe('default'); }); it('returns default when value is null', function (): void { $data = ['name' => null]; - expect(data_get($data, 'name'))->toBeNull() - ->and(data_get($data, 'name', 'default'))->toBe('default'); + expect(data_get_str($data, 'name'))->toBeNull() + ->and(data_get_str($data, 'name', 'default'))->toBe('default'); }); it('returns default when value is empty string', function (): void { $data = ['name' => '']; - expect(data_get($data, 'name'))->toBeNull() - ->and(data_get($data, 'name', 'default'))->toBe('default'); + expect(data_get_str($data, 'name'))->toBeNull() + ->and(data_get_str($data, 'name', 'default'))->toBe('default'); }); it('trims string values', function (): void { $data = ['name' => ' John ']; - expect(data_get($data, 'name'))->toBe('John'); + expect(data_get_str($data, 'name'))->toBe('John'); }); it('returns default when trimmed value is empty', function (): void { $data = ['name' => ' ']; - expect(data_get($data, 'name'))->toBeNull() - ->and(data_get($data, 'name', 'default'))->toBe('default'); + expect(data_get_str($data, 'name'))->toBeNull() + ->and(data_get_str($data, 'name', 'default'))->toBe('default'); }); it('returns non-string values as-is', function (): void { @@ -51,14 +51,14 @@ 'price' => 19.99, ]; - expect(data_get($data, 'count'))->toBe(42) - ->and(data_get($data, 'active'))->toBeTrue() - ->and(data_get($data, 'items'))->toBe(['a', 'b']) - ->and(data_get($data, 'price'))->toBe(19.99); + expect(data_get_str($data, 'count'))->toBe(42) + ->and(data_get_str($data, 'active'))->toBeTrue() + ->and(data_get_str($data, 'items'))->toBe(['a', 'b']) + ->and(data_get_str($data, 'price'))->toBe(19.99); }); it('returns default for missing nested keys', function (): void { $data = ['user' => ['name' => 'John']]; - expect(data_get($data, 'email', 'missing'))->toBe('missing'); + expect(data_get_str($data, 'email', 'missing'))->toBe('missing'); }); From 3c84f7b715c699ebc31f5b2e877df47de90d7aa1 Mon Sep 17 00:00:00 2001 From: Mohammed Elhaouari Date: Sun, 22 Feb 2026 18:03:25 +0100 Subject: [PATCH 2/2] Update changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 12bbb27..39cffa2 100644 --- a/changelog.md +++ b/changelog.md @@ -8,3 +8,4 @@ All notable changes to `phpjuice/wati-sdk` will be documented in this file. - Pre-built API classes for Wati API: - `Wati\Api\GetContacts` - Get paginated list of contacts - PHP 8.3+ support +- Add Laravel service provider