Skip to content

Commit

Permalink
Add laravel notification support
Browse files Browse the repository at this point in the history
  • Loading branch information
nuradiyana committed Sep 15, 2022
1 parent a9a44f0 commit 3e17c39
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 7 deletions.
64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Sending WhatsApp message via Qontak API, using [HTTPlug](https://github.com/php-

## Installation

First
install [HTTPlug](https://github.com/php-http/httplug) [adapter or client](https://docs.php-http.org/en/latest/clients.html)
First install HTTPlug [adapter or client](https://docs.php-http.org/en/latest/clients.html)
and PSR-17 package compatible

```bash
composer require php-http/curl-client
composer require php-http/curl-client laminas/laminas-diactoros
```

and then install this package :
Expand All @@ -19,6 +19,8 @@ composer require inisiatif/whatsapp-qontak-php

## Usage

### Non framework usage

First your must be created a valid and approved WhatsApp template.

```php
Expand Down Expand Up @@ -65,6 +67,62 @@ echo $response->getName();
\var_dump($response->getData());
```

### Using in Laravel as Notification Channel

1. Add new config value in `config/services.php` and then setting each value in `.env`

```php
'qontak' => [
'username' => env('QONTAK_USERNAME', null),
'password' => env('QONTAK_PASSWORD', null),
'client_id' => env('QONTAK_CLIENT_ID', null),
'client_secret' => env('QONTAK_CLIENT_SECRET', null),
],
```

2. Add this code in `register` method `AppServiceProvider`

```php
$this->app->singleton(\Inisiatif\WhatsappQontakPhp\ClientInterface::class, function () {
return $this->app->runningUnitTests() ? \Inisiatif\WhatsappQontakPhp\ClientFactory::makeTestingClient() : \Inisiatif\WhatsappQontakPhp\ClientFactory::makeFromArray(
config('service.qontak')
);
});
```

3. Then create or register `ContakChannel` in notification class

```php
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Inisiatif\WhatsappQontakPhp\Message\Message;
use Inisiatif\WhatsappQontakPhp\Message\Receiver;
use Inisiatif\WhatsappQontakPhp\Illuminate\Envelope;
use Inisiatif\WhatsappQontakPhp\Illuminate\QontakChannel;
use Inisiatif\WhatsappQontakPhp\Illuminate\QontakNotification;

class InvoicePaid extends Notification implements QontakNotification
{
use Queueable;

public function via($notifiable): array
{
return [QontakChannel::class];
}

public function toQontak($notifiable): Envelope
{
// First create message object
$receiver = new Receiver('+6281318788271', 'Nuradiyana');
$message = new Message($receiver);

// Then create envelope object and return it
return new Envelope('templateId', 'channelId', $message);
}
}
```

## Testing

🧹 Fixing codebase with **Easy Coding Standard**:
Expand Down
5 changes: 1 addition & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@
}
},
"config": {
"sort-packages": true,
"platform": {
"php": "7.1.99"
}
"sort-packages": true
},
"scripts": {
"test": "phpunit",
Expand Down
41 changes: 41 additions & 0 deletions src/ClientFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp;

use Http\Client\HttpClient;

final class ClientFactory
{
/**
* @var Client|null
*/
private static $client = null;

/**
* @var NullClient|null
*/
private static $nullClient = null;

public static function makeFromArray(array $config, HttpClient $httpClient = null): ClientInterface
{
if (! self::$client instanceof Client) {
self::$client = new Client(
Credential::fromArray($config),
$httpClient
);
}

return self::$client;
}

public static function makeTestingClient(): ClientInterface
{
if (! self::$nullClient instanceof NullClient) {
self::$nullClient = new NullClient();
}

return self::$nullClient;
}
}
14 changes: 14 additions & 0 deletions src/Credential.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Inisiatif\WhatsappQontakPhp;

use Webmozart\Assert\Assert;

final class Credential
{
/**
Expand Down Expand Up @@ -34,6 +36,18 @@ public function __construct(string $username, string $password, string $clientId
$this->clientSecret = $clientSecret;
}

public static function fromArray(array $data): self
{
Assert::allStringNotEmpty($data);

Assert::keyExists($data, 'username');
Assert::keyExists($data, 'password');
Assert::keyExists($data, 'client_id');
Assert::keyExists($data, 'client_secret');

return new self($data['username'], $data['password'], $data['client_id'], $data['client_secret']);
}

public function getUsername(): string
{
return $this->username;
Expand Down
47 changes: 47 additions & 0 deletions src/Illuminate/Envelope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp\Illuminate;

use Inisiatif\WhatsappQontakPhp\Message\Message;

final class Envelope
{
/**
* @var string
*/
private $templateId;

/**
* @var string
*/
private $channelId;

/**
* @var Message
*/
private $message;

public function __construct(string $templateId, string $channelId, Message $message)
{
$this->templateId = $templateId;
$this->channelId = $channelId;
$this->message = $message;
}

public function getTemplateId(): string
{
return $this->templateId;
}

public function getChannelId(): string
{
return $this->channelId;
}

public function getMessage(): Message
{
return $this->message;
}
}
34 changes: 34 additions & 0 deletions src/Illuminate/QontakChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp\Illuminate;

use Inisiatif\WhatsappQontakPhp\ClientInterface;

final class QontakChannel
{
/**
* @var ClientInterface
*/
private $client;

public function __construct(ClientInterface $client)
{
$this->client = $client;
}

/**
* @param mixed $notifiable
*/
public function send($notifiable, QontakNotification $notification): void
{
$envelope = $notification->toQontak($notifiable);

$this->client->send(
$envelope->getTemplateId(),
$envelope->getChannelId(),
$envelope->getMessage()
);
}
}
13 changes: 13 additions & 0 deletions src/Illuminate/QontakNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp\Illuminate;

interface QontakNotification
{
/**
* @param mixed $notifiable
*/
public function toQontak($notifiable): Envelope;
}
15 changes: 15 additions & 0 deletions src/NullClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp;

use Inisiatif\WhatsappQontakPhp\Message\Message;

final class NullClient implements ClientInterface
{
public function send(string $templateId, string $channelId, Message $message): Response
{
return new Response('messageId', $message->getReceiver()->getName());
}
}
56 changes: 56 additions & 0 deletions tests/ClientFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Inisiatif\WhatsappQontakPhp\Tests;

use Mockery;
use PHPUnit\Framework\TestCase;
use Inisiatif\WhatsappQontakPhp\Client;
use Inisiatif\WhatsappQontakPhp\NullClient;
use Inisiatif\WhatsappQontakPhp\ClientFactory;
use Http\Client\Common\HttpMethodsClientInterface;

final class ClientFactoryTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
}

public function test_can_create_client(): void
{
$config = [
'username' => 'username',
'password' => 'password',
'client_id' => 'clientId',
'client_secret' => 'secret',
];

$httpClient = Mockery::mock(HttpMethodsClientInterface::class)->makePartial();

$client = ClientFactory::makeFromArray($config, $httpClient);
$this->assertInstanceOf(Client::class, $client);

$client = ClientFactory::makeTestingClient();
$this->assertInstanceOf(NullClient::class, $client);
}

public function test_create_same_object_in_multiple_creation(): void
{
$config = [
'username' => 'username',
'password' => 'password',
'client_id' => 'clientId',
'client_secret' => 'secret',
];

$httpClient = Mockery::mock(HttpMethodsClientInterface::class)->makePartial();

$client1 = ClientFactory::makeFromArray($config, $httpClient);
$this->assertInstanceOf(Client::class, $client1);

$client2 = ClientFactory::makeFromArray($config, $httpClient);
$this->assertSame($client1, $client2);
}
}
14 changes: 14 additions & 0 deletions tests/CredentialTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,18 @@ public function test_get_oauth_credential(): void
$credential->getOAuthCredential()
);
}

public function test_create_from_array_credentials(): void
{
$config = [
'username' => 'username',
'password' => 'password',
'client_id' => 'clientId',
'client_secret' => 'secret',
];

$credential = Credential::fromArray($config);

$this->assertSame($config, $credential->toArray());
}
}

0 comments on commit 3e17c39

Please sign in to comment.