├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── phpcs.xml
├── phpunit.xml
├── src
├── Facade.php
├── LaravelSMSProvider.php
├── MailAdapter.php
└── config.php
└── tests
├── ServiceProviderTest.php
└── TestCase.php
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | .DS_Store
3 | vendor/
4 | composer.lock
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 7.0
5 | - 7.1
6 |
7 | before_script:
8 | - travis_retry composer self-update
9 | - travis_retry composer install --no-interaction --prefer-source --dev
10 |
11 | script: vendor/bin/phpunit
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Matthew Daly
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # laravel-sms
2 | [](https://travis-ci.org/matthewbdaly/laravel-sms)
3 |
4 | SMS service provider for Laravel and Lumen. Uses [SMS Client](https://github.com/matthewbdaly/sms-client) to enable sending SMS messages using the following drivers:
5 |
6 | * `nexmo`
7 | * `clockwork`
8 | * `textlocal`
9 | * `twilio`
10 | * `aws` (requires installation of `aws/aws-sdk-php`)
11 | * `mail` (somewhat untested and may be too generic to be much use)
12 |
13 | Also has the following drivers for testing purposes:
14 |
15 | * `log`
16 | * `null`
17 | * `requestbin`
18 |
19 | Installation for Laravel
20 | ------------------------
21 |
22 | This package is only intended for Laravel 5.5 and up. Install it with the following command:
23 |
24 | ```bash
25 | $ composer require matthewbdaly/laravel-sms
26 | ```
27 |
28 | Then publish the config file:
29 |
30 | ```bash
31 | $ php artisan vendor:publish
32 | ```
33 |
34 | You will need to select the service provider `Matthewbdaly\LaravelSMS\LaravelSMSProvider`. Then set your driver and any settings required in the `.env` file for your project:
35 |
36 | ```
37 | SMS_DRIVER=nexmo
38 | NEXMO_API_KEY=foo
39 | NEXMO_API_SECRET=bar
40 | CLOCKWORK_API_KEY=baz
41 | TEXTLOCAL_API_KEY=baz
42 | REQUESTBIN_PATH=foo
43 | AWS_SNS_API_KEY=foo
44 | AWS_SNS_API_SECRET=bar
45 | AWS_SNS_API_REGION=baz
46 | MAIL_SMS_DOMAIN=my.sms-gateway.com
47 | TWILIO_ACCOUNT_ID=foo
48 | TWILIO_API_TOKEN=bar
49 | ```
50 |
51 | Installation for Lumen
52 | ----------------------
53 |
54 | The installation process with Lumen is identical to that for Laravel, although if you wish to use the facade you will need to uncomment the appropriate section of `bootstrap/app.php` as usual.
55 |
56 | Usage
57 | -----
58 |
59 | Once the package is installed and configured, you can use the facade to send SMS messages:
60 |
61 | ```php
62 | use SMS;
63 |
64 | $msg = [
65 | 'to' => '+44 01234 567890',
66 | 'content' => 'Just testing',
67 | ];
68 | SMS::send($msg);
69 | ```
70 |
71 | Or fetch it from the app:
72 |
73 | ```php
74 | $msg = [
75 | 'to' => '+44 01234 567890',
76 | 'content' => 'Just testing',
77 | ];
78 | $sms = app()['sms']
79 | $sms->send($msg);
80 | ```
81 |
82 | Or resolve the interface `Matthewbdaly\SMS\Contracts\Client`:
83 |
84 | ```php
85 | $msg = [
86 | 'to' => '+44 01234 567890',
87 | 'content' => 'Just testing',
88 | ];
89 | $sms = app()->make('Matthewbdaly\SMS\Contracts\Client');
90 | $sms->send($msg);
91 | ```
92 |
93 | Here we use the `app()` helper, but you'll normally want to inject it into a constructor or method of another class.
94 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "matthewbdaly/laravel-sms",
3 | "description": "A Laravel and Lumen integration for matthewbdaly/sms-client to enable sending SMS messages",
4 | "type": "library",
5 | "keywords": ["sms","laravel","lumen"],
6 | "require": {
7 | "matthewbdaly/sms-client": "^1.0"
8 | },
9 | "require-dev": {
10 | "orchestra/testbench": "3.5",
11 | "phpunit/phpunit": "^6.3",
12 | "mockery/mockery": "^0.9.9",
13 | "squizlabs/php_codesniffer": "^3.1",
14 | "aws/aws-sdk-php": "3.*",
15 | "psy/psysh": "^0.8.11"
16 | },
17 | "license": "MIT",
18 | "authors": [
19 | {
20 | "name": "Matthew Daly",
21 | "email": "matthewbdaly@gmail.com"
22 | }
23 | ],
24 | "autoload": {
25 | "psr-4": {
26 | "Matthewbdaly\\LaravelSMS\\": "src/"
27 | }
28 | },
29 | "autoload-dev": {
30 | "psr-4": {
31 | "Tests\\": "tests/"
32 | }
33 | },
34 | "extra": {
35 | "laravel": {
36 | "providers": [
37 | "Matthewbdaly\\LaravelSMS\\LaravelSMSProvider"
38 | ],
39 | "aliases": {
40 | "SMS": "Matthewbdaly\\LaravelSMS\\Facade"
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Coding standard for SMS API integration.
4 | src
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests
14 |
15 |
16 |
17 |
18 | ./src
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/Facade.php:
--------------------------------------------------------------------------------
1 | publishes([
32 | __DIR__.'/config.php' => config_path('sms.php'),
33 | ]);
34 | }
35 |
36 | /**
37 | * Register the application services.
38 | *
39 | * @return void
40 | */
41 | public function register()
42 | {
43 | $this->app->singleton('sms', function ($app) {
44 | $config = $app['config'];
45 | switch ($config['sms.default']) {
46 | case 'null':
47 | $driver = new NullDriver(
48 | new GuzzleClient,
49 | new GuzzleResponse
50 | );
51 | break;
52 | case 'nexmo':
53 | $driver = new Nexmo(
54 | new GuzzleClient,
55 | new GuzzleResponse,
56 | [
57 | 'api_key' => $config['sms.drivers.nexmo.api_key'],
58 | 'api_secret' => $config['sms.drivers.nexmo.api_secret'],
59 | ]
60 | );
61 | break;
62 | case 'clockwork':
63 | $driver = new Clockwork(
64 | new GuzzleClient,
65 | new GuzzleResponse,
66 | [
67 | 'api_key' => $config['sms.drivers.clockwork.api_key'],
68 | ]
69 | );
70 | break;
71 | case 'textlocal':
72 | $driver = new TextLocal(
73 | new GuzzleClient,
74 | new GuzzleResponse,
75 | [
76 | 'api_key' => $config['sms.drivers.textlocal.api_key'],
77 | ]
78 | );
79 | break;
80 | case 'twilio':
81 | $driver = new Twilio(
82 | new GuzzleClient,
83 | new GuzzleResponse,
84 | [
85 | 'account_id' => $config['sms.drivers.twilio.account_id'],
86 | 'api_token' => $config['sms.drivers.twilio.api_token'],
87 | ]
88 | );
89 | break;
90 | case 'requestbin':
91 | $driver = new RequestBin(
92 | new GuzzleClient,
93 | new GuzzleResponse,
94 | [
95 | 'path' => $config['sms.drivers.requestbin.path'],
96 | ]
97 | );
98 | break;
99 | case 'aws':
100 | $driver = new Aws([
101 | 'api_key' => $config['sms.drivers.aws.api_key'],
102 | 'api_secret' => $config['sms.drivers.aws.api_secret'],
103 | 'api_region' => $config['sms.drivers.aws.api_region'],
104 | ]);
105 | break;
106 | case 'mail':
107 | $driver = new MailDriver(new MailAdapter, [
108 | 'domain' => $config['sms.drivers.mail.domain'],
109 | ]);
110 | break;
111 | default:
112 | $driver = new LogDriver(
113 | $app['log']
114 | );
115 | break;
116 | }
117 | return new Client($driver);
118 | });
119 |
120 | $this->app->bind('Matthewbdaly\SMS\Contracts\Client', function ($app) {
121 | return $app['sms'];
122 | });
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/MailAdapter.php:
--------------------------------------------------------------------------------
1 | make('Illuminate\Contracts\Mail\Mailer');
23 | return $mailer->to($recipient)->raw($message);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/config.php:
--------------------------------------------------------------------------------
1 | env('SMS_DRIVER', 'log'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Drivers
21 | |--------------------------------------------------------------------------
22 | |
23 | | Here you can define the settings for each driver.
24 | |
25 | */
26 |
27 | 'drivers' => [
28 |
29 | 'clockwork' => [
30 | 'driver' => 'clockwork',
31 | 'api_key' => env('CLOCKWORK_API_KEY', null),
32 | ],
33 |
34 | 'textlocal' => [
35 | 'driver' => 'textlocal',
36 | 'api_key' => env('TEXTLOCAL_API_KEY', null),
37 | ],
38 |
39 | 'log' => [
40 | 'driver' => 'log',
41 | ],
42 |
43 | 'requestbin' => [
44 | 'path' => env('REQUESTBIN_PATH', null),
45 | ],
46 |
47 | 'nexmo' => [
48 | 'driver' => 'nexmo',
49 | 'api_key' => env('NEXMO_API_KEY', null),
50 | 'api_secret' => env('NEXMO_API_secret', null),
51 | ],
52 |
53 | 'twilio' => [
54 | 'driver' => 'twilio',
55 | 'account_id' => env('TWILIO_ACCOUNT_ID', null),
56 | 'api_token' => env('TWILIO_API_TOKEN', null),
57 | ],
58 |
59 | 'aws' => [
60 | 'driver' => 'aws',
61 | 'api_key' => env('AWS_SNS_API_KEY', null),
62 | 'api_secret' => env('AWS_SNS_API_SECRET', null),
63 | 'api_region' => env('AWS_SNS_API_REGION', null),
64 | ],
65 |
66 | 'mail' => [
67 | 'domain' => env('MAIL_SMS_DOMAIN', null),
68 | ],
69 |
70 | 'null' => [
71 | 'driver' => 'null',
72 | ],
73 | ],
74 | ];
75 |
--------------------------------------------------------------------------------
/tests/ServiceProviderTest.php:
--------------------------------------------------------------------------------
1 | app['config']->set('sms.default', 'null');
13 | $client = $this->app->make('sms');
14 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
15 | $this->assertEquals('Null', $client->getDriver());
16 | }
17 |
18 | public function testDefaultDriverSetup()
19 | {
20 | $client = $this->app->make('sms');
21 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
22 | $this->assertEquals('Log', $client->getDriver());
23 | }
24 |
25 | public function testLogDriverSetup()
26 | {
27 | $this->app['config']->set('sms.default', 'log');
28 | $client = $this->app->make('sms');
29 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
30 | $this->assertEquals('Log', $client->getDriver());
31 | }
32 |
33 | public function testNexmoDriverSetup()
34 | {
35 | $this->app['config']->set('sms.default', 'nexmo');
36 | $this->app['config']->set('sms.drivers.nexmo.api_key', 'MY_NEXMO_API_KEY');
37 | $this->app['config']->set('sms.drivers.nexmo.api_secret', 'MY_NEXMO_API_SECRET');
38 | $client = $this->app->make('sms');
39 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
40 | $this->assertEquals('Nexmo', $client->getDriver());
41 | }
42 |
43 | public function testClockworkDriverSetup()
44 | {
45 | $this->app['config']->set('sms.default', 'clockwork');
46 | $this->app['config']->set('sms.drivers.clockwork.api_key', 'MY_CLOCKWORK_API_KEY');
47 | $client = $this->app->make('sms');
48 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
49 | $this->assertEquals('Clockwork', $client->getDriver());
50 | }
51 |
52 | public function testTextLocalDriverSetup()
53 | {
54 | $this->app['config']->set('sms.default', 'textlocal');
55 | $this->app['config']->set('sms.drivers.textlocal.api_key', 'MY_TEXTLOCAL_API_KEY');
56 | $client = $this->app->make('sms');
57 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
58 | $this->assertEquals('TextLocal', $client->getDriver());
59 | }
60 |
61 | public function testRequestBinDriverSetup()
62 | {
63 | $this->app['config']->set('sms.default', 'requestbin');
64 | $this->app['config']->set('sms.drivers.requestbin.path', 'REQUESTBIN_PATH');
65 | $client = $this->app->make('sms');
66 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
67 | $this->assertEquals('RequestBin', $client->getDriver());
68 | }
69 |
70 | public function testAwsSnsDriverSetup()
71 | {
72 | $this->app['config']->set('sms.default', 'aws');
73 | $this->app['config']->set('sms.drivers.aws.api_key', 'MY_AWS_SNS_API_KEY');
74 | $this->app['config']->set('sms.drivers.aws.api_secret', 'MY_AWS_SNS_API_SECRET');
75 | $this->app['config']->set('sms.drivers.aws.api_region', 'MY_AWS_SNS_API_REGION');
76 | $client = $this->app->make('sms');
77 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
78 | $this->assertEquals('Aws', $client->getDriver());
79 | }
80 |
81 | public function testTwilioDriverSetup()
82 | {
83 | $this->app['config']->set('sms.default', 'twilio');
84 | $this->app['config']->set('sms.drivers.aws.account_id', 'MY_TWILIO_ACCOUNT_ID');
85 | $this->app['config']->set('sms.drivers.aws.api_token', 'MY_TWILIO_API_TOKEN');
86 | $client = $this->app->make('sms');
87 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
88 | $this->assertEquals('Twilio', $client->getDriver());
89 | }
90 |
91 | public function testMailDriverSetup()
92 | {
93 | $this->app['config']->set('sms.default', 'mail');
94 | $this->app['config']->set('sms.drivers.mail.domain', 'my.sms-gateway.com');
95 | $client = $this->app->make('sms');
96 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
97 | $this->assertEquals('Mail', $client->getDriver());
98 | }
99 |
100 | public function testFacade()
101 | {
102 | $msg = [
103 | 'to' => '+44 01234 567890',
104 | 'content' => 'Just testing',
105 | ];
106 | $mock = m::mock('Matthewbdaly\SMS\Client');
107 | $mock->shouldReceive('send')->with($msg)->once()->andReturn(true);
108 | $this->app->instance('sms', $mock);
109 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $this->app['sms']);
110 | SMS::send($msg);
111 | }
112 |
113 | public function testInject()
114 | {
115 | $client = $this->app->make('Matthewbdaly\SMS\Contracts\Client');
116 | $this->assertInstanceOf('Matthewbdaly\SMS\Contracts\Client', $client);
117 | $this->assertInstanceOf('Matthewbdaly\SMS\Client', $client);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | 'Matthewbdaly\LaravelSMS\Facade'
18 | ];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------