From 9696afa40918fa84e75d6a0c51d17b586d64869f Mon Sep 17 00:00:00 2001 From: Kalyan Halder Date: Wed, 24 Feb 2021 12:15:11 +0600 Subject: [PATCH] Laravel SMS BD --- .gitignore | 6 ++ .travis.yml | 4 + LICENSE | 21 +++++ README.md | 94 +++++++++++++++++++ composer.json | 38 ++++++++ src/Config/sms.php | 54 +++++++++++ src/Console/MakeGatewayCommand.php | 51 ++++++++++ src/Console/stubs/gateway.stub | 108 ++++++++++++++++++++++ src/Facades/SMS.php | 23 +++++ src/Gateways/BangladeshSMS.php | 143 +++++++++++++++++++++++++++++ src/Interfaces/SMSInterface.php | 50 ++++++++++ src/SMS.php | 121 ++++++++++++++++++++++++ src/SMSServiceProvider.php | 46 ++++++++++ src/helpers.php | 14 +++ 14 files changed, 773 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/Config/sms.php create mode 100644 src/Console/MakeGatewayCommand.php create mode 100644 src/Console/stubs/gateway.stub create mode 100644 src/Facades/SMS.php create mode 100644 src/Gateways/BangladeshSMS.php create mode 100644 src/Interfaces/SMSInterface.php create mode 100644 src/SMS.php create mode 100644 src/SMSServiceProvider.php create mode 100644 src/helpers.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae499f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/storage/*.key +/vendor +/.idea +/.vagrant +.env \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..80a2819 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: php +php: + - '7.1' + - '7.2' \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f268814 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Crafted Systems + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d2f4331 --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +# Laravel SMS BD + + +This is a Laravel library to send SMS and switch between multiple SMS Gateways. + +## Installation + +You can install the package via composer: + +``` bash +composer require kalyan312/laravel-sms-bd +``` +The package will register itself automatically. + +Then publish the package configuration file + +```bash +php artisan vendor:publish --provider=Khbd\LaravelSmsBD\SMSServiceProvider +``` + +## Usage + +Check the config file of all variables required, and then + +```php +(new SMS())->send('01945602071','Test SMS'); +``` +or using Facade + +```php +SMS::send('01945602071','Test SMS'); +``` + +or using helper + +```php +sms()->send('01945602071','Test SMS'); +``` + +## Adding new Gateway + +use command +```bash +php artisan make:gateway MyGateway +``` + +A class `MyGateway.php` will be generated under `App/Gateways` folder. + +The class extends the [SMSInterface]() + +Remember to `map` your gateway in the sms config file. + +### Changing Gateway + +Apart from declaring your default gateway on the sms config or env files, you can also change the gateway you want to use on the fly. e.g: + +```php +SMS::gateway('mygateway')->send('254712345678','Test SMS'); +``` + +### Checking SMS balance + +```php +SMS::getBalance(); + +//or + +SMS::gateway('mygateway')->getBalance(); + +``` +### Delivery Reports +```php +sms()->getDeliveryReports(Request $request); + +//or + +sms()->gateway('mygateway')->getDeliveryReports(Request $request); +``` + +## Contributing + +Suggestions, pull requests , bug reporting and code improvements are all welcome. Feel free. + +## TODO + +Write Tests + +## Credits + +- [Kalyan Halder](https://github.com/kalyan312) + +## License + +The MIT License (MIT). Please see [License File](LICENSE) for more information. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..afbad29 --- /dev/null +++ b/composer.json @@ -0,0 +1,38 @@ +{ + "name": "khbd/laravel-sms-bd", + "description": "Laravel sms BD is a Laravel Package for Sending out SMS from multiple Gateways", + "license": "MIT", + "type": "library", + "require": { + "php": "^7.2", + "illuminate/support": "^6.0|^7.0|^8.0", + "ixudra/curl": "6.*" + }, + "authors": [ + { + "name": "Kalyan Halder", + "email": "kalyanhalder0@gmail.com", + "homepage": "https://github.com/kalyan312", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "Khbd\\LaravelSmsBD\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "extra": { + "laravel": { + "providers": [ + "Khbd\\LaravelSmsBD\\SMSServiceProvider" + ], + "aliases": { + "SMS": "Khbd\\LaravelSmsBD\\Facades\\SMS" + } + } + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/src/Config/sms.php b/src/Config/sms.php new file mode 100644 index 0000000..5b72e19 --- /dev/null +++ b/src/Config/sms.php @@ -0,0 +1,54 @@ + env('DEFAULT_SMS_GATEWAY', 'bangladesh_sms'), + + /* + |-------------------------------------------------------------------------- + | List of Gateways + |-------------------------------------------------------------------------- + | + | These are the list of gateways to use for this package. + | You can change the name. Then you'll have to change + | it in the map array too. + | + */ + + 'gateways' => [ + + 'bangladesh_sms' => [ + 'username' => env('BANGLADESH_SMS_USERNAME'), + 'api_key' => env('BANGLADESH_SMS_API_KEY'), + 'from' => env('BANGLADESH_SMS_FROM'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Class Maps + |-------------------------------------------------------------------------- + | + | This is the array of Classes that maps to Gateways above. + | You can create your own driver if you like and add the + | config in the drivers array and the class to use + | here with the same name. You will have to implement + | Khbd\LaravelSmsBD\Contracts\SMSContract in your gateway. + | + */ + + 'map' => [ + 'bangladesh_sms' => \Khbd\LaravelSmsBD\BangladeshSMS::class, + + ], +]; diff --git a/src/Console/MakeGatewayCommand.php b/src/Console/MakeGatewayCommand.php new file mode 100644 index 0000000..8183cbe --- /dev/null +++ b/src/Console/MakeGatewayCommand.php @@ -0,0 +1,51 @@ +settings = (object)$settings; + } + + /** + * @param $recipient + * @param $message + * @param null $params + * @return object + */ + public function send(string $recipient, string $message, $params = null) + { + // implement the send sms method + + $this->is_success = ''; // define what determines success from the response + $this->message_id = ''; // reference the message id here. auto generate if not available + $arr = [ + 'is_success' => '', + 'message_id' => '' + // e.t.c + ]; // the rest of data that is returned + + $this->data = (object)$arr; + + return $this; + } + + /** + * initialize the is_success parameter + * @return bool + */ + public function is_successful(): bool + { + return $this->is_success; + } + + /** + * assign the message ID as received on the response,auto generate if not available + * @return mixed + */ + public function getMessageID() + { + return $this->message_id; + } + + /** + * auto generate if not available + */ + public function getBalance(): float + { + // implement the get balance method + } + + + /** + * @param Request $request + * @return object + */ + public function getDeliveryReports(Request $request) + { + // implement the processing of delivery reports here. POST/PUSH implementation encouraged + + $data = [ + 'status' => '',//delivery report status (e.g DeliveredToTerminal,Success,Failed) + 'message_id' => '' //the message id for purpose of matching + // e.t.c + ]; // the rest of data that is returned + + return (object)$data; + } +} \ No newline at end of file diff --git a/src/Facades/SMS.php b/src/Facades/SMS.php new file mode 100644 index 0000000..d8f315f --- /dev/null +++ b/src/Facades/SMS.php @@ -0,0 +1,23 @@ +settings = (object) $settings; + } + + /** + * @param $recipient + * @param $message + * @param null $params + * + * @return object + */ + public function send(string $recipient, string $message, $params = null) + { + $AT = new SMSGateway($this->settings->username, $this->settings->api_key); + $sms = $AT->sms(); + + $result = $sms->send([ + 'to' => $recipient, + 'message' => $message, + 'from' => $this->settings->from, + ]); + + // message sending successful + if ($result['status'] == 'success') { + $data = $result['data']->SMSMessageData->Recipients[0]; + + $this->is_success = $data->status == 'Success'; // define what determines success from the response + $this->message_id = $data->messageId; // reference the message id here. auto generate if not available + $arr = [ + 'is_success' => $data->status == 'Success', + 'message_id' => $data->messageId, + 'number' => $data->number, + 'cost' => $data->cost, + 'status' => $data->status, + 'statusCode' => $data->statusCode, + ]; + + $this->data = (object) $arr; + + return $this; + } else { + // sms sending failed // problem with gateway + $arr = $result; + $this->data = (object) $arr; + + return $this; + } + } + + /** + * initialize the is_success parameter. + * + * @return bool + */ + public function is_successful(): bool + { + return $this->is_success; + } + + /** + * assign the message ID as received on the response,auto generate if not available. + * + * @return mixed + */ + public function getMessageID() + { + return $this->message_id; + } + + /** + * auto generate if not available. + */ + public function getBalance(): float + { + $AT = new SMSGateway($this->settings->username, $this->settings->api_key); + $application = $AT->application(); + $balance = $application->fetchApplicationData()['data']->UserData->balance; + $replacements = ['/\bKES\b/', '/\bUGX\b/', '/\TSH\b/']; + + return (float) str_replace(' ', '', preg_replace($replacements, '', $balance)); + } + + /** + * @param Request $request + * + * @return object + */ + public function getDeliveryReports(Request $request) + { + $status = $request->status; + + if ($status == 'Failed' || $status == 'Rejected') { + $fs = $request->failureReason; + } else { + $fs = $status; + } + + $data = [ + 'status' => $fs, + 'message_id' => $request->id, + 'phone_number' => '', + ]; + + return (object) $data; + } +} diff --git a/src/Interfaces/SMSInterface.php b/src/Interfaces/SMSInterface.php new file mode 100644 index 0000000..e8df7df --- /dev/null +++ b/src/Interfaces/SMSInterface.php @@ -0,0 +1,50 @@ +config = config('sms'); + $this->gateway = $this->config['default']; + $this->mapGateway(); + } + + /** + * Change the gateway on the fly. + * + * @param $gateway + * + * @return $this + */ + public function gateway($gateway) + { + $this->gateway = $gateway; + $this->mapGateway(); + + return $this; + } + + /** + *map the gateway that will be used to send. + */ + private function mapGateway() + { + $this->settings = $this->config['gateways'][$this->gateway]; + $class = $this->config['map'][$this->gateway]; + $this->object = new $class($this->settings); + } + + /** + * @param $recipient + * @param $message + * @param null $params + * + * @return mixed + */ + public function send($recipient, $message, $params = null) + { + return $this->object->send($recipient, $message, $params); + } + + /** + * define when the a message is successfully sent. + * + * @return bool + */ + public function is_successful() + { + return $this->object->is_successful(); + } + + /** + * the message ID as received on the response. + * + * @return mixed + */ + public function getMessageID() + { + return $this->object->getMessageID(); + } + + /** + * @return mixed + */ + public function getBalance() + { + return $this->object->getBalance(); + } + + /** + * @param Request $request + * + * @return mixed + */ + public function getDeliveryReports(Request $request) + { + return $this->object->getDeliveryReports($request); + } +} diff --git a/src/SMSServiceProvider.php b/src/SMSServiceProvider.php new file mode 100644 index 0000000..857f9d9 --- /dev/null +++ b/src/SMSServiceProvider.php @@ -0,0 +1,46 @@ +publishes([ + __DIR__.'/Config/sms.php' => config_path('sms.php'), + ], 'laravel_sms_config'); + + $this->app->singleton(SMS::class, function () { + return new SMS(); + }); + + $this->app->alias(SMS::class, 'sms'); + + if ($this->app->runningInConsole()) { + $this->commands([ + MakeGatewayCommand::class, + ]); + } + } + + /** + * Register the application services. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom( + __DIR__.'/Config/sms.php', + 'laravel-sms-bd' + ); + } +} diff --git a/src/helpers.php b/src/helpers.php new file mode 100644 index 0000000..d687e01 --- /dev/null +++ b/src/helpers.php @@ -0,0 +1,14 @@ +