Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
77ba353
Adding status codes to PHP exceptions
glennjacobs Jun 23, 2015
0005043
Adapted Message.php for Nexmo's keyword marketing
Aug 10, 2015
3992e7c
Merge pull request #1 from thelaurence/thelaurence-MarketingMessage
Aug 10, 2015
d549f5d
Create MarketingMessageTest.php
Aug 11, 2015
c13c311
Update MarketingMessageTest.php
Aug 11, 2015
054ffe2
Update MarketingMessageTest.php
Aug 11, 2015
057c420
Update MarketingMessageTest.php
Aug 11, 2015
33fb414
empty MarketingMessageTest.php
Aug 11, 2015
0d56c8e
add property-read\MarketingMessage
Aug 11, 2015
b4f161d
add MarketingMessage to testConstructor
Aug 11, 2015
de7b560
put marketing tests back
Aug 11, 2015
dba8baf
just trying stuff
Aug 11, 2015
0baeb5e
Update MarketingMessageTest.php
Aug 11, 2015
2d8579a
Delete MarketingMessageTest.php
Aug 12, 2015
2fe24a1
Update ClientTest.php
Aug 12, 2015
26f1b8f
Update MarketingMessage
Aug 12, 2015
ea9d496
Rename MarketingMessage to MarketingMessage.php
Aug 24, 2015
f68a791
re-added tests
Aug 24, 2015
9375d04
Merge pull request #2 from gmo/master
Aug 24, 2015
16c716b
Update MarketingMessageTest.php
Aug 24, 2015
e44d8f4
Added Number/Buy, Number/Search and Number/Cancel services. Modified …
quinncomendant Aug 30, 2015
05fdead
Added Number/Buy, Number/Search and Number/Cancel services. (New file…
quinncomendant Aug 30, 2015
e8b1ac6
Updated the Message->containsUnicode() method to detect characters wh…
quinncomendant Aug 30, 2015
d122406
Updated README with usage examples.
quinncomendant Aug 30, 2015
00c9ea9
Merge pull request #15 from quinncomendant/docs
vood Sep 8, 2015
ce25ac5
Merge pull request #5 from neondigital/master
vood Sep 8, 2015
c7cc689
Merge pull request #13 from quinncomendant/unicode
vood Sep 8, 2015
f0aac3b
Merge pull request #11 from quinncomendant/number-services
vood Sep 8, 2015
a69e72d
fixing up unit tests
Sep 9, 2015
d8024b9
Fixed strict php errors during tests
geekdevs Mar 9, 2016
9794061
Merge remote-tracking branch 'upstream/master'
Mar 15, 2016
e885bea
Merge remote-tracking branch 'geekdevs/fix_strict'
Mar 15, 2016
5c82a4c
fixed build errors
Mar 15, 2016
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
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,133 @@ Unofficial [Nexmo](https://www.nexmo.com/) Rest Client
[Nexmo API Documentation](https://docs.nexmo.com/)
## How to Install
```composer require connect-corp/nexmo-client```

## Usage examples

### Setting up the client object

$nexmo_client_options = array(
'apiKey' => '…',
'apiSecret' => '…',
'debug' => false,
'timeout' => 5.0,
);
$nexmo = new \Nexmo\Client($nexmo_client_options);

### Sending a message

$from = '1234567890';
$to = '15551232020';
$text = 'hello world';
try {
$response = $nexmo->message->invoke($from, $to, 'text', $text);
} catch (Exception $e) {
die($e->getMessage());
}
foreach ($response['messages'] as $i => $m) {
switch ($m['status']) {
case '0':
echo 'Message sent successfully:';
print_r($m);
break;

default:
echo 'Message sending failed:'
print_r($m);
break;
}
}

### Getting account balance

try {
$response = $nexmo->account->balance();
} catch (Exception $e) {
die($e->getMessage());
}
echo "Account balance is $response";

### Getting pricing by destination country

$country = 'US';
try {
$response = $nexmo->account->pricing->country($country);
} catch (Exception $e) {
die($e->getMessage());
}
echo 'Price is ' . $response->price();

### Getting pricing by recipient number

$number = '15551232020';
try {
// SMS pricing.
$response = $nexmo->account->pricing->sms($number);
// Voice pricing.
$response = $nexmo->account->pricing->voice($number);
} catch (Exception $e) {
die($e->getMessage());
}
echo 'Price is ' . $response->price();


### Search for long virtual numbers by country

$country = 'US';
try {
$response = $nexmo->number->search($country);
} catch (Exception $e) {
die($e->getMessage());
}
$all = $response->all();
if (isset($all['numbers'])) {
foreach ($all['numbers'] as $n) {
printf("%d \$%01.2f %-10s %-15s\n", $n['msisdn'], $n['cost'], $n['type'], join(',', $n['features']));
}
}

### Buy a long virtual number

$country = 'US';
$msisdn = '1234567890'; // Number found using $nexmo->number->search()
try {
$response = $nexmo->number->buy($country, $msisdn);
} catch (Exception $e) {
die($e->getMessage());
}
if (200 == $response['error-code']) {
echo 'Number purchase success';
}

### List long virtual numbers in your account

$country = 'US';
try {
$response = $nexmo->account->numbers();
} catch (Exception $e) {
die($e->getMessage());
}
$all = $response->all();
if (isset($all['numbers'])) {
foreach ($all['numbers'] as $n) {
printf("%d %-2s %-10s %-15s\n", $n['msisdn'], $n['country'], $n['type'], join(',', $n['features']));
}
}

### Cancel a long virtual number

$country = 'US';
$msisdn = '1234567890'; // Number found using $nexmo->account->numbers()
try {
$response = $nexmo->number->cancel($country, $msisdn);
} catch (Exception $e) {
die($e->getMessage());
}
if (200 == $response['error-code']) {
echo 'Number cancel success';
}

## Contributors
- @CarsonF
- @com

9 changes: 5 additions & 4 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
/**
* Class Client
*
* @property-read Service\Account $account Account management APIs
* @property-read Service\Message $message
* @property-read Service\Voice $voice
* @property-read Service\Verify $verify
* @property-read Service\Account $account Account management APIs
* @property-read Service\MarketingMessage $marketingmessage
* @property-read Service\Message $message
* @property-read Service\Voice $voice
* @property-read Service\Verify $verify
*
* @package Nexmo\Client
*/
Expand Down
85 changes: 85 additions & 0 deletions src/Service/MarketingMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Nexmo\Service;

use Nexmo\Exception as NexmoException;
use Nexmo\Exception;

/**
* Class MarketingMessage
* @package Nexmo\Service
*/
class MarketingMessage extends Service
{
/**
* @return string The short code marketing SMS endpoint.
*/
public function getEndpoint()
{
return 'sc/us/marketing/json';
}

/**
* Send a marketing message from Nexmo's shared short code.
*
* @param string|int $from Required. Nexmo Shared Short Code, can be found on your Dashboard.
* @param string $keyword Required. The keyword you selected during Shared Short Code sign up process.
* @param string|int $to Required. Mobile number in international format.
* Ex: 447525856424 or 00447525856424 when sending to UK.
* @param string $text Required. Body of the text message.
* @throws \Nexmo\Exception
* @return array
*/
public function invoke($from = null, $keyword = null, $to = null, $text = '')
{
if(!$from) {
throw new Exception("\$from parameter cannot be blank");
}

if(!$keyword) {
throw new Exception("\$keyword parameter cannot be blank");
}

if(!$to) {
throw new Exception("\$to parameter cannot be blank");
}

if(!$text) {
throw new Exception("\$text parameter cannot be blank");
}

return $this->exec([
'from' => $from,
'keyword' => $keyword,
'to' => $to,
'text' => $text
]);
}

protected function validateResponse(array $json)
{
if (!isset($json['message-count'])) {
throw new NexmoException('message-count property expected');
}

if (!isset($json['messages'])) {
throw new NexmoException('messages property expected');
}

foreach ($json['messages'] as $message) {
if (!isset($message['status'])) {
throw new NexmoException('status property expected');
}

if (!empty($message["error-text"])) {
throw new NexmoException("Unable to send sms message: " . $message["error-text"] . ' - status ' . $message['status']);
}

if ($message['status'] > 0) {
throw new NexmoException("Unable to send sms message: status " . $message['status']);
}
}

return true;
}
}
34 changes: 32 additions & 2 deletions src/Service/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public function invoke(
throw new Exception("\$text parameter cannot be blank");
}

if ($this->containsUnicode($text)) {
// If $type is empty, 'text' will be assumed by Nexmo's SMS API.
if (($type == '' || $type === 'text') && $this->containsUnicode($text)) {
$type = 'unicode';
}

Expand All @@ -102,9 +103,38 @@ public function invoke(
]);
}

/**
* @param string $text
* @return int
*/
protected function containsUnicode($text)
{
return max(array_map('ord', str_split($text))) > 127;
// Valid GSM default character-set codepoint values from http://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT
$gsm_0338_codepoints = [0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC, 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5, 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8, 0x03A3, 0x0398, 0x039E, 0x00A0, 0x000C, 0x005E, 0x007B, 0x007D, 0x005C, 0x005B, 0x007E, 0x005D, 0x007C, 0x20AC, 0x00C6, 0x00E6, 0x00DF, 0x00C9, 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x00A1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC, 0x00A7, 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0];

// Split $text into an array in a way that respects multibyte characters.
$text_chars = preg_split('//u', $text, null, PREG_SPLIT_NO_EMPTY);

// Array of codepoint values for characters in $text.
$text_codepoints = array_map([$this, 'uord'], $text_chars);

// Filter the array to contain only codepoints from $text that are not in the set of valid GSM codepoints.
$non_gsm_codepoints = array_diff($text_codepoints, $gsm_0338_codepoints);

// The text contains unicode if the result is not empty.
return !empty($non_gsm_codepoints);
}

/**
* @param char $unicode_char
* @return int
*/
public function uord($unicode_char)
{
$k = mb_convert_encoding($unicode_char, 'UCS-2LE', 'UTF-8');
$k1 = ord(substr($k, 0, 1));
$k2 = ord(substr($k, 1, 1));
return $k2 * 256 + $k1;
}

/**
Expand Down
40 changes: 40 additions & 0 deletions src/Service/Number.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Nexmo\Service;

use Nexmo\Entity;
use Nexmo\Entity\MatchingStrategy;
use Nexmo\Exception;

/**
* Class Number
* @package Nexmo\Service
*/
class Number extends ResourceCollection
{
/**
* @return array
* @throws Exception
*/
public function search($country = null, $index = 1, $size = 10, $pattern = null, $searchPattern = MatchingStrategy::STARTS_WITH, $features = 'SMS')
{
return $this->search->invoke($country, $index, $size, $pattern, $searchPattern, $features);
}

/**
* @return array
* @throws Exception
*/
public function buy($country, $msisdn)
{
return $this->buy->invoke($country, $msisdn);
}
/**
* @return array
* @throws Exception
*/
public function cancel($country, $msisdn)
{
return $this->cancel->invoke($country, $msisdn);
}
}
Loading