Skip to content

Commit

Permalink
Merge pull request #19 from thomaskonrad/websms
Browse files Browse the repository at this point in the history
Add websms provider
  • Loading branch information
K-Phoen committed Oct 20, 2014
2 parents 4622514 + 9548f47 commit 816acb8
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The following providers are supported:
* [CardBoardFish](http://www.cardboardfish.com/)
* [ValueFirst](http://vfirst.com/) (only covering India's networks)
* [Swisscom](http://developer.swisscom.com/) (based on the [GSMA OneAPI](http://www.gsma.com/oneapi/) Specification)
* [websms](https://websms.at/)

Installation
------------
Expand Down
163 changes: 163 additions & 0 deletions src/SmsSender/Provider/WebsmsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

/**
* This file is part of the SmsSender package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

namespace SmsSender\Provider;

use SmsSender\Exception as Exception;
use SmsSender\HttpAdapter\HttpAdapterInterface;
use SmsSender\Result\ResultInterface;

/**
* @author Thomas Konrad <[email protected]>
* @see <https://websms.at/entwickler/sms-api/api-rest/rest-schnittstellenspezifikation>
*/
class WebsmsProvider extends AbstractProvider
{
/**
* @var string
*/
const ENDPOINT_URL = 'https://api.websms.com/rest/smsmessaging/text';

/**
* @var string
*/
protected $accessToken;

/**
* @var string
*/
protected $internationalPrefix;

/**
* {@inheritDoc}
*/
public function __construct(HttpAdapterInterface $adapter, $accessToken, $internationalPrefix = '+43')
{
parent::__construct($adapter);

$this->accessToken = $accessToken;
$this->internationalPrefix = $internationalPrefix;
}

/**
* {@inheritDoc}
*/
public function getName()
{
return 'websms';
}

/**
* {@inheritDoc}
*/
public function send($recipient, $body, $originator = '')
{
if (null === $this->accessToken) {
throw new Exception\InvalidCredentialsException('No API credentials provided');
}

$params = array(
'messageContent' => $body,
'recipientAddressList' => array(
$this->removeLeadingPlusIfPresent(
$this->localNumberToInternational($recipient, $this->internationalPrefix)
)
)
);

return $this->executeQuery(self::ENDPOINT_URL, $params, array(
'recipient' => $recipient,
'body' => $body,
'originator' => $originator,
));
}

/**
* Issues the actual HTTP query.
*
* @param $url
* @param array $data
* @param array $extra_result_data
* @return array
*/
protected function executeQuery($url, array $data = array(), array $extra_result_data = array())
{
$headers = array(
sprintf('Authorization: Bearer %s', $this->accessToken),
'Content-Type: application/json',
'Accept: application/json'
);

// Issue the request
$content = $this->getAdapter()->getContent($url, 'POST', $headers, json_encode($data));

if (null === $content) {
return array_merge($this->getDefaults(), $extra_result_data);
}

return $this->parseResults($content, $extra_result_data);
}

/**
* Parses the data returned by the API.
*
* @param string $result The raw result string.
* @return array
*/
protected function parseResults($result, array $extra_result_data = array())
{
$data = json_decode($result, true);
$smsData = array();

// There was an error
if (empty($data['transferId']) || empty($data['statusCode'])) {
return array_merge($this->getDefaults(), $extra_result_data, array(
'status' => ResultInterface::STATUS_FAILED,
)
);
}

// Get the transfer id
$smsData['id'] = $data['transferId'];

// Get the status
switch ($data['statusCode']) {
case 2000:
$smsData['status'] = ResultInterface::STATUS_SENT;
break;
case 2001:
$smsData['status'] = ResultInterface::STATUS_QUEUED;
break;
default:
$smsData['status'] = ResultInterface::STATUS_FAILED;
break;
}

return array_merge($this->getDefaults(), $extra_result_data, $smsData);
}

/**
* Removes the leading plus sign from the international phone number as websms requires it that way.
*
* @param string $number The number to strip the plus sign from
* @return string
*/
protected function removeLeadingPlusIfPresent($number)
{
if ($number[0] !== '+') {
// The number has no leading "+" sign
return $number;
} else {

// Remove the leading "+" sign and add the prefix
return substr($number, 1);
}
}
}
117 changes: 117 additions & 0 deletions tests/SmsSender/Tests/Provider/WebsmsProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

namespace SmsSender\Tests\Provider;

use SmsSender\Provider\TwilioProvider;
use SmsSender\Provider\WebsmsProvider;
use SmsSender\Result\ResultInterface;

class WebsmsProviderTest extends BaseProviderTest
{
protected function getProvider($adapter)
{
return new WebsmsProvider($adapter, 'access_token');
}

/**
* @expectedException \SmsSender\Exception\InvalidCredentialsException
* @expectedExceptionMessage No API credentials provided
*/
public function testSendWithNullApiCredentials()
{
$adapter = $this->getMock('\SmsSender\HttpAdapter\HttpAdapterInterface');
$provider = new WebsmsProvider($adapter, null, null);
$provider->send('066412345678', 'foo!');
}

public function testSend()
{
$provider = $this->getProvider($this->getMockAdapter());
$result = $provider->send('066412345678', 'foo', 'originator');

$this->assertNull($result['id']);
$this->assertEquals(ResultInterface::STATUS_FAILED, $result['status']);
$this->assertEquals('066412345678', $result['recipient']);
$this->assertEquals('foo', $result['body']);
$this->assertEquals('originator', $result['originator']);
}

public function testSendWithMockData()
{
$data = <<<EOF
{"statusCode":2000,"statusMessage":"OK","transferId":"005440da3e00078f5214"}
EOF;
$provider = $this->getProvider($this->getMockAdapter(null, $data));
$result = $provider->send('066412345678', 'foo');

$this->assertEquals('005440da3e00078f5214', $result['id']);
$this->assertEquals(ResultInterface::STATUS_SENT, $result['status']);
$this->assertEquals('066412345678', $result['recipient']);
$this->assertEquals('foo', $result['body']);
}

/**
* @dataProvider validRecipientProvider
*/
public function testSendCleansRecipientNumber($recipient, $expectedRecipient, $internationalPrefix = null)
{
// setup the adapter
$adapter = $this->getMock('\SmsSender\HttpAdapter\HttpAdapterInterface');
$adapter
->expects($this->once())
->method('getContent')
->with(
$this->anything(), // URL
$this->equalTo('POST'), // method
$this->anything(), // headers
$this->callback(function ($data) use ($expectedRecipient) {
$dataArray = json_decode($data, true);

return is_array($dataArray['recipientAddressList'])
&& count($dataArray['recipientAddressList']) > 0
&& $dataArray['recipientAddressList'][0] === $expectedRecipient;
})
);

// setup the provider
if ($internationalPrefix === null) {
$provider = new WebsmsProvider($adapter, 'access_token');
} else {
$provider = new WebsmsProvider($adapter, 'access_token', $internationalPrefix);
}

// launch the test
$provider->send($recipient, 'foo');
}

public function validRecipientProvider()
{
return array(
array('066412345678', '4366412345678', null),
array('066412345678', '4366412345678', '+43'),
array('066412345678', '4466412345678', '+44'),
array('+4366412345678', '4366412345678', '+43'),
array('+4366412345678', '4366412345678', '+44'),
);
}

/**
* @requires extension curl
*/
public function testRealSend()
{
if (empty($_SERVER['WEBSMS_ACCESS_TOKEN'])) {
$this->markTestSkipped('No test credentials configured.');
}

$adapter = new \SmsSender\HttpAdapter\CurlHttpAdapter();
$provider = new WebsmsProvider($adapter, $_SERVER['WEBSMS_ACCESS_TOKEN']);
$sender = new \SmsSender\SmsSender($provider);
$result = $sender->send('066412345678', 'foo');

$this->assertTrue(!empty($result['id']));
$this->assertEquals(ResultInterface::STATUS_SENT, $result['status']);
$this->assertEquals('066412345678', $result['recipient']);
$this->assertEquals('foo', $result['body']);
}
}

0 comments on commit 816acb8

Please sign in to comment.