mirror of
https://gitlab.com/signalytic/client-external/streamline/streamline-emr.git
synced 2026-09-13 11:41:31 +00:00
updated streamline-setup v2
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
vendor/
|
||||
tests/Fixtures.php
|
||||
.idea/
|
||||
/.phpunit.result.cache
|
||||
.phpunit.cache/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Africa's Talking
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,246 @@
|
||||
# Africa's Talking PHP SDK
|
||||
|
||||
[](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`
|
||||
|
||||
- `isPromoBundle`: This is an optional field that can be either `true` or `false`.
|
||||
|
||||
- **$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).
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"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/",
|
||||
"AfricasTalking\\SDK\\Tests\\": "tests"
|
||||
}
|
||||
}
|
||||
}
|
||||
+2350
File diff suppressed because it is too large
Load Diff
+12
@@ -0,0 +1,12 @@
|
||||
# Example
|
||||
|
||||
|
||||
**Run**
|
||||
|
||||
First, make sure to put your sandbox api key in `index.php`, then:
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
$ php -S localhost:9090
|
||||
$ # open http://localhost:9090
|
||||
```
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "africastalking-example",
|
||||
"description": "Simple SDK usage",
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"africastalking/africastalking": "dev-develop",
|
||||
"altorouter/altorouter": "1.1.0"
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
|
||||
$username = "sandbox";
|
||||
$apiKey = getenv("API_KEY");
|
||||
|
||||
$AT = new AfricasTalking($username, $apiKey);
|
||||
|
||||
// Router
|
||||
$router = new AltoRouter();
|
||||
|
||||
$router->map( 'GET', '/', function() {
|
||||
require __DIR__ . '/views/index.php';
|
||||
});
|
||||
|
||||
$router->map( 'POST', '/auth/register/[*:phone]', function ($phone) {
|
||||
global $AT;
|
||||
$sms = $AT->sms();
|
||||
$response = $sms->send(array(
|
||||
"to" => $phone,
|
||||
"from" => "AT2FA",
|
||||
"message" => "Welcome to Awesome Company",
|
||||
));
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
echo json_encode($response);
|
||||
});
|
||||
|
||||
$router->map( 'POST', '/airtime/[*:phone]', function ($phone) {
|
||||
global $AT;
|
||||
$airtime = $AT->airtime();
|
||||
$response = $airtime->send(array(
|
||||
"recipients" => array(
|
||||
array(
|
||||
"phoneNumber" => $phone,
|
||||
"amount" => $_GET['amount'],
|
||||
)
|
||||
)
|
||||
));
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
echo json_encode($response);
|
||||
});
|
||||
|
||||
$match = $router->match();
|
||||
if( $match && is_callable( $match['target'] ) ) {
|
||||
call_user_func_array( $match['target'], $match['params'] );
|
||||
} else {
|
||||
header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/* Space out content a bit */
|
||||
body {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
/* Everything but the jumbotron gets side spacing for mobile first views */
|
||||
.header,
|
||||
.marketing,
|
||||
.footer {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
/* Custom page header */
|
||||
.header {
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
/* Make the masthead heading the same height as the navigation */
|
||||
.header h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
line-height: 40px;
|
||||
}
|
||||
/* Custom page footer */
|
||||
.footer {
|
||||
padding-top: 19px;
|
||||
color: #777;
|
||||
}
|
||||
/* Customize container */
|
||||
@media (min-width: 768px) {
|
||||
/*.container {
|
||||
max-width: 1200px;
|
||||
}*/
|
||||
}
|
||||
.container-narrow > hr {
|
||||
margin: 30px 0;
|
||||
}
|
||||
/* Main marketing message and sign up button */
|
||||
.jumbotron {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
/*.jumbotron .btn {
|
||||
padding: 14px 24px;
|
||||
font-size: 21px;
|
||||
}*/
|
||||
/* Supporting marketing content */
|
||||
.marketing {
|
||||
margin: 40px 0;
|
||||
}
|
||||
.marketing p + h4 {
|
||||
margin-top: 28px;
|
||||
}
|
||||
/* Responsive: Portrait tablets and up */
|
||||
@media screen and (min-width: 768px) {
|
||||
/* Remove the padding we set earlier */
|
||||
.header,
|
||||
.marketing,
|
||||
.footer {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
/* Space out the masthead */
|
||||
.header {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
/* Remove the bottom border on the jumbotron for visual effect */
|
||||
.jumbotron {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
background: white;
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
"use strict";
|
||||
|
||||
$(function () {
|
||||
|
||||
|
||||
function log(message) {
|
||||
$("#response").text(message);
|
||||
$('pre span').each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
|
||||
$("#signUp").click(() => {
|
||||
let phone = $("#phone").val();
|
||||
if (!phone) {
|
||||
log(JSON.stringify({ error: "Enter a phone number"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
log("Sending SMS...");
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/auth/register/${phone}`,
|
||||
success: (resp) => {
|
||||
try {
|
||||
log(JSON.stringify(resp, null, 2));
|
||||
} catch (ex) {
|
||||
log(resp);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("#airtime").click(() => {
|
||||
const phone = $("#phone").val();
|
||||
const amount = $("#amount").val();
|
||||
if (!phone) {
|
||||
log(JSON.stringify({ error: "Enter a phone number"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!amount) {
|
||||
log(JSON.stringify({ error: "Enter an amount (with currency) e,g, KES 334"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
log("Sending Airtime...");
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/airtime/${phone}?amount=${amount}`,
|
||||
success: (resp) => {
|
||||
try {
|
||||
log(JSON.stringify(resp, null, 2));
|
||||
} catch (ex) {
|
||||
log(resp);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("#mobileCheckout").click(() => {
|
||||
const phone = $("#phone").val();
|
||||
const amount = $("#mobileCheckoutAmount").val();
|
||||
if (!phone) {
|
||||
log(JSON.stringify({ error: "Enter a phone number"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!amount) {
|
||||
log(JSON.stringify({ error: "Enter an amount (with currency) e,g, KES 334"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
log("Initiating Mobile Checkout...");
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/mobile/checkout/${phone}?amount=${amount}`,
|
||||
success: (resp) => {
|
||||
try {
|
||||
log(JSON.stringify(resp, null, 2));
|
||||
} catch (ex) {
|
||||
log(resp);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$("#mobileB2C").click(() => {
|
||||
const phone = $("#phone").val();
|
||||
const amount = $("#mobileB2CAmount").val();
|
||||
if (!phone) {
|
||||
log(JSON.stringify({ error: "Enter a phone number"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!amount) {
|
||||
log(JSON.stringify({ error: "Enter an amount (with currency) e,g, KES 334"}, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
log("Initiating Mobile B2C...");
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: `/mobile/b2c/${phone}?amount=${amount}`,
|
||||
success: (resp) => {
|
||||
try {
|
||||
log(JSON.stringify(resp, null, 2));
|
||||
} catch (ex) {
|
||||
log(resp);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Africa's Talking</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/paper/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/tomorrow.min.css" />
|
||||
<link href="public/css/style.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="header clearfix">
|
||||
<nav>
|
||||
<ul class="nav nav-pills pull-right">
|
||||
<li role="presentation" class="active"><a href="#">Home</a></li>
|
||||
<li role="presentation"><a href="http://docs.africastalking.com" target="_blank">Docs</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h3 class="text-muted">Africa's Talking</h3>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="col-md-6">
|
||||
<pre><span id="response"></span></pre>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p class="lead">Try clicking some buttons</p>
|
||||
<div class="col-sm-6 col-offset-sm-3">
|
||||
<input id="phone" type="text" class="form-control" placeholder="Your phone number">
|
||||
</div>
|
||||
<p><a class="btn btn-success btn-sm" role="button" id="signUp">Send SMS</a></p>
|
||||
<div class="col-sm-6 col-offset-sm-3">
|
||||
<input id="amount" type="text" class="form-control" placeholder="Amount e.g. USD 35">
|
||||
</div>
|
||||
<p><a class="btn btn-success btn-sm" role="button" id="airtime">Airtime</a></p>
|
||||
<div class="col-sm-6 col-offset-sm-3">
|
||||
<input id="mobileCheckoutAmount" type="text" class="form-control" placeholder="Amount e.g. KES 4456">
|
||||
</div>
|
||||
<p><a class="btn btn-success btn-sm" role="button" id="mobileCheckout">Mobile Checkout</a></p>
|
||||
<div class="col-sm-6 col-offset-sm-3">
|
||||
<input id="mobileB2CAmount" type="text" class="form-control" placeholder="Amount e.g. KES 4456">
|
||||
</div>
|
||||
<p><a class="btn btn-success btn-sm" role="button" id="mobileB2C">Mobile B2C</a></p>
|
||||
</div>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/json.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/javascript.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/xml.min.js"></script>
|
||||
<script src="public/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="./vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
|
||||
<testsuites>
|
||||
<testsuite name="AfricasTalking Test Suite">
|
||||
<directory suffix="Test.php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
<?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 $voiceClient;
|
||||
protected $tokenClient;
|
||||
protected $contentClient;
|
||||
protected $mobileDataClient;
|
||||
|
||||
public $baseUrl;
|
||||
protected $voiceUrl;
|
||||
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,62 @@
|
||||
<?php
|
||||
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
class Airtime extends Service
|
||||
{
|
||||
public function send($parameters, $options = [])
|
||||
{
|
||||
if(empty($parameters['recipients'])) {
|
||||
return $this->error("recipients must be specified");
|
||||
}
|
||||
|
||||
if(!is_array($parameters['recipients'])) {
|
||||
return $this->error("recipients must be an array");
|
||||
}
|
||||
|
||||
foreach ($parameters['recipients'] as $key=>$recipient){
|
||||
|
||||
if(!is_array($recipient)) {
|
||||
return $this->error("every recipient must be an array");
|
||||
}
|
||||
|
||||
if(!array_key_exists('phoneNumber', $recipient) || !array_key_exists('currencyCode', $recipient) || !array_key_exists('amount', $recipient)) {
|
||||
return $this->error("phoneNumber, currencyCode and amount must be specified for each recipient");
|
||||
}
|
||||
|
||||
$currencyCode = $recipient['currencyCode'];
|
||||
if (strlen($currencyCode) != 3) {
|
||||
return $this->error('currencyCode must be in 3-digit ISO format');
|
||||
}
|
||||
|
||||
$recipient['amount'] = $recipient['currencyCode'].' '.$recipient['amount'];
|
||||
|
||||
unset($recipient['currencyCode']);
|
||||
|
||||
$parameters['recipients'][$key] = $recipient;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'username' => $this->username,
|
||||
'recipients' => json_encode($parameters['recipients'])
|
||||
];
|
||||
|
||||
if (isset($options['maxNumRetry']) && is_numeric($options['maxNumRetry']) && $options['maxNumRetry'] > 0) {
|
||||
$data['maxNumRetry'] = $options['maxNumRetry'];
|
||||
}
|
||||
|
||||
$requestOptions = [
|
||||
'form_params' => $data,
|
||||
];
|
||||
|
||||
if(isset($options['idempotencyKey'])) {
|
||||
$requestOptions['headers'] = [
|
||||
'Idempotency-Key' => $options['idempotencyKey'],
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->post('airtime/send', $requestOptions);
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
class Application extends Service
|
||||
{
|
||||
public function doFetchApplication()
|
||||
{
|
||||
$response = $this->client->get('user', ['query' => ['username'=> $this->username]]);
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
public function fetchApplicationData()
|
||||
{
|
||||
return $this->doFetchApplication();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?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']
|
||||
];
|
||||
|
||||
$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);
|
||||
|
||||
}
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
<?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,
|
||||
];
|
||||
|
||||
if (isset($parameters['isPromoBundles'])) {
|
||||
$requestData['isPromoBundle'] = $parameters['isPromoBundles'];
|
||||
}
|
||||
|
||||
$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,82 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
class SMS extends Service
|
||||
{
|
||||
protected $content;
|
||||
|
||||
public function __construct($client, $username, $apiKey, $content)
|
||||
{
|
||||
parent::__construct($client, $username, $apiKey);
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
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'])) {
|
||||
$data['from'] = $options['from'];
|
||||
}
|
||||
|
||||
$response = $this->client->post('messaging', ['form_params' => $data ]);
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
public function fetchMessages($options = [])
|
||||
{
|
||||
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']
|
||||
];
|
||||
|
||||
$response = $this->client->get('messaging', ['query' => $data ] );
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
public function sendPremium($options)
|
||||
{
|
||||
return $this->content->send($options);
|
||||
}
|
||||
|
||||
public function createSubscription ($options)
|
||||
{
|
||||
return $this->content->createSubscription($options);
|
||||
}
|
||||
|
||||
public function deleteSubscription ($options)
|
||||
{
|
||||
return $this->content->deleteSubscription($options);
|
||||
}
|
||||
|
||||
public function fetchSubscriptions($options)
|
||||
{
|
||||
return $this->content->fetchSubscriptions($options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
abstract class Service
|
||||
{
|
||||
protected $client;
|
||||
|
||||
protected $username;
|
||||
|
||||
protected $apiKey;
|
||||
|
||||
public function __construct($client, $username, $apiKey)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->username = $username;
|
||||
$this->apiKey = $apiKey;
|
||||
}
|
||||
|
||||
protected static function error($data) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'data' => $data
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected static function success($data) {
|
||||
return [
|
||||
'status' => 'success',
|
||||
'data' => json_decode($data->getBody()->getContents())
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
class Token extends Service
|
||||
{
|
||||
public function generateAuthToken()
|
||||
{
|
||||
$requestData = json_encode(['username' => $this->username]);
|
||||
$response = $this->client->post('auth-token/generate', ['body' => $requestData ] );
|
||||
return $this->success($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
<?php
|
||||
|
||||
namespace AfricasTalking\SDK;
|
||||
|
||||
class Voice extends Service
|
||||
{
|
||||
private $xmlString;
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// First check if method exists
|
||||
if (method_exists($this, 'build' . $method)) {
|
||||
if (!isset($args[0])) {
|
||||
$args = [ 0 => ''];
|
||||
}
|
||||
return $this->stringBuilder('build'. $method, $args[0]);
|
||||
} else if (method_exists($this, 'do' . $method)) {
|
||||
if (!isset($args[0])) {
|
||||
$args = [ 0 => ''];
|
||||
}
|
||||
return $this->apiCall('do' . $method, $args[0]);
|
||||
} else {
|
||||
return $this->error($method .' is an invalid Voice SDK Method');
|
||||
}
|
||||
}
|
||||
|
||||
public function messageBuilder()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function stringBuilder($method, $args)
|
||||
{
|
||||
$result = $this->$method($args);
|
||||
|
||||
if (empty($this->xmlString)) {
|
||||
$this->xmlString = '<?xml version="1.0" encoding="UTF-8"?><Response>'. $result;
|
||||
} else {
|
||||
$this->xmlString .= $result;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function apiCall($method, $args)
|
||||
{
|
||||
return $this->$method($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds XML string from chained voice actions
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
if (empty($this->xmlString)) {
|
||||
return null;
|
||||
}
|
||||
return $this->xmlString . '</Response>';
|
||||
}
|
||||
|
||||
protected function doCall($options)
|
||||
{
|
||||
if (!isset($options['to']) || !isset($options['from'])) {
|
||||
return $this->error('The parameters to and from must be defined');
|
||||
}
|
||||
|
||||
// Validate callTo
|
||||
$checkCallTo = strpos($options['to'], '+');
|
||||
if ($checkCallTo === false || $checkCallTo !== 0) {
|
||||
return $this->error('callTo must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
|
||||
// Validate callFrom
|
||||
$checkCallFrom = strpos($options['from'], '+');
|
||||
if ($checkCallFrom === false || $checkCallFrom !== 0) {
|
||||
return $this->error('callFrom must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
|
||||
$requestData = [
|
||||
'username' => $this->username,
|
||||
'to' => $options['to'],
|
||||
'from' => $options['from']
|
||||
];
|
||||
|
||||
if (isset($options['clientRequestId']) && !empty($options['clientRequestId'])) {
|
||||
$requestData['clientRequestId'] = (string) $options['clientRequestId'];
|
||||
}
|
||||
|
||||
$response = $this->client->post('call', ['form_params' => $requestData ] );
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
protected function doUploadMediaFile($options)
|
||||
{
|
||||
// Check and validate phoneNumber
|
||||
if (!isset($options['phoneNumber'])) {
|
||||
return $this->error('Phone number is required and must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
$phoneNumber = $options['phoneNumber'];
|
||||
|
||||
$checkPhoneNumber = strpos($phoneNumber, '+');
|
||||
if ($checkPhoneNumber === false || $checkPhoneNumber != 0) {
|
||||
return $this->error('Phone number must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
|
||||
if (!isset($options['url'])) {
|
||||
return $this->error('url must be defined');
|
||||
}
|
||||
$url = $options['url'];
|
||||
|
||||
// Check if valid URL passed
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
|
||||
return $this->error('URL not valid');
|
||||
}
|
||||
|
||||
$requestData = [
|
||||
'username' => $this->username,
|
||||
'phoneNumber' => $phoneNumber,
|
||||
'url' => $url
|
||||
];
|
||||
|
||||
$response = $this->client->post('mediaUpload', ['form_params' => $requestData]);
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
protected function dofetchQueuedCalls($options)
|
||||
{
|
||||
// Check and validate phoneNumber
|
||||
if (!isset($options['phoneNumber'])) {
|
||||
return $this->error('Phone number is required and must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
$phoneNumber = $options['phoneNumber'];
|
||||
|
||||
$checkPhoneNumber = strpos($phoneNumber, '+');
|
||||
if ($checkPhoneNumber === false || $checkPhoneNumber != 0) {
|
||||
return $this->error('Phone number must be in the format \'+2XXYYYYYYYYY\'');
|
||||
}
|
||||
|
||||
$requestData = [
|
||||
'username' => $this->username,
|
||||
'phoneNumbers' => $phoneNumber
|
||||
];
|
||||
|
||||
if(isset($options['name'])) {
|
||||
$requestData['name'] = $options['name'];
|
||||
}
|
||||
|
||||
$response = $this->client->post('queueStatus', ['form_params' => $requestData]);
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
protected function buildSay($options)
|
||||
{
|
||||
|
||||
if (is_string($options)) {
|
||||
return "<Say>$options</Say>";
|
||||
}
|
||||
|
||||
// Check for text
|
||||
if (!isset($options['text'])) {
|
||||
return $this->error('Please set text to be read out');
|
||||
}
|
||||
$text = $options['text'];
|
||||
|
||||
// Check if read out voice has been set
|
||||
if (isset($options['voice'])) {
|
||||
$voice = $options['voice'];
|
||||
}
|
||||
|
||||
// Check if playBeep option has been set
|
||||
if (isset($options['playBeep'])) {
|
||||
$playBeep = $options['playBeep'];
|
||||
}
|
||||
|
||||
if (isset($options['voice']) && isset($options['playBeep'])) {
|
||||
$sayString = '<Say voice="' . $voice . '" playBeep="'. $playBeep .'">'. $text .'</Say>';
|
||||
} else if (isset($options['voice'])) {
|
||||
$sayString = '<Say voice="' . $voice . '">'. $text .'</Say>';
|
||||
} else if (isset($options['playBeep'])) {
|
||||
$sayString = '<Say playBeep="'. $playBeep .'">'. $text .'</Say>';
|
||||
} else {
|
||||
$sayString = "<Say>$text</Say>";
|
||||
}
|
||||
|
||||
return $sayString;
|
||||
}
|
||||
|
||||
protected function buildPlay($url)
|
||||
{
|
||||
if (!$this->isValidURL($url))
|
||||
return $this->error('Play URL is not valid');
|
||||
|
||||
$playString = '<Play url="'. $url . '"/>';
|
||||
|
||||
return $playString;
|
||||
}
|
||||
|
||||
protected function buildGetDigits($options) {
|
||||
|
||||
// Check for text
|
||||
if (!isset($options['text'])) {
|
||||
return $this->error('Please set text to be read out');
|
||||
}
|
||||
$text = $options['text'];
|
||||
|
||||
// Check if URL is set
|
||||
if (isset($options['url'])) {
|
||||
$url = $options['url'];
|
||||
}
|
||||
|
||||
// Get number of digits
|
||||
if(isset($options['numDigits'])) {
|
||||
$numDigits = $options['numDigits'];
|
||||
if (!is_numeric($numDigits)) {
|
||||
return $this->error('Please set a number value for the timeout');
|
||||
}
|
||||
}
|
||||
|
||||
// Get timeout
|
||||
if(isset($options['timeout'])) {
|
||||
$timeout = $options['timeout'];
|
||||
if (!is_numeric($timeout)) {
|
||||
return $this->error('Please set a number value for the timeout');
|
||||
}
|
||||
}
|
||||
|
||||
// Get finishOnKey
|
||||
$finishOnKey = $options['finishOnKey'];
|
||||
|
||||
// Get callbackURL
|
||||
if (isset($options['callBackUrl'])) {
|
||||
$callBackUrl = $options['callBackUrl'];
|
||||
if (!$this->isValidURL($callBackUrl)) {
|
||||
return $this->error('Please set a valid callback URL');
|
||||
}
|
||||
}
|
||||
|
||||
// -- NOW TO BUILD STRING
|
||||
|
||||
// Build opening tag
|
||||
$getDigitsString = '<GetDigits ';
|
||||
if (!empty($finishOnKey)) {
|
||||
$getDigitsString .= ' finishOnKey="'. $finishOnKey .'"';
|
||||
}
|
||||
if (!empty($timeout)) {
|
||||
$getDigitsString .= ' timeout="'. $timeout .'"';
|
||||
}
|
||||
if (!empty($numDigits)) {
|
||||
$getDigitsString .= ' numDigits="'. $numDigits .'"';
|
||||
}
|
||||
if (!empty($callBackUrl)) {
|
||||
$getDigitsString .= ' callBackUrl="'. $callBackUrl .'"';
|
||||
}
|
||||
$getDigitsString .= '>';
|
||||
|
||||
// ... add child element
|
||||
if (!empty($text)) {
|
||||
$getDigitsString .= $this->buildSay($text);
|
||||
}
|
||||
|
||||
if (!empty($url)) {
|
||||
$getDigitsString .= $this->buildPlay($url);
|
||||
}
|
||||
|
||||
$getDigitsString .= '</GetDigits>';
|
||||
|
||||
return $getDigitsString;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected function buildDial($options)
|
||||
{
|
||||
|
||||
// Validate phoneNumber
|
||||
if (!isset($options['phoneNumbers'])) {
|
||||
return $this->error('Please specifiy at least one number to dial');
|
||||
}
|
||||
$phoneNumbers = implode(",", $options["phoneNumbers"]);
|
||||
|
||||
// Check if ringback tone is set
|
||||
if (isset($options['ringbackTone'])) {
|
||||
if (!$this->isValidURL($options['ringbackTone'])) {
|
||||
return $this->error('ringbackTone not a valid URL');
|
||||
}
|
||||
$ringbackTone = $options['ringbackTone'];
|
||||
}
|
||||
|
||||
// Check if record is set
|
||||
if (!isset($options['record']) || !is_bool($options['record'])) {
|
||||
$record = false;
|
||||
} else {
|
||||
$record = $options['record'];
|
||||
}
|
||||
// change record to true or false string
|
||||
$record ? $record = "true" : $record ="false";
|
||||
|
||||
// Check if sequential
|
||||
if (!isset($options['sequential']) || !is_bool($options['sequential'])) {
|
||||
$sequential = false;
|
||||
} else {
|
||||
$sequential = $options['sequential'];
|
||||
}
|
||||
// change sequential to true or false string
|
||||
$sequential ? $sequential = "true" : $sequential ="false";
|
||||
|
||||
// Check if callerId is set
|
||||
|
||||
if (!isset($options['callerId']) || !($options['callerId'])) {
|
||||
$callerId = false;
|
||||
} else {
|
||||
$callerId = $options['callerId'];
|
||||
}
|
||||
// change callerId to number provided or false string
|
||||
|
||||
$callerId ? $callerId = $callerId : $callerId ="false";
|
||||
|
||||
// Check if maxDuration is set
|
||||
if(isset($options['maxDuration'])) {
|
||||
$maxDuration = $options['maxDuration'];
|
||||
if (!is_integer($maxDuration) || $maxDuration < 0) {
|
||||
return $this->error('Max duration must be an integer value');
|
||||
}
|
||||
}
|
||||
|
||||
$dialString = '<Dial phoneNumbers="'. $phoneNumbers . '"';
|
||||
if (!empty($record)) {
|
||||
$dialString .= ' record="'. $record .'"';
|
||||
}
|
||||
if (!empty($sequential)) {
|
||||
$dialString .= ' sequential="'. $sequential .'"';
|
||||
}
|
||||
if (!empty($callerId)) {
|
||||
$dialString .= ' callerId="'. $callerId .'"';
|
||||
}
|
||||
if (!empty($ringbackTone)) {
|
||||
$dialString .= ' ringbackTone="'. $ringbackTone .'"';
|
||||
}
|
||||
if (!empty($maxDuration)) {
|
||||
$dialString .= ' maxDuration="'. $maxDuration .'"';
|
||||
}
|
||||
$dialString .= ' />';
|
||||
|
||||
return $dialString;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected function buildRecord($options)
|
||||
{
|
||||
|
||||
/** Terminal Recording **/
|
||||
|
||||
if (empty($options)) {
|
||||
return '<Record />';
|
||||
}
|
||||
|
||||
/** Partial Recording **/
|
||||
|
||||
// Get finishOnKey
|
||||
$finishOnKey = $options['finishOnKey'];
|
||||
|
||||
// Get Max Length
|
||||
if (isset($options['maxLength'])) {
|
||||
$maxLength = $options['maxLength'];
|
||||
if (!is_numeric($maxLength)) {
|
||||
return $this->error('Please set a number value for the timeout');
|
||||
}
|
||||
}
|
||||
|
||||
// Get timeout
|
||||
if (isset($options['timeout'])) {
|
||||
$timeout = $options['timeout'];
|
||||
if (!is_numeric($timeout)) {
|
||||
return $this->error('Please set a number value for the timeout');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if trimSilence is set
|
||||
if (!isset($options['trimSilence']) || !is_bool($options['trimSilence'])) {
|
||||
$trimSilence = false;
|
||||
} else {
|
||||
$trimSilence = $options['trimSilence'];
|
||||
}
|
||||
|
||||
|
||||
// change trimSilence to true or false string
|
||||
$trimSilence ? $trimSilence = "true" : $trimSilence ="false";
|
||||
|
||||
// Check if playBeep option has been set
|
||||
if (!isset($options['playBeep']) || !is_bool($options['playBeep'])) {
|
||||
$playBeep = false;
|
||||
} else {
|
||||
$playBeep = $options['playBeep'];
|
||||
}
|
||||
// change playBeep to true or false string
|
||||
$playBeep ? $playBeep = "true" : $playBeep ="false";
|
||||
|
||||
// Get callbackURL
|
||||
if (isset($options['callBackUrl'])) {
|
||||
$callBackUrl = $options['callBackUrl'];
|
||||
if (!$this->isValidURL($callBackUrl)) {
|
||||
return $this->error('Please set a valid callback URL');
|
||||
}
|
||||
}
|
||||
|
||||
// Build opening tag
|
||||
$recordString = '<Record';
|
||||
if (!empty($finishOnKey)) {
|
||||
$recordString .= ' finishOnKey="'. $finishOnKey .'"';
|
||||
}
|
||||
if (!empty($maxLength)) {
|
||||
$recordString .= ' maxLength="'. $maxLength .'"';
|
||||
}
|
||||
if (!empty($timeout)) {
|
||||
$recordString .= ' timeout="'. $timeout .'"';
|
||||
}
|
||||
if (!empty($trimSilence)) {
|
||||
$recordString .= ' trimSilence="'. $trimSilence .'"';
|
||||
}
|
||||
if (!empty($playBeep)) {
|
||||
$playBeep .= ' playBeep="'. $playBeep .'"';
|
||||
}
|
||||
if (!empty($callBackUrl)) {
|
||||
$getDigitsString .= ' callBackUrl="'. $callBackUrl .'"';
|
||||
}
|
||||
$recordString .= ' />';
|
||||
|
||||
return $recordString;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected function buildEnqueue($options)
|
||||
{
|
||||
// Check if holdMusic option has been set
|
||||
if (isset($options['holdMusic'])) {
|
||||
$holdMusic = $options['holdMusic'];
|
||||
if (!$this->isValidURL($holdMusic)) {
|
||||
return $this->error('Please set a valid URL value for holdMusic');
|
||||
}
|
||||
}
|
||||
|
||||
// Build opening tag
|
||||
$enqueueString = '<Enqueue';
|
||||
if (!empty($holdMusic)) {
|
||||
$enqueueString .= ' holdMusic="'. $holdMusic .'"';
|
||||
}
|
||||
|
||||
if (isset($options['name'])) {
|
||||
$name = $options['name'];
|
||||
$enqueueString .= ' name="'. $name .'"';
|
||||
}
|
||||
$enqueueString .= ' />';
|
||||
|
||||
return $enqueueString;
|
||||
|
||||
}
|
||||
|
||||
protected function buildDequeue($options)
|
||||
{
|
||||
// Check if holdMusic option has been set
|
||||
if (!isset($options['phoneNumber'])) {
|
||||
return $this->error('Please enter a valid phone number');
|
||||
}
|
||||
$phoneNumber = $options['phoneNumber'];
|
||||
|
||||
|
||||
// Build opening tag
|
||||
$dequeueString = '<Dequeue phoneNumber="'. $phoneNumber . '"';
|
||||
if (isset($options['name'])) {
|
||||
$name = $options['name'];
|
||||
$dequeueString .= ' name="'. $name .'"';
|
||||
}
|
||||
$dequeueString .= ' />';
|
||||
|
||||
return $dequeueString;
|
||||
|
||||
}
|
||||
|
||||
protected function buildConference()
|
||||
{
|
||||
return '<Conference />';
|
||||
}
|
||||
|
||||
protected function buildRedirect($url)
|
||||
{
|
||||
return '<Redirect>'. $url.'</Redirect>';
|
||||
}
|
||||
|
||||
protected function buildReject($url)
|
||||
{
|
||||
return '<Reject />';
|
||||
}
|
||||
|
||||
private function isValidURL($url)
|
||||
{
|
||||
// If no url passed then it can't be valid
|
||||
if (empty($url)) {
|
||||
return false;
|
||||
}
|
||||
return !filter_var($url, FILTER_VALIDATE_URL) === false;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
class Fixtures
|
||||
{
|
||||
public static $username = 'sandbox';
|
||||
public static $apiKey = '';
|
||||
public static $dateOfBirth = '';
|
||||
public static $accountName = 'Test Bank Account';
|
||||
public static $accountNumber = '0123456789';
|
||||
public static $phoneNumber = '+254724486439';
|
||||
public static $multiplePhoneNumbersSMS = ['+254724486439', '+254724567567', '+254724567569'];
|
||||
public static $voicePhoneNumber = '+254711082489';
|
||||
public static $voicePhoneNumber2 = '+254724486439';
|
||||
public static $narration = 'Test Payment';
|
||||
public static $shortCode = '';
|
||||
public static $keyword = 'Test';
|
||||
public static $alphanumeric = 'Test';
|
||||
public static $targetProductCode = 1411;
|
||||
public static $mediaUrl = 'http://thesoundeffect.com/music/mp3/AintTooProudToBeg.mp3';
|
||||
public static $amount = '60';
|
||||
public static $currencyCode = 'KES';
|
||||
public static $currencyCode2 = 'NGN';
|
||||
public static $productName = 'TestProduct';
|
||||
public static $provider = 'ATHENA';
|
||||
public static $transferType = '';
|
||||
public static $startDate = '2018-01-01';
|
||||
public static $endDate = '2018-12-30';
|
||||
public static $transactionId = 'ATPid_SampleTxnId1';
|
||||
public static $otp = '1234';
|
||||
|
||||
public static $MobileDataRecipients = array([
|
||||
'phoneNumber' => '25471xxxxxxx',
|
||||
'quantity' => 15,
|
||||
'unit' => 'MB',
|
||||
'validity' => 'Day',
|
||||
'metadata' => ['notes' => 'Data for January 2018']
|
||||
]);
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use AfricasTalking\SDK\MobileData;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
class MobileDataTest 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->mobileData();
|
||||
}
|
||||
|
||||
|
||||
public function testSend()
|
||||
{
|
||||
$response = $this->client->send([
|
||||
'productName' => Fixtures::$productName,
|
||||
'recipients' => Fixtures::$MobileDataRecipients,
|
||||
]);
|
||||
$this->assertArrayHasKey('status', $response);
|
||||
}
|
||||
|
||||
public function testFindTransaction()
|
||||
{
|
||||
$response = $this->client->findTransaction([
|
||||
'transactionId' => Fixtures::$transactionId
|
||||
]);
|
||||
$this->assertEquals('Failure', $response['data']->status);
|
||||
}
|
||||
|
||||
public function testFetchWalletBalance()
|
||||
{
|
||||
$response = $this->client->fetchWalletBalance();
|
||||
$this->assertEquals('Success', $response['data']->status);
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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->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']);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
namespace AfricasTalking\SDK\Tests;
|
||||
|
||||
use AfricasTalking\SDK\AfricasTalking;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
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
|
||||
// }
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user