From 16f56847850bca740096bb56d02c1b5d8d1aa798 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Mon, 7 Aug 2017 15:14:54 +0530 Subject: [PATCH 01/63] Add Textlocal Channel Which provides the ability to send SMS via textlocal.in API --- CHANGELOG.md | 7 + CONTRIBUTING.md | 55 ++ LICENSE.md | 21 + README.md | 94 ++- composer.json | 39 + phpunit.xml.dist | 29 + src/Exceptions/CouldNotSendNotification.php | 11 + src/Textlocal.php | 825 ++++++++++++++++++++ src/TextlocalChannel.php | 58 ++ src/TextlocalServiceProvider.php | 36 + tests/ExampleTest.php | 12 + 11 files changed, 1184 insertions(+), 3 deletions(-) create mode 100755 CHANGELOG.md create mode 100755 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 composer.json create mode 100644 phpunit.xml.dist create mode 100644 src/Exceptions/CouldNotSendNotification.php create mode 100644 src/Textlocal.php create mode 100644 src/TextlocalChannel.php create mode 100644 src/TextlocalServiceProvider.php create mode 100644 tests/ExampleTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 00000000..ce1e1d29 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to `Textlocal` will be documented in this file + +## 0.0.1 - 2017-08-07 + +- initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100755 index 00000000..4da74e3f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# Contributing + +Contributions are **welcome** and will be fully **credited**. + +Please read and understand the contribution guide before creating an issue or pull request. + +## Etiquette + +This project is open source, and as such, the maintainers give their free time to build and maintain the source code +held within. They make the code freely available in the hope that it will be of use to other developers. It would be +extremely unfair for them to suffer abuse or anger for their hard work. + +Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the +world that developers are civilized and selfless people. + +It's the duty of the maintainer to ensure that all submissions to the project are of sufficient +quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. + +## Viability + +When requesting or submitting new features, first consider whether it might be useful to others. Open +source projects are used by many developers, who may have entirely different needs to your own. Think about +whether or not your feature is likely to be used by other users of the project. + +## Procedure + +Before filing an issue: + +- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. +- Check to make sure your feature suggestion isn't already present within the project. +- Check the pull requests tab to ensure that the bug doesn't have a fix in progress. +- Check the pull requests tab to ensure that the feature isn't already in progress. + +Before submitting a pull request: + +- Check the codebase to ensure that your feature doesn't already exist. +- Check the pull requests to ensure that another person hasn't already submitted the feature or fix. + +## Requirements + +If the project maintainer has any additional requirements, you will find them listed here. + +- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). + +- **Add tests!** - Your patch won't be accepted if it doesn't have tests. + +- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. + +- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. + +- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. + +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. + +**Happy coding**! diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..e65b3a7c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) Manash Jyoti Sonowal + +> 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 index 746a917d..1ba7e1c0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,93 @@ -# new-channels +This package allows to send SMS using Textlocal API using laravel notifications -Discuss about new channel proposals our share your finished channels in the [proposal issue](https://github.com/laravel-notification-channels/new-channels/issues/6). +Here's the latest documentation on Laravel 5.4 Notifications System: -Take a look at our [FAQ](http://laravel-notification-channels.com/) to see our small list of rules, to provide top-notch notification channels. +https://laravel.com/docs/5.4/notifications + +# Found any bugs or improvement open an issue or send me a PR + +[![Latest Version on Packagist](https://img.shields.io/packagist/v/laravel-notification-channels/textlocal.svg?style=flat-square)](https://packagist.org/packages/laravel-notification-channels/textlocal) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Build Status](https://img.shields.io/travis/laravel-notification-channels/textlocal/master.svg?style=flat-square)](https://travis-ci.org/laravel-notification-channels/textlocal) +[![StyleCI](https://styleci.io/repos/:style_ci_id/shield)](https://styleci.io/repos/:style_ci_id) +[![SensioLabsInsight](https://img.shields.io/sensiolabs/i/:sensio_labs_id.svg?style=flat-square)](https://insight.sensiolabs.com/projects/:sensio_labs_id) +[![Quality Score](https://img.shields.io/scrutinizer/g/laravel-notification-channels/textlocal.svg?style=flat-square)](https://scrutinizer-ci.com/g/laravel-notification-channels/textlocal) +[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/laravel-notification-channels/textlocal/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/laravel-notification-channels/textlocal/?branch=master) +[![Total Downloads](https://img.shields.io/packagist/dt/laravel-notification-channels/textlocal.svg?style=flat-square)](https://packagist.org/packages/laravel-notification-channels/textlocal) + +This package makes it easy to send notifications using [textlocal](https://www.textlocal.in/) with Laravel 5.3.+ + + + +## Contents + +- [Installation](#installation) + - [Setting up the textlocal service](#setting-up-the-textlocal-service) +- [Usage](#usage) + - [Available Message methods](#available-message-methods) +- [Changelog](#changelog) +- [Testing](#testing) +- [Security](#security) +- [Contributing](#contributing) +- [Credits](#credits) +- [License](#license) + + +## Installation + +Create an account in textlocal then create an API key or hash(password). + +`composer require laravel-notification-channels/textlocal` + +### Setting up the textlocal service + +put the followings and to your config/services +``` +'sms' => [ + 'textlocal' => [ + 'username' => env('TEXTLOCAL_USERNAME'), + 'hash' => env('TEXTLOCAL_HASH'), + 'sender' => env('TEXTLOCAL_SENDER'), +] +``` + + +## Usage +textlocal +implement this method `routeNotificationForSms()` in your notifiable class/model which will return array of mobile numbers +and lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. + +### Available Message methods + +A list of all available options + +## Changelog + +Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. + +## Testing + +``` bash +$ composer test +``` + +## Security + +If you discover any security related issues, please email manash149@gmail.com instead of using the issue tracker. + +## Contributing + +Please see [CONTRIBUTING](CONTRIBUTING.md) for details. + +## Credits + +- [Manash Jyoti Sonowal](https://github.com/msonowal) +- [All Contributors](../../contributors) + +## License + +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. + +## TODO +Need to convert to Guzzle Http as a Client in core +add tests diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..55d87036 --- /dev/null +++ b/composer.json @@ -0,0 +1,39 @@ +{ + "name": "laravel-notification-channels/textlocal", + "description": "This package helps to send SMS via Textlocal API in laravel way", + "homepage": "https://github.com/laravel-notification-channels/textlocal", + "license": "MIT", + "authors": [ + { + "name": "Manash Jyoti Sonowal", + "email": "manash149@gmail.com", + "homepage": "https://github.com/msonowal", + "role": "Developer" + } + ], + "require": { + "php": ">=5.6.4", + "illuminate/notifications": "^5.3|^5.4", + "illuminate/support": "^5.1|^5.2|^5.3|^5.4" + }, + "require-dev": { + "mockery/mockery": "^0.9.5", + "phpunit/phpunit": "4.*" + }, + "autoload": { + "psr-4": { + "NotificationChannels\\Textlocal\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "NotificationChannels\\Textlocal\\Test\\": "tests" + } + }, + "scripts": { + "test": "vendor/bin/phpunit" + }, + "config": { + "sort-packages": true + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..f9e82497 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + tests + + + + + src/ + + + + + + + + + + diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php new file mode 100644 index 00000000..f9dc566c --- /dev/null +++ b/src/Exceptions/CouldNotSendNotification.php @@ -0,0 +1,11 @@ + + * @version 1.4-IN + * @const REQUEST_URL URL to make the request to + * @const REQUEST_TIMEOUT Timeout in seconds for the HTTP request + * @const REQUEST_HANDLER Handler to use when making the HTTP request (for future use) + */ +class Textlocal +{ + const REQUEST_URL = 'https://api.textlocal.in/'; + const REQUEST_TIMEOUT = 60; + const REQUEST_HANDLER = 'curl'; + + private $username; + private $hash; + private $apiKey; + + private $errorReporting = false; + + public $errors = array(); + public $warnings = array(); + + public $lastRequest = array(); + + /** + * Instantiate the object + * + * @param $username + * @param $hash + */ + function __construct($username, $hash, $apiKey = false) + { + $this->username = $username; + $this->hash = $hash; + if ($apiKey) { + $this->apiKey = $apiKey; + } + + } + + /** + * Private function to construct and send the request and handle the response + * + * @param $command + * @param array $params + * @return array|mixed + * @throws Exception + * @todo Add additional request handlers - eg fopen, file_get_contacts + */ + private function _sendRequest($command, $params = array()) + { + if ($this->apiKey && !empty($this->apiKey)) { + $params['apiKey'] = $this->apiKey; + + } else { + $params['hash'] = $this->hash; + } + // Create request string + $params['username'] = $this->username; + + $this->lastRequest = $params; + + if (self::REQUEST_HANDLER == 'curl') { + $rawResponse = $this->_sendRequestCurl($command, $params); + } else { throw new Exception('Invalid request handler.'); + } + + $result = json_decode($rawResponse); + if (isset($result->errors)) { + if (count($result->errors) > 0) { + foreach ($result->errors as $error) { + switch ($error->code) { + default: + throw new Exception($error->message); + } + } + } + } + + return $result; + } + + /** + * Curl request handler + * + * @param $command + * @param $params + * @return mixed + * @throws Exception + */ + private function _sendRequestCurl($command, $params) + { + + $url = self::REQUEST_URL . $command . '/'; + + // Initialize handle + $ch = curl_init($url); + curl_setopt_array( + $ch, array( + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $params, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_TIMEOUT => self::REQUEST_TIMEOUT + ) + ); + + $rawResponse = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($rawResponse === false) { + throw new Exception('Failed to connect to the Textlocal service: ' . $error); + } elseif ($httpCode != 200) { + throw new Exception('Bad response from the Textlocal service: HTTP code ' . $httpCode); + } + + return $rawResponse; + } + + /** + * fopen() request handler + * + * @param $command + * @param $params + * @throws Exception + */ + private function _sendRequestFopen($command, $params) + { + throw new Exception('Unsupported transfer method'); + } + + /** + * Get last request's parameters + * + * @return array + */ + public function getLastRequest() + { + return $this->lastRequest; + } + + /** + * Send an SMS to one or more comma separated numbers + * + * @param $numbers + * @param $message + * @param $sender + * @param null $sched + * @param false $test + * @param null $receiptURL + * @param numm $custom + * @param false $optouts + * @param false $simpleReplyService + * @return array|mixed + * @throws Exception + */ + + public function sendSms($numbers, $message, $sender, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) + { + + if (!is_array($numbers)) { + throw new Exception('Invalid $numbers format. Must be an array'); + } + if (empty($message)) { + throw new Exception('Empty message'); + } + if (empty($sender)) { + throw new Exception('Empty sender name'); + } + if (!is_null($sched) && !is_numeric($sched)) { + throw new Exception('Invalid date format. Use numeric epoch format'); + } + + $params = array( + 'message' => rawurlencode($message), + 'numbers' => implode(',', $numbers), + 'sender' => rawurlencode($sender), + 'schedule_time' => $sched, + 'test' => $test, + 'receipt_url' => $receiptURL, + 'custom' => $custom, + 'optouts' => $optouts, + 'simple_reply' => $simpleReplyService + ); + + return $this->_sendRequest('send', $params); + } + + + /** + * Send an SMS to a Group of contacts - group IDs can be retrieved from getGroups() + * + * @param $groupId + * @param $message + * @param null $sender + * @param false $test + * @param null $receiptURL + * @param numm $custom + * @param false $optouts + * @param false $simpleReplyService + * @return array|mixed + * @throws Exception + */ + public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) + { + + if (!is_numeric($groupId)) { + throw new Exception('Invalid $groupId format. Must be a numeric group ID'); + } + if (empty($message)) { + throw new Exception('Empty message'); + } + if (empty($sender)) { + throw new Exception('Empty sender name'); + } + if (!is_null($sched) && !is_numeric($sched)) { + throw new Exception('Invalid date format. Use numeric epoch format'); + } + + $params = array( + 'message' => rawurlencode($message), + 'group_id' => $groupId, + 'sender' => rawurlencode($sender), + 'schedule_time' => $sched, + 'test' => $test, + 'receipt_url' => $receiptURL, + 'custom' => $custom, + 'optouts' => $optouts, + 'simple_reply' => $simpleReplyService + ); + + return $this->_sendRequest('send', $params); + } + + + /** + * Send an MMS to a one or more comma separated contacts + * + * @param $numbers + * @param $fileSource - either an absolute or relative path, or http url to a file. + * @param $message + * @param null $sched + * @param false $test + * @param false $optouts + * @return array|mixed + * @throws Exception + */ + public function sendMms($numbers, $fileSource, $message, $sched = null, $test = false, $optouts = false) + { + + if (!is_array($numbers)) { + throw new Exception('Invalid $numbers format. Must be an array'); + } + if (empty($message)) { + throw new Exception('Empty message'); + } + if (empty($fileSource)) { + throw new Exception('Empty file source'); + } + if (!is_null($sched) && !is_numeric($sched)) { + throw new Exception('Invalid date format. Use numeric epoch format'); + } + + $params = array( + 'message' => rawurlencode($message), + 'numbers' => implode(',', $numbers), + 'schedule_time' => $sched, + 'test' => $test, + 'optouts' => $optouts + ); + + /** + * Local file. POST to service +*/ + if (is_readable($fileSource)) { + $params['file'] = '@' . $fileSource; + } else { $params['url'] = $fileSource; + } + + return $this->_sendRequest('send_mms', $params); + } + + /** + * Send an MMS to a group - group IDs can be + * + * @param $groupId + * @param $fileSource + * @param $message + * @param null $sched + * @param false $test + * @param false $optouts + * @return array|mixed + * @throws Exception + */ + public function sendMmsGroup($groupId, $fileSource, $message, $sched = null, $test = false, $optouts = false) + { + + if (!is_numeric($groupId)) { + throw new Exception('Invalid $groupId format. Must be a numeric group ID'); + } + if (empty($message)) { + throw new Exception('Empty message'); + } + if (empty($fileSource)) { + throw new Exception('Empty file source'); + } + if (!is_null($sched) && !is_numeric($sched)) { + throw new Exception('Invalid date format. Use numeric epoch format'); + } + + $params = array( + 'message' => rawurlencode($message), + 'group_id' => $groupId, + 'schedule_time' => $sched, + 'test' => $test, + 'optouts' => $optouts + ); + + /** + * Local file. POST to service +*/ + if (is_readable($fileSource)) { + $params['file'] = '@' . $fileSource; + } else { $params['url'] = $fileSource; + } + + return $this->_sendRequest('send_mms', $params); + } + + /** + * Returns reseller customer's ID's + * + * @return array + **/ + + public function getUsers() + { + return $this->_sendRequest('get_users'); + } + + /** + * Transfer credits to a reseller's customer + * + * @param $user - can be ID or Email + * @param $credits + * @return array|mixed + * @throws Exception + **/ + + public function transferCredits($user, $credits) + { + + if (!is_numeric($credits)) { + throw new Exception('Invalid credits format'); + } + if (!is_numeric($user)) { + throw new Exception('Invalid user'); + } + if (empty($user)) { + throw new Exception('No user specified'); + } + if (empty($credits)) { + throw new Exception('No credits specified'); + } + + if (is_int($user)) { + $params = array( + 'user_id' => $user, + 'credits' => $credits + ); + } else { + $params = array( + 'user_email' => rawurlencode($user), + 'credits' => $credits + ); + } + + return $this->_sendRequest('transfer_credits', $params); + } + + /**Get templates from an account **/ + + public function getTemplates() + { + return $this->_sendRequest('get_templates'); + } + + /** + * Check the availability of a keyword + * + * @param $keyword + * return array|mixed + */ + public function checkKeyword($keyword) + { + + $params = array('keyword' => $keyword); + return $this->_sendRequest('check_keyword', $params); + } + + /** + * Create a new contact group + * + * @param $name + * @return array|mixed + */ + public function createGroup($name) + { + $params = array('name' => $name); + return $this->_sendRequest('create_group', $params); + } + + /** + * Get contacts from a group - Group IDs can be retrieved with the getGroups() function + * + * @param $groupId + * @param $limit + * @param int $startPos + * @return array|mixed + * @throws Exception + */ + public function getContacts($groupId, $limit, $startPos = 0) + { + + if (!is_numeric($groupId)) { + throw new Exception('Invalid $groupId format. Must be a numeric group ID'); + } + if (!is_numeric($startPos) || $startPos < 0) { + throw new Exception('Invalid $startPos format. Must be a numeric start position, 0 or above'); + } + if (!is_numeric($limit) || $limit < 1) { + throw new Exception('Invalid $limit format. Must be a numeric limit value, 1 or above'); + } + + $params = array( + 'group_id' => $groupId, + 'start' => $startPos, + 'limit' => $limit + ); + return $this->_sendRequest('get_contacts', $params); + } + + /** + * Create one or more number-only contacts in a specific group, defaults to 'My Contacts' + * + * @param $numbers + * @param string $groupid + * @return array|mixed + */ + public function createContacts($numbers, $groupid = '5') + { + $params = array("group_id" => $groupid); + + if (is_array($numbers)) { + $params['numbers'] = implode(',', $numbers); + } else { + $params['numbers'] = $numbers; + } + + return $this->_sendRequest('create_contacts', $params); + } + + /** + * Create bulk contacts - with name and custom information from an array of: + * [first_name] [last_name] [number] [custom1] [custom2] [custom3] + * + * @param array $contacts + * @param string $groupid + * @return array|mixed + */ + function createContactsBulk($contacts, $groupid = '5') + { + // JSON & URL-encode array + $contacts = rawurlencode(json_encode($contacts)); + + $params = array + ("group_id" => $groupid, "contacts" => $contacts); + return $this->_sendRequest('create_contacts_bulk', $params); + } + + /** + * Get a list of groups and group IDs + * + * @return array|mixed + */ + public function getGroups() + { + return $this->_sendRequest('get_groups'); + } + + /** + * Get the status of a message based on the Message ID - this can be taken from sendSMS or from a history report + * + * @param $messageid + * @return array|mixed + */ + public function getMessageStatus($messageid) + { + $params = array("message_id" => $messageid); + return $this->_sendRequest('status_message', $params); + } + + /** + * Get the status of a message based on the Batch ID - this can be taken from sendSMS or from a history report + * + * @param $batchid + * @return array|mixed + */ + public function getBatchStatus($batchid) + { + $params = array("batch_id" => $batchid); + return $this->_sendRequest('status_batch', $params); + } + + /** + * Get sender names + * + * @return array|mixed + */ + public function getSenderNames() + { + return $this->_sendRequest('get_sender_names'); + } + + /** + * Get inboxes available on the account + * + * @return array|mixed + */ + public function getInboxes() + { + return $this->_sendRequest('get_inboxes'); + } + + /** + * Get Credit Balances + * + * @return array + */ + public function getBalance() + { + $result = $this->_sendRequest('balance'); + return array('sms' => $result->balance->sms, 'mms' => $result->balance->mms); + } + + /** + * Get messages from an inbox - The ID can ge retrieved from getInboxes() + * + * @param $inbox + * @return array|bool|mixed + */ + public function getMessages($inbox) + { + if (!isset($inbox)) { return false; + } + $options = array('inbox_id' => $inbox); + return $this->_sendRequest('get_messages', $options); + } + + /** + * Cancel a scheduled message based on a message ID from getScheduledMessages() + * + * @param $id + * @return array|bool|mixed + */ + public function cancelScheduledMessage($id) + { + if (!isset($id)) { return false; + } + $options = array('sent_id' => $id); + return $this->_sendRequest('cancel_scheduled', $options); + } + + /** + * Get Scheduled Message information + * + * @return array|mixed + */ + public function getScheduledMessages() + { + return $this->_sendRequest('get_scheduled'); + } + + /** + * Delete a contact based on telephone number from a group + * + * @param $number + * @param int $groupid + * @return array|bool|mixed + */ + public function deleteContact($number, $groupid = 5) + { + if (!isset($number)) { return false; + } + $options = array('number' => $number, 'group_id' => $groupid); + return $this->_sendRequest('delete_contact', $options); + } + + /** + * Delete a group - Be careful, we can not recover any data deleted by mistake + * + * @param $groupid + * @return array|mixed + */ + public function deleteGroup($groupid) + { + $options = array('group_id' => $groupid); + return $this->_sendRequest('delete_group', $options); + } + + + /** + * Get single SMS history (single numbers, comma seperated numbers when sending) + * + * @param $start + * @param $limit + * @param $min_time Unix timestamp + * @param $max_time Unix timestamp + * @return array|bool|mixed + */ + public function getSingleMessageHistory($start, $limit, $min_time, $max_time) + { + return $this->getHistory('get_history_single', $start, $limit, $min_time, $max_time); + } + + /** + * Get API SMS Message history + * + * @param $start + * @param $limit + * @param $min_time Unix timestamp + * @param $max_time Unix timestamp + * @return array|bool|mixed + */ + public function getAPIMessageHistory($start, $limit, $min_time, $max_time) + { + return $this->getHistory('get_history_api', $start, $limit, $min_time, $max_time); + } + + /** + * Get Email to SMS History + * + * @param $start + * @param $limit + * @param $min_time Unix timestamp + * @param $max_time Unix timestamp + * @return array|bool|mixed + */ + public function getEmailToSMSHistory($start, $limit, $min_time, $max_time) + { + return $this->getHistory('get_history_email', $start, $limit, $min_time, $max_time); + } + + /** + * Get group SMS history + * + * @param $start + * @param $limit + * @param $min_time Unix timestamp + * @param $max_time Unix timestamp + * @return array|bool|mixed + */ + public function getGroupMessageHistory($start, $limit, $min_time, $max_time) + { + return $this->getHistory('get_history_group', $start, $limit, $min_time, $max_time); + } + + /** + * Generic function to provide validation and the request method for getting all types of history + * + * @param $type + * @param $start + * @param $limit + * @param $min_time + * @param $max_time + * @return array|bool|mixed + */ + private function getHistory($type, $start, $limit, $min_time, $max_time) + { + if (!isset($start) || !isset($limit) || !isset($min_time) || !isset($max_time)) { return false; + } + $options = array('start' => $start, 'limit' => $limit, 'min_time' => $min_time, 'max_time' => $max_time); + return $this->_sendRequest($type, $options); + } + + /** + * Get a list of surveys + * + * @return array|mixed + */ + public function getSurveys() + { + return $this->_sendRequest('get_surveys'); + } + + /** + * Get a deatils of a survey + * + * @return array|mixed + */ + public function getSurveyDetails() + { + $options = array('survey_id' => $surveyid); + return $this->_sendRequest('get_survey_details'); + } + + /** + * Get a the results of a given survey + * + * @return array|mixed + */ + public function getSurveyResults($surveyid, $start, $end) + { + $options = array('survey_id' => $surveyid, 'start_date' => $start, 'end_date' => $end); + return $this->_sendRequest('get_surveys', $options); + } + + /** + * Get all account optouts + * + * @return array|mixed + */ + + public function getOptouts($time = null) + { + return $this->_sendRequest('get_optouts'); + } +} + +; + +class Contact +{ + var $number; + var $first_name; + var $last_name; + var $custom1; + var $custom2; + var $custom3; + + var $groupID; + + /** + * Structure of a contact object + * + * @param $number + * @param string $firstname + * @param string $lastname + * @param string $custom1 + * @param string $custom2 + * @param string $custom3 + */ + function __construct($number, $firstname = '', $lastname = '', $custom1 = '', $custom2 = '', $custom3 = '') + { + $this->number = $number; + $this->first_name = $firstname; + $this->last_name = $lastname; + $this->custom1 = $custom1; + $this->custom2 = $custom2; + $this->custom3 = $custom3; + } +} + +; + +/** + * If the json_encode function does not exist, then create it.. + */ + +if (!function_exists('json_encode')) { + function json_encode($a = false) + { + if (is_null($a)) { return 'null'; + } + if ($a === false) { return 'false'; + } + if ($a === true) { return 'true'; + } + if (is_scalar($a)) { + if (is_float($a)) { + // Always use "." for floats. + return floatval(str_replace(",", ".", strval($a))); + } + + if (is_string($a)) { + static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); + return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; + } else { + return $a; + } + } + $isList = true; + for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { + if (key($a) !== $i) { + $isList = false; + break; + } + } + $result = array(); + if ($isList) { + foreach ($a as $v) { $result[] = json_encode($v); + } + return '[' . join(',', $result) . ']'; + } else { + foreach ($a as $k => $v) { $result[] = json_encode($k) . ':' . json_encode($v); + } + return '{' . join(',', $result) . '}'; + } + } +} + + diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php new file mode 100644 index 00000000..683dde55 --- /dev/null +++ b/src/TextlocalChannel.php @@ -0,0 +1,58 @@ +client = $client; + $this->sender = config('services.sms.textlocal.sender'); + } + + /** + * Send the given notification. + * + * @param mixed $notifiable + * @param \Illuminate\Notifications\Notification $notification + * + * @throws \NotificationChannels\Textlocal\Exceptions\CouldNotSendNotification + */ + public function send($notifiable, Notification $notification) + { + // Get the mobile number/s from the model + $numbers = (array) $notifiable->routeNotificationForSms(); + + if (empty($numbers)) { + return; + } + + if (!is_array($numbers) ) { + $numbers = array($numbers); + } + + // Get the message from the notification class + $message = (string) $notification->toSms($notifiable); + + if (empty($message)) { + return; + } + + try { + $response = $this->client->sendSms($numbers, $message, $this->sender); + return json_decode(json_encode($response), true); + + } catch (\Exception $exception) { + throw CouldNotSendNotification::serviceRespondedWithAnError($exception); + } + } +} diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php new file mode 100644 index 00000000..53d23354 --- /dev/null +++ b/src/TextlocalServiceProvider.php @@ -0,0 +1,36 @@ +app->when(TextlocalChannel::class) + ->needs(Textlocal::class) + ->give( + function () { + $textlocalConfig = config('services.sms.textlocal'); + + return new Textlocal( + $textlocalConfig['username'], + $textlocalConfig['hash'] + ); + } + ); + } + + /** + * Register the application services. + */ + public function register() + { + } +} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php new file mode 100644 index 00000000..c6d9b11b --- /dev/null +++ b/tests/ExampleTest.php @@ -0,0 +1,12 @@ +assertTrue(true); + } +} From 0feceaa9ccc6e55f444ddda98fd7ed2cb735f2c3 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Mon, 7 Aug 2017 15:23:58 +0530 Subject: [PATCH 02/63] Exception handling --- src/Exceptions/CouldNotSendNotification.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index f9dc566c..b89deae1 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -1,11 +1,11 @@ getMessage()); } } From ccf2195d1c50c4263c4538c2b5fe78c7a20e8779 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Mon, 7 Aug 2017 15:34:53 +0530 Subject: [PATCH 03/63] Apply Patch from CI --- src/Exceptions/CouldNotSendNotification.php | 2 +- src/Textlocal.php | 382 +++++++++++--------- src/TextlocalChannel.php | 14 +- 3 files changed, 216 insertions(+), 182 deletions(-) diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index b89deae1..a2c90b3b 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -6,6 +6,6 @@ class CouldNotSendNotification extends \Exception { public static function serviceRespondedWithAnError($exception) { - return new static("Could Not Send SMS to TEXTLOCAL ." . $exception->getMessage()); + return new static('Could Not Send SMS to TEXTLOCAL .'.$exception->getMessage()); } } diff --git a/src/Textlocal.php b/src/Textlocal.php index feb1a352..1944e997 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -3,14 +3,13 @@ namespace NotificationChannels\Textlocal; /** - * Textlocal API2 Wrapper Class + * Textlocal API2 Wrapper Class. * * This class is used to interface with the Textlocal API2 to send messages, manage contacts, retrieve messages from * inboxes, track message delivery statuses, access history reports * - * @package Textlocal - * @subpackage API * @author Andy Dixon + * * @version 1.4-IN * @const REQUEST_URL URL to make the request to * @const REQUEST_TIMEOUT Timeout in seconds for the HTTP request @@ -28,41 +27,42 @@ class Textlocal private $errorReporting = false; - public $errors = array(); - public $warnings = array(); + public $errors = []; + public $warnings = []; - public $lastRequest = array(); + public $lastRequest = []; /** - * Instantiate the object + * Instantiate the object. * * @param $username * @param $hash */ - function __construct($username, $hash, $apiKey = false) + public function __construct($username, $hash, $apiKey = false) { $this->username = $username; $this->hash = $hash; if ($apiKey) { $this->apiKey = $apiKey; } - } /** - * Private function to construct and send the request and handle the response + * Private function to construct and send the request and handle the response. * * @param $command - * @param array $params - * @return array|mixed + * @param array $params + * * @throws Exception + * + * @return array|mixed + * * @todo Add additional request handlers - eg fopen, file_get_contacts */ - private function _sendRequest($command, $params = array()) + private function _sendRequest($command, $params = []) { if ($this->apiKey && !empty($this->apiKey)) { $params['apiKey'] = $this->apiKey; - } else { $params['hash'] = $this->hash; } @@ -73,7 +73,8 @@ private function _sendRequest($command, $params = array()) if (self::REQUEST_HANDLER == 'curl') { $rawResponse = $this->_sendRequestCurl($command, $params); - } else { throw new Exception('Invalid request handler.'); + } else { + throw new Exception('Invalid request handler.'); } $result = json_decode($rawResponse); @@ -92,28 +93,29 @@ private function _sendRequest($command, $params = array()) } /** - * Curl request handler + * Curl request handler. * * @param $command * @param $params - * @return mixed + * * @throws Exception + * + * @return mixed */ private function _sendRequestCurl($command, $params) { - - $url = self::REQUEST_URL . $command . '/'; + $url = self::REQUEST_URL.$command.'/'; // Initialize handle $ch = curl_init($url); curl_setopt_array( - $ch, array( + $ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $params, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_TIMEOUT => self::REQUEST_TIMEOUT - ) + CURLOPT_TIMEOUT => self::REQUEST_TIMEOUT, + ] ); $rawResponse = curl_exec($ch); @@ -122,19 +124,20 @@ private function _sendRequestCurl($command, $params) curl_close($ch); if ($rawResponse === false) { - throw new Exception('Failed to connect to the Textlocal service: ' . $error); + throw new Exception('Failed to connect to the Textlocal service: '.$error); } elseif ($httpCode != 200) { - throw new Exception('Bad response from the Textlocal service: HTTP code ' . $httpCode); + throw new Exception('Bad response from the Textlocal service: HTTP code '.$httpCode); } return $rawResponse; } /** - * fopen() request handler + * fopen() request handler. * * @param $command * @param $params + * * @throws Exception */ private function _sendRequestFopen($command, $params) @@ -143,7 +146,7 @@ private function _sendRequestFopen($command, $params) } /** - * Get last request's parameters + * Get last request's parameters. * * @return array */ @@ -153,24 +156,24 @@ public function getLastRequest() } /** - * Send an SMS to one or more comma separated numbers + * Send an SMS to one or more comma separated numbers. * * @param $numbers * @param $message * @param $sender - * @param null $sched - * @param false $test - * @param null $receiptURL - * @param numm $custom - * @param false $optouts - * @param false $simpleReplyService - * @return array|mixed + * @param null $sched + * @param false $test + * @param null $receiptURL + * @param numm $custom + * @param false $optouts + * @param false $simpleReplyService + * * @throws Exception + * + * @return array|mixed */ - public function sendSms($numbers, $message, $sender, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) { - if (!is_array($numbers)) { throw new Exception('Invalid $numbers format. Must be an array'); } @@ -184,7 +187,7 @@ public function sendSms($numbers, $message, $sender, $sched = null, $test = fals throw new Exception('Invalid date format. Use numeric epoch format'); } - $params = array( + $params = [ 'message' => rawurlencode($message), 'numbers' => implode(',', $numbers), 'sender' => rawurlencode($sender), @@ -193,30 +196,30 @@ public function sendSms($numbers, $message, $sender, $sched = null, $test = fals 'receipt_url' => $receiptURL, 'custom' => $custom, 'optouts' => $optouts, - 'simple_reply' => $simpleReplyService - ); + 'simple_reply' => $simpleReplyService, + ]; return $this->_sendRequest('send', $params); } - /** - * Send an SMS to a Group of contacts - group IDs can be retrieved from getGroups() + * Send an SMS to a Group of contacts - group IDs can be retrieved from getGroups(). * * @param $groupId * @param $message - * @param null $sender - * @param false $test - * @param null $receiptURL - * @param numm $custom - * @param false $optouts - * @param false $simpleReplyService - * @return array|mixed + * @param null $sender + * @param false $test + * @param null $receiptURL + * @param numm $custom + * @param false $optouts + * @param false $simpleReplyService + * * @throws Exception + * + * @return array|mixed */ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) { - if (!is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } @@ -230,7 +233,7 @@ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, throw new Exception('Invalid date format. Use numeric epoch format'); } - $params = array( + $params = [ 'message' => rawurlencode($message), 'group_id' => $groupId, 'sender' => rawurlencode($sender), @@ -239,28 +242,28 @@ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, 'receipt_url' => $receiptURL, 'custom' => $custom, 'optouts' => $optouts, - 'simple_reply' => $simpleReplyService - ); + 'simple_reply' => $simpleReplyService, + ]; return $this->_sendRequest('send', $params); } - /** - * Send an MMS to a one or more comma separated contacts + * Send an MMS to a one or more comma separated contacts. * * @param $numbers * @param $fileSource - either an absolute or relative path, or http url to a file. * @param $message - * @param null $sched - * @param false $test - * @param false $optouts - * @return array|mixed + * @param null $sched + * @param false $test + * @param false $optouts + * * @throws Exception + * + * @return array|mixed */ public function sendMms($numbers, $fileSource, $message, $sched = null, $test = false, $optouts = false) { - if (!is_array($numbers)) { throw new Exception('Invalid $numbers format. Must be an array'); } @@ -274,40 +277,42 @@ public function sendMms($numbers, $fileSource, $message, $sched = null, $test = throw new Exception('Invalid date format. Use numeric epoch format'); } - $params = array( + $params = [ 'message' => rawurlencode($message), 'numbers' => implode(',', $numbers), 'schedule_time' => $sched, 'test' => $test, - 'optouts' => $optouts - ); + 'optouts' => $optouts, + ]; - /** + /* * Local file. POST to service */ if (is_readable($fileSource)) { - $params['file'] = '@' . $fileSource; - } else { $params['url'] = $fileSource; + $params['file'] = '@'.$fileSource; + } else { + $params['url'] = $fileSource; } return $this->_sendRequest('send_mms', $params); } /** - * Send an MMS to a group - group IDs can be + * Send an MMS to a group - group IDs can be. * * @param $groupId * @param $fileSource * @param $message - * @param null $sched - * @param false $test - * @param false $optouts - * @return array|mixed + * @param null $sched + * @param false $test + * @param false $optouts + * * @throws Exception + * + * @return array|mixed */ public function sendMmsGroup($groupId, $fileSource, $message, $sched = null, $test = false, $optouts = false) { - if (!is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } @@ -321,48 +326,48 @@ public function sendMmsGroup($groupId, $fileSource, $message, $sched = null, $te throw new Exception('Invalid date format. Use numeric epoch format'); } - $params = array( + $params = [ 'message' => rawurlencode($message), 'group_id' => $groupId, 'schedule_time' => $sched, 'test' => $test, - 'optouts' => $optouts - ); + 'optouts' => $optouts, + ]; - /** + /* * Local file. POST to service */ if (is_readable($fileSource)) { - $params['file'] = '@' . $fileSource; - } else { $params['url'] = $fileSource; + $params['file'] = '@'.$fileSource; + } else { + $params['url'] = $fileSource; } return $this->_sendRequest('send_mms', $params); } /** - * Returns reseller customer's ID's + * Returns reseller customer's ID's. * * @return array **/ - public function getUsers() { return $this->_sendRequest('get_users'); } /** - * Transfer credits to a reseller's customer + * Transfer credits to a reseller's customer. * * @param $user - can be ID or Email * @param $credits - * @return array|mixed + * * @throws Exception + * + * @return array|mixed **/ - public function transferCredits($user, $credits) { - if (!is_numeric($credits)) { throw new Exception('Invalid credits format'); } @@ -377,15 +382,15 @@ public function transferCredits($user, $credits) } if (is_int($user)) { - $params = array( + $params = [ 'user_id' => $user, - 'credits' => $credits - ); + 'credits' => $credits, + ]; } else { - $params = array( + $params = [ 'user_email' => rawurlencode($user), - 'credits' => $credits - ); + 'credits' => $credits, + ]; } return $this->_sendRequest('transfer_credits', $params); @@ -399,42 +404,45 @@ public function getTemplates() } /** - * Check the availability of a keyword + * Check the availability of a keyword. * * @param $keyword * return array|mixed */ public function checkKeyword($keyword) { + $params = ['keyword' => $keyword]; - $params = array('keyword' => $keyword); return $this->_sendRequest('check_keyword', $params); } /** - * Create a new contact group + * Create a new contact group. * * @param $name + * * @return array|mixed */ public function createGroup($name) { - $params = array('name' => $name); + $params = ['name' => $name]; + return $this->_sendRequest('create_group', $params); } /** - * Get contacts from a group - Group IDs can be retrieved with the getGroups() function + * Get contacts from a group - Group IDs can be retrieved with the getGroups() function. * * @param $groupId * @param $limit - * @param int $startPos - * @return array|mixed + * @param int $startPos + * * @throws Exception + * + * @return array|mixed */ public function getContacts($groupId, $limit, $startPos = 0) { - if (!is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } @@ -445,24 +453,26 @@ public function getContacts($groupId, $limit, $startPos = 0) throw new Exception('Invalid $limit format. Must be a numeric limit value, 1 or above'); } - $params = array( + $params = [ 'group_id' => $groupId, 'start' => $startPos, - 'limit' => $limit - ); + 'limit' => $limit, + ]; + return $this->_sendRequest('get_contacts', $params); } /** - * Create one or more number-only contacts in a specific group, defaults to 'My Contacts' + * Create one or more number-only contacts in a specific group, defaults to 'My Contacts'. * * @param $numbers - * @param string $groupid + * @param string $groupid + * * @return array|mixed */ public function createContacts($numbers, $groupid = '5') { - $params = array("group_id" => $groupid); + $params = ['group_id' => $groupid]; if (is_array($numbers)) { $params['numbers'] = implode(',', $numbers); @@ -475,24 +485,25 @@ public function createContacts($numbers, $groupid = '5') /** * Create bulk contacts - with name and custom information from an array of: - * [first_name] [last_name] [number] [custom1] [custom2] [custom3] + * [first_name] [last_name] [number] [custom1] [custom2] [custom3]. + * + * @param array $contacts + * @param string $groupid * - * @param array $contacts - * @param string $groupid * @return array|mixed */ - function createContactsBulk($contacts, $groupid = '5') + public function createContactsBulk($contacts, $groupid = '5') { // JSON & URL-encode array $contacts = rawurlencode(json_encode($contacts)); - $params = array - ("group_id" => $groupid, "contacts" => $contacts); + $params = ['group_id' => $groupid, 'contacts' => $contacts]; + return $this->_sendRequest('create_contacts_bulk', $params); } /** - * Get a list of groups and group IDs + * Get a list of groups and group IDs. * * @return array|mixed */ @@ -502,31 +513,35 @@ public function getGroups() } /** - * Get the status of a message based on the Message ID - this can be taken from sendSMS or from a history report + * Get the status of a message based on the Message ID - this can be taken from sendSMS or from a history report. * * @param $messageid + * * @return array|mixed */ public function getMessageStatus($messageid) { - $params = array("message_id" => $messageid); + $params = ['message_id' => $messageid]; + return $this->_sendRequest('status_message', $params); } /** - * Get the status of a message based on the Batch ID - this can be taken from sendSMS or from a history report + * Get the status of a message based on the Batch ID - this can be taken from sendSMS or from a history report. * * @param $batchid + * * @return array|mixed */ public function getBatchStatus($batchid) { - $params = array("batch_id" => $batchid); + $params = ['batch_id' => $batchid]; + return $this->_sendRequest('status_batch', $params); } /** - * Get sender names + * Get sender names. * * @return array|mixed */ @@ -536,7 +551,7 @@ public function getSenderNames() } /** - * Get inboxes available on the account + * Get inboxes available on the account. * * @return array|mixed */ @@ -546,46 +561,53 @@ public function getInboxes() } /** - * Get Credit Balances + * Get Credit Balances. * * @return array */ public function getBalance() { $result = $this->_sendRequest('balance'); - return array('sms' => $result->balance->sms, 'mms' => $result->balance->mms); + + return ['sms' => $result->balance->sms, 'mms' => $result->balance->mms]; } /** - * Get messages from an inbox - The ID can ge retrieved from getInboxes() + * Get messages from an inbox - The ID can ge retrieved from getInboxes(). * * @param $inbox + * * @return array|bool|mixed */ public function getMessages($inbox) { - if (!isset($inbox)) { return false; + if (!isset($inbox)) { + return false; } - $options = array('inbox_id' => $inbox); + $options = ['inbox_id' => $inbox]; + return $this->_sendRequest('get_messages', $options); } /** - * Cancel a scheduled message based on a message ID from getScheduledMessages() + * Cancel a scheduled message based on a message ID from getScheduledMessages(). * * @param $id + * * @return array|bool|mixed */ public function cancelScheduledMessage($id) { - if (!isset($id)) { return false; + if (!isset($id)) { + return false; } - $options = array('sent_id' => $id); + $options = ['sent_id' => $id]; + return $this->_sendRequest('cancel_scheduled', $options); } /** - * Get Scheduled Message information + * Get Scheduled Message information. * * @return array|mixed */ @@ -595,40 +617,45 @@ public function getScheduledMessages() } /** - * Delete a contact based on telephone number from a group + * Delete a contact based on telephone number from a group. * * @param $number - * @param int $groupid + * @param int $groupid + * * @return array|bool|mixed */ public function deleteContact($number, $groupid = 5) { - if (!isset($number)) { return false; + if (!isset($number)) { + return false; } - $options = array('number' => $number, 'group_id' => $groupid); + $options = ['number' => $number, 'group_id' => $groupid]; + return $this->_sendRequest('delete_contact', $options); } /** - * Delete a group - Be careful, we can not recover any data deleted by mistake + * Delete a group - Be careful, we can not recover any data deleted by mistake. * * @param $groupid + * * @return array|mixed */ public function deleteGroup($groupid) { - $options = array('group_id' => $groupid); + $options = ['group_id' => $groupid]; + return $this->_sendRequest('delete_group', $options); } - /** - * Get single SMS history (single numbers, comma seperated numbers when sending) + * Get single SMS history (single numbers, comma seperated numbers when sending). * * @param $start * @param $limit * @param $min_time Unix timestamp * @param $max_time Unix timestamp + * * @return array|bool|mixed */ public function getSingleMessageHistory($start, $limit, $min_time, $max_time) @@ -637,12 +664,13 @@ public function getSingleMessageHistory($start, $limit, $min_time, $max_time) } /** - * Get API SMS Message history + * Get API SMS Message history. * * @param $start * @param $limit * @param $min_time Unix timestamp * @param $max_time Unix timestamp + * * @return array|bool|mixed */ public function getAPIMessageHistory($start, $limit, $min_time, $max_time) @@ -651,12 +679,13 @@ public function getAPIMessageHistory($start, $limit, $min_time, $max_time) } /** - * Get Email to SMS History + * Get Email to SMS History. * * @param $start * @param $limit * @param $min_time Unix timestamp * @param $max_time Unix timestamp + * * @return array|bool|mixed */ public function getEmailToSMSHistory($start, $limit, $min_time, $max_time) @@ -665,12 +694,13 @@ public function getEmailToSMSHistory($start, $limit, $min_time, $max_time) } /** - * Get group SMS history + * Get group SMS history. * * @param $start * @param $limit * @param $min_time Unix timestamp * @param $max_time Unix timestamp + * * @return array|bool|mixed */ public function getGroupMessageHistory($start, $limit, $min_time, $max_time) @@ -679,25 +709,28 @@ public function getGroupMessageHistory($start, $limit, $min_time, $max_time) } /** - * Generic function to provide validation and the request method for getting all types of history + * Generic function to provide validation and the request method for getting all types of history. * * @param $type * @param $start * @param $limit * @param $min_time * @param $max_time + * * @return array|bool|mixed */ private function getHistory($type, $start, $limit, $min_time, $max_time) { - if (!isset($start) || !isset($limit) || !isset($min_time) || !isset($max_time)) { return false; + if (!isset($start) || !isset($limit) || !isset($min_time) || !isset($max_time)) { + return false; } - $options = array('start' => $start, 'limit' => $limit, 'min_time' => $min_time, 'max_time' => $max_time); + $options = ['start' => $start, 'limit' => $limit, 'min_time' => $min_time, 'max_time' => $max_time]; + return $this->_sendRequest($type, $options); } /** - * Get a list of surveys + * Get a list of surveys. * * @return array|mixed */ @@ -707,54 +740,53 @@ public function getSurveys() } /** - * Get a deatils of a survey + * Get a deatils of a survey. * * @return array|mixed */ public function getSurveyDetails() { - $options = array('survey_id' => $surveyid); + $options = ['survey_id' => $surveyid]; + return $this->_sendRequest('get_survey_details'); } /** - * Get a the results of a given survey + * Get a the results of a given survey. * * @return array|mixed */ public function getSurveyResults($surveyid, $start, $end) { - $options = array('survey_id' => $surveyid, 'start_date' => $start, 'end_date' => $end); + $options = ['survey_id' => $surveyid, 'start_date' => $start, 'end_date' => $end]; + return $this->_sendRequest('get_surveys', $options); } /** - * Get all account optouts + * Get all account optouts. * * @return array|mixed */ - public function getOptouts($time = null) { return $this->_sendRequest('get_optouts'); } } -; - class Contact { - var $number; - var $first_name; - var $last_name; - var $custom1; - var $custom2; - var $custom3; + public $number; + public $first_name; + public $last_name; + public $custom1; + public $custom2; + public $custom3; - var $groupID; + public $groupID; /** - * Structure of a contact object + * Structure of a contact object. * * @param $number * @param string $firstname @@ -763,7 +795,7 @@ class Contact * @param string $custom2 * @param string $custom3 */ - function __construct($number, $firstname = '', $lastname = '', $custom1 = '', $custom2 = '', $custom3 = '') + public function __construct($number, $firstname = '', $lastname = '', $custom1 = '', $custom2 = '', $custom3 = '') { $this->number = $number; $this->first_name = $firstname; @@ -774,30 +806,32 @@ function __construct($number, $firstname = '', $lastname = '', $custom1 = '', $c } } -; - -/** +/* * If the json_encode function does not exist, then create it.. */ if (!function_exists('json_encode')) { function json_encode($a = false) { - if (is_null($a)) { return 'null'; + if (is_null($a)) { + return 'null'; } - if ($a === false) { return 'false'; + if ($a === false) { + return 'false'; } - if ($a === true) { return 'true'; + if ($a === true) { + return 'true'; } if (is_scalar($a)) { if (is_float($a)) { // Always use "." for floats. - return floatval(str_replace(",", ".", strval($a))); + return floatval(str_replace(',', '.', strval($a))); } if (is_string($a)) { - static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); - return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; + static $jsonReplaces = [['\\', '/', "\n", "\t", "\r", "\b", "\f", '"'], ['\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"']]; + + return '"'.str_replace($jsonReplaces[0], $jsonReplaces[1], $a).'"'; } else { return $a; } @@ -809,17 +843,19 @@ function json_encode($a = false) break; } } - $result = array(); + $result = []; if ($isList) { - foreach ($a as $v) { $result[] = json_encode($v); + foreach ($a as $v) { + $result[] = json_encode($v); } - return '[' . join(',', $result) . ']'; + + return '['.implode(',', $result).']'; } else { - foreach ($a as $k => $v) { $result[] = json_encode($k) . ':' . json_encode($v); + foreach ($a as $k => $v) { + $result[] = json_encode($k).':'.json_encode($v); } - return '{' . join(',', $result) . '}'; + + return '{'.implode(',', $result).'}'; } } } - - diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 683dde55..1bc821bc 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -2,10 +2,8 @@ namespace NotificationChannels\Textlocal; -use NotificationChannels\Textlocal\Exceptions\CouldNotSendNotification; -use NotificationChannels\Textlocal\Events\MessageWasSent; -use NotificationChannels\Textlocal\Events\SendingMessage; use Illuminate\Notifications\Notification; +use NotificationChannels\Textlocal\Exceptions\CouldNotSendNotification; class TextlocalChannel { @@ -15,8 +13,8 @@ class TextlocalChannel public function __construct(Textlocal $client) { // Initialisation code here - $this->client = $client; - $this->sender = config('services.sms.textlocal.sender'); + $this->client = $client; + $this->sender = config('services.sms.textlocal.sender'); } /** @@ -36,8 +34,8 @@ public function send($notifiable, Notification $notification) return; } - if (!is_array($numbers) ) { - $numbers = array($numbers); + if (!is_array($numbers)) { + $numbers = [$numbers]; } // Get the message from the notification class @@ -49,8 +47,8 @@ public function send($notifiable, Notification $notification) try { $response = $this->client->sendSms($numbers, $message, $this->sender); - return json_decode(json_encode($response), true); + return json_decode(json_encode($response), true); } catch (\Exception $exception) { throw CouldNotSendNotification::serviceRespondedWithAnError($exception); } From 9ea8b72ed7135d810b4f775af868f55c7b108971 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Mon, 7 Aug 2017 15:39:50 +0530 Subject: [PATCH 04/63] modified default case namespace --- tests/ExampleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index c6d9b11b..b2cb7d5e 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -1,6 +1,6 @@ Date: Wed, 9 Aug 2017 13:05:56 +0530 Subject: [PATCH 05/63] updated exception import which was incorrect previously --- src/Exceptions/CouldNotSendNotification.php | 2 +- src/Textlocal.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index a2c90b3b..38e61ccb 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -6,6 +6,6 @@ class CouldNotSendNotification extends \Exception { public static function serviceRespondedWithAnError($exception) { - return new static('Could Not Send SMS to TEXTLOCAL .'.$exception->getMessage()); + return new static('Could Not Send SMS Error: '.$exception->getMessage()); } } diff --git a/src/Textlocal.php b/src/Textlocal.php index 1944e997..c4fb4799 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -2,6 +2,8 @@ namespace NotificationChannels\Textlocal; +use \Exception; + /** * Textlocal API2 Wrapper Class. * From 519cd6206bd6f1fae30c2baa12c8ab2ff37e0dc9 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Wed, 9 Aug 2017 13:10:42 +0530 Subject: [PATCH 06/63] apply fixes from styleci --- src/Exceptions/CouldNotSendNotification.php | 2 +- src/Textlocal.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index 38e61ccb..947a81b8 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -6,6 +6,6 @@ class CouldNotSendNotification extends \Exception { public static function serviceRespondedWithAnError($exception) { - return new static('Could Not Send SMS Error: '.$exception->getMessage()); + return new static('Could Not Send SMS : '.$exception->getMessage()); } } diff --git a/src/Textlocal.php b/src/Textlocal.php index c4fb4799..2ff875ee 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -2,7 +2,7 @@ namespace NotificationChannels\Textlocal; -use \Exception; +use Exception; /** * Textlocal API2 Wrapper Class. From 30ec260389c631a53241d02c8bb5cb57de0b2be2 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 25 Nov 2017 14:00:02 +0530 Subject: [PATCH 07/63] Update composer.json --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 55d87036..00adbc17 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "laravel-notification-channels/textlocal", - "description": "This package helps to send SMS via Textlocal API in laravel way", + "name": "msonowal/laravel-notification-channel-textlocal", + "description": "This Driver for textlocal sms to send SMS via Textlocal API through laravel notification", "homepage": "https://github.com/laravel-notification-channels/textlocal", "license": "MIT", "authors": [ @@ -13,8 +13,8 @@ ], "require": { "php": ">=5.6.4", - "illuminate/notifications": "^5.3|^5.4", - "illuminate/support": "^5.1|^5.2|^5.3|^5.4" + "illuminate/notifications": "^5.3|^5.4|^5.5", + "illuminate/support": "^5.1|^5.2|^5.3|^5.4|^5.5" }, "require-dev": { "mockery/mockery": "^0.9.5", From e51d5ac800e7fb01f4c02f5918c3d6121b41da22 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 25 Nov 2017 14:04:34 +0530 Subject: [PATCH 08/63] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ba7e1c0..3fa110e5 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ This package makes it easy to send notifications using [textlocal](https://www.t Create an account in textlocal then create an API key or hash(password). -`composer require laravel-notification-channels/textlocal` +`composer require msonowal/laravel-notification-channel-textlocal` ### Setting up the textlocal service From 83e3f76fa8436ee2fe7b6519ca33718142571fbc Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 25 Nov 2017 14:38:52 +0530 Subject: [PATCH 09/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 1bc821bc..61d60797 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -37,6 +37,10 @@ public function send($notifiable, Notification $notification) if (!is_array($numbers)) { $numbers = [$numbers]; } + + if (! array_filter($numbers, 'is_int')) { + return; + } // Get the message from the notification class $message = (string) $notification->toSms($notifiable); From b37a6726c266643fe29294a9e3e4228f5a97086b Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 25 Nov 2017 14:45:58 +0530 Subject: [PATCH 10/63] Update README.md --- README.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3fa110e5..90c5ba41 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,9 @@ https://laravel.com/docs/5.4/notifications # Found any bugs or improvement open an issue or send me a PR -[![Latest Version on Packagist](https://img.shields.io/packagist/v/laravel-notification-channels/textlocal.svg?style=flat-square)](https://packagist.org/packages/laravel-notification-channels/textlocal) -[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) -[![Build Status](https://img.shields.io/travis/laravel-notification-channels/textlocal/master.svg?style=flat-square)](https://travis-ci.org/laravel-notification-channels/textlocal) -[![StyleCI](https://styleci.io/repos/:style_ci_id/shield)](https://styleci.io/repos/:style_ci_id) -[![SensioLabsInsight](https://img.shields.io/sensiolabs/i/:sensio_labs_id.svg?style=flat-square)](https://insight.sensiolabs.com/projects/:sensio_labs_id) -[![Quality Score](https://img.shields.io/scrutinizer/g/laravel-notification-channels/textlocal.svg?style=flat-square)](https://scrutinizer-ci.com/g/laravel-notification-channels/textlocal) -[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/laravel-notification-channels/textlocal/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/laravel-notification-channels/textlocal/?branch=master) -[![Total Downloads](https://img.shields.io/packagist/dt/laravel-notification-channels/textlocal.svg?style=flat-square)](https://packagist.org/packages/laravel-notification-channels/textlocal) +[![Latest Stable Version](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/v/stable)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) +[![License](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/license)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) +[![Total Downloads](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/downloads)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) This package makes it easy to send notifications using [textlocal](https://www.textlocal.in/) with Laravel 5.3.+ @@ -44,10 +39,11 @@ Create an account in textlocal then create an API key or hash(password). put the followings and to your config/services ``` 'sms' => [ - 'textlocal' => [ - 'username' => env('TEXTLOCAL_USERNAME'), - 'hash' => env('TEXTLOCAL_HASH'), - 'sender' => env('TEXTLOCAL_SENDER'), + 'textlocal' => [ + 'username' => env('TEXTLOCAL_USERNAME'), + 'hash' => env('TEXTLOCAL_HASH'), + 'sender' => env('TEXTLOCAL_SENDER'), + ] ] ``` From 5e0e269047e03fe7e3e9687e40f351a744d15bf4 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 2 Dec 2017 20:57:25 +0530 Subject: [PATCH 11/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 61d60797..fb9a4a9d 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -38,9 +38,7 @@ public function send($notifiable, Notification $notification) $numbers = [$numbers]; } - if (! array_filter($numbers, 'is_int')) { - return; - } + //TODO check if numbers are correct // Get the message from the notification class $message = (string) $notification->toSms($notifiable); From 0b5230f51cc17136b06b13a097869c5b72f3a163 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 4 Apr 2018 11:36:21 +0530 Subject: [PATCH 12/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index fb9a4a9d..073d05de 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -52,7 +52,7 @@ public function send($notifiable, Notification $notification) return json_decode(json_encode($response), true); } catch (\Exception $exception) { - throw CouldNotSendNotification::serviceRespondedWithAnError($exception); + throw CouldNotSendNotification::serviceRespondedWithAnError($exception, $message); } } } From e7906c6abdee28de33f32551eadd53440f994302 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 4 Apr 2018 11:37:12 +0530 Subject: [PATCH 13/63] Update CouldNotSendNotification.php --- src/Exceptions/CouldNotSendNotification.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index 947a81b8..466ecc63 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -4,8 +4,8 @@ class CouldNotSendNotification extends \Exception { - public static function serviceRespondedWithAnError($exception) + public static function serviceRespondedWithAnError($exception, $message = null) { - return new static('Could Not Send SMS : '.$exception->getMessage()); + return new static('Could Not Send SMS : '.$exception->getMessage() . ' message: ' . $message); } } From 1792aea2d6a77d5a609aefbdddeff699534c14ba Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Fri, 19 Oct 2018 14:42:00 +0530 Subject: [PATCH 14/63] Added Multiple region textlocal config --- README.md | 15 ++++++++-- scrutinizer.yml | 21 +++++++++++++ src/Textlocal.php | 51 ++++++++++++++++++-------------- src/TextlocalServiceProvider.php | 6 +++- src/config/textlocal.php | 9 ++++++ styleci.yml | 1 + travis.yml | 22 ++++++++++++++ 7 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 scrutinizer.yml create mode 100644 src/config/textlocal.php create mode 100644 styleci.yml create mode 100644 travis.yml diff --git a/README.md b/README.md index 90c5ba41..49376232 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,19 @@ put the followings and to your config/services ] ] ``` +### Configuring .env +``` + TEXTLOCAL_USERNAME=Your email id or api key + TEXTLOCAL_HASH=get it from url '/docs/' under your API KEYS section + TEXTLOCAL_SENDER=Name of the Sender that will be displayed to the recipient (max 6 Characters). + TEXTLOCAL_COUNTRY=Your Two letter(ISO-3166-alpha-2) Country Code. It should be the Country of the TEXTLOCAL account. +``` +Currently, only textlocal of two country is supported IN(India) and UK(United Kingdom). ## Usage -textlocal -implement this method `routeNotificationForSms()` in your notifiable class/model which will return array of mobile numbers -and lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. + +Implement this method `routeNotificationForSms()` in your notifiable class/model which will return array of mobile numbers. Please make sure the mobile number contains the dial code as well (e.g +91 for India). And lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. ### Available Message methods @@ -78,6 +85,7 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details. ## Credits - [Manash Jyoti Sonowal](https://github.com/msonowal) +- [Manash Jyoti Sonowal](https://github.com/tomonsoejang) - [All Contributors](../../contributors) ## License @@ -86,4 +94,5 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio ## TODO Need to convert to Guzzle Http as a Client in core +Add more countries add tests diff --git a/scrutinizer.yml b/scrutinizer.yml new file mode 100644 index 00000000..6fad5be9 --- /dev/null +++ b/scrutinizer.yml @@ -0,0 +1,21 @@ +filter: + excluded_paths: [tests/*] + +checks: + php: + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true + +tools: + external_code_coverage: true diff --git a/src/Textlocal.php b/src/Textlocal.php index 2ff875ee..2d874cf7 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -13,16 +13,18 @@ * @author Andy Dixon * * @version 1.4-IN - * @const REQUEST_URL URL to make the request to + * @string $request_url URL to make the request to * @const REQUEST_TIMEOUT Timeout in seconds for the HTTP request * @const REQUEST_HANDLER Handler to use when making the HTTP request (for future use) */ class Textlocal { - const REQUEST_URL = 'https://api.textlocal.in/'; const REQUEST_TIMEOUT = 60; const REQUEST_HANDLER = 'curl'; + private $request_url; + private $country; + private $username; private $hash; private $apiKey; @@ -47,6 +49,9 @@ public function __construct($username, $hash, $apiKey = false) if ($apiKey) { $this->apiKey = $apiKey; } + + $this->country = config('textlocal.country'); + $this->request_url = config('textlocal.request_urls')[$this->country]; } /** @@ -63,7 +68,7 @@ public function __construct($username, $hash, $apiKey = false) */ private function _sendRequest($command, $params = []) { - if ($this->apiKey && !empty($this->apiKey)) { + if ($this->apiKey && ! empty($this->apiKey)) { $params['apiKey'] = $this->apiKey; } else { $params['hash'] = $this->hash; @@ -106,7 +111,7 @@ private function _sendRequest($command, $params = []) */ private function _sendRequestCurl($command, $params) { - $url = self::REQUEST_URL.$command.'/'; + $url = $this->request_url.$command.'/'; // Initialize handle $ch = curl_init($url); @@ -176,7 +181,7 @@ public function getLastRequest() */ public function sendSms($numbers, $message, $sender, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) { - if (!is_array($numbers)) { + if (! is_array($numbers)) { throw new Exception('Invalid $numbers format. Must be an array'); } if (empty($message)) { @@ -185,7 +190,7 @@ public function sendSms($numbers, $message, $sender, $sched = null, $test = fals if (empty($sender)) { throw new Exception('Empty sender name'); } - if (!is_null($sched) && !is_numeric($sched)) { + if (! is_null($sched) && ! is_numeric($sched)) { throw new Exception('Invalid date format. Use numeric epoch format'); } @@ -222,7 +227,7 @@ public function sendSms($numbers, $message, $sender, $sched = null, $test = fals */ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) { - if (!is_numeric($groupId)) { + if (! is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } if (empty($message)) { @@ -231,7 +236,7 @@ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, if (empty($sender)) { throw new Exception('Empty sender name'); } - if (!is_null($sched) && !is_numeric($sched)) { + if (! is_null($sched) && ! is_numeric($sched)) { throw new Exception('Invalid date format. Use numeric epoch format'); } @@ -266,7 +271,7 @@ public function sendSmsGroup($groupId, $message, $sender = null, $sched = null, */ public function sendMms($numbers, $fileSource, $message, $sched = null, $test = false, $optouts = false) { - if (!is_array($numbers)) { + if (! is_array($numbers)) { throw new Exception('Invalid $numbers format. Must be an array'); } if (empty($message)) { @@ -275,7 +280,7 @@ public function sendMms($numbers, $fileSource, $message, $sched = null, $test = if (empty($fileSource)) { throw new Exception('Empty file source'); } - if (!is_null($sched) && !is_numeric($sched)) { + if (! is_null($sched) && ! is_numeric($sched)) { throw new Exception('Invalid date format. Use numeric epoch format'); } @@ -315,7 +320,7 @@ public function sendMms($numbers, $fileSource, $message, $sched = null, $test = */ public function sendMmsGroup($groupId, $fileSource, $message, $sched = null, $test = false, $optouts = false) { - if (!is_numeric($groupId)) { + if (! is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } if (empty($message)) { @@ -324,7 +329,7 @@ public function sendMmsGroup($groupId, $fileSource, $message, $sched = null, $te if (empty($fileSource)) { throw new Exception('Empty file source'); } - if (!is_null($sched) && !is_numeric($sched)) { + if (! is_null($sched) && ! is_numeric($sched)) { throw new Exception('Invalid date format. Use numeric epoch format'); } @@ -370,10 +375,10 @@ public function getUsers() **/ public function transferCredits($user, $credits) { - if (!is_numeric($credits)) { + if (! is_numeric($credits)) { throw new Exception('Invalid credits format'); } - if (!is_numeric($user)) { + if (! is_numeric($user)) { throw new Exception('Invalid user'); } if (empty($user)) { @@ -445,13 +450,13 @@ public function createGroup($name) */ public function getContacts($groupId, $limit, $startPos = 0) { - if (!is_numeric($groupId)) { + if (! is_numeric($groupId)) { throw new Exception('Invalid $groupId format. Must be a numeric group ID'); } - if (!is_numeric($startPos) || $startPos < 0) { + if (! is_numeric($startPos) || $startPos < 0) { throw new Exception('Invalid $startPos format. Must be a numeric start position, 0 or above'); } - if (!is_numeric($limit) || $limit < 1) { + if (! is_numeric($limit) || $limit < 1) { throw new Exception('Invalid $limit format. Must be a numeric limit value, 1 or above'); } @@ -583,7 +588,7 @@ public function getBalance() */ public function getMessages($inbox) { - if (!isset($inbox)) { + if (! isset($inbox)) { return false; } $options = ['inbox_id' => $inbox]; @@ -600,7 +605,7 @@ public function getMessages($inbox) */ public function cancelScheduledMessage($id) { - if (!isset($id)) { + if (! isset($id)) { return false; } $options = ['sent_id' => $id]; @@ -628,7 +633,7 @@ public function getScheduledMessages() */ public function deleteContact($number, $groupid = 5) { - if (!isset($number)) { + if (! isset($number)) { return false; } $options = ['number' => $number, 'group_id' => $groupid]; @@ -723,7 +728,7 @@ public function getGroupMessageHistory($start, $limit, $min_time, $max_time) */ private function getHistory($type, $start, $limit, $min_time, $max_time) { - if (!isset($start) || !isset($limit) || !isset($min_time) || !isset($max_time)) { + if (! isset($start) || ! isset($limit) || ! isset($min_time) || ! isset($max_time)) { return false; } $options = ['start' => $start, 'limit' => $limit, 'min_time' => $min_time, 'max_time' => $max_time]; @@ -812,7 +817,7 @@ public function __construct($number, $firstname = '', $lastname = '', $custom1 = * If the json_encode function does not exist, then create it.. */ -if (!function_exists('json_encode')) { +if (! function_exists('json_encode')) { function json_encode($a = false) { if (is_null($a)) { @@ -860,4 +865,4 @@ function json_encode($a = false) return '{'.implode(',', $result).'}'; } } -} +} \ No newline at end of file diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index 53d23354..b9d3c221 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -25,6 +25,10 @@ function () { ); } ); + + $this->publishes([ + __DIR__.'/../config/textlocal.php' => config_path('textlocal.php'), + ], 'textlocal'); } /** @@ -33,4 +37,4 @@ function () { public function register() { } -} +} \ No newline at end of file diff --git a/src/config/textlocal.php b/src/config/textlocal.php new file mode 100644 index 00000000..42134547 --- /dev/null +++ b/src/config/textlocal.php @@ -0,0 +1,9 @@ + [ + 'IN' => 'https://api.textlocal.in/', + 'UK' => 'https://api.txtlocal.com/' + ], + 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), +]; \ No newline at end of file diff --git a/styleci.yml b/styleci.yml new file mode 100644 index 00000000..0285f179 --- /dev/null +++ b/styleci.yml @@ -0,0 +1 @@ +preset: laravel diff --git a/travis.yml b/travis.yml new file mode 100644 index 00000000..ff42c2c5 --- /dev/null +++ b/travis.yml @@ -0,0 +1,22 @@ +language: php + +php: + - 5.6 + - 7.0 + - 7.1 + +env: + matrix: + - COMPOSER_FLAGS="--prefer-lowest" + - COMPOSER_FLAGS="" + +before_script: + - travis_retry composer self-update + - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source + +script: + - phpunit --coverage-text --coverage-clover=coverage.clover + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover From 3e2438f2d96cfaff1eb4e341f3b43f6a7b39c752 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Fri, 19 Oct 2018 15:36:38 +0530 Subject: [PATCH 15/63] moved config dir --- README.md | 11 ++++++++--- {src/config => config}/textlocal.php | 0 2 files changed, 8 insertions(+), 3 deletions(-) rename {src/config => config}/textlocal.php (100%) diff --git a/README.md b/README.md index 49376232..177c7828 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ put the followings and to your config/services ``` 'sms' => [ 'textlocal' => [ - 'username' => env('TEXTLOCAL_USERNAME'), - 'hash' => env('TEXTLOCAL_HASH'), - 'sender' => env('TEXTLOCAL_SENDER'), + 'username' => env('TEXTLOCAL_USERNAME'), + 'hash' => env('TEXTLOCAL_HASH'), + 'sender' => env('TEXTLOCAL_SENDER'), ] ] ``` @@ -54,6 +54,11 @@ put the followings and to your config/services TEXTLOCAL_COUNTRY=Your Two letter(ISO-3166-alpha-2) Country Code. It should be the Country of the TEXTLOCAL account. ``` +### Publish Config +``` + php artisan vendor:publish --tag=textlocal +``` + Currently, only textlocal of two country is supported IN(India) and UK(United Kingdom). ## Usage diff --git a/src/config/textlocal.php b/config/textlocal.php similarity index 100% rename from src/config/textlocal.php rename to config/textlocal.php From c4c56044e12475cbb7f0583c52d1f2828282aaee Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Fri, 19 Oct 2018 15:37:58 +0530 Subject: [PATCH 16/63] updated contributors name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 177c7828..c279d9d5 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details. ## Credits - [Manash Jyoti Sonowal](https://github.com/msonowal) -- [Manash Jyoti Sonowal](https://github.com/tomonsoejang) +- [Mr Ejang](https://github.com/tomonsoejang) - [All Contributors](../../contributors) ## License From 964f1bd17d06aca9277237f53b98ae1a6d808b86 Mon Sep 17 00:00:00 2001 From: Manash Jyoti Sonowal Date: Wed, 24 Oct 2018 22:37:59 +0530 Subject: [PATCH 17/63] Fixed a bug which occurs when textlocal config is not published and hence no URL is set so resulting in unable to connect to host Now it merges the configurations with default fallback added notification channel for on demand support --- src/TextlocalChannel.php | 5 ++++- src/TextlocalServiceProvider.php | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 073d05de..7955bee2 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -28,7 +28,10 @@ public function __construct(Textlocal $client) public function send($notifiable, Notification $notification) { // Get the mobile number/s from the model - $numbers = (array) $notifiable->routeNotificationForSms(); + if (! $numbers = $notifiable->routeNotificationFor('textlocal')) { + return; + } + //$numbers = (array) $notifiable->routeNotificationForSms(); if (empty($numbers)) { return; diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index b9d3c221..e4e3a55d 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -26,9 +26,7 @@ function () { } ); - $this->publishes([ - __DIR__.'/../config/textlocal.php' => config_path('textlocal.php'), - ], 'textlocal'); + $this->publishConfiguration(); } /** @@ -36,5 +34,17 @@ function () { */ public function register() { + $config = __DIR__ . '/../config/textlocal.php'; + + $this->mergeConfigFrom($config, 'textlocal'); + } + + public function publishConfiguration() + { + $path = realpath(__DIR__.'/../config/textlocal.php'); + + $this->publishes([ + $path => config_path('textlocal.php') + ], 'textlocal'); } } \ No newline at end of file From 09f53ab1a8f638a9fda2af142ca55b795f851feb Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Mon, 29 Oct 2018 22:42:11 +0530 Subject: [PATCH 18/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 7955bee2..a3f505e1 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -28,7 +28,7 @@ public function __construct(Textlocal $client) public function send($notifiable, Notification $notification) { // Get the mobile number/s from the model - if (! $numbers = $notifiable->routeNotificationFor('textlocal')) { + if (! $numbers = $notifiable->routeNotificationFor('sms')) { return; } //$numbers = (array) $notifiable->routeNotificationForSms(); From e14ddd6c2172b09bfaf81ea673232626be898aa3 Mon Sep 17 00:00:00 2001 From: nikugogoi <95nikass@gmail.com> Date: Fri, 5 Apr 2019 20:49:14 +0530 Subject: [PATCH 19/63] auto package discovery for newer laravel versions need to check if working --- composer.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/composer.json b/composer.json index 00adbc17..be3cce97 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,13 @@ "NotificationChannels\\Textlocal\\Test\\": "tests" } }, + "extra": { + "laravel": { + "providers": [ + "NotificationChannels\\Textlocal\\TextlocalServiceProvider" + ] + } + }, "scripts": { "test": "vendor/bin/phpunit" }, From e3b5ef94cd16e1e373ebe3d9f54432675860c7fd Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Mon, 29 Jul 2019 15:11:44 +0530 Subject: [PATCH 20/63] updated to use api_key from config updated api_key in constructor which was previously only taking hash --- src/TextlocalServiceProvider.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index e4e3a55d..3a7a7d90 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -21,7 +21,8 @@ function () { return new Textlocal( $textlocalConfig['username'], - $textlocalConfig['hash'] + $textlocalConfig['hash'], + $textlocalConfig['api_key'], ); } ); @@ -47,4 +48,4 @@ public function publishConfiguration() $path => config_path('textlocal.php') ], 'textlocal'); } -} \ No newline at end of file +} From 244e5fbef7033762754e0080f2b067b98488dd38 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Mon, 29 Jul 2019 15:13:33 +0530 Subject: [PATCH 21/63] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c279d9d5..daea08b4 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ put the followings and to your config/services 'sms' => [ 'textlocal' => [ 'username' => env('TEXTLOCAL_USERNAME'), + 'password' => env('TEXTLOCAL_PASSWORD'), 'hash' => env('TEXTLOCAL_HASH'), + 'api_key' => env('TEXTLOCAL_API_KEY'), 'sender' => env('TEXTLOCAL_SENDER'), ] ] @@ -50,6 +52,7 @@ put the followings and to your config/services ``` TEXTLOCAL_USERNAME=Your email id or api key TEXTLOCAL_HASH=get it from url '/docs/' under your API KEYS section + TEXTLOCAL_API_KEY get it from url '/docs/' under your API KEYS section TEXTLOCAL_SENDER=Name of the Sender that will be displayed to the recipient (max 6 Characters). TEXTLOCAL_COUNTRY=Your Two letter(ISO-3166-alpha-2) Country Code. It should be the Country of the TEXTLOCAL account. ``` From 34d77ac693f9a69fdc180a8a38a63a99e48d7395 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Mon, 29 Jul 2019 18:14:00 +0530 Subject: [PATCH 22/63] Update TextlocalServiceProvider.php --- src/TextlocalServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index 3a7a7d90..e9b46a6d 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -22,7 +22,7 @@ function () { return new Textlocal( $textlocalConfig['username'], $textlocalConfig['hash'], - $textlocalConfig['api_key'], + $textlocalConfig['api_key'] ); } ); From 0db29099836b19d2fd53337e10bfd0c74aff8d93 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Thu, 12 Sep 2019 12:36:14 +0530 Subject: [PATCH 23/63] Added Laravel 6 support --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index be3cce97..1ece52d4 100644 --- a/composer.json +++ b/composer.json @@ -13,12 +13,12 @@ ], "require": { "php": ">=5.6.4", - "illuminate/notifications": "^5.3|^5.4|^5.5", - "illuminate/support": "^5.1|^5.2|^5.3|^5.4|^5.5" + "illuminate/notifications": "^5.3|^5.4|^5.5|^5.6|^5.7|^5.8|^6.0", + "illuminate/support": "^5.1|^5.2|^5.3|^5.4|^5.5|^5.6|^5.7|^5.8|^6.0" }, "require-dev": { - "mockery/mockery": "^0.9.5", - "phpunit/phpunit": "4.*" + "mockery/mockery": "^0.9.5|^1.0", + "phpunit/phpunit": "4.*|^8.0" }, "autoload": { "psr-4": { From b4d67d8a4495bf6cf55d839f7857563ce78fe308 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Thu, 12 Sep 2019 12:37:07 +0530 Subject: [PATCH 24/63] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index daea08b4..2d96136e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ This package allows to send SMS using Textlocal API using laravel notifications -Here's the latest documentation on Laravel 5.4 Notifications System: - -https://laravel.com/docs/5.4/notifications +Supports Laravel 5.x to 6.x # Found any bugs or improvement open an issue or send me a PR From 56bf3c932e625e6d7bb98532448a8ee34556d089 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 13 Sep 2019 11:05:38 +0530 Subject: [PATCH 25/63] Update composer.json Co-Authored-By: atymic <50683531+atymic@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1ece52d4..20a85d63 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "require": { "php": ">=5.6.4", "illuminate/notifications": "^5.3|^5.4|^5.5|^5.6|^5.7|^5.8|^6.0", - "illuminate/support": "^5.1|^5.2|^5.3|^5.4|^5.5|^5.6|^5.7|^5.8|^6.0" + "illuminate/support": "~5.5||~6.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", From 9ad75cfb531923dfc657d33ccf532ee8b5de170f Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 13 Sep 2019 11:05:46 +0530 Subject: [PATCH 26/63] Update composer.json Co-Authored-By: atymic <50683531+atymic@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 20a85d63..59eda5b3 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", - "phpunit/phpunit": "4.*|^8.0" + "phpunit/phpunit": "~5|^8.0" }, "autoload": { "psr-4": { From 2b94219a1fbe13b2efe8e70baa1789196c2d66dc Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 13 Sep 2019 11:06:01 +0530 Subject: [PATCH 27/63] Update phpunit.xml.dist Co-Authored-By: atymic <50683531+atymic@users.noreply.github.com> --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f9e82497..7042c52b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -22,7 +22,7 @@ - + From 6e7607fc70279b5ef95f8bc5c661a41cf2cc4eea Mon Sep 17 00:00:00 2001 From: Shankar Akunuri Date: Tue, 29 Oct 2019 22:17:03 +0530 Subject: [PATCH 28/63] Adding unicode support to SMS. (#8) * Update Textlocal.php Adding unicode SMS support. * Update TextlocalChannel.php Adding unicode SMS support. --- src/Textlocal.php | 36 +++++++++++++++++++++++++----------- src/TextlocalChannel.php | 9 ++++++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/Textlocal.php b/src/Textlocal.php index 2d874cf7..0713e619 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -35,6 +35,7 @@ class Textlocal public $warnings = []; public $lastRequest = []; + public $treatAsUnicode = 0; /** * Instantiate the object. @@ -171,7 +172,7 @@ public function getLastRequest() * @param null $sched * @param false $test * @param null $receiptURL - * @param numm $custom + * @param null $custom * @param false $optouts * @param false $simpleReplyService * @@ -195,15 +196,16 @@ public function sendSms($numbers, $message, $sender, $sched = null, $test = fals } $params = [ - 'message' => rawurlencode($message), - 'numbers' => implode(',', $numbers), - 'sender' => rawurlencode($sender), - 'schedule_time' => $sched, - 'test' => $test, - 'receipt_url' => $receiptURL, - 'custom' => $custom, - 'optouts' => $optouts, - 'simple_reply' => $simpleReplyService, + 'message' => rawurlencode($message), + 'numbers' => implode(',', $numbers), + 'sender' => rawurlencode($sender), + 'schedule_time' => $sched, + 'test' => $test, + 'receipt_url' => $receiptURL, + 'custom' => $custom, + 'optouts' => $optouts, + 'simple_reply' => $simpleReplyService, + 'unicode' => $this->treatAsUnicode, ]; return $this->_sendRequest('send', $params); @@ -779,6 +781,18 @@ public function getOptouts($time = null) { return $this->_sendRequest('get_optouts'); } + + /** + * Set unicode mode + * + * @param bool $mode + * @return \NotificationChannels\Textlocal\Textlocal + */ + public function setUnicodeMode(bool $mode) + { + $this->treatAsUnicode = (int) $mode; + return $this; + } } class Contact @@ -865,4 +879,4 @@ function json_encode($a = false) return '{'.implode(',', $result).'}'; } } -} \ No newline at end of file +} diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index a3f505e1..50db5862 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -50,8 +50,15 @@ public function send($notifiable, Notification $notification) return; } + // Get unicode parameter from notification class + $unicode = false; + if (method_exists($notification, 'getUnicodeMode')) { + $unicode = $notification->getUnicodeMode(); + } + try { - $response = $this->client->sendSms($numbers, $message, $this->sender); + $response = $this->client->setUnicodeMode($unicode) + ->sendSms($numbers, $message, $this->sender); return json_decode(json_encode($response), true); } catch (\Exception $exception) { From d24268bde7e8183f343cfc287cea01c8535fdc5d Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:15:20 +0530 Subject: [PATCH 29/63] updated minimum php version to 7.0 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 59eda5b3..e2a97e37 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,9 @@ } ], "require": { - "php": ">=5.6.4", - "illuminate/notifications": "^5.3|^5.4|^5.5|^5.6|^5.7|^5.8|^6.0", - "illuminate/support": "~5.5||~6.0" + "php": ">=7.0", + "illuminate/notifications": "~5.5|~6.0", + "illuminate/support": "~5.5|~6.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", From ffebe51db76f754ab6e5ccf319d064e948fe4c86 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:21:45 +0530 Subject: [PATCH 30/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 50db5862..a124c25c 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -58,9 +58,9 @@ public function send($notifiable, Notification $notification) try { $response = $this->client->setUnicodeMode($unicode) - ->sendSms($numbers, $message, $this->sender); + ->sendSms($numbers, $message, $this->sender); - return json_decode(json_encode($response), true); + return $response; } catch (\Exception $exception) { throw CouldNotSendNotification::serviceRespondedWithAnError($exception, $message); } From 5c0f0da15dbb60a4da02261cb12a5e517778d28b Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:22:43 +0530 Subject: [PATCH 31/63] Update travis.yml --- travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/travis.yml b/travis.yml index ff42c2c5..1ca768d9 100644 --- a/travis.yml +++ b/travis.yml @@ -1,9 +1,11 @@ language: php php: - - 5.6 - 7.0 - 7.1 + - 7.2 + - 7.3 + - 7.4 env: matrix: From 620d6a41e99c432fcda06103819b55540035d219 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:24:56 +0530 Subject: [PATCH 32/63] Update textlocal.php --- config/textlocal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/textlocal.php b/config/textlocal.php index 42134547..56495470 100644 --- a/config/textlocal.php +++ b/config/textlocal.php @@ -6,4 +6,4 @@ 'UK' => 'https://api.txtlocal.com/' ], 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), -]; \ No newline at end of file +]; From 8c62761901b9d192b4017261c250915def7ff920 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:26:38 +0530 Subject: [PATCH 33/63] Update TextlocalServiceProvider.php --- src/TextlocalServiceProvider.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index e9b46a6d..0410131c 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -17,12 +17,12 @@ public function boot() ->needs(Textlocal::class) ->give( function () { - $textlocalConfig = config('services.sms.textlocal'); + $config = config('textlocal'); return new Textlocal( - $textlocalConfig['username'], - $textlocalConfig['hash'], - $textlocalConfig['api_key'] + $config['username'], + $config['hash'], + $config['api_key'] ); } ); From 00fb886cc5036402c558d0e171dc11c45861357e Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:29:47 +0530 Subject: [PATCH 34/63] Update Textlocal.php --- src/Textlocal.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Textlocal.php b/src/Textlocal.php index 0713e619..989b0b69 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -42,12 +42,13 @@ class Textlocal * * @param $username * @param $hash + * @param string|null $apiKey */ - public function __construct($username, $hash, $apiKey = false) + public function __construct($username, $hash, $apiKey = null) { $this->username = $username; $this->hash = $hash; - if ($apiKey) { + if (! is_null($apiKey)) { $this->apiKey = $apiKey; } @@ -170,7 +171,7 @@ public function getLastRequest() * @param $message * @param $sender * @param null $sched - * @param false $test + * @param bool $test * @param null $receiptURL * @param null $custom * @param false $optouts @@ -180,7 +181,7 @@ public function getLastRequest() * * @return array|mixed */ - public function sendSms($numbers, $message, $sender, $sched = null, $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) + public function sendSms($numbers, $message, $sender, $sched = null, bool $test = false, $receiptURL = null, $custom = null, $optouts = false, $simpleReplyService = false) { if (! is_array($numbers)) { throw new Exception('Invalid $numbers format. Must be an array'); From 4495ca3edf32b7d5d9d4e33749e0313dd947bd41 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:32:55 +0530 Subject: [PATCH 35/63] Update Textlocal.php --- src/Textlocal.php | 54 ----------------------------------------------- 1 file changed, 54 deletions(-) diff --git a/src/Textlocal.php b/src/Textlocal.php index 989b0b69..e8fc1f66 100644 --- a/src/Textlocal.php +++ b/src/Textlocal.php @@ -827,57 +827,3 @@ public function __construct($number, $firstname = '', $lastname = '', $custom1 = $this->custom3 = $custom3; } } - -/* - * If the json_encode function does not exist, then create it.. - */ - -if (! function_exists('json_encode')) { - function json_encode($a = false) - { - if (is_null($a)) { - return 'null'; - } - if ($a === false) { - return 'false'; - } - if ($a === true) { - return 'true'; - } - if (is_scalar($a)) { - if (is_float($a)) { - // Always use "." for floats. - return floatval(str_replace(',', '.', strval($a))); - } - - if (is_string($a)) { - static $jsonReplaces = [['\\', '/', "\n", "\t", "\r", "\b", "\f", '"'], ['\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"']]; - - return '"'.str_replace($jsonReplaces[0], $jsonReplaces[1], $a).'"'; - } else { - return $a; - } - } - $isList = true; - for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { - if (key($a) !== $i) { - $isList = false; - break; - } - } - $result = []; - if ($isList) { - foreach ($a as $v) { - $result[] = json_encode($v); - } - - return '['.implode(',', $result).']'; - } else { - foreach ($a as $k => $v) { - $result[] = json_encode($k).':'.json_encode($v); - } - - return '{'.implode(',', $result).'}'; - } - } -} From 4c981b0c42982ba6375c124682a6e5159d04c66a Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:34:28 +0530 Subject: [PATCH 36/63] Update composer.json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index e2a97e37..157818de 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ ], "require": { "php": ">=7.0", + "ext-json": "*", "illuminate/notifications": "~5.5|~6.0", "illuminate/support": "~5.5|~6.0" }, From 203efc289424c04bba0c572169f685dd4fbbee43 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:35:40 +0530 Subject: [PATCH 37/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index a124c25c..a72face2 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -12,9 +12,8 @@ class TextlocalChannel public function __construct(Textlocal $client) { - // Initialisation code here $this->client = $client; - $this->sender = config('services.sms.textlocal.sender'); + $this->sender = config('textlocal.sender'); } /** From 8bb470156559213dff0251aa6d3d24f3698f26ee Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:39:18 +0530 Subject: [PATCH 38/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index a72face2..8d6ddf46 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -5,11 +5,21 @@ use Illuminate\Notifications\Notification; use NotificationChannels\Textlocal\Exceptions\CouldNotSendNotification; +/** + * Textlocal channel class which is used to interact with core + * textlocal sdk and faciliate to send sms via + * laravel notification system + */ class TextlocalChannel { private $client; private $sender; + /** + * creates a textlocal channel object by using the configs + * + * @param Textlocal $client + */ public function __construct(Textlocal $client) { $this->client = $client; @@ -56,7 +66,8 @@ public function send($notifiable, Notification $notification) } try { - $response = $this->client->setUnicodeMode($unicode) + $response = $this->client + ->setUnicodeMode($unicode) ->sendSms($numbers, $message, $this->sender); return $response; From 56795f2efe7f384d1f20bd6f42c678a5ca093124 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:40:02 +0530 Subject: [PATCH 39/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 8d6ddf46..aca54ef9 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -40,7 +40,6 @@ public function send($notifiable, Notification $notification) if (! $numbers = $notifiable->routeNotificationFor('sms')) { return; } - //$numbers = (array) $notifiable->routeNotificationForSms(); if (empty($numbers)) { return; From 8deb52c6ae8b3dd08a870dd8d450321cb73148d1 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:42:40 +0530 Subject: [PATCH 40/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index aca54ef9..4482c432 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -48,8 +48,6 @@ public function send($notifiable, Notification $notification) if (!is_array($numbers)) { $numbers = [$numbers]; } - - //TODO check if numbers are correct // Get the message from the notification class $message = (string) $notification->toSms($notifiable); From 03788690d943b05a4fff18e1127d160018a64613 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:51:56 +0530 Subject: [PATCH 41/63] updated method routeNotificationFor('sms') to routeNotificationFor('Textlocal') updated method routeNotificationFor('sms') to routeNotificationFor('Textlocal') instead of generic --- src/TextlocalChannel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 4482c432..a6226570 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -37,7 +37,7 @@ public function __construct(Textlocal $client) public function send($notifiable, Notification $notification) { // Get the mobile number/s from the model - if (! $numbers = $notifiable->routeNotificationFor('sms')) { + if (! $numbers = $notifiable->routeNotificationFor('Textlocal')) { return; } From 610ba8292a7b4de9c968a2bf7b5196faa4b94b91 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:54:40 +0530 Subject: [PATCH 42/63] Update textlocal.php --- config/textlocal.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/textlocal.php b/config/textlocal.php index 56495470..95f99867 100644 --- a/config/textlocal.php +++ b/config/textlocal.php @@ -1,6 +1,11 @@ env('TEXTLOCAL_USERNAME'), + 'password' => env('TEXTLOCAL_PASSWORD'), + 'hash' => env('TEXTLOCAL_HASH'), + 'api_key' => env('TEXTLOCAL_API_KEY'), + 'sender' => env('TEXTLOCAL_SENDER'), 'request_urls' => [ 'IN' => 'https://api.textlocal.in/', 'UK' => 'https://api.txtlocal.com/' From 8a6196e17433ad0acab1370eb424efd5a08538d4 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:56:01 +0530 Subject: [PATCH 43/63] Update README.md --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2d96136e..9933c82f 100644 --- a/README.md +++ b/README.md @@ -34,17 +34,20 @@ Create an account in textlocal then create an API key or hash(password). ### Setting up the textlocal service -put the followings and to your config/services +default textlocal config update as desired ``` -'sms' => [ - 'textlocal' => [ - 'username' => env('TEXTLOCAL_USERNAME'), - 'password' => env('TEXTLOCAL_PASSWORD'), - 'hash' => env('TEXTLOCAL_HASH'), - 'api_key' => env('TEXTLOCAL_API_KEY'), - 'sender' => env('TEXTLOCAL_SENDER'), - ] -] +return [ + 'username' => env('TEXTLOCAL_USERNAME'), + 'password' => env('TEXTLOCAL_PASSWORD'), + 'hash' => env('TEXTLOCAL_HASH'), + 'api_key' => env('TEXTLOCAL_API_KEY'), + 'sender' => env('TEXTLOCAL_SENDER'), + 'request_urls' => [ + 'IN' => 'https://api.textlocal.in/', + 'UK' => 'https://api.txtlocal.com/' + ], + 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), +]; ``` ### Configuring .env ``` @@ -64,7 +67,7 @@ Currently, only textlocal of two country is supported IN(India) and UK(United Ki ## Usage -Implement this method `routeNotificationForSms()` in your notifiable class/model which will return array of mobile numbers. Please make sure the mobile number contains the dial code as well (e.g +91 for India). And lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. +Implement this method `routeNotificationForTextlocal()` in your notifiable class/model which will return array of mobile numbers. Please make sure the mobile number contains the dial code as well (e.g +91 for India). And lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. ### Available Message methods From 4881869c56f23b05bdc64e0bb0e6b54e7841321f Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Wed, 30 Oct 2019 11:57:05 +0530 Subject: [PATCH 44/63] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9933c82f..57f8694a 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ return [ 'hash' => env('TEXTLOCAL_HASH'), 'api_key' => env('TEXTLOCAL_API_KEY'), 'sender' => env('TEXTLOCAL_SENDER'), - 'request_urls' => [ - 'IN' => 'https://api.textlocal.in/', - 'UK' => 'https://api.txtlocal.com/' - ], - 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), + 'request_urls' => [ + 'IN' => 'https://api.textlocal.in/', + 'UK' => 'https://api.txtlocal.com/' + ], + 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), ]; ``` ### Configuring .env From ee8e7e5cc0e7d728d9254b6f71e6b1c2b716a091 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Tue, 5 Nov 2019 12:45:08 +0530 Subject: [PATCH 45/63] Update composer.json Co-Authored-By: atymic --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 157818de..4b1c4899 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "msonowal/laravel-notification-channel-textlocal", - "description": "This Driver for textlocal sms to send SMS via Textlocal API through laravel notification", + "description": "Textlocal Notifications Channel for Laravel", "homepage": "https://github.com/laravel-notification-channels/textlocal", "license": "MIT", "authors": [ From 610c6e823902f8b742693e951112c4ad0ab06649 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Tue, 5 Nov 2019 12:45:31 +0530 Subject: [PATCH 46/63] Update README.md Co-Authored-By: atymic --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57f8694a..3873e7d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ This package allows to send SMS using Textlocal API using laravel notifications -Supports Laravel 5.x to 6.x +Supports Laravel 5.5 to 6.x # Found any bugs or improvement open an issue or send me a PR From 37ad61364940cf45f1264b907fc28c0c66d24bd1 Mon Sep 17 00:00:00 2001 From: tsainadh <56969292+tsainadh@users.noreply.github.com> Date: Mon, 9 Dec 2019 22:00:56 +0530 Subject: [PATCH 47/63] Update TextlocalChannel.php (#12) set sender id from notification if having multiple sender id's to manage. --- src/TextlocalChannel.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index a6226570..0637adec 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -62,6 +62,10 @@ public function send($notifiable, Notification $notification) $unicode = $notification->getUnicodeMode(); } + if (method_exists($notification, 'getSenderId')) { + $this->sender = $notification->getSenderId(); + } + try { $response = $this->client ->setUnicodeMode($unicode) From e41ddde6bc1745b3c8ca634da32f8ad0394aefda Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 30 Dec 2021 17:03:40 +0530 Subject: [PATCH 48/63] Upgrade to GitHub-native Dependabot (#13) Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5446bcee --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: +- package-ecosystem: composer + directory: "/" + schedule: + interval: daily + time: "23:30" + open-pull-requests-limit: 10 From 4431763e529dc991ae5254243b45a93f51cde14a Mon Sep 17 00:00:00 2001 From: rupamjbordoloi Date: Thu, 30 Dec 2021 17:05:57 +0530 Subject: [PATCH 49/63] Laravel 7.x & 8.x support (#14) * laravel 8 support * readme updated Co-authored-by: rupam4 --- README.md | 2 +- composer.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3873e7d9..a5ae9475 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ This package allows to send SMS using Textlocal API using laravel notifications -Supports Laravel 5.5 to 6.x +Supports Laravel 5.5 to 8.x # Found any bugs or improvement open an issue or send me a PR diff --git a/composer.json b/composer.json index 4b1c4899..54a5a2ba 100644 --- a/composer.json +++ b/composer.json @@ -14,12 +14,12 @@ "require": { "php": ">=7.0", "ext-json": "*", - "illuminate/notifications": "~5.5|~6.0", - "illuminate/support": "~5.5|~6.0" + "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0", + "illuminate/support": "~5.5|~6.0|~7.0|~8.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", - "phpunit/phpunit": "~5|^8.0" + "phpunit/phpunit": "~5|^8.0|^9.0" }, "autoload": { "psr-4": { From 1d3cde634adf5b74306405a5fe2c9d95abb38279 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 16 Jul 2022 13:52:00 +0530 Subject: [PATCH 50/63] updated support for Laravel 9 LTS --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 54a5a2ba..9913709b 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ "require": { "php": ">=7.0", "ext-json": "*", - "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0", - "illuminate/support": "~5.5|~6.0|~7.0|~8.0" + "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0|~9.0", + "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", From 5ae212f9db5ccd7dfc7948a1320e33f1ce1f4109 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 12:25:46 +0530 Subject: [PATCH 51/63] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a5ae9475..c2745707 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ This package allows to send SMS using Textlocal API using laravel notifications -Supports Laravel 5.5 to 8.x +Supports Laravel 5.5 to 9.x # Found any bugs or improvement open an issue or send me a PR @@ -34,7 +34,7 @@ Create an account in textlocal then create an API key or hash(password). ### Setting up the textlocal service -default textlocal config update as desired +default config `textlocal.php` update where desired ``` return [ 'username' => env('TEXTLOCAL_USERNAME'), @@ -55,7 +55,7 @@ return [ TEXTLOCAL_HASH=get it from url '/docs/' under your API KEYS section TEXTLOCAL_API_KEY get it from url '/docs/' under your API KEYS section TEXTLOCAL_SENDER=Name of the Sender that will be displayed to the recipient (max 6 Characters). - TEXTLOCAL_COUNTRY=Your Two letter(ISO-3166-alpha-2) Country Code. It should be the Country of the TEXTLOCAL account. + TEXTLOCAL_COUNTRY=Your Two letter(ISO-3166-alpha-2) Country Code. It should be the Country of the TEXTLOCAL account. defaults to IN ``` ### Publish Config From f57475a399fb7f46c1e0dd1d980ca5b4fb22dbae Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 12:37:09 +0530 Subject: [PATCH 52/63] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index c2745707..3e63519d 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,39 @@ Currently, only textlocal of two country is supported IN(India) and UK(United Ki Implement this method `routeNotificationForTextlocal()` in your notifiable class/model which will return array of mobile numbers. Please make sure the mobile number contains the dial code as well (e.g +91 for India). And lastly implement `toSms()` method in the notification class which will return the (string) sms or template that is defined in textlocal account that needs to be send. + +## Usage + +You can use the channel in your `via()` method inside the notification: + +```php +use Illuminate\Notifications\Notification; +use NotificationChannels\Textlocal\TextlocalChannel; + +class TestOTPNotification extends Notification +{ + public function via($notifiable) + { + return [TextlocalChannel::class]; + } + + public function toSms($notifiable) + { + return SmscRuMessage::create("Task #{$notifiable->id} is complete!"); + } +} +``` + +In your notifiable model, make sure to include a `routeNotificationForTextlocal()` method, which returns a phone number or multiple numbers in array +or an array of phone numbers. + +```php +public function routeNotificationForTextlocal(): array +{ + return [$this->mobile_no]; +} +``` + ### Available Message methods A list of all available options @@ -95,6 +128,7 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details. - [Manash Jyoti Sonowal](https://github.com/msonowal) - [Mr Ejang](https://github.com/tomonsoejang) +- [Sinadh](https://github.com/tsainadh) - [All Contributors](../../contributors) ## License From d75d588d56a69603f4c21ea095cee5026e69f99b Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 12:38:16 +0530 Subject: [PATCH 53/63] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e63519d..ffabe017 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ class TestOTPNotification extends Notification public function toSms($notifiable) { - return SmscRuMessage::create("Task #{$notifiable->id} is complete!"); + return 'Use 1234 as OTP for resetting your password.'; } } ``` From 0ecbbe61a30cfef6c7b475fc1f6a44058aadac59 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 12:51:14 +0530 Subject: [PATCH 54/63] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index ffabe017..f86b81ac 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,20 @@ public function routeNotificationForTextlocal(): array ### Available Message methods +And if you want to have a specific sender based on Notification, e.g. like you are sending promotional notification using one and another for transaction then you can just define this method in your notification class which will return your sender id for that notification only +``` +public function getSenderId() +{ + return 'YOUR_SENDER_ID'; +} +``` + +Unicode support +If you want to send the notification content to have unicode support set define this method in your notification which will return boolean based on which the sms will set the unicode mode in textlocal API +``` +getUnicodeMode +``` + A list of all available options ## Changelog From f645e053c5dab6c0fd2f32eb83dae66edf1add7d Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 13:09:33 +0530 Subject: [PATCH 55/63] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f86b81ac..c6f701eb 100644 --- a/README.md +++ b/README.md @@ -108,14 +108,17 @@ And if you want to have a specific sender based on Notification, e.g. like you a ``` public function getSenderId() { - return 'YOUR_SENDER_ID'; + return 'YOUR_SENDER_ID'; } ``` Unicode support -If you want to send the notification content to have unicode support set define this method in your notification which will return boolean based on which the sms will set the unicode mode in textlocal API +If you want to send the notification content to have unicode support. Define this method in your notification which will return boolean based on which the sms will set the unicode mode in textlocal API ``` -getUnicodeMode +public function getUnicodeMode() +{ + return true; +} ``` A list of all available options From 82739656e471ceef604503035eb5d19ad522f3e7 Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 13:10:20 +0530 Subject: [PATCH 56/63] Update README.md Update README.md --- README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c6f701eb..6afa1c4e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -This package allows to send SMS using Textlocal API using laravel notifications +This package allows to send SMS using Textlocal API using laravel notifications channel textlocal sms Supports Laravel 5.5 to 9.x -# Found any bugs or improvement open an issue or send me a PR - [![Latest Stable Version](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/v/stable)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) [![License](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/license)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) [![Total Downloads](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/downloads)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) @@ -35,12 +33,15 @@ Create an account in textlocal then create an API key or hash(password). ### Setting up the textlocal service default config `textlocal.php` update where desired + +Important Either specify a Key OR a Hash - don't enter both! + ``` return [ 'username' => env('TEXTLOCAL_USERNAME'), 'password' => env('TEXTLOCAL_PASSWORD'), - 'hash' => env('TEXTLOCAL_HASH'), - 'api_key' => env('TEXTLOCAL_API_KEY'), + 'hash' => env('TEXTLOCAL_HASH'), //optional if api_key is set + 'api_key' => env('TEXTLOCAL_API_KEY'), //optional if hash is set 'sender' => env('TEXTLOCAL_SENDER'), 'request_urls' => [ 'IN' => 'https://api.textlocal.in/', @@ -102,6 +103,12 @@ public function routeNotificationForTextlocal(): array } ``` +Annoynmous Notifable when say mobile no is not added to a notifiable model you can directly send to mobile no by using that + +```php +Notification::route('Textlocal', $mobileNo')->notify(new VerifyMobileNotification($otp)); +``` + ### Available Message methods And if you want to have a specific sender based on Notification, e.g. like you are sending promotional notification using one and another for transaction then you can just define this method in your notification class which will return your sender id for that notification only @@ -137,6 +144,8 @@ $ composer test If you discover any security related issues, please email manash149@gmail.com instead of using the issue tracker. +# Found any bugs or improvement open an issue or send me a PR + ## Contributing Please see [CONTRIBUTING](CONTRIBUTING.md) for details. From be0bc25d06122ce90d8a7c36be29d946dce143fc Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Fri, 29 Jul 2022 13:10:20 +0530 Subject: [PATCH 57/63] feat: custom client configuration usage via per notification or notifiable Update Textlocal.php, TextlocalChannel.php, TextlocalServiceProvider.php Create INotificationUsesTextlocalClientConfig.php Create IUsesTextlocalClientConfig.php Update README.md --- README.md | 10 ++++++- ...INotificationUsesTextlocalClientConfig.php | 12 +++++++++ src/Contracts/IUsesTextlocalClientConfig.php | 12 +++++++++ src/Textlocal.php | 23 +++++----------- src/TextlocalChannel.php | 27 ++++++++++++++++++- src/TextlocalServiceProvider.php | 3 ++- 6 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 src/Contracts/INotificationUsesTextlocalClientConfig.php create mode 100644 src/Contracts/IUsesTextlocalClientConfig.php diff --git a/README.md b/README.md index 6afa1c4e..987d09cf 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,9 @@ Supports Laravel 5.5 to 9.x This package makes it easy to send notifications using [textlocal](https://www.textlocal.in/) with Laravel 5.3.+ +To use version ^2.3.0 onwards will require PHP 8.0 + +for other PHP version use upto ^2.2.0 ## Contents @@ -48,9 +51,14 @@ return [ 'UK' => 'https://api.txtlocal.com/' ], 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), + 'extra' => [ + // extra config define keys as desired for use within the textlocal client config + // if you want to use the custom client config for each notification or notifiable + // INotificationUsesTextlocalClientConfig + ] ]; ``` -### Configuring .env +### Configuring .env ``` TEXTLOCAL_USERNAME=Your email id or api key TEXTLOCAL_HASH=get it from url '/docs/' under your API KEYS section diff --git a/src/Contracts/INotificationUsesTextlocalClientConfig.php b/src/Contracts/INotificationUsesTextlocalClientConfig.php new file mode 100644 index 00000000..0fa0acd4 --- /dev/null +++ b/src/Contracts/INotificationUsesTextlocalClientConfig.php @@ -0,0 +1,12 @@ +username = $username; - $this->hash = $hash; - if (! is_null($apiKey)) { - $this->apiKey = $apiKey; - } - - $this->country = config('textlocal.country'); - $this->request_url = config('textlocal.request_urls')[$this->country]; + $this->request_url = config('textlocal.request_urls')[$country]; } /** diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 0637adec..faafa590 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -3,6 +3,8 @@ namespace NotificationChannels\Textlocal; use Illuminate\Notifications\Notification; +use NotificationChannels\Textlocal\Contracts\INotificationUsesTextlocalClientConfig; +use NotificationChannels\Textlocal\Contracts\IUsesTextlocalClientConfig; use NotificationChannels\Textlocal\Exceptions\CouldNotSendNotification; /** @@ -66,8 +68,10 @@ public function send($notifiable, Notification $notification) $this->sender = $notification->getSenderId(); } + $client = $this->getClient($notifiable, $notification); + try { - $response = $this->client + $response = $client ->setUnicodeMode($unicode) ->sendSms($numbers, $message, $this->sender); @@ -76,4 +80,25 @@ public function send($notifiable, Notification $notification) throw CouldNotSendNotification::serviceRespondedWithAnError($exception, $message); } } + + public function getClient($notifiable, Notification $notification) + { + $client = $this->client; + + if ($notifiable instanceof IUsesTextlocalClientConfig) { + + [$username, $hash, $apiKey, $country] = $notification->getTextlocalClientConfig($notification); + + $client = new Textlocal($username, $hash, $apiKey, $country); + } + + if ($notification instanceof INotificationUsesTextlocalClientConfig) { + + [$username, $hash, $apiKey, $country] = $notification->getTextlocalClientConfig($notifiable); + + $client = new Textlocal($username, $hash, $apiKey, $country); + } + + return $client; + } } diff --git a/src/TextlocalServiceProvider.php b/src/TextlocalServiceProvider.php index 0410131c..ef02a7cc 100644 --- a/src/TextlocalServiceProvider.php +++ b/src/TextlocalServiceProvider.php @@ -22,7 +22,8 @@ function () { return new Textlocal( $config['username'], $config['hash'], - $config['api_key'] + $config['api_key'], + $config['country'] ); } ); From 38bda2cbb8a6634324f009b4bc80084995191b61 Mon Sep 17 00:00:00 2001 From: msonowal Date: Wed, 17 Aug 2022 21:33:49 +0530 Subject: [PATCH 58/63] Update TextlocalChannel.php Update README.md Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ README.md | 7 +++---- src/TextlocalChannel.php | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce1e1d29..ded9163a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to `Textlocal` will be documented in this file + +## 2.4.0 - 2022-08-17 + +`public function getSenderId($notifiable)` + +method has changed from `public function getSenderId()`, so now the notifiable is passed as parameter +giving more control to the imeplementation to decide based on user/recipent in case want to use some alternate deciding factor + ## 0.0.1 - 2017-08-07 - initial release diff --git a/README.md b/README.md index 987d09cf..a9fc5150 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,7 @@ return [ // extra config define keys as desired for use within the textlocal client config // if you want to use the custom client config for each notification or notifiable // INotificationUsesTextlocalClientConfig - ] -]; -``` + ]public function getSenderId($notifiable) ### Configuring .env ``` TEXTLOCAL_USERNAME=Your email id or api key @@ -121,12 +119,13 @@ Notification::route('Textlocal', $mobileNo')->notify(new VerifyMobileNotificatio And if you want to have a specific sender based on Notification, e.g. like you are sending promotional notification using one and another for transaction then you can just define this method in your notification class which will return your sender id for that notification only ``` -public function getSenderId() +public function getSenderId($notifiable) { return 'YOUR_SENDER_ID'; } ``` + Unicode support If you want to send the notification content to have unicode support. Define this method in your notification which will return boolean based on which the sms will set the unicode mode in textlocal API ``` diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index faafa590..9d4793f1 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -65,7 +65,7 @@ public function send($notifiable, Notification $notification) } if (method_exists($notification, 'getSenderId')) { - $this->sender = $notification->getSenderId(); + $this->sender = $notification->getSenderId($notifiable); } $client = $this->getClient($notifiable, $notification); From 1ae7cf2e051090c6df419f5d94a9d37da1ad1ea2 Mon Sep 17 00:00:00 2001 From: msonowal Date: Thu, 18 Aug 2022 00:27:46 +0530 Subject: [PATCH 59/63] Update INotificationUsesTextlocalClientConfig.php Update IUsesTextlocalClientConfig.php --- src/Contracts/INotificationUsesTextlocalClientConfig.php | 8 ++++++++ src/Contracts/IUsesTextlocalClientConfig.php | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Contracts/INotificationUsesTextlocalClientConfig.php b/src/Contracts/INotificationUsesTextlocalClientConfig.php index 0fa0acd4..cebbb99d 100644 --- a/src/Contracts/INotificationUsesTextlocalClientConfig.php +++ b/src/Contracts/INotificationUsesTextlocalClientConfig.php @@ -4,6 +4,14 @@ interface INotificationUsesTextlocalClientConfig { + /** + * This method would be responsible if the user wants to use custom config + * for the current notification otherwise will work as is meaning using the + * default config + * @param $notification + * @return bool + */ + public function shouldUseCustomTextlocalConfig($notification): bool; /** * @param $notifiable * @return array [$username, $hash, $apiKey, $country] diff --git a/src/Contracts/IUsesTextlocalClientConfig.php b/src/Contracts/IUsesTextlocalClientConfig.php index d5d67815..540a49be 100644 --- a/src/Contracts/IUsesTextlocalClientConfig.php +++ b/src/Contracts/IUsesTextlocalClientConfig.php @@ -4,6 +4,14 @@ interface IUsesTextlocalClientConfig { + /** + * This method would be responsible if the user wants to use custom config + * for the current notification otherwise will work as is meaning using the + * default config + * @param $notification + * @return bool + */ + public function shouldUseCustomTextlocalConfig($notification): bool; /** * @param $notification * @return array [$username, $hash, $apiKey, $country] From 2409b6f9e82f17d736a4d83d67eaf446fc523a6a Mon Sep 17 00:00:00 2001 From: msonowal Date: Thu, 18 Aug 2022 00:27:51 +0530 Subject: [PATCH 60/63] Update TextlocalChannel.php --- src/TextlocalChannel.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/TextlocalChannel.php b/src/TextlocalChannel.php index 9d4793f1..7d155a7f 100644 --- a/src/TextlocalChannel.php +++ b/src/TextlocalChannel.php @@ -14,7 +14,6 @@ */ class TextlocalChannel { - private $client; private $sender; /** @@ -22,9 +21,8 @@ class TextlocalChannel * * @param Textlocal $client */ - public function __construct(Textlocal $client) + public function __construct(private Textlocal $client) { - $this->client = $client; $this->sender = config('textlocal.sender'); } @@ -87,13 +85,21 @@ public function getClient($notifiable, Notification $notification) if ($notifiable instanceof IUsesTextlocalClientConfig) { - [$username, $hash, $apiKey, $country] = $notification->getTextlocalClientConfig($notification); + if (! $notifiable->shouldUseCustomTextlocalConfig($notification)) { + return $client; + } + + [$username, $hash, $apiKey, $country] = $notifiable->getTextlocalClientConfig($notification); $client = new Textlocal($username, $hash, $apiKey, $country); } if ($notification instanceof INotificationUsesTextlocalClientConfig) { + if (! $notification->shouldUseCustomTextlocalConfig($notification)) { + return $client; + } + [$username, $hash, $apiKey, $country] = $notification->getTextlocalClientConfig($notifiable); $client = new Textlocal($username, $hash, $apiKey, $country); From d509d1704aa0030cd17fd5066873fb7ee443655e Mon Sep 17 00:00:00 2001 From: msonowal Date: Thu, 18 Aug 2022 01:14:40 +0530 Subject: [PATCH 61/63] Update textlocal.php config with sample/example stub for custom usage --- config/textlocal.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/config/textlocal.php b/config/textlocal.php index 95f99867..6dfa12a3 100644 --- a/config/textlocal.php +++ b/config/textlocal.php @@ -1,14 +1,26 @@ - env('TEXTLOCAL_USERNAME'), - 'password' => env('TEXTLOCAL_PASSWORD'), - 'hash' => env('TEXTLOCAL_HASH'), - 'api_key' => env('TEXTLOCAL_API_KEY'), - 'sender' => env('TEXTLOCAL_SENDER'), + 'username' => env('TEXTLOCAL_USERNAME'), + 'password' => env('TEXTLOCAL_PASSWORD'), + 'hash' => env('TEXTLOCAL_HASH'), + 'api_key' => env('TEXTLOCAL_API_KEY'), + 'sender' => env('TEXTLOCAL_SENDER', 'DOCONL'), 'request_urls' => [ 'IN' => 'https://api.textlocal.in/', - 'UK' => 'https://api.txtlocal.com/' + 'UK' => 'https://api.txtlocal.com/', ], - 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), + 'country' => env('TEXTLOCAL_COUNTRY', 'IN'), + /* + // a sample way to organize custom config when using mutliple on demand config + // uncomment this for that purpose or feel free to use your own implementations + 'UK' => [ + 'username' => env('TEXTLOCAL_USERNAME_UK'), + 'password' => env('TEXTLOCAL_PASSWORD_UK'), + 'hash' => env('TEXTLOCAL_HASH_UK'), + 'api_key' => env('TEXTLOCAL_API_KEY_UK'), + 'sender' => env('TEXTLOCAL_SENDER_UK', 'DOCONL'), + 'country' => env('TEXTLOCAL_COUNTRY_UK', 'UK'), + ], + */ ]; From 8a2349f3b2078d84f1fb9a374009617058d7a1ed Mon Sep 17 00:00:00 2001 From: Manash Sonowal Date: Sat, 18 Feb 2023 14:42:03 +0530 Subject: [PATCH 62/63] feat: added support for laravel 10 Update composer.json Update README.md --- README.md | 2 +- composer.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a9fc5150..31a41247 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ This package allows to send SMS using Textlocal API using laravel notifications channel textlocal sms -Supports Laravel 5.5 to 9.x +Supports Laravel 5.5 upto 10.x [![Latest Stable Version](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/v/stable)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) [![License](https://poser.pugx.org/msonowal/laravel-notification-channel-textlocal/license)](https://packagist.org/packages/msonowal/laravel-notification-channel-textlocal) diff --git a/composer.json b/composer.json index 9913709b..cc7c6336 100644 --- a/composer.json +++ b/composer.json @@ -14,12 +14,12 @@ "require": { "php": ">=7.0", "ext-json": "*", - "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0|~9.0", - "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0" + "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0", + "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", - "phpunit/phpunit": "~5|^8.0|^9.0" + "phpunit/phpunit": "~5|^8.0|^9.0|^10.0" }, "autoload": { "psr-4": { From 30cac8b9aa7f8c983c8db8a922241422c5378df0 Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Sat, 11 May 2024 09:42:49 +0100 Subject: [PATCH 63/63] Add Laravel 11 Support --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index cc7c6336..3921a676 100644 --- a/composer.json +++ b/composer.json @@ -14,12 +14,12 @@ "require": { "php": ">=7.0", "ext-json": "*", - "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0", - "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0" + "illuminate/notifications": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0|~11.0", + "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0|~10.0|~11.0" }, "require-dev": { "mockery/mockery": "^0.9.5|^1.0", - "phpunit/phpunit": "~5|^8.0|^9.0|^10.0" + "phpunit/phpunit": "~5|^8.0|^9.0|^10.0|~11.0" }, "autoload": { "psr-4": {