diff --git a/README.md b/README.md
index adba3c3..028ec06 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,300 @@
-### WIP
-This package is __WIP__, please do not use it in a production project yet.
+# Laravel Sendy is a simple and clean wrapper for the Sendy API
+
+[](https://packagist.org/packages/coderflexx/laravel-sendy)
+[](https://github.com/coderflexx/laravel-sendy/actions?query=workflow%3Arun-tests+branch%3Amain)
+[](https://github.com/coderflexx/laravel-sendy/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
+[](https://packagist.org/packages/coderflexx/laravel-sendy)
+
+---
+
+Laravel Sendy is a simple and clean wrapper for the Sendy API, making it easy to manage subscribers, lists, and campaigns directly from your Laravel application.
+
+
+## Installation
+
+You can install the package via composer:
+
+```bash
+composer require coderflexx/laravel-sendy
+```
+
+You can publish the config file with:
+
+```bash
+php artisan vendor:publish --tag="laravel-sendy"
+```
+
+This is the contents of the published config file:
+
+```php
+return [
+ /*
+ |--------------------------------------------------------------------------
+ | Sendy Installation URL
+ |--------------------------------------------------------------------------
+ |
+ | This URL is used to connect to your Sendy installation. It should
+ | point to the root of your Sendy installation. For example:
+ | https://your-sendy-installation.com
+ */
+ 'sendy_installation_url' => env('SENDY_INSTALLATION_URL', 'https://your-sendy-installation.com'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Sendy API Key
+ |--------------------------------------------------------------------------
+ |
+ | This key is used to authenticate your application with the Sendy
+ | installation. You can find your API key in the Sendy settings.
+ | Make sure to keep this key secure and do not share it with anyone.
+ | It is recommended to use environment variables to store sensitive
+ | information like API keys. You can set the SENDY_API_KEY
+ */
+ 'sendy_api_key' => env('SENDY_API_KEY', 'your-sendy-api-key'),
+];
+```
+
+## API Keys
+After Installation, you can grab your `API KEYS` from the sendy app installation, then add them in `.env` file
+
+```env
+SENDY_INSTALLATION_URL=https://your-app-installation.com/
+SENDY_API_KEY=your-api-key
+```
+
+## Sendy Version
+This package is compatible with __Sendy v6.1.2__ (Latest)
+
+## Usage
+
+In order to use the package, you can use the facade directly, followed by the main method api (e.g. `subscribers()` then the verb (action))
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$sendy = Sendy::{$service()}->{$action()}
+```
+
+### Async Argument for HTTP Requests
+
+All HTTP requests support an `async` option, allowing you to __defer execution__. This is useful when a request doesn't need to run immediately or isn't a high priority. You can handle it later using await when you're ready to process the result.
+
+Example:
+
+```php
+$promise = Sendy::subscribers()->subscribe(
+ data: $data,
+ async: true // The request is deferred and returns a promise
+);
+
+// perform other tasks/operation here
+
+// later, wait for the response when you're ready.
+$response = $promise->await();
+```
+
+### Subscribers
+In order to create a create/delete a subscriber, you have to access the subscribers service first, then to the action
+
+#### Subscribe a User
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'name' => 'John Doe',
+ 'email' => 'john@example.com',
+ 'list' => '123',
+ 'country' => 'US',
+];
+
+$response = Sendy::subscribers()->subscribe(
+ data: $data,
+ async: false
+ );
+```
+
+Full Documentation [Here](https://sendy.co/api#subscribe)
+
+#### Unsubscribe a User
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'email' => 'john@example.com',
+ 'list' => '123',
+ 'boolean' => true, // to get plan text response, instead of json.
+];
+
+$response = Sendy::subscribers()->unsubscribe(
+ data: $data,
+ async: false
+ );
+
+```
+Full Documentation [Here](https://sendy.co/api#unsubscribe)
+
+#### Delete Subscriber
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'email' => 'john@example.com',
+ 'list_id' => '123',
+];
+
+$response = Sendy::subscribers()->delete(
+ data: $data,
+ async: false
+ );
+
+```
+
+Full Documentation [Here](https://sendy.co/api#delete-subscriber)
+
+#### Subscriber Status
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'email' => 'john@example.com',
+ 'list_id' => '123',
+];
+
+$response = Sendy::subscribers()->status(
+ data: $data,
+ async: false
+ );
+
+```
+
+Full Documentation [Here](https://sendy.co/api#subscription-status)
+
+#### Subscribers Count
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'email' => 'john@example.com',
+ 'list_id' => '123',
+];
+
+$response = Sendy::subscribers()->count(
+ listId: '123',
+ async: false
+ );
+
+```
+
+Full Documentation [Here](https://sendy.co/api#active-subscriber-count)
+
+### Lists
+
+Same thing as the __subscribers__ service, you can access the `lists()` service, then the http action you want.
+
+#### Get Lists
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'brand_id' => '123',
+ 'include_hidden' => 'yes', // either yes or no.
+];
+
+$response = Sendy::lists()->get(
+ data: $data,
+ async: false
+ );
+
+```
+Full Documentation [Here](https://sendy.co/api#get-lists)
+
+### Brands
+
+__Laravel Sendy__ allows you to retrieve all the brand list you have by
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$response = Sendy::brands()->get();
+
+```
+
+Full Documentation [Here](https://sendy.co/api#get-brands)
+
+### Create & Send Compaigns
+
+```php
+use Coderflex\LaravelSendy\Facades\Sendy;
+
+$data = [
+ 'subject' => 'Test Subject',
+ 'from_name' => 'John Doe',
+ 'from_email' => 'john@example.com',
+ 'reply_to' => 'alex@example.com',
+ 'title' => 'Test Title',
+ 'plain_text' => 'This is a plain text version of the email.',
+ 'html_text' => '
This is a HTML version of the email.
',
+ 'list_ids' => 'abc123',
+ 'segment_ids' => 'xyz456',
+ 'exclude_list_ids' => null,
+ 'exclude_segment_ids' => null,
+ 'brand_id' => '123',
+ 'query_string' => null,
+ 'track_opens' => 1,
+ 'track_clicks' => 1,
+ 'send_campaign' => 1, // if set to 1 the compaign will be created & sent.
+ 'schedule_date_time' => null,
+ 'schedule_timezone' => null,
+];
+
+$response = Sendy::compaigns()->create(
+ data: $data,
+ async: false
+ );
+
+```
+
+If you want to create and send the compaign at the same time, use `createAndSend` method
+
+```php
+
+$response = Sendy::compaigns()->createAndSend(
+ data: $data,
+ async: false
+ );
+```
+
+Full Documentation [Here](https://sendy.co/api#create-send-campaigns)
+
+## Testing
+
+```bash
+composer test
+```
+
+## Changelog
+
+Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
+
+## Contributing
+
+Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
+
+## Security Vulnerabilities
+
+Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
+
+## Credits
+
+- [Oussama Sid](https://github.com/ousid)
+- [All Contributors](../../contributors)
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
diff --git a/src/Facades/LaravelSendy.php b/src/Facades/Sendy.php
similarity index 76%
rename from src/Facades/LaravelSendy.php
rename to src/Facades/Sendy.php
index f98ecbc..2adc9fa 100644
--- a/src/Facades/LaravelSendy.php
+++ b/src/Facades/Sendy.php
@@ -5,17 +5,17 @@
use Illuminate\Support\Facades\Facade;
/**
- * @see \Coderflex\LaravelSendy\LaravelSendy
+ * @see \Coderflex\LaravelSendy\Sendy
*
* @method static \Coderflex\LaravelSendy\Resources\Subscribers subscribers()
* @method static \Coderflex\LaravelSendy\Resources\Lists lists()
* @method static \Coderflex\LaravelSendy\Resources\Brands brands()
* @method static \Coderflex\LaravelSendy\Resources\Campaigns campaigns()
*/
-class LaravelSendy extends Facade
+class Sendy extends Facade
{
protected static function getFacadeAccessor(): string
{
- return \Coderflex\LaravelSendy\LaravelSendy::class;
+ return \Coderflex\LaravelSendy\Sendy::class;
}
}
diff --git a/src/Resources/Brands.php b/src/Resources/Brands.php
index ba94cf1..4f2a9b2 100644
--- a/src/Resources/Brands.php
+++ b/src/Resources/Brands.php
@@ -2,12 +2,12 @@
namespace Coderflex\LaravelSendy\Resources;
-use Coderflex\LaravelSendy\Facades\LaravelSendy;
+use Coderflex\LaravelSendy\Facades\Sendy;
class Brands
{
public function get()
{
- return LaravelSendy::post('/api/brands/get-brands.php');
+ return Sendy::post('/api/brands/get-brands.php');
}
}
diff --git a/src/Resources/Campaigns.php b/src/Resources/Campaigns.php
index b3fb387..ecc9977 100644
--- a/src/Resources/Campaigns.php
+++ b/src/Resources/Campaigns.php
@@ -3,14 +3,23 @@
namespace Coderflex\LaravelSendy\Resources;
use Coderflex\LaravelSendy\DTOs\Campaigns\CampaignDTO;
-use Coderflex\LaravelSendy\Facades\LaravelSendy;
+use Coderflex\LaravelSendy\Facades\Sendy;
class Campaigns
{
- public function create(array $data)
+ public function create(array $data, bool $async = false)
{
$data = CampaignDTO::validate($data);
- return LaravelSendy::post('/api/campaigns/create.php', $data);
+ return Sendy::post('/api/campaigns/create.php', $data, $async);
+ }
+
+ public function createAndSend(array $data, bool $async = false)
+ {
+ $data = array_merge($data, [
+ 'send_compaign' => 1,
+ ]);
+
+ return Sendy::post('/api/campaigns/create.php', $data, $async);
}
}
diff --git a/src/Resources/Lists.php b/src/Resources/Lists.php
index dde78e3..abbc42f 100644
--- a/src/Resources/Lists.php
+++ b/src/Resources/Lists.php
@@ -3,7 +3,7 @@
namespace Coderflex\LaravelSendy\Resources;
use Coderflex\LaravelSendy\DTOs\Lists\ListsDTO;
-use Coderflex\LaravelSendy\Facades\LaravelSendy;
+use Coderflex\LaravelSendy\Facades\Sendy;
class Lists
{
@@ -16,6 +16,6 @@ public function get(array $data, bool $async = false)
{
$data = ListsDTO::validate($data);
- return LaravelSendy::post('/api/lists/get-lists.php', $data, $async);
+ return Sendy::post('/api/lists/get-lists.php', $data, $async);
}
}
diff --git a/src/Resources/Subscribers.php b/src/Resources/Subscribers.php
index 61500b1..afd833d 100644
--- a/src/Resources/Subscribers.php
+++ b/src/Resources/Subscribers.php
@@ -6,7 +6,7 @@
use Coderflex\LaravelSendy\DTOs\Subscribers\SubscribeDTO;
use Coderflex\LaravelSendy\DTOs\Subscribers\SubscriberStatusDTO;
use Coderflex\LaravelSendy\DTOs\Subscribers\UnsubscribeDTO;
-use Coderflex\LaravelSendy\Facades\LaravelSendy;
+use Coderflex\LaravelSendy\Facades\Sendy;
class Subscribers
{
@@ -14,28 +14,28 @@ public function subscribe(array $data, bool $async = false)
{
$data = SubscribeDTO::validate($data);
- return LaravelSendy::post('subscribe', $data, $async);
+ return Sendy::post('subscribe', $data, $async);
}
public function unsubscribe(array $data, bool $async = false)
{
$data = UnsubscribeDTO::validate($data);
- return LaravelSendy::post('api/subscribers/unsubscribe.php', $data, $async);
+ return Sendy::post('api/subscribers/unsubscribe.php', $data, $async);
}
public function delete(array $data, bool $async = false)
{
$data = DeleteSubscriberDTO::validate($data);
- return LaravelSendy::post('api/subscribers/delete.php', $data, $async);
+ return Sendy::post('api/subscribers/delete.php', $data, $async);
}
public function status(array $data, bool $async = false)
{
$data = SubscriberStatusDTO::validate($data);
- return LaravelSendy::post('api/subscribers/subscription-status.php', $data, $async);
+ return Sendy::post('api/subscribers/subscription-status.php', $data, $async);
}
public function count(int $listId, bool $async = false)
@@ -44,6 +44,6 @@ public function count(int $listId, bool $async = false)
'list_id' => $listId,
];
- return LaravelSendy::post('api/subscribers/subscriber-count.php', $data, $async);
+ return Sendy::post('api/subscribers/subscriber-count.php', $data, $async);
}
}
diff --git a/src/LaravelSendy.php b/src/Sendy.php
similarity index 96%
rename from src/LaravelSendy.php
rename to src/Sendy.php
index 59e7257..2abdd1a 100644
--- a/src/LaravelSendy.php
+++ b/src/Sendy.php
@@ -4,7 +4,7 @@
use Coderflex\LaravelSendy\Concerns\InteractsWithHttpRequests;
-class LaravelSendy
+class Sendy
{
use InteractsWithHttpRequests;
diff --git a/tests/Resources/BrandsTest.php b/tests/Resources/BrandsTest.php
index 3e98357..13e4922 100644
--- a/tests/Resources/BrandsTest.php
+++ b/tests/Resources/BrandsTest.php
@@ -1,6 +1,6 @@
Http::response([123 => 'Brand Name'], 200),
]);
- $response = LaravelSendy::brands()->get();
+ $response = Sendy::brands()->get();
expect($response->json())->toBe([123 => 'Brand Name']);
diff --git a/tests/Resources/CompaignsTest.php b/tests/Resources/CompaignsTest.php
index cd83292..7b9321f 100644
--- a/tests/Resources/CompaignsTest.php
+++ b/tests/Resources/CompaignsTest.php
@@ -1,6 +1,6 @@
Http::response(['status' => 'Campaign created'], 200),
+ ]);
+
+ $response = Sendy::campaigns()->create([
+ 'subject' => 'Test Subject',
+ 'from_name' => 'John Doe',
+ 'from_email' => 'john@example.com',
+ 'reply_to' => 'alex@example.com',
+ 'title' => 'Test Title',
+ 'plain_text' => 'This is a plain text version of the email.',
+ 'html_text' => 'This is a HTML version of the email.
',
+ 'list_ids' => 'abc123',
+ 'segment_ids' => 'xyz456',
+ 'exclude_list_ids' => null,
+ 'exclude_segment_ids' => null,
+ 'brand_id' => 'brand123',
+ 'query_string' => null,
+ 'track_opens' => 1,
+ 'track_clicks' => 1,
+ 'send_campaign' => 0,
+ 'schedule_date_time' => null,
+ 'schedule_timezone' => null,
+ ]);
+
+ expect($response->json())->toBe(['status' => 'Campaign created']);
+
+ Http::assertSent(function ($request) {
+ return $request->url() === 'https://sendy.test/api/campaigns/create.php' &&
+ $request['from_email'] === 'john@example.com' &&
+ $request['from_name'] === 'John Doe' &&
+ $request['api_key'] === 'test_api_key';
+ });
+});
+
it('can create and send a campaigns', function () {
Http::fake([
'https://sendy.test/api/campaigns/create.php' => Http::response(['status' => 'Campaign created and now sending'], 200),
]);
- $response = LaravelSendy::campaigns()->create([
+ $response = Sendy::campaigns()->createAndSend([
'subject' => 'Test Subject',
'from_name' => 'John Doe',
'from_email' => 'john@example.com',
@@ -31,7 +67,6 @@
'query_string' => null,
'track_opens' => 1,
'track_clicks' => 1,
- 'send_campaign' => 1,
'schedule_date_time' => null,
'schedule_timezone' => null,
]);
diff --git a/tests/Resources/EndpointsTest.php b/tests/Resources/EndpointsTest.php
index e0a72b2..37b51a2 100644
--- a/tests/Resources/EndpointsTest.php
+++ b/tests/Resources/EndpointsTest.php
@@ -1,6 +1,6 @@
Http::response(true, 200),
]);
- $response = LaravelSendy::brands()->get();
+ $response = Sendy::brands()->get();
})->throws(\Coderflex\LaravelSendy\Exceptions\InvalidApiKeyException::class);
@@ -27,6 +27,6 @@
'laravel-sendy.api_url' => null,
]);
- $response = LaravelSendy::brands()->get();
+ $response = Sendy::brands()->get();
})->throws(\Coderflex\LaravelSendy\Exceptions\InvalidApiUrlException::class);
diff --git a/tests/Resources/ListsTest.php b/tests/Resources/ListsTest.php
index 87a7b6d..d6efbe7 100644
--- a/tests/Resources/ListsTest.php
+++ b/tests/Resources/ListsTest.php
@@ -1,6 +1,6 @@
Http::response([123 => 'Custom List'], 200),
]);
- $response = LaravelSendy::lists()->get([
+ $response = Sendy::lists()->get([
'brand_id' => 123,
'include_hidden' => 'yes',
]);
diff --git a/tests/Resources/SubscribersTest.php b/tests/Resources/SubscribersTest.php
index 7d7ba94..62b3a2b 100644
--- a/tests/Resources/SubscribersTest.php
+++ b/tests/Resources/SubscribersTest.php
@@ -1,6 +1,6 @@
Http::response(true, 200),
]);
- $response = LaravelSendy::subscribers()->subscribe([
+ $response = Sendy::subscribers()->subscribe([
'name' => 'John Doe',
'email' => 'john@example.com',
'list' => 'abc123',
@@ -37,7 +37,7 @@
'https://sendy.test/api/subscribers/unsubscribe.php' => Http::response(true, 200),
]);
- $response = LaravelSendy::subscribers()->unsubscribe([
+ $response = Sendy::subscribers()->unsubscribe([
'list' => 123,
'email' => 'jane@example.com',
'boolean' => true,
@@ -57,7 +57,7 @@
'https://sendy.test/api/subscribers/delete.php' => Http::response(true, 200),
]);
- $response = LaravelSendy::subscribers()->delete([
+ $response = Sendy::subscribers()->delete([
'list_id' => 123,
'email' => 'john@example.com',
]);
@@ -74,7 +74,7 @@
'https://sendy.test/api/subscribers/subscription-status.php' => Http::response(['status' => 'Subscribed'], 200),
]);
- $response = LaravelSendy::subscribers()->status([
+ $response = Sendy::subscribers()->status([
'list_id' => 123,
'email' => 'john@example.com',
]);
@@ -87,7 +87,7 @@
'https://sendy.test/api/subscribers/subscriber-count.php' => Http::response(25, 200),
]);
- $response = LaravelSendy::subscribers()->count(123);
+ $response = Sendy::subscribers()->count(123);
expect($response->json())->toBe(25);
});