resolved conflicts

This commit is contained in:
2025-03-31 03:46:05 +03:00
6454 changed files with 1520539 additions and 9 deletions
@@ -0,0 +1,244 @@
# Africa's Talking PHP SDK
[![Latest Stable Version](https://img.shields.io/packagist/v/africastalking/africastalking)](https://packagist.org/packages/africastalking/africastalking)
> This SDK provides convenient access to the Africa's Talking API for applications written in PHP.
## Documentation
Take a look at the [API docs here](https://developers.africastalking.com).
## Install
You can install the PHP SDK via composer or by downloading the source
#### Via Composer
The recommended way to install the SDK is with [Composer](http://getcomposer.org/).
```bash
composer require africastalking/africastalking
```
## Usage
The SDK needs to be instantiated using your username and API key, which you can get from the [dashboard](https://account.africastalking.com).
> You can use this SDK for either production or sandbox apps. For sandbox, the app username is **ALWAYS** `sandbox`
```php
use AfricasTalking\SDK\AfricasTalking;
$username = 'YOUR_USERNAME'; // use 'sandbox' for development in the test environment
$apiKey = 'YOUR_API_KEY'; // use your sandbox app API key for development in the test environment
$AT = new AfricasTalking($username, $apiKey);
// Get one of the services
$sms = $AT->sms();
// Use the service
$result = $sms->send([
'to' => '+2XXYYYOOO',
'message' => 'Hello World!'
]);
print_r($result);
```
See [example](example/) for more usage examples.
## Instantiation
Instantiating the class will give you an object with available methods
- `$AT = new AfricasTalking($username, $apiKey)`: Instantiate the class
- Get available service
- [SMS Service](#sms): `$sms = $AT->sms()`
- [Content Service](#content): `$content = $AT->content()`
- [Airtime Service](#airtime): `$airtime = $AT->airtime()`
- [Mobile Data Service](#mobiledata): `$mobileData = $AT->mobileData()`
- [Voice Service](#voice): `$voice = $AT->voice()`
- [Token Service](#token): `$token = $AT->token()`
- [Application Service](#application): `$application = $AT->application()`
### Application
- `fetchApplicationData()`: Get app information. e.g balance
### Airtime
- `send($parameters, $options)`: Send airtime
- **$parameters:** associative array with the following keys:
- `recipients`: An array of arrays containing the following keys
- `phoneNumber`: Recipient of airtime. `REQUIRED`
- `currencyCode`: 3-digit ISO format currency code (e.g `KES`, `USD`, `UGX` etc). `REQUIRED`
- `amount`: Amount to send. `REQUIRED`
- **$options:** optional associative array with the following keys:
- `idempotencyKey`: Key to use when making idempotent requests
- `maxNumRetry`: Maximum number of retries in case of failed airtime deliveries due to telco unavailability or any other reason.
### SMS
- `send($options)`: Send a message
- `message`: SMS content. `REQUIRED`
- `to`: An array of phone numbers. `REQUIRED`
- `from`: Shortcode or alphanumeric ID that is registered with your Africa's Talking account.
- `enqueue`: Set to `true` if you would like to deliver as many messages to the API without waiting for an acknowledgement from telcos.
- `fetchMessages($options)`: Fetch your messages
- `lastReceivedId`: This is the id of the message you last processed. Defaults to `0`
***The followoing methods have been moved to the content service, but, have been maintained on SMS for backwards compatibility:***
- `sendPremium($options)`: Send a premium SMS. Calls `$content->send($options)`
- `createSubscription($options)`: Create a premium subscription. Calls `$content->createSubscription($options)`
- `fetchSubscriptions($options)`: Fetch your premium subscription data. Calls `$content->fetchSubscriptions($options)`
- `deleteSubscription($options)`: Delete a phone number from a premium subscription. Calls `$content->$deleteSubscription($options)`
### Content
- `send($options)`: Send a premium SMS
- `message`: SMS content. `REQUIRED`
- `to`: An array of phone numbers. `REQUIRED`
- `from`: Shortcode that is registered with your Africa's Talking account. `REQUIRED`
- `keyword`: Your premium product keyword
- `linkId`: "[...] We forward the `linkId` to your application when a user sends a message to your onDemand service"
- `retryDurationInHours`: "This specifies the number of hours your subscription message should be retried in case it's not delivered to the subscriber"
- `createSubscription($options)`: Create a premium subscription
- `shortCode`: Premium short code mapped to your account. `REQUIRED`
- `keyword`: Premium keyword under the above short code and is also mapped to your account. `REQUIRED`
- `phoneNumber`: PhoneNumber to be subscribed `REQUIRED`
- `fetchSubscriptions($options)`: Fetch your premium subscription data
- `shortCode`: Premium short code mapped to your account. `REQUIRED`
- `keyword`: Premium keyword under the above short code and mapped to your account. `REQUIRED`
- `lastReceivedId`: ID of the subscription you believe to be your last. Defaults to `0`
- `deleteSubscription($options)`: Delete a phone number from a premium subscription
- `shortCode`: Premium short code mapped to your account. `REQUIRED`
- `keyword`: Premium keyword under the above short code and is also mapped to your account. `REQUIRED`
- `phoneNumber`: PhoneNumber to be subscribed `REQUIRED`
### Mobile Data
- `send($parameters, $options)`: Send mobile data to customers
- **$parameters:** associative array with the following keys:
- `productName`: Payment product on Africa's Talking. `REQUIRED`
- `recipients`: A list of recipients. Each recipient has:
- `phoneNumber`: Customer phone number (in international format). `REQUIRED`
- `quantity`: Mobile data amount. `REQUIRED`
- `unit`: Mobile data unit. Can either be `MB` or `GB`. `REQUIRED`
- `validity`: How long the mobile data is valid for. Must be one of `Day`, `Week` and `Month`. `REQUIRED`
- `metadata`: Additional data to associate with the tranasction. `REQUIRED`
- **$options:** optional associative array with the following keys:
- `idempotencyKey`: Key to use when making idempotent requests
- `findTransaction($parameters)`: Find a particular transaction
- `transactionId`: ID of trancation to find. `REQUIRED`
- `fetchWalletBalance()`: Fetch your payment wallet balance
### Voice
- `call($options)`: Initiate a phone call
- `to`: Phone number that you wish to dial (in international format). `REQUIRED`
- `from`: Phone number on Africa's Talking (in international format). `REQUIRED`
- `clientRequestId`: Variable sent to your Events Callback URL that can be used to tag the call. `OPTIONAL`
- `fetchQueuedCalls($options)`: Fetch queued calls on a phone number
- `phoneNumber`: Phone number mapped to your Africa's Talking account (in international format). `REQUIRED`
- `name`: Fetch calls for a specific queue.
- `uploadMediaFile($options)`: Upload a voice media file
- `phoneNumber`: phone number mapped to your Africa's Talking account (in international format). `REQUIRED`
- `url`: The url of the file to upload. Should start with `http(s)://`. `REQUIRED`
#### MessageBuilder
Build voice xml when callback URL receives a POST from the voice API. Actions can be chained to create an XML string.
```php
$voiceActions = $voice->messageBuilder();
$xmlresponse = $voiceActions
->getDigits($options)
->say($text)
->record()
->build();
```
- `say($text)`: Add a `Say` action
- `text`: Text (in English) that will be read out to the user.
- `play($url)`: Add a `Play` action
- `url`: Public url to an audio file. This file will be played back to user.
- `getDigits($options)`: Add a `GetDigits` action
- `numDigits`: Number of digits should be gotten from the user
- `timeout`: Timeout (in seconds) for getting digits from a user.
- `finishOnKey`: key which will terminate the action of getting digits.
- `callbackUrl`: URL to forward the results of the GetDigits action.
- `dial($options)`: Add a `Dial` action
- `phoneNumbers`: An array of phone numbers (in international format) to call. `REQUIRED`
- `record`: Boolean - Whether to record the conversation.
- `sequenntial`: Boolean - If many numbers provided for `phoneNumbers`, determines whether the phone numbers will be dialed one after the other or at the same time.
- `callerId`: Africa's Talking number you want to dial out with.
- `ringBackTone`: URL location of a media playback you would want the user to listen to when the call has been placed before its picked up.
- `maxDuration`: maximum amount of time in seconds a call should take.
- `conference()`: Add a `Conference` action
- `record($options)`: Add a `Record` action
- `finishOnKey`: Key which will terminate the action of recording.
- `maxLength`: Maximum amount of time in seconds a recording should take.
- `timeout`: Timeout (in seconds) for getting a recording from a user.
- `trimSilence`: Boolean - Specifies whether you want to remove the initial and final parts of a recording where user was silent.
- `playBeep`: Boolean - Specifies whether the API should play a beep when recording starts.
- `callbackUrl`: URL to forward the results of the Recording action.
- `enqueue($options)`: Add an `Enqueue` action
- `holdMusic`: URL to the file to be played while the user is on hold.
- `name`: Name of queue to put call on.
- `deqeue($options)`: Add a `Dequeue` acton
- `phoneNumber`: Phone number mapped to your Africa's Talking account which a user called to join the queue. `REQUIRED`
- `name`: Name of queue you want to dequeue from.
- `reject()`: Add a `Reject` action
- `redirect($url)`: Add a `Redirect` action
- `url`: URL to transfer control of the call to
- `build()`: Build the xml after chaining some of the above actions
### Token
- `generateAuthToken()`: Generate an auth token to use for authenticating API requests instead of your API key.
## Testing the SDK
The SDK uses [PHPUnit](https://phpunit.de/manual/current/en/index.html) as the test runner.
To run available tests, from the root of the project run:
```bash
# Configure needed fixtures, e.g sandbox api key, Africa's Talking products
cp tests/Fixtures.php.tpl tests/Fixtures.php
# Run tests
phpunit --testdox
```
## Issues
If you find a bug, please file an issue on [our issue tracker on GitHub](https://github.com/AfricasTalkingLtd/africastalking-php/issues).
@@ -0,0 +1,32 @@
{
"name": "africastalking/africastalking",
"description": "Official Africa's Talking PHP SDK",
"keywords": ["sms", "voice", "ussd", "text message", "airtime", "api", "africastalking"],
"homepage": "http://github.com/AfricasTalkingLtd/africastalking-php",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Africas's Talking",
"email": "support@africastalking.com",
"homepage": "https://www.africastalking.com"
}
],
"require": {
"php": ">=7.1",
"guzzlehttp/guzzle": "^6.0 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^9.3"
},
"autoload": {
"psr-4": {
"AfricasTalking\\SDK\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"AfricasTalking\\SDK\\Tests\\": "tests"
}
}
}
@@ -0,0 +1,137 @@
<?php
namespace AfricasTalking\SDK;
use GuzzleHttp\Client;
class AfricasTalking
{
const BASE_DOMAIN = "africastalking.com";
const BASE_SANDBOX_DOMAIN = "sandbox." . self::BASE_DOMAIN;
protected $username;
protected $apiKey;
protected $client;
protected $contentClient;
protected $voiceClient;
protected $tokenClient;
protected $mobileDataClient;
protected $baseDomain;
public $baseUrl;
protected $voiceUrl;
protected $checkoutTokenUrl;
protected $contentUrl;
protected $mobileDataUrl;
public function __construct($username, $apiKey)
{
if($username === 'sandbox') {
$this->baseDomain = self::BASE_SANDBOX_DOMAIN;
} else {
$this->baseDomain = self::BASE_DOMAIN;
}
$this->baseUrl = "https://api." . $this->baseDomain . "/version1/";
$this->voiceUrl = "https://voice." . $this->baseDomain . "/";
$this->mobileDataUrl = "https://bundles." . $this->baseDomain . "/";
$this->contentUrl = ($username === "sandbox") ? ($this->baseUrl) : ("https://content." . $this->baseDomain . "/version1/");
$this->checkoutTokenUrl = "https://api." . $this->baseDomain . "/";
if ($username === 'sandbox') {
$this->contentUrl = $this->baseUrl;
}
$this->username = $username;
$this->apiKey = $apiKey;
$this->client = new Client([
'base_uri' => $this->baseUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json'
]
]);
$this->contentClient = new Client([
'base_uri' => $this->contentUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json'
]
]);
$this->voiceClient = new Client([
'base_uri' => $this->voiceUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json'
]
]);
$this->mobileDataClient = new Client([
'base_uri' => $this->mobileDataUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json'
]
]);
$this->tokenClient = new Client([
'base_uri' => $this->checkoutTokenUrl,
'headers' => [
'apikey' => $this->apiKey,
'Content-Type' => 'application/json',
'Accept' => 'application/json'
]
]);
}
public function sms()
{
$content = new Content($this->contentClient, $this->username, $this->apiKey);
$sms = new SMS($this->client, $this->username, $this->apiKey, $content);
return $sms;
}
public function content()
{
$content = new Content($this->contentClient, $this->username, $this->apiKey);
return $content;
}
public function airtime()
{
$airtime = new Airtime($this->client, $this->username, $this->apiKey);
return $airtime;
}
public function voice()
{
$voice = new Voice($this->voiceClient, $this->username, $this->apiKey);
return $voice;
}
public function application()
{
$application = new Application($this->client, $this->username, $this->apiKey);
return $application;
}
public function mobileData()
{
$mobileData = new MobileData($this->mobileDataClient, $this->username, $this->apiKey);
return $mobileData;
}
public function token()
{
$token = new Token($this->tokenClient, $this->username, $this->apiKey);
return $token;
}
}
@@ -0,0 +1,132 @@
<?php
namespace AfricasTalking\SDK;
class Content extends Service
{
public function send ($options)
{
if (empty($options['to']) || empty($options['message'])) {
return $this->error('recipient and message must be defined');
}
if (!is_array($options['to'])) {
$options['to'] = [$options['to']];
}
$data = [
'username' => $this->username,
'to' => implode(",", $options['to']),
'message' => $options['message']
];
if (array_key_exists('enqueue', $options) && $options['enqueue']) {
$data['enqueue'] = 1;
}
if (empty($options['from'])) {
return [
'status' => 'error',
'data' => 'from is required for premium SMS'
];
} else {
$data['from'] = $options['from'];
}
if (!empty($options['keyword'])) {
$data['keyword'] = $options['keyword'];
}
if (!empty($options['linkId'])) {
$data['linkId'] = $options['linkId'];
}
if (!empty($options['retryDurationInHours'])) {
$data['retryDurationInHours'] = $options['retryDurationInHours'];
}
// turn off bulk sms mode
$data['bulkSMSMode'] = 0;
$response = $this->client->post('messaging', ['form_params' => $data ]);
return $this->success($response);
}
public function createSubscription ($options)
{
if (empty($options['phoneNumber']) ||
empty($options['shortCode']) ||
empty($options['keyword'])) {
return $this->error("phoneNumber, shortCode and keyword must be specified");
}
$data = [
'username' => $this->username,
'phoneNumber' => $options['phoneNumber'],
'shortCode' => $options['shortCode'],
'keyword' => $options['keyword']
];
/**
* checkoutToken Key was removed in commit:339f7057d8ff640ffa9802b4d3a812848b1072a9.
* To prevent breaking applications in production, we conditionally add it to
* the request otherwise previous behaviour persists.
**/
if(array_key_exists('checkoutToken',$options)){
$data['checkoutToken'] = $options['checkoutToken'];
}
$response = $this->client->post('subscription/create', ['form_params' => $data ] );
return $this->success($response);
}
public function deleteSubscription ($options)
{
if (empty($options['phoneNumber']) ||
empty($options['shortCode']) ||
empty($options['keyword'])) {
return $this->error("phoneNumber, shortCode and keyword must be specified");
}
$data = [
'username' => $this->username,
'phoneNumber' => $options['phoneNumber'],
'shortCode' => $options['shortCode'],
'keyword' => $options['keyword']
];
$response = $this->client->post('subscription/delete', ['form_params' => $data ] );
return $this->success($response);
}
public function fetchSubscriptions($options)
{
if(empty($options['shortCode']) || empty($options['keyword'])) {
return $this->error("shortCode and keyword must be specified");
}
if (empty($options['lastReceivedId'])) {
$options['lastReceivedId'] = 0;
}
if (!is_numeric($options['lastReceivedId'])) {
return $this->error('lastReceivedId must be an integer');
}
$data = [
'username' => $this->username,
'lastReceivedId' => $options['lastReceivedId'],
'shortCode' => $options['shortCode'],
'keyword' => $options['keyword']
];
$response = $this->client->get('subscription', ['query' => $data ] );
return $this->success($response);
}
}
@@ -0,0 +1,104 @@
<?php
namespace AfricasTalking\SDK;
class MobileData extends Service
{
public function __call($method, $args)
{
// First check if method exists
if (method_exists($this, 'do' . $method)) {
$func = 'do' . $method;
if (!isset($args[0])) {
$args = [ 0 => ''];
}
return $this->$func($args[0]);
} else {
return $this->error($method .' is an invalid Mobile Data SDK Method');
}
}
protected function doSend($parameters, $options = [])
{
// Check if productName is set
if (!isset($parameters['productName'])) {
return $this->error('productName must be defined');
}
$productName = $parameters['productName'];
// Check if recipients array is provided
if (!isset($parameters['recipients'])) {
return $this->error('recipients must be an array containing phoneNumber, unit, quatity, validity and metadata');
} else if (isset($parameters['recipients']) && is_array($parameters['recipients'])) {
$recipients = $parameters['recipients'];
foreach ($recipients as $r) {
if (!isset($r['phoneNumber']) ||
!isset($r['quantity']) ||
!isset($r['unit']) ||
!isset($r['validity']) ||
!isset($r['metadata'])) {
return $this->error('recipients must be an array containing phoneNumber, quantity, unit, validity and metadata');
}
if (isset($r['validity'])) {
if (!in_array($r['validity'], ['Day', 'Month', 'Week'])) {
return $this->error('validity must be one of Day, Week, Month');
}
}
if (isset($r['unit'])) {
if (!in_array($r['unit'], ['MB', 'GB'])) {
return $this->error('unit must be one of MB, GB');
}
}
}
}
// Make request data array
$requestData = [
'username' => $this->username,
'productName' => $productName,
'recipients' => $recipients,
];
$requestOptions = [
'json' => $requestData,
];
if(isset($options['idempotencyKey'])) {
$requestOptions['headers'] = [
'Idempotency-Key' => $options['idempotencyKey'],
];
}
$response = $this->client->post('mobile/data/request', $requestOptions);
return $this->success($response);
}
protected function doFindTransaction($options)
{
if (!isset($options['transactionId'])) {
return $this->error('transactionId must be defined');
}
$requestData = [
'username' => $this->username,
'transactionId' => $options['transactionId']
];
$response = $this->client->get('query/transaction/find', ['query' => $requestData]);
return $this->success($response);
}
protected function doFetchWalletBalance()
{
$requestData = [
'username' => $this->username
];
$response = $this->client->get('query/wallet/balance', ['query' => $requestData]);
return $this->success($response);
}
}
@@ -0,0 +1,47 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class AfricasTalkingTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$this->client = new AfricasTalking($this->username, $this->apiKey);
}
public function testSMSClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\SMS::class, $this->client->sms());
}
public function testContentClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\Content::class, $this->client->content());
}
public function testAirtimeClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\Airtime::class, $this->client->airtime());
}
public function testVoiceClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\Voice::class, $this->client->voice());
}
public function testApplicationClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\Application::class, $this->client->application());
}
public function testMobileDataClass()
{
$this->assertInstanceOf(\AfricasTalking\SDK\MobileData::class, $this->client->mobileData());
}
}
@@ -0,0 +1,64 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class AirtimeTest extends \PHPUnit\Framework\TestCase
{
public function setup(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->airtime();
}
public function testSendAirtimeToOne()
{
$response = $this->client->send([
'recipients' => [[
'phoneNumber' => Fixtures::$phoneNumber,
'currencyCode' => Fixtures::$currencyCode,
'amount' => Fixtures::$amount
]]
]);
$this->assertObjectHasProperty('responses', $response['data']);
}
public function testSendAirtimeIdempotency()
{
$response = $this->client->send([
'recipients' => [[
'phoneNumber' => Fixtures::$phoneNumber,
'currencyCode' => Fixtures::$currencyCode,
'amount' => Fixtures::$amount
]]
], [
'idempotencyKey' => 'req-' . mt_rand(10, 100),
]);
$this->assertObjectHasProperty('responses', $response['data']);
}
public function testSendAirtimeToMany()
{
$response = $this->client->send([
'recipients' => [[
'phoneNumber' => Fixtures::$phoneNumber,
'currencyCode' => Fixtures::$currencyCode,
'amount' => Fixtures::$amount
], [
'phoneNumber' => '+2347038151149',
'currencyCode' => 'NGN',
'amount' => '10000'
]]
]);
$this->assertObjectHasProperty('responses', $response['data']);
}
}
@@ -0,0 +1,25 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class ApplicationTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->application();
}
public function testFetchAplication()
{
$response = $this->client->fetchApplicationData();
$this->assertObjectHasProperty('UserData', $response['data']);
}
}
@@ -0,0 +1,67 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class ContentTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->content();
$this->tokenClient = $at->token();
}
public function send()
{
$response = $this->client->send([
'to' => Fixtures::$multiplePhoneNumbersSMS,
'linkId' => 'messageLinkId',
'keyword' => Fixtures::$keyword,
'from' => Fixtures::$shortCode,
'message' => 'Testing Premium...'
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testCreateSubscription()
{
$response = $this->client->createSubscription([
'phoneNumber' => Fixtures::$phoneNumber,
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword,
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('success',$response['status']);
}
public function testDeleteSubscription()
{
$response = $this->client->deleteSubscription([
'phoneNumber' => Fixtures::$phoneNumber,
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('success',$response['status']);
}
public function testFetchSubscriptions()
{
$response = $this->client->fetchSubscriptions([
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword
]);
$this->assertObjectHasProperty('responses', $response['data']);
}
}
@@ -0,0 +1,138 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class SMSTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->sms();
$this->tokenClient = $at->token();
}
public function testSMSWithEmptyMessage()
{
$response = $this->client->send([
'to' => Fixtures::$multiplePhoneNumbersSMS,
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
public function testSMSWithEmptyRecipient()
{
$response = $this->client->send([
'message' => 'Testing...'
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
public function testSingleSMSSending()
{
$response = $this->client->send([
'to' => Fixtures::$phoneNumber,
'message' => 'Testing SMS...'
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testMultipleSMSSending()
{
$response = $this->client->send([
'to' => Fixtures::$multiplePhoneNumbersSMS,
'message' => 'Testing multiple sending...'
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testSMSSendingWithShortcode()
{
$response = $this->client->send([
'to' => Fixtures::$multiplePhoneNumbersSMS,
'message' => 'Testing with short code...',
'from' => Fixtures::$shortCode
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testSMSSendingWithAlphanumeric()
{
$response = $this->client->send([
'to' => Fixtures::$multiplePhoneNumbersSMS,
'message' => 'Testing with AlphaNumeric...',
'from' => Fixtures::$alphanumeric
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testPremiumSMSSending()
{
$response = $this->client->sendPremium([
'to' => Fixtures::$multiplePhoneNumbersSMS,
'linkId' => 'messageLinkId',
'keyword' => Fixtures::$keyword,
'from' => Fixtures::$shortCode,
'message' => 'Testing Premium...'
]);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testFetchMessages()
{
$response = $this->client->fetchMessages(['lastReceivedId' => '8796']);
$this->assertObjectHasProperty('SMSMessageData', $response['data']);
}
public function testCreateSubscription()
{
$response = $this->client->createSubscription([
'phoneNumber' => Fixtures::$phoneNumber,
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword,
]);
$this->assertArrayHasKey('status',$response);
$this->assertArrayHasKey('data',$response);
$this->assertEquals('success',$response['status']);
$this->assertEquals('Success',$response['data']->status);
}
public function testDeleteSubscription()
{
$response = $this->client->deleteSubscription([
'phoneNumber' => Fixtures::$phoneNumber,
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('success',$response['status']);
}
public function testFetchSubscriptions()
{
$response = $this->client->fetchSubscriptions([
'shortCode' => Fixtures::$shortCode,
'keyword' => Fixtures::$keyword
]);
$this->assertObjectHasProperty('responses', $response['data']);
}
}
@@ -0,0 +1,25 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class TokenTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->token();
}
public function testGenerateAuthToken()
{
$response = $this->client->generateAuthToken();
$this->assertEquals(3600, $response['data']->lifetimeInSeconds);
}
}
@@ -0,0 +1,91 @@
<?php
namespace AfricasTalking\SDK\Tests;
use AfricasTalking\SDK\AfricasTalking;
use GuzzleHttp\Exception\GuzzleException;
#[\AllowDynamicProperties]
class VoiceTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->username = Fixtures::$username;
$this->apiKey = Fixtures::$apiKey;
$at = new AfricasTalking($this->username, $this->apiKey);
$this->client = $at->voice();
}
public function testCall()
{
$response = $this->client->call([
'from' => Fixtures::$voicePhoneNumber,
'to' => Fixtures::$voicePhoneNumber2
]);
$this->assertObjectHasProperty('entries', $response['data']);
}
public function testCallsMustHaveRequiredAttributes()
{
$response = $this->client->call([
'from' => Fixtures::$voicePhoneNumber
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
public function testFetchQueuedCalls()
{
$response = $this->client->fetchQueuedCalls([
'phoneNumber' => Fixtures::$voicePhoneNumber,
'name' => 'someQueueName'
]);
$this->assertArrayHasKey('status', $response);
}
public function testFetchQueuedCallsMustHaveRequiredAttributes()
{
$response = $this->client->fetchQueuedCalls();
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
public function testUploadMediaFile()
{
$response = $this->client->uploadMediaFile([
'phoneNumber' => Fixtures::$voicePhoneNumber,
'url' => Fixtures::$mediaUrl
]);
$this->assertArrayHasKey('status', $response);
}
public function testuploadMediaFileMustHaveRequiredAttributes()
{
$response = $this->client->uploadMediaFile([
'url' => 'test@google'
]);
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
public function testuploadMediaFileCannotBeEmpty()
{
$response = $this->client->uploadMediaFile();
$this->assertArrayHasKey('status',$response);
$this->assertEquals('error',$response['status']);
}
// public function testMessageBuilder()
// {
// // TODO
// }
}