Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/samuelmwangiw/africastalking-laravel
An Elegant Laravel SDK for interacting with Africa's Talking APIs
https://github.com/samuelmwangiw/africastalking-laravel
africastalking africastalking-php hacktoberfest laravel laravel-sms laravel-sms-notifications
Last synced: 3 months ago
JSON representation
An Elegant Laravel SDK for interacting with Africa's Talking APIs
- Host: GitHub
- URL: https://github.com/samuelmwangiw/africastalking-laravel
- Owner: SamuelMwangiW
- License: mit
- Created: 2022-03-08T16:39:08.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-04-15T19:27:24.000Z (9 months ago)
- Last Synced: 2024-04-16T11:40:36.611Z (9 months ago)
- Topics: africastalking, africastalking-php, hacktoberfest, laravel, laravel-sms, laravel-sms-notifications
- Language: PHP
- Homepage:
- Size: 656 KB
- Stars: 2
- Watchers: 1
- Forks: 2
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
# africastalking-laravel
[![Latest Version on Packagist](https://img.shields.io/packagist/v/samuelmwangiw/africastalking-laravel.svg?style=flat-square)](https://packagist.org/packages/samuelmwangiw/africastalking-laravel)
[![run-tests](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/run-tests.yml/badge.svg)](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/run-tests.yml)
[![PHPStan](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/phpstan.yml/badge.svg)](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/phpstan.yml)
[![Code styling](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/SamuelMwangiW/africastalking-laravel/actions/workflows/php-cs-fixer.yml)
[![Total Downloads](https://img.shields.io/packagist/dt/samuelmwangiw/africastalking-laravel.svg?style=flat-square)](https://packagist.org/packages/samuelmwangiw/africastalking-laravel)This is an unofficial Laravel SDK for interacting
with [Africa's Talking](https://developers.africastalking.com/docs/sms/overview) APIs that takes advantage of native
Laravel components such as- [HTTP Client](https://laravel.com/docs/9.x/http-client#main-content) in place of Guzzle client
- [Service Container](https://laravel.com/docs/9.x/container#main-content) for a great dev experience
- [Notifications](https://laravel.com/docs/9.x/notifications) to allow you route notifications via Africastalking
- [Config](https://laravel.com/docs/9.x/configuration#main-content)
- [Collections](https://laravel.com/docs/9.x/collections#main-content)
- Among many others## Installation
You can install the package via composer:
```bash
composer require samuelmwangiw/africastalking-laravel
```You can publish the config file with:
```bash
php artisan vendor:publish --tag="africastalking-config"
```This is the contents of the published config file:
```php
return [
'username' => env('AFRICASTALKING_USERNAME', 'sandbox'),
'api-key' => env('AFRICASTALKING_API_KEY'),
'sms' => [
'from' => env('AFRICASTALKING_FROM'),
],
'payment' => [
'product-name' => env('AFRICASTALKING_PAYMENT_PRODUCT'),
],
'voice' => [
'from' => env('AFRICASTALKING_VOICE_PHONE_NUMBER'),
]
];
```You should configure the package by setting the `env` variables in your `.env` file.
## Usage
### Application Balance
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;/** @var \SamuelMwangiW\Africastalking\ValueObjects\Balance $account */
$account = Africastalking::application()->balance();// Or using the global helper function
$account = africastalking()->application()->balance();
```### Bulk Messages
The most basic example to send out a message is
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;$response = Africastalking::sms('Hello mom!')
->to('+254712345678')
->send();// Or using the global helper function
$response = africastalking()->sms("Hello Mom")
->to('+254712345678')
->send();
```Other valid examples are
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;$response = Africastalking::sms('It is quality rather than quantity that matters. - Lucius Annaeus Seneca')
->message("We made it!") //overwrites any text previously set
->text("Look, am on the internet") //alias to message()
->as('MyBIZ') // optional: When the senderId is different from `config('africastalking.sms.from')`
->to(['+254712345678','+256706123567'])
->bulk() // optional: Messages are bulk by default
->enqueue() //used for Bulk SMS clients that would like to deliver as many messages to the API before waiting for an acknowledgement from the Telcos
->send()// Or using the global helper function
$response = africastalking()->sms()
->message("Hello Mom") //overwrites any text previously set
->to('+254712345678')
->send();
```The response is Collection of `\SamuelMwangiW\Africastalking\ValueObjects\RecipientsApiResponse` objects
### Premium Messages
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;$response = Africastalking::sms('It is quality rather than quantity that matters. - Lucius Annaeus Seneca')
->as('90012') // optional: When the senderId is different from `config('africastalking.sms.from')`
->to(['+254712345678','+256706123567'])
->premium() // Required to designate messages as bulk
->bulkMode(false) // True to send premium messages in bulkMode and false to send as premium
->retry(2) //specifies the number of hours your subscription message should be retried in case itβs not delivered to the subscriber.
->keyword('keyword') // optional:
->linkId('message-link-id') // optional:
->send()```
The response is Collection of `\SamuelMwangiW\Africastalking\ValueObjects\RecipientsApiResponse` objects
### Airtime
The most basic example to disburse airtime is
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;$response = Africastalking::airtime()
->to('+254712345678','KES',100)
->send();// Or using the global helper function
$response = africastalking()->airtime()
->to('+256706345678','UGX',100)
->send();
```You may also pass an instance of `AirtimeTransaction`
```php
use SamuelMwangiW\Africastalking\Facades\Africastalking;
use SamuelMwangiW\Africastalking\ValueObjects\AirtimeTransaction;
use SamuelMwangiW\Africastalking\ValueObjects\PhoneNumber;
use SamuelMwangiW\Africastalking\Enum\Currency;$transaction = new AirtimeTransaction(PhoneNumber::make('+256769000000'),Currency::UGANDA,1000)
$response = Africastalking::airtime()
->to($transaction)
->send();
```The Airtime class provides an `add()` that's basically an alias to the `to()` and since either of these methods can be
fluently chained, it unlocks capabilities such as adding the recipients in a loop and sending once at the end```php
use App\Models\Clients;$airtime = africastalking()->airtime();
Clients::query()->chunk(1000, function ($clients) use($airtime) {
foreach ($clients as $client) {
$airtime->add($client->phone,'TZS',3000);
}
});
$results = $airtime->send();
```### USSD Response
This package allows to easily create `USSD` response by exposing a `\SamuelMwangiW\Africastalking\Response\UssdResponse`
class that implements Laravel's Responsable contract.To send a ussd response, simply return `africastalking()->ussd()` in your controller.
The `ussd` optionally takes 2 parameters and returns an instance of `UssdResponse`:
- `response` - The response message to be displayed to the client
- `expectsInput` - A boolean whether or not to prompt for user input. The default value is `true`The `UssdResponse` class has the following methods that can be chained fluently
- `response` - Receives the response message to be displayed to the client as an argument
- `expectsInput` - Receives the expectsInput boolean to be displayed to the client as an argument. The default value is
true
- `end` - Is an alias `expectsInput()` but sets the boolean value `false` alwaysSee below an example controller that makes of the `UssdResponse` and Ussd's `HttpRequest`:
```php
userInput()) {
return africastalking()->ussd('Kindly enter your account number');
}$account = Client::query()
->whereAccountNo(
Str::of($request->userInput())->afterLast('*')->toString()
)->first();if ($account?->exists()) {
return africastalking()
->ussd("Your account Balance is KES {$account->balance}")->end();
}return africastalking()
->ussd("The account you entered does not exists.\n\nKindly enter a valid account number");
}public function event(UssdEventRequest $request)
{
//Handle the USSD event here
return response('OK');
}
}
```### Payments (wip)
#### Mobile Checkout
```php
africastalking()
->payment()
->mobileCheckout()
->to('+254720123123')
->amount(5000)
->currency('KES')
->send()
```#### Wallet Balance
```php
/** @var \SamuelMwangiW\Africastalking\ValueObjects\Balance $balance **/
$balance = africastalking()->wallet()->balance();
```#### Stash top up
```php
africastalking()
->stash()
->topup('TZS',100000);//or fluently
africastalking()
->stash()
->amount(10000)
->currency('USD')
->product('My Product') //To override the product name in config
->topup(); //topup() has an alias named send() if you fancy```
### Voice Responses
This package provides an easy and intuitive voice response builder that allows any combination of the following:
Note that all params marked as optional in
the [documentation](https://developers.africastalking.com/docs/voice/actions/overview) are also optional```php
voice()
->say(message: '', playBeep: "false", voice: "en-US-Standard-C")
->play(url: 'https://example.com/audio.wav')
->getDigits(
say: 'Please enter your account number followed by the hash sign',
finishOnKey: '#',
timeout: '30',
callbackUrl: 'http://mycallbackURL.com',
)->dial(
phoneNumbers: ['+254711XXXYYY', '+25631XYYZZZZ', '[email protected]'],
record: true,
ringBackTone: 'http://mymediafile.com/playme.mp3',
maxDuration: 5,
sequential: false,
callerId: '+254711XXXYYY',
)->record(
say: 'Please enter your account number followed by the hash sign',
finishOnKey: '#',
timeout: '30',
maxLength: 10,
playBeep: true,
trimSilence: true
)->redirect(
url: 'http://www.myotherhandler.com/process.php',
)->reject();
```See example in a controller below:
```php
input('isActive')){
return africastalking()->voice()
->say('Welcome to Unicorn bank.')
->getDigits(
say:'Please enter your account Number followed by the # key',
finishOnKey: '#'
)
}
return response('OK');
}
}```
```php
input('isActive')){
return africastalking()->voice()
->say('Our working hours are 9AM - 7PM, Monday to to Friday')
->record(
say: 'Please leave a message after the tone.',
finishOnKey: '#',
playBeep: true,
maxLength: 10,
trimSilence: true,
);
}
return response('OK');
}
}```
```php
input('isActive')){
return africastalking()->voice()
->say('Our working hours are 9AM - 7PM, Monday to to Friday')
->reject();
}
return response('OK');
}
}```
```php
input('isActive')){
$doctor = Doctor::query()->onDuty()->first();
return africastalking()->voice()
->dial(
phoneNumbers: [$doctor->number],
record: true,
ringBackTone: "https://example.com/marketing-tone.wave"
);
}
return response('OK');
}
}```
#### Synthesized Speech Attributes.
The `````` action supports the use of Speech Synthesis Markup Language(SSML).
To respond with *Synthesized Speech*, pass a callback `say()` above as the first parameter that receives an instance of ```SynthesisedSpeech``` object
```php
input('isActive')){
return africastalking()->voice()
->say(
fn(SynthesisedSpeech $speech) => $speech
->say('Welcome to Wasafi. Your airtime balance is')
->sayAsCurrency('$1000','en-US')
->say(' and expires on ')
->sayAsDate('20420420')
->say(' at ')
->sayAsTime('04:42PM')
->pause('69ms')
->say('For assistance Call our customer service team on ')
->sayAsTelephone('0800694269')
->bleep('Thank you for choosing us π')
)
}
return response('OK');
}
}
```> **Note**
> You can only have a single `````` within an XML response### Making Calls
```php
// Most basic call
africastalking()->voice()
->call('+254720123123')
->done();// Call a list of users
africastalking()->voice()
->call(['+254720123123','+254731234567'])
->done();// override the callerId
africastalking()->voice()
->call('+254720123123')
->as('+254711082999')
->done();// Set the call Request Id
africastalking()->voice()
->call('+254720123123')
->requestId('id_12345')
->done();// You can also use send if like that better
africastalking()->voice()
->call('+254720123123')
->send();
```### WebRTC
```php
user()?->name ?? 'Browser';
$token = africastalking()
->voice()
->webrtc()
->for($clientName)
->token();
return [
'token' => $token->token,
'clientName' => $token->clientName,
'expire' => $token->lifeTimeSec,
];
}
}
```## HTTP Requests
The package ships with the following [Laravel Requests](https://laravel.com/docs/9.x/validation#creating-form-requests)
that you can inject into your application controllers:```php
\SamuelMwangiW\Africastalking\Http\Requests\AirtimeStatusRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\AirtimeValidationRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\BulkSmsOptOutRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\IncomingMessageRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\MessageDeliveryRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\MobileC2BValidationRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\PaymentNotificationRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\SubscriptionRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\UssdEventRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\UssdSessionRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\VoiceCallRequest::class;
\SamuelMwangiW\Africastalking\Http\Requests\VoiceEventRequest::class;
```In addition to exposing the post params in a nice FormRequest object, these classes also include nice helper methods
where applicable e.g.- `id()` to retrieve the unique ATPid associated with every request
- `phone()` to retrieve the client's phone number
- `userInput()` to retrieve ussd user input
- `status()` to get transaction / request final status
- `deliveryFailed()` returns a boolean `true` if sms or airtime delivery failed and `false` otherwise
- among many othersExample for a Message Delivery callback action Controller
```php
where(['transaction_id'=>$request->id()])
->firstOrFail();
$message->update([
'delivered_at'=>now(),
'status'=>$request->status(),
]);
return response('OK');
}
}```
## Notification
The package ships with a Channel to allow for easily routing of notifications via Africastalking SMS.
To route a notification via Africastalking, return `SamuelMwangiW\Africastalking\Notifications\AfricastalkingChannel` in
your notifications `via` method and the text message to be sent in the `toAfricastalking` method```php
name}. Your account at Unicorn Bank has been created. Hope you enjoy the service";
}
}```
Also ensure that the notifiable model implements `SamuelMwangiW\Africastalking\Contracts\ReceivesSmsMessages` and that
the model's `routeNotificationForAfricastalking()` returns the phone number to receive the message```php
phone;
}
}```
## Testing
```bash
composer test
```## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
## Security Vulnerabilities
Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
## Credits
- [Samuel Mwangi](https://github.com/SamuelMwangiW)
- [All Contributors](../../contributors)## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.