Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VoIP support with additional channel #91

Merged
merged 8 commits into from
Mar 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,39 @@ return ApnMessage::create()
->via($customClient)
```

### VoIP push notifications

Sending VoIP push notifications is very similar. You just need to use the `ApnVoipChannel` channel with `ApnVoipMessage` (which has the same API has a regular `ApnMessage`).

```php
use NotificationChannels\Apn\ApnVoipChannel;
use NotificationChannels\Apn\ApnVoipMessage;
use Illuminate\Notifications\Notification;

class AccountApproved extends Notification
{
public function via($notifiable)
{
return [ApnVoipChannel::class];
}

public function toApnVoip($notifiable)
{
return ApnVoipMessage::create()
->badge(1);
}
}
```

In your `notifiable` model, make sure to include a `routeNotificationForApnVoip()` method, which return one or an array of tokens.

```php
public function routeNotificationForApnVoip()
{
return $this->apn_voip_token;
}
```

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
Expand Down
36 changes: 36 additions & 0 deletions src/ApnVoipChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace NotificationChannels\Apn;

use Illuminate\Notifications\Notification;

class ApnVoipChannel extends ApnChannel
{
/**
* Send the notification to Apple Push Notification Service.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return array|void
*/
public function send($notifiable, Notification $notification)
{
$tokens = (array) $notifiable->routeNotificationFor('apn_voip', $notification);

if (empty($tokens)) {
return;
}

$message = $notification->toApnVoip($notifiable);

$responses = $this->sendNotifications(
$message->client ?? $this->client,
$message,
$tokens
);

$this->dispatchEvents($notifiable, $notification, $responses);

return $responses;
}
}
13 changes: 13 additions & 0 deletions src/ApnVoipMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace NotificationChannels\Apn;

class ApnVoipMessage extends ApnMessage
{
/**
* Value indicating when the message will expire.
*
* @var \string
*/
public $pushType = 'voip';
}
44 changes: 1 addition & 43 deletions tests/ApnChannelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Notifications\Events\NotificationFailed;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Mockery;
use NotificationChannels\Apn\ApnChannel;
use NotificationChannels\Apn\ApnMessage;
use Pushok\Client;
use Pushok\Response;

class ChannelTest extends TestCase
class ApnChannelTest extends TestCase
{
protected $client;
protected $events;
Expand Down Expand Up @@ -66,42 +63,3 @@ public function it_dispatches_events_for_failed_notifications()
$this->channel->send(new TestNotifiable, new TestNotification);
}
}

class TestNotifiable
{
use Notifiable;

/**
* @return array
*/
public function routeNotificationForApn()
{
return [
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd8',
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd9',
];
}
}

class TestNotification extends Notification
{
public function toApn($notifiable)
{
return new ApnMessage('title');
}
}

class TestNotificationWithClient extends Notification
{
protected $client;

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

public function toApn($notifiable)
{
return (new ApnMessage('title'))->via($this->client);
}
}
129 changes: 129 additions & 0 deletions tests/ApnVoipChannelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace NotificationChannels\Apn\Tests;

use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Notifications\Events\NotificationFailed;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Mockery;
use NotificationChannels\Apn\ApnMessage;
use NotificationChannels\Apn\ApnVoipChannel;
use Pushok\Client;
use Pushok\Response;

class ApnVoipChannelTest extends TestCase
{
protected $client;
protected $events;
protected $notification;
protected $channel;

public function setUp(): void
{
$this->client = Mockery::mock(Client::class);
$this->events = Mockery::mock(Dispatcher::class);
$this->channel = new ApnVoipChannel($this->client, $this->events);
}

/** @test */
public function it_can_send_a_notification()
{
$this->client->shouldReceive('addNotification');
$this->client->shouldReceive('push')->once();

$this->channel->send(new TestNotifiable, new TestNotification);
}

/** @test */
public function it_can_send_a_notification_with_custom_client()
{
$customClient = Mockery::mock(Client::class);

$this->client->shouldNotReceive('addNotification');

$customClient->shouldReceive('addNotification');
$customClient->shouldReceive('push')->once();

$this->channel->send(new TestNotifiable, (new TestNotificationWithClient($customClient)));
}

/** @test */
public function it_dispatches_events_for_failed_notifications()
{
$this->events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationFailed::class));

$this->client->shouldReceive('addNotification');
$this->client->shouldReceive('push')
->once()
->andReturn([
new Response(200, 'headers', 'body'),
new Response(400, 'headers', 'body'),
]);

$this->channel->send(new TestNotifiable, new TestNotification);
}
}

class TestNotifiable
{
use Notifiable;

/**
* @return array
*/
public function routeNotificationForApn()
{
return [
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd8',
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd9',
];
}

/**
* @return array
*/
public function routeNotificationForApnVoip()
{
return [
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd1',
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd2',
];
}
}

class TestNotification extends Notification
{
public function toApn($notifiable)
{
return new ApnMessage('title');
}

public function toApnVoip($notifiable)
{
return (new ApnMessage)
->pushType('voip');
}
}

class TestNotificationWithClient extends Notification
{
protected $client;

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

public function toApn($notifiable)
{
return (new ApnMessage('title'))->via($this->client);
}

public function toApnVoip($notifiable)
{
return (new ApnMessage)->pushType('voip')->via($this->client);
}
}
16 changes: 16 additions & 0 deletions tests/ApnVoipMessageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace NotificationChannels\Apn\Tests;

use NotificationChannels\Apn\ApnVoipMessage;

class ApnVoipMessageTest extends TestCase
{
/** @test */
public function it_defaults_push_type_to_voip()
{
$message = new ApnVoipMessage;

$this->assertEquals('voip', $message->pushType);
}
}
32 changes: 32 additions & 0 deletions tests/TestNotifiable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace NotificationChannels\Apn\Tests;

use Illuminate\Notifications\Notifiable;

class TestNotifiable
{
use Notifiable;

/**
* @return array
*/
public function routeNotificationForApn()
{
return [
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd8',
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd9',
];
}

/**
* @return array
*/
public function routeNotificationForApnVoip()
{
return [
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd1',
'662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd2',
];
}
}
20 changes: 20 additions & 0 deletions tests/TestNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace NotificationChannels\Apn\Tests;

use Illuminate\Notifications\Notification;
use NotificationChannels\Apn\ApnMessage;
use NotificationChannels\Apn\ApnVoipMessage;

class TestNotification extends Notification
{
public function toApn($notifiable)
{
return new ApnMessage('title');
}

public function toApnVoip($notifiable)
{
return new ApnVoipMessage('title');
}
}
27 changes: 27 additions & 0 deletions tests/TestNotificationWithClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace NotificationChannels\Apn\Tests;

use Illuminate\Notifications\Notification;
use NotificationChannels\Apn\ApnMessage;
use NotificationChannels\Apn\ApnVoipMessage;

class TestNotificationWithClient extends Notification
{
protected $client;

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

public function toApn($notifiable)
{
return (new ApnMessage('title'))->via($this->client);
}

public function toApnVoip($notifiable)
{
return (new ApnVoipMessage)->via($this->client);
}
}