diff --git a/readme.md b/readme.md index eca0451..400867e 100644 --- a/readme.md +++ b/readme.md @@ -14,6 +14,12 @@ You can install the package via composer: composer require sparors/laravel-ussd:^3 ``` +For older version use + +``` bash +composer require sparors/laravel-ussd:^2 +``` + Laravel Ussd provides zero configuration out of the box. To publish the config, run the vendor publish command: ``` bash @@ -22,127 +28,161 @@ php artisan vendor:publish --provider="Sparors\Ussd\UssdServiceProvider" --tag=u ## Usage -### Context - -The context of the ussd contains vital data required to succcessfully run a ussd application. It require 3 major input and any addition one you may choose to provide. - -SID: refers to a unique id for every session. - -GID: refers to a group id that is common to a user accross session. This is ussually just the phone number or msisdn. - -Input: is the last input the user entered. +For older version look here: [V2 README](./v2.readme.md) -Aside these, you may choose to pass addition information like network and phone number if you may need them. +### Creating USSD menus -``` php +```php with([ - 'network' => request('network'), - 'phone_number' => request('phoneNumber') -]) -``` +namespace App\Ussd\States; -### Record +use App\Ussd\Actions\TransferAccountAction; +use Sparors\Ussd\Attributes\Paginate; +use Sparors\Ussd\Attributes\Transition; +use Sparors\Ussd\Context; +use Sparors\Ussd\Contracts\State; +use Sparors\Ussd\Decisions\Equal; +use Sparors\Ussd\Decisions\Fallback; +use Sparors\Ussd\Decisions\In; +use Sparors\Ussd\Menu; +use Sparors\Ussd\Record; +use Sparors\Ussd\Traits\WithPagination; + +#[Transition(to: TransferAccountAction::class, match: new Equal(1))] +#[Transition(to: TransferAmountState::class, match: new In(2, 3), callback: [self::class, 'setTransferType'])] +#[Transition(to: NewAccountNameState::class, match: new Equal(4))] +#[Transition(to: HelplineState::class, match: new Equal(5))] +#[Transition(to: InvalidInputState::class, match: new Fallback())] +#[Paginate(next: new Equal('#'), previous: new Equal('0'))] +class CustomerMenuState implements State +{ + use WithPagination; -Ussd record provides a simple way to save data as your application runs. + public function render(): Menu + { + return Menu::build() + ->line('Banc') + ->listing($this->getItems(), page: $this->currentPage(), perPage: $this->perPage()) + ->when($this->hasPreviousPage(), fn (Menu $menu) => $menu->line('0. Previous')) + ->when($this->hasNextPage(), fn (Menu $menu) => $menu->line('#. Next')) + ->text('Powered by Sparors'); + } -``` php -input() ? 'deposit' : 'withdraw'; -use Sparors\Ussd\Record; + $record->set('transfer_type', $transferType); + } -$record = App::make(Record::class); + public function getItems(): array + { + return [ + 'Transfer', + 'Deposit', + 'Withdraw', + 'New Account', + 'Helpline', + ]; + } -$record->set('name', 'Isaac'); + public function perPage(): int + { + return 3; + } +} ``` -### Dependency Injection +An example of a final state -You can inject record and context into ussd application to make use of them when needed. +``` php +text('Bye bye ' . $record->get('name')); + } +} ``` -States help build ussd menus that users interupt with. `Sparors\Ussd\Menu` provides a fluent API to easily create menus. `Sparors\Ussd\Attributes\Transition` attributes help to define how to connect one state to another while `Sparors\Ussd\Attributes\Terminate` help know the final state. +Due to some limitation with PHP 8.0, you can not pass class instance to attributes. So to other come this limitation, you can pass an array with the full class path as the first element and the rest should be argument required. eg. ``` php text('Welcome To Laravel USSD') - ->lineBreak(2) - ->line('Select an option . ' . $context->get('network')) - ->listing([ - 'Airtime Topup', - 'Data Bundle', - 'TV Subscription', - 'ECG/GWCL', - 'Talk To Us' - ]) - ->lineBreak(2) - ->text('Powered by Sparors'); + return Menu::build()->text('Welcome'); } } ``` -The first state should implement `Sparors\Ussd\Contracts\InitialState` instead of the generic state. +### Building USSD -Due to some limitation with PHP 8.0, you can not pass class instance to attributes. So to other come this limitation, you can pass an array with the full class path as the first element and the rest should be argument required. +```php +text('Bye bye ' . $record->get('name')); + $lastText = $request->input('text') ?? ''; + + if (strlen($lastText) > 0) { + $lastText = explode('*', $lastText); + $lastText = end($lastText); + } + + return Ussd::build( + Context::create( + $request->input('sessionId'), + $request->input('phoneNumber'), + $lastText + ) + ->with(['phone_number' => $request->input('phoneNumber')]) + ) + ->useInitialState(MenuAction::class) + ->useContinuingState(ContinuingMode::CONFIRM, now()->addMinute(), WouldYouLikeToContinueState::class) + ->useResponse(AfricasTalkingResponse::class) + ->run(); } } ``` -### Actions - -We provide a ussd artisan command which allows you to quickly create new actions. Action should have one method execute which returns a string. - -``` bash -php artisan ussd:action MakePaymentAction -``` +### Conditional Branching -Actions should return a string which is the full qualified path to a state or another action. +Use USSD action to conditional decide which state should be the next. ``` php ok()) { - return PaymentSuccess::class; + return PaymentSuccessState::class; } - return PaymentError::class; + return PaymentErrorState::class; } } ``` -### Running a ussd Application - -``` php -with([ - 'network' => request('network'), - 'phone_number' => request('phoneNumber') - ]) - ) - ->useInitialState(WelcomeState::class) - ->run(); - } -} -``` - -### Simplifying USSD with configurator +You can use configurator to simplify repetitive parts of your application so they can be shared easily. -You can use configurator to simplify repetitive parts of your application so they can be shared easily. Just implement and `Sparors\Ussd\Contracts\Configurator` interface and use it in your machine. ```php ``` -```php -useConfigurator(Nsano::class) - ->useInitialState(Welcome::class) - ->run(); - } -} -?> -``` - -### Documentation - -You'll find the documentation on [https://sparors.github.io/ussd-docs](https://sparors.github.io/ussd-docs/). - ### Testing -You can easily test how your ussd application will respond to user input +You can easily test how your ussd application with our testing utilities ``` php