Skip to content

Commit

Permalink
add twilio channel
Browse files Browse the repository at this point in the history
  • Loading branch information
tuyakhov committed Oct 23, 2016
1 parent 19fefc6 commit d89ceb5
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 8 deletions.
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -19,7 +19,8 @@
},
"require": {
"php": ">=5.4.0",
"yiisoft/yii2": "*"
"yiisoft/yii2": "*",
"yiisoft/yii2-httpclient": "^2.0"
},
"require-dev": {
"phpunit/phpunit": "5.5.*"
Expand Down
61 changes: 54 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

113 changes: 113 additions & 0 deletions src/channels/TwilioChannel.php
@@ -0,0 +1,113 @@
<?php
/**
* @copyright Anton Tuyakhov <atuyakhov@gmail.com>
*/
namespace tuyakhov\notifications\channels;

use tuyakhov\notifications\messages\SmsMessage;
use tuyakhov\notifications\NotifiableInterface;
use tuyakhov\notifications\NotificationInterface;
use yii\base\Component;
use yii\di\Instance;
use yii\httpclient\Client;

/**
* Sending an SMS or MMS using Twilio REST API.
*
* ```php
* [
* 'components' => [
* 'notifier' => [
* 'class' => '\tuyakhov\notifications\Notifier',
* 'channels' => [
* 'mail' => [
* 'class' => '\tuyakhov\notifications\channels\TwilioChannel,
* 'accountSid' => '...',
* 'authToken' => '...',
* 'from' => '+1234567890'
* ]
* ],
* ],
* ],
* ]
* ```
*/
class TwilioChannel extends Component implements ChannelInterface
{
/**
* @var string
*/
public $baseUrl = 'https://api.twilio.com/2010-04-01';

/**
* A Twilio account SID
* @var string
*/
public $accountSid;

/**
* A Twilio account auth token
* @var string
*/
public $authToken;

/**
* A Twilio phone number (in E.164 format) or alphanumeric sender ID enabled for the type of message you wish to send.
* @var string
*/
public $from;

/**
* @var Client|array|string
*/
public $httpClient;

/**
* @inheritdoc
*/
public function init()
{
parent::init();
if (!isset($this->httpClient)) {
$this->httpClient = [
'class' => Client::className(),
'baseUrl' => $this->baseUrl
];
}
$this->httpClient = Instance::ensure($this->httpClient, Client::className());
}

/**
* The Messages list resource URI
* @return string
*/
public function getUri()
{
return sprintf('%s/%s/%s', 'Accounts', $this->accountSid, 'Messages.json');
}

/**
* @inheritdoc
*/
public function send(NotifiableInterface $recipient, NotificationInterface $notification)
{
/** @var SmsMessage $message */
$message = $notification->exportFor('sms');
$data = [
'From' => isset($message->from) ? $message->from : $this->from,
'To' => $recipient->routeNotificationFor('sms'),
'Body' => $message->body
];
if (isset($message->mediaUrl)) {
$data['MedialUrl'] = $message->mediaUrl;
}
$this->httpClient
->createRequest()
->setMethod('post')
->setUrl($this->getUri())
->addHeaders(['Authorization' => 'Basic ' . base64_encode("{$this->accountSid}:{$this->authToken}")])
->setData($data)
->send();
}

}
30 changes: 30 additions & 0 deletions src/messages/SmsMessage.php
@@ -0,0 +1,30 @@
<?php
/**
* @link http://www.stombox.com/
* @copyright Copyright (c) 2015 Stombox LLC
* @license http://www.stombox.com/license/
*/

namespace tuyakhov\notifications\messages;


class SmsMessage extends AbstractMessage
{
/**
* A phone number in E.164 format.
* @var string
*/
public $from;

/**
* The text of the message you want to send, limited to 1600 characters.
* @var string
*/
public $body;

/**
* The URL of the media you wish to send out with the message.
* @var string
*/
public $mediaUrl;
}
57 changes: 57 additions & 0 deletions tests/TwilioChannelTest.php
@@ -0,0 +1,57 @@
<?php
/**
* @copyright Anton Tuyakhov <atuyakhov@gmail.com>
*/

namespace tuyakhov\notifications\tests;


use tuyakhov\notifications\channels\MailChannel;
use tuyakhov\notifications\channels\TwilioChannel;
use tuyakhov\notifications\messages\MailMessage;
use tuyakhov\notifications\messages\SmsMessage;
use tuyakhov\notifications\NotifiableInterface;
use tuyakhov\notifications\NotificationInterface;
use yii\httpclient\Client;
use yii\httpclient\Request;
use yii\mail\MailerInterface;
use yii\mail\MessageInterface;

class TwilioChannelTest extends TestCase
{

public function testSend()
{
$recipient = $this->createMock(NotifiableInterface::class);
$recipient->expects($this->once())
->method('routeNotificationFor')
->with('sms')
->willReturn('+1234567890');

$client = $this->createMock(Client::className());
$client->expects($this->once())
->method('send');
$client->method('createRequest')
->willReturn(\Yii::createObject([
'class' => Request::className(),
'client' => $client
]));

$channel = \Yii::createObject([
'class' => TwilioChannel::className(),
'from' => '+1234567890123',
'httpClient' => $client
]);

$notification = $this->createMock(NotificationInterface::class);
$notification->expects($this->once())
->method('exportFor')
->with('sms')
->willReturn(\Yii::createObject([
'class' => SmsMessage::className(),
'body' => 'Test message body',
]));
$channel->send($recipient, $notification);

}
}

0 comments on commit d89ceb5

Please sign in to comment.