├── src ├── views │ └── welcome.blade.php ├── SimpleSoftwareIO │ └── SMS │ │ ├── Facades │ │ └── SMS.php │ │ ├── Drivers │ │ ├── DriverInterface.php │ │ ├── InfobipSMS.php │ │ ├── LabsMobileSMS.php │ │ ├── MozeoSMS.php │ │ ├── CallFireSMS.php │ │ ├── EZTextingSMS.php │ │ ├── NexmoSMS.php │ │ ├── AbstractSMS.php │ │ ├── TwilioSMS.php │ │ └── EmailSMS.php │ │ ├── SMSServiceProvider.php │ │ ├── IncomingMessage.php │ │ ├── DriverManager.php │ │ ├── OutgoingMessage.php │ │ └── SMS.php └── config │ └── sms.php ├── .gitignore ├── CONTRIBUTING.md ├── .travis.yml ├── tests ├── bootstrap.php ├── SMSTest.php └── MessageTest.php ├── phpunit.xml ├── LICENSE ├── composer.json ├── CHANGELOG.md ├── docs └── laravel4.md └── README.md /src/views/welcome.blade.php: -------------------------------------------------------------------------------- 1 | This is a test message sent with Simple-SMS. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | .idea -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Please submit all issues and pull requests to the [simplesoftwareio/simple-sms](https://github.com/simplesoftwareio/simple-sms) repository! -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | sudo: false 3 | php: 4 | - 5.5 5 | - 5.6 6 | - 7.0 7 | - hhvm 8 | 9 | before_script: 10 | - composer install --dev 11 | - composer update -o 12 | 13 | script: phpunit --bootstrap tests/bootstrap.php --configuration phpunit.xml tests 14 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Facades/SMS.php: -------------------------------------------------------------------------------- 1 | sms = new SMS(m::mock('SimpleSoftwareIO\SMS\Drivers\DriverInterface')); 25 | } 26 | 27 | public function testIsPretendingByDefault() 28 | { 29 | $this->assertFalse($this->sms->isPretending()); 30 | } 31 | 32 | public function testPretendIsSet() 33 | { 34 | $this->sms->setPretending(true); 35 | 36 | $this->assertTrue($this->sms->isPretending()); 37 | } 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simple Software LLC www.simplesoftware.io 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. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplesoftwareio/simple-sms", 3 | "description": "Simple-SMS is a package made for Laravel to send/receive (polling/pushing) text messages. Currently supports CallFire, EZTexting, Email Gateways, Mozeo, and Twilio.", 4 | "keywords": ["sms", "laravel", "simple", "twilio", "callfire", "eztexting", "mozeo", "labsmobile", "nexmo", "text messages", "send", "receive"], 5 | "homepage": "http://www.simplesoftware.io", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Simple Software LLC", 10 | "email": "support@simplesoftware.io" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.5.0", 15 | "illuminate/mail": ">=5.0.0", 16 | "illuminate/log": ">=5.0.0", 17 | "illuminate/queue": ">=5.0.0", 18 | "illuminate/support": ">=5.0.0", 19 | "illuminate/view": ">=5.0.0", 20 | "twilio/sdk": "~4", 21 | "guzzlehttp/guzzle": "~6", 22 | "infobip/oneapi": "^1.1" 23 | }, 24 | "require-dev": { 25 | "mockery/mockery": "0.9.*", 26 | "phpunit/phpunit": "4.7.*" 27 | }, 28 | "autoload": { 29 | "psr-0": { 30 | "SimpleSoftwareIO\\SMS\\": "src/" 31 | } 32 | }, 33 | "minimum-stability": "stable" 34 | } 35 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/DriverInterface.php: -------------------------------------------------------------------------------- 1 | smsClient = $client; 31 | } 32 | 33 | 34 | protected function processReceive($rawMessage) 35 | { 36 | // TODO: Implement processReceive() method. 37 | } 38 | 39 | public function send(OutgoingMessage $message) 40 | { 41 | // TODO: Implement send() method. 42 | 43 | $smsMessage = new SMSRequest(); 44 | $smsMessage->senderAddress = $message->getFrom(); 45 | $smsMessage->address = count($message->getTo()) ==1 ? $message->getTo()[0] : $message->getTo(); 46 | $smsMessage->message = $message->composeMessage(); 47 | $smsMessageSendResult = $this->smsClient->sendSMS($smsMessage); 48 | $smsMessageStatus = $this->smsClient->queryDeliveryStatus($smsMessageSendResult); 49 | 50 | if( ! $smsMessageStatus->isSuccess()) { 51 | $exceptionMsg = 'Message id:'. $smsMessageStatus->exception->messageId . 52 | 'Text:' . $smsMessageStatus->exception->text. 53 | 'Variables:' .$smsMessageStatus->exception->variables; 54 | throw new \Exception($exceptionMsg); 55 | } 56 | 57 | } 58 | 59 | public function checkMessages(array $options = []) 60 | { 61 | // TODO: Implement checkMessages() method. 62 | } 63 | 64 | public function getMessage($messageId) 65 | { 66 | // TODO: Implement getMessage() method. 67 | } 68 | 69 | public function receive($raw) 70 | { 71 | // TODO: Implement receive() method. 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /tests/MessageTest.php: -------------------------------------------------------------------------------- 1 | message = new OutgoingMessage(m::mock('\Illuminate\View\Factory')); 25 | } 26 | 27 | public function testMSMIsSetOnAttachImage() 28 | { 29 | $this->assertFalse($this->message->isMMS()); 30 | 31 | $this->message->attachImage('foo.jpg'); 32 | 33 | $this->assertTrue($this->message->isMMS()); 34 | } 35 | 36 | public function testAddImage() 37 | { 38 | $images = $this->message->getAttachImages(); 39 | 40 | $this->assertTrue(empty($images)); 41 | 42 | $singleImage = [0 => 'foo.jpg']; 43 | $this->message->attachImage('foo.jpg'); 44 | $images = $this->message->getAttachImages(); 45 | 46 | $this->assertEquals($singleImage, $images); 47 | } 48 | 49 | public function testAddImages() 50 | { 51 | $mutiImage = [0 => 'foo.jpg', 1 => 'bar.jpg']; 52 | $this->message->attachImage(['foo.jpg', 'bar.jpg']); 53 | $images = $this->message->getAttachImages(); 54 | 55 | $this->assertEquals($mutiImage, $images); 56 | } 57 | 58 | public function testAddToWithCarrier() 59 | { 60 | $toAddresses = $this->message->getToWithCarriers(); 61 | $this->assertTrue(empty($toAddresses)); 62 | 63 | $to = [0 => ['number' => '+15555555555', 'carrier' => 'att']]; 64 | $this->message->to('+15555555555', 'att'); 65 | 66 | $this->assertEquals($to, $this->message->getToWithCarriers()); 67 | 68 | $to = [ 69 | 0 => ['number' => '+15555555555', 'carrier' => 'att'], 70 | 1 => ['number' => '+14444444444', 'carrier' => 'verizon'] 71 | ]; 72 | $this->message->to('+14444444444', 'verizon'); 73 | $this->assertEquals($to, $this->message->getToWithCarriers()); 74 | } 75 | 76 | public function testAddToWithoutCarrier() 77 | { 78 | $to = ['+15555555555']; 79 | $this->message->to('+15555555555'); 80 | 81 | $this->assertEquals($to, $this->message->getTo()); 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/SMSServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 32 | __DIR__.'/../../config/sms.php' => config_path('sms.php'), 33 | ]); 34 | } 35 | 36 | /** 37 | * Register the service provider. 38 | * 39 | * @return void 40 | */ 41 | public function register() 42 | { 43 | $this->app->singleton('sms', function ($app) { 44 | 45 | $this->registerSender(); 46 | $sms = new SMS($app['sms.sender']); 47 | $this->setSMSDependencies($sms, $app); 48 | 49 | //Set the from and pretending settings 50 | if ($app['config']->has('sms.from')) { 51 | $sms->alwaysFrom($app['config']['sms']['from']); 52 | } 53 | 54 | $sms->setPretending($app['config']->get('sms.pretend', false)); 55 | 56 | return $sms; 57 | }); 58 | } 59 | 60 | /** 61 | * Register the correct driver based on the config file. 62 | * 63 | * @return void 64 | */ 65 | public function registerSender() 66 | { 67 | $this->app['sms.sender'] = $this->app->share(function ($app) { 68 | return (new DriverManager($app))->driver(); 69 | }); 70 | } 71 | 72 | /** 73 | * Set a few dependencies on the sms instance. 74 | * 75 | * @param SMS $sms 76 | * @param $app 77 | * @return void 78 | */ 79 | private function setSMSDependencies($sms, $app) 80 | { 81 | $sms->setContainer($app); 82 | $sms->setLogger($app['log']); 83 | $sms->setQueue($app['queue']); 84 | } 85 | 86 | /** 87 | * Get the services provided by the provider. 88 | * 89 | * @return array 90 | */ 91 | public function provides() 92 | { 93 | return array('sms', 'sms.sender'); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/LabsMobileSMS.php: -------------------------------------------------------------------------------- 1 | client = $client; 41 | } 42 | 43 | /** 44 | * Sends a SMS message. 45 | * 46 | * @param OutgoingMessage $message The SMS message instance. 47 | * @return void 48 | */ 49 | public function send(OutgoingMessage $message) 50 | { 51 | $composeMessage = $message->composeMessage(); 52 | 53 | foreach($message->getTo() as $to) 54 | { 55 | $data = [ 56 | 'msisdn' => $to, 57 | 'message' => $composeMessage 58 | ]; 59 | 60 | $this->buildBody($data); 61 | 62 | $this->getRequest(); 63 | } 64 | } 65 | 66 | /** 67 | * Creates many IncomingMessage objects and sets all of the properties. 68 | * 69 | * @throws \RuntimeException 70 | */ 71 | protected function processReceive($rawMessage) 72 | { 73 | throw new \RuntimeException('LabsMobile does not support Inbound API Calls.'); 74 | } 75 | 76 | /** 77 | * Checks the server for messages and returns their results. 78 | * 79 | * @throws \RuntimeException 80 | */ 81 | public function checkMessages(Array $options = array()) 82 | { 83 | throw new \RuntimeException('LabsMobile does not support Inbound API Calls.'); 84 | } 85 | 86 | /** 87 | * Gets a single message by it's ID. 88 | * 89 | * @throws \RuntimeException 90 | */ 91 | public function getMessage($messageId) 92 | { 93 | throw new \RuntimeException('LabsMobile does not support Inbound API Calls.'); 94 | } 95 | 96 | /** 97 | * Receives an incoming message via REST call. 98 | * 99 | * @param $raw 100 | * @return IncomingMessage|void 101 | * @throws \RuntimeException 102 | */ 103 | public function receive($raw) 104 | { 105 | throw new \RuntimeException('LabsMobile does not support Inbound API Calls.'); 106 | } 107 | } -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/IncomingMessage.php: -------------------------------------------------------------------------------- 1 | raw; 57 | } 58 | 59 | /** 60 | * Sets the raw data. 61 | * 62 | * @param mixed $raw 63 | */ 64 | public function setRaw($raw) 65 | { 66 | $this->raw = $raw; 67 | } 68 | 69 | /** 70 | * Returns the message id. 71 | * 72 | * @return string 73 | */ 74 | public function id() 75 | { 76 | return $this->id; 77 | } 78 | 79 | /** 80 | * Sets the message id. 81 | * 82 | * @param string $id 83 | */ 84 | public function setId($id) 85 | { 86 | $this->id = $id; 87 | } 88 | 89 | /** 90 | * Returns the from address. 91 | * 92 | * @return string 93 | */ 94 | public function from() 95 | { 96 | return $this->from; 97 | } 98 | 99 | /** 100 | * Sets the from address. 101 | * 102 | * @param string $from 103 | */ 104 | public function setFrom($from) 105 | { 106 | $this->from = $from; 107 | } 108 | 109 | /** 110 | * Returns the to address. 111 | * 112 | * @return string 113 | */ 114 | public function to() 115 | { 116 | return $this->to; 117 | } 118 | 119 | /** 120 | * Sets the to address. 121 | * 122 | * @param string $to 123 | */ 124 | public function setTo($to) 125 | { 126 | $this->to = $to; 127 | } 128 | 129 | /** 130 | * Returns the message body. 131 | * 132 | * @return string 133 | */ 134 | public function message() 135 | { 136 | return $this->message; 137 | } 138 | 139 | /** 140 | * Sets the message body. 141 | * 142 | * @param string $message 143 | */ 144 | public function setMessage($message) 145 | { 146 | $this->message = $message; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/MozeoSMS.php: -------------------------------------------------------------------------------- 1 | client = $client; 40 | } 41 | 42 | /** 43 | * Sends a SMS message. 44 | * 45 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 46 | * @return void 47 | */ 48 | public function send(OutgoingMessage $message) 49 | { 50 | $composeMessage = $message->composeMessage(); 51 | 52 | foreach ($message->getTo() as $to) { 53 | $data = [ 54 | 'to' => $to, 55 | 'messagebody' => $composeMessage 56 | ]; 57 | 58 | $this->buildBody($data); 59 | 60 | $this->postRequest(); 61 | } 62 | } 63 | 64 | /** 65 | * Creates many IncomingMessage objects and sets all of the properties. 66 | * 67 | * @throws \RuntimeException 68 | */ 69 | protected function processReceive($rawMessage) 70 | { 71 | throw new \RuntimeException('Mozeo does not support Inbound API Calls.'); 72 | } 73 | 74 | /** 75 | * Checks the server for messages and returns their results. 76 | * 77 | * @param array $options 78 | * @return array 79 | * @throws \RuntimeException 80 | */ 81 | public function checkMessages(array $options = []) 82 | { 83 | throw new \RuntimeException('Mozeo does not support Inbound API Calls.'); 84 | } 85 | 86 | /** 87 | * Gets a single message by it's ID. 88 | * 89 | * @param string|int $messageId 90 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 91 | * @throws \RangeException 92 | */ 93 | public function getMessage($messageId) 94 | { 95 | throw new \RuntimeException('Mozeo does not support Inbound API Calls.'); 96 | } 97 | 98 | /** 99 | * Receives an incoming message via REST call. 100 | * 101 | * @param mixed $raw 102 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 103 | * @throws \RuntimeException 104 | */ 105 | public function receive($raw) 106 | { 107 | throw new \RuntimeException('Mozeo does not support Inbound API Calls.'); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/CallFireSMS.php: -------------------------------------------------------------------------------- 1 | client = $client; 39 | } 40 | 41 | /** 42 | * Sends a SMS message. 43 | * 44 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 45 | * @return void 46 | */ 47 | public function send(OutgoingMessage $message) 48 | { 49 | $composeMessage = $message->composeMessage(); 50 | 51 | //Convert to callfire format. 52 | $numbers = implode(",", $message->getTo()); 53 | 54 | $data = [ 55 | 'To' => $numbers, 56 | 'Message' => $composeMessage 57 | ]; 58 | 59 | $this->buildCall('/text'); 60 | $this->buildBody($data); 61 | 62 | $this->postRequest(); 63 | } 64 | 65 | /** 66 | * Creates many IncomingMessage objects and sets all of the properties. 67 | * 68 | * @param $rawMessage 69 | * @return mixed 70 | */ 71 | protected function processReceive($rawMessage) 72 | { 73 | $incomingMessage = $this->createIncomingMessage(); 74 | $incomingMessage->setRaw($rawMessage); 75 | $incomingMessage->setFrom((string)$rawMessage->FromNumber); 76 | $incomingMessage->setMessage((string)$rawMessage->TextRecord->Message); 77 | $incomingMessage->setId((string)$rawMessage['id']); 78 | $incomingMessage->setTo((string)$rawMessage->ToNumber); 79 | 80 | return $incomingMessage; 81 | } 82 | 83 | /** 84 | * Checks the server for messages and returns their results. 85 | * 86 | * @param array $options 87 | * @return array 88 | */ 89 | public function checkMessages(array $options = []) 90 | { 91 | $this->buildCall('/text'); 92 | 93 | $rawMessages = $this->getRequest()->xml(); 94 | 95 | return $this->makeMessages($rawMessages->Text); 96 | } 97 | 98 | /** 99 | * Gets a single message by it's ID. 100 | * 101 | * @param string|int $messageId 102 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 103 | */ 104 | public function getMessage($messageId) 105 | { 106 | $this->buildCall('/text/' . $messageId); 107 | 108 | return $this->makeMessage($this->getRequest()->xml()->Text); 109 | } 110 | 111 | /** 112 | * Receives an incoming message via REST call. 113 | * 114 | * @param mixed $raw 115 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 116 | * @throws \RuntimeException 117 | */ 118 | public function receive($raw) 119 | { 120 | throw new \RuntimeException('CallFire push messages is not supported.'); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/EZTextingSMS.php: -------------------------------------------------------------------------------- 1 | 'json']; 38 | 39 | /** 40 | * Constructs a new instance. 41 | * 42 | * @param Client $client 43 | */ 44 | public function __construct(Client $client) 45 | { 46 | $this->client = $client; 47 | } 48 | 49 | /** 50 | * Sends a SMS message. 51 | * 52 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 53 | * @return void 54 | */ 55 | public function send(OutgoingMessage $message) 56 | { 57 | $composedMessage = $message->composeMessage(); 58 | 59 | $data = [ 60 | 'PhoneNumbers' => $message->getTo(), 61 | 'Message' => $composedMessage 62 | ]; 63 | 64 | $this->buildCall('/sending/messages'); 65 | $this->buildBody($data); 66 | 67 | $this->postRequest(); 68 | } 69 | 70 | /** 71 | * Checks the server for messages and returns their results. 72 | * 73 | * @param array $options 74 | * @return array 75 | */ 76 | public function checkMessages(array $options = []) 77 | { 78 | $this->buildCall('/incoming-messages'); 79 | $this->buildBody($options); 80 | 81 | $rawMessages = $this->getRequest()->json(); 82 | return $this->makeMessages($rawMessages['Response']['Entries']); 83 | } 84 | 85 | /** 86 | * Gets a single message by it's ID. 87 | * 88 | * @param string|int $messageId 89 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 90 | */ 91 | public function getMessage($messageId) 92 | { 93 | $this->buildCall('/incoming-messages'); 94 | $this->buildCall('/' . $messageId); 95 | 96 | $rawMessage = $this->getRequest()->json(); 97 | 98 | return $this->makeMessage($rawMessage['Response']['Entry']); 99 | } 100 | 101 | /** 102 | * Returns an IncomingMessage object with it's properties filled out. 103 | * 104 | * @param $rawMessage 105 | * @return mixed|\SimpleSoftwareIO\SMS\IncomingMessage 106 | */ 107 | protected function processReceive($rawMessage) 108 | { 109 | $incomingMessage = $this->createIncomingMessage(); 110 | $incomingMessage->setRaw($rawMessage); 111 | $incomingMessage->setFrom($rawMessage['PhoneNumber']); 112 | $incomingMessage->setMessage($rawMessage['Message']); 113 | $incomingMessage->setId($rawMessage['ID']); 114 | $incomingMessage->setTo('313131'); 115 | 116 | return $incomingMessage; 117 | } 118 | 119 | /** 120 | * Receives an incoming message via REST call. 121 | * 122 | * @param mixed $raw 123 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 124 | */ 125 | public function receive($raw) 126 | { 127 | //Due to the way EZTexting handles Keyword Submits vs Replys 128 | //We must check both values. 129 | $from = $raw->get('PhoneNumber') ? $raw->get('PhoneNumber') : $raw->get('from'); 130 | $message = $raw->get('Message') ? $raw->get('Message') : $raw->get('message'); 131 | 132 | $incomingMessage = $this->createIncomingMessage(); 133 | $incomingMessage->setRaw($raw->get()); 134 | $incomingMessage->setFrom($from); 135 | $incomingMessage->setMessage($message); 136 | $incomingMessage->setTo('313131'); 137 | 138 | return $incomingMessage; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/NexmoSMS.php: -------------------------------------------------------------------------------- 1 | client = $client; 42 | $this->apiKey = $apiKey; 43 | $this->apiSecret = $apiSecret; 44 | } 45 | 46 | /** 47 | * Sends a SMS message. 48 | * 49 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 50 | * @return void 51 | */ 52 | public function send(OutgoingMessage $message) 53 | { 54 | $from = $message->getFrom(); 55 | $composeMessage = $message->composeMessage(); 56 | 57 | //Convert to callfire format. 58 | $numbers = implode(",", $message->getTo()); 59 | 60 | $data = [ 61 | 'from' => $from, 62 | 'to' => $numbers, 63 | 'text' => $composeMessage, 64 | 'api_key' => $this->apiKey, 65 | 'api_secret' => $this->apiSecret, 66 | ]; 67 | 68 | $this->buildCall('/sms/json'); 69 | $this->buildBody($data); 70 | 71 | return $this->postRequest(); 72 | } 73 | 74 | /** 75 | * Creates many IncomingMessage objects and sets all of the properties. 76 | * 77 | * @param $rawMessage 78 | * @return mixed 79 | */ 80 | protected function processReceive($rawMessage) 81 | { 82 | $incomingMessage = $this->createIncomingMessage(); 83 | $incomingMessage->setRaw($rawMessage); 84 | $incomingMessage->setFrom((string)$rawMessage->from); 85 | $incomingMessage->setMessage((string)$rawMessage->body); 86 | $incomingMessage->setId((string)$rawMessage->{'message-id'}); 87 | $incomingMessage->setTo((string)$rawMessage->to); 88 | 89 | return $incomingMessage; 90 | } 91 | 92 | /** 93 | * Checks the server for messages and returns their results. 94 | * 95 | * @param array $options 96 | * @return array 97 | */ 98 | public function checkMessages(array $options = []) 99 | { 100 | $this->buildCall('/search/messages/' . $this->apiKey . '/' . $this->apiSecret); 101 | 102 | $this->buildBody($options); 103 | 104 | $rawMessages = json_decode($this->getRequest()->getBody()->getContents()); 105 | 106 | return $this->makeMessages($rawMessages->items); 107 | } 108 | 109 | /** 110 | * Gets a single message by it's ID. 111 | * 112 | * @param string|int $messageId 113 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 114 | */ 115 | public function getMessage($messageId) 116 | { 117 | $this->buildCall('/search/message/' . $this->apiKey . '/' . $this->apiSecret . '/' . $messageId); 118 | 119 | return $this->makeMessage(json_decode($this->getRequest()->getBody()->getContents())); 120 | } 121 | 122 | /** 123 | * Receives an incoming message via REST call. 124 | * 125 | * @param mixed $raw 126 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 127 | */ 128 | public function receive($raw) 129 | { 130 | $incomingMessage = $this->createIncomingMessage(); 131 | $incomingMessage->setRaw($raw->get()); 132 | $incomingMessage->setMessage($raw->get('text')); 133 | $incomingMessage->setFrom($raw->get('msisdn')); 134 | $incomingMessage->setId($raw->get('messageId')); 135 | $incomingMessage->setTo($raw->get('to')); 136 | 137 | return $incomingMessage; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/config/sms.php: -------------------------------------------------------------------------------- 1 | 'Selected Driver', 65 | 'from' => 'Your Number or Email', 66 | 'callfire' => [ 67 | 'app_login' => 'Your CallFire API Login', 68 | 'app_password' => 'Your CallFire API Password' 69 | ], 70 | 'eztexting' => [ 71 | 'username' => 'Your EZTexting Username', 72 | 'password' => 'Your EZTexting Password' 73 | ], 74 | 'labsmobile' => [ 75 | 'client' => 'Your client ID', 76 | 'username' => 'Your Usernbame', 77 | 'password' => 'Your Password', 78 | 'test' => false 79 | ], 80 | 'mozeo' => [ 81 | 'company_key' => 'Your Mozeo Company Key', 82 | 'username' => 'Your Mozeo Username', 83 | 'password' => 'Your Mozeo Password' 84 | ], 85 | 'nexmo' => [ 86 | 'api_key' => 'Your Nexmo api key', 87 | 'api_secret' => 'Your Nexmo api secret' 88 | ], 89 | 'twilio' => [ 90 | 'account_sid' => 'Your SID', 91 | 'auth_token' => 'Your Token', 92 | 'verify' => true, 93 | ], 94 | 'infobip'=> [ 95 | 'username' => 'username of infobip', 96 | 'password' => 'password of infobip' 97 | ] 98 | ]; -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/DriverManager.php: -------------------------------------------------------------------------------- 1 | , 9 | * 10 | */ 11 | 12 | use GuzzleHttp\Client; 13 | use Illuminate\Support\Manager; 14 | use SimpleSoftwareIO\SMS\Drivers\CallFireSMS; 15 | use SimpleSoftwareIO\SMS\Drivers\EmailSMS; 16 | use SimpleSoftwareIO\SMS\Drivers\EZTextingSMS; 17 | use SimpleSoftwareIO\SMS\Drivers\InfobipSMS; 18 | use SimpleSoftwareIO\SMS\Drivers\LabsMobileSMS; 19 | use SimpleSoftwareIO\SMS\Drivers\MozeoSMS; 20 | use SimpleSoftwareIO\SMS\Drivers\NexmoSMS; 21 | use SimpleSoftwareIO\SMS\Drivers\TwilioSMS; 22 | 23 | class DriverManager extends Manager 24 | { 25 | /** 26 | * Get the default sms driver name. 27 | * 28 | * @return string 29 | */ 30 | public function getDefaultDriver() 31 | { 32 | return $this->app['config']['sms.driver']; 33 | } 34 | 35 | /** 36 | * Set the default sms driver name. 37 | * 38 | * @param string $name 39 | * @return void 40 | */ 41 | public function setDefaultDriver($name) 42 | { 43 | $this->app['config']['sms.driver'] = $name; 44 | } 45 | 46 | /** 47 | * Create an instance of the callfire driver 48 | * 49 | * @return CallFireSMS 50 | */ 51 | protected function createCallfireDriver() 52 | { 53 | $config = $this->app['config']->get('sms.callfire', []); 54 | 55 | $provider = new CallFireSMS(new Client); 56 | 57 | $provider->setUser($config['app_login']); 58 | $provider->setPassword($config['app_password']); 59 | 60 | return $provider; 61 | } 62 | 63 | /** 64 | * Creates an instance of the email driver 65 | * 66 | * @return EmailSMS 67 | */ 68 | protected function createEmailDriver() 69 | { 70 | $provider = new EmailSMS($this->app['mailer']); 71 | 72 | return $provider; 73 | } 74 | 75 | /** 76 | * Create an instance of the eztexting driver 77 | * 78 | * @return EZTextingSMS 79 | */ 80 | protected function createEztextingDriver() 81 | { 82 | $config = $this->app['config']->get('sms.eztexting', []); 83 | 84 | $provider = new EZTextingSMS(new Client); 85 | 86 | $data = [ 87 | 'User' => $config['username'], 88 | 'Password' => $config['password'] 89 | ]; 90 | $provider->buildBody($data); 91 | 92 | return $provider; 93 | } 94 | 95 | protected function createLabsMobileDriver() 96 | { 97 | $config = $this->app['config']->get('sms.labsmobile', []); 98 | 99 | $provider = new LabsMobileSMS(new Client); 100 | 101 | $auth = [ 102 | 'client' => $config['client'], 103 | 'username' => $config['username'], 104 | 'password' => $config['password'], 105 | 'test' => $config['test'] 106 | ]; 107 | 108 | $provider->buildBody($auth); 109 | 110 | return $provider; 111 | } 112 | 113 | /** 114 | * Create an instance of the mozeo driver 115 | * 116 | * @return MozeoSMS 117 | */ 118 | protected function createMozeoDriver() 119 | { 120 | $config = $this->app['config']->get('sms.mozeo', []); 121 | 122 | $provider = new MozeoSMS(new Client); 123 | 124 | $auth = [ 125 | 'companykey' => $config['company_key'], 126 | 'username' => $config['username'], 127 | 'password' => $config['password'], 128 | ]; 129 | $provider->buildBody($auth); 130 | 131 | return $provider; 132 | } 133 | 134 | /** 135 | * Create an instance of the nexmo driver 136 | * 137 | * @return MozeoSMS 138 | */ 139 | protected function createNexmoDriver() 140 | { 141 | $config = $this->app['config']->get('sms.nexmo', []); 142 | 143 | $provider = new NexmoSMS( 144 | new Client, 145 | $config['api_key'], 146 | $config['api_secret'] 147 | ); 148 | 149 | return $provider; 150 | } 151 | 152 | /** 153 | * Create an instance of the Twillo driver 154 | * 155 | * @return TwilioSMS 156 | */ 157 | protected function createTwilioDriver() 158 | { 159 | $config = $this->app['config']->get('sms.twilio', []); 160 | 161 | return new TwilioSMS( 162 | new \Services_Twilio($config['account_sid'], $config['auth_token']), 163 | $config['auth_token'], 164 | $this->app['request']->url(), 165 | $config['verify'] 166 | ); 167 | } 168 | 169 | protected function createInfobipDriver() 170 | { 171 | $config = $this->app['config']->get('sms.infobip', []); 172 | $provider = new InfobipSMS(new \infobip\SmsClient($config['username'], $config['password'])); 173 | 174 | return $provider; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/OutgoingMessage.php: -------------------------------------------------------------------------------- 1 | views = $views; 73 | } 74 | 75 | /** 76 | * Composes a message. 77 | * 78 | * @return \Illuminate\View\Factory 79 | */ 80 | public function composeMessage() 81 | { 82 | // Attempts to make a view. 83 | // If a view can not be created; it is assumed that simple message is passed through. 84 | try { 85 | return $this->views->make($this->view, $this->data)->render(); 86 | } catch (\InvalidArgumentException $e) { 87 | return $this->view; 88 | } 89 | } 90 | 91 | /** 92 | * Sets the numbers messages will be sent from. 93 | * 94 | * @param string $number Holds the number that messages 95 | * @return void 96 | */ 97 | public function from($number) 98 | { 99 | $this->from = $number; 100 | } 101 | 102 | /** 103 | * Gets the from address 104 | * 105 | * @return string 106 | */ 107 | public function getFrom() 108 | { 109 | return $this->from; 110 | } 111 | 112 | /** 113 | * Sets the to addresses 114 | * 115 | * @param string $number Holds the number that a message will be sent to. 116 | * @param string $carrier The carrier the number is on. 117 | * @return $this 118 | */ 119 | public function to($number, $carrier = null) 120 | { 121 | $this->to[] = [ 122 | 'number' => $number, 123 | 'carrier' => $carrier 124 | ]; 125 | 126 | return $this; 127 | } 128 | 129 | /** 130 | * Returns the To addresses without the carriers 131 | * 132 | * @return array 133 | */ 134 | public function getTo() 135 | { 136 | $numbers = array(); 137 | foreach ($this->to as $to) { 138 | $numbers[] = $to['number']; 139 | } 140 | return $numbers; 141 | } 142 | 143 | /** 144 | * Returns all numbers that a message is being sent to and includes their carriers. 145 | * 146 | * @return array An array with numbers and carriers 147 | */ 148 | public function getToWithCarriers() 149 | { 150 | return $this->to; 151 | } 152 | 153 | /** 154 | * Sets the view file to be loaded. 155 | * 156 | * @param string $view The desired view file 157 | * @return void 158 | */ 159 | public function view($view) 160 | { 161 | $this->view = $view; 162 | } 163 | 164 | /** 165 | * Sets the data for the view file. 166 | * 167 | * @param array $data An array of values to be passed to the View Factory. 168 | * @return void 169 | */ 170 | public function data($data) 171 | { 172 | $this->data = $data; 173 | } 174 | 175 | /** 176 | * Returns the current view file.Returns 177 | * 178 | * @return string 179 | */ 180 | public function getView() 181 | { 182 | return $this->view; 183 | } 184 | 185 | /** 186 | * Returns the view data. 187 | * 188 | * @return array 189 | */ 190 | public function getData() 191 | { 192 | return $this->data; 193 | } 194 | 195 | /** 196 | * Attaches an image to a message. 197 | * 198 | * @param string $image Path to image. 199 | */ 200 | public function attachImage($image) 201 | { 202 | $this->mms = true; 203 | 204 | if (is_array($image)) { 205 | $this->attachImages = array_merge($this->attachImages, $image); 206 | } else { 207 | $this->attachImages[] = $image; 208 | } 209 | } 210 | 211 | /** 212 | * Returns the attached image. 213 | * 214 | * @return array 215 | */ 216 | public function getAttachImages() 217 | { 218 | return $this->attachImages; 219 | } 220 | 221 | /** 222 | * Returns if a message is a MMS.Returns 223 | * 224 | * @return boolean 225 | */ 226 | public function isMMS() 227 | { 228 | return $this->mms; 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/AbstractSMS.php: -------------------------------------------------------------------------------- 1 | apiBase .= $url; 48 | } 49 | 50 | /** 51 | * Builds a URL 52 | * 53 | * @param array $segments 54 | * @return string 55 | */ 56 | protected function buildUrl(Array $segments = []) 57 | { 58 | //Get the base URL and add a ? 59 | $url = $this->apiBase . '?'; 60 | 61 | if (isset($this->apiEnding)) { 62 | $segments = array_merge($segments, $this->apiEnding); 63 | } 64 | 65 | foreach ($segments as $key => $value) { 66 | $url = $url . "$key=$value&"; 67 | } 68 | 69 | //Remove the final & 70 | $url = substr($url, 0, -1); 71 | 72 | return $url; 73 | } 74 | 75 | /** 76 | * Builds the body part of the request and adds it to the body array. 77 | * 78 | * @param array|string $values Provides the data to be merged into the array. If a string, the key must be provided. 79 | * @param null $key Holds the key in which a string will be merged into the array. 80 | */ 81 | public function buildBody($values, $key = null) 82 | { 83 | if (is_array($values)) { 84 | $this->body = array_merge($this->body, $values); 85 | } else { 86 | $this->body[$key] = $values; 87 | } 88 | } 89 | 90 | /** 91 | * Returns the body array. 92 | * 93 | * @return array 94 | */ 95 | protected function getBody() 96 | { 97 | return $this->body; 98 | } 99 | 100 | /** 101 | * Sets the username for auth. 102 | * 103 | * @param $username 104 | * @return void. 105 | */ 106 | public function setUser($username) 107 | { 108 | $this->auth['username'] = $username; 109 | } 110 | 111 | /** 112 | * Sets the password for auth. 113 | * 114 | * @param $password 115 | * @return void 116 | */ 117 | public function setPassword($password) 118 | { 119 | $this->auth['password'] = $password; 120 | } 121 | 122 | /** 123 | * Returns the auth array for requests. If not set, will return null. 124 | * 125 | * @return array|null 126 | */ 127 | protected function getAuth() 128 | { 129 | if (isset($this->auth['username']) && isset($this->auth['password'])) { 130 | return [$this->auth['username'], $this->auth['password']]; 131 | } 132 | return null; 133 | } 134 | 135 | /** 136 | * Creates and sends a POST request to the requested URL. 137 | * 138 | * @return mixed 139 | * @throws \Exception 140 | */ 141 | protected function postRequest() 142 | { 143 | $response = $this->client->post($this->buildUrl(), 144 | [ 145 | 'auth' => $this->getAuth(), 146 | 'form_params' => $this->getBody() 147 | ]); 148 | 149 | if ($response->getStatusCode() != 201 && $response->getStatusCode() != 200) { 150 | throw new \Exception('Unable to request from API.'); 151 | } 152 | 153 | return $response; 154 | } 155 | 156 | /** 157 | * Creates and sends a GET request to the requested URL. 158 | * 159 | * @return mixed 160 | * @throws \Exception 161 | */ 162 | protected function getRequest() 163 | { 164 | $url = $this->buildUrl($this->getBody()); 165 | 166 | $response = $this->client->get($url, ['auth' => $this->getAuth()]); 167 | 168 | if ($response->getStatusCode() != 201 && $response->getStatusCode() != 200) { 169 | throw new \Exception('Unable to request from API.'); 170 | } 171 | 172 | return $response; 173 | } 174 | 175 | /** 176 | * Creates many IncomingMessage objects. 177 | * 178 | * @param $rawMessages 179 | * @return array 180 | */ 181 | protected function makeMessages($rawMessages) 182 | { 183 | $incomingMessages = []; 184 | foreach ($rawMessages as $rawMessage) { 185 | $incomingMessages[] = $this->processReceive($rawMessage); 186 | } 187 | 188 | return $incomingMessages; 189 | } 190 | 191 | /** 192 | * Creates a single IncomingMessage object. 193 | * 194 | * @param $rawMessage 195 | * @return mixed 196 | */ 197 | protected function makeMessage($rawMessage) 198 | { 199 | return $this->processReceive($rawMessage); 200 | } 201 | 202 | /** 203 | * Creates many IncomingMessage objects and sets all of the properties. 204 | * 205 | * @param $rawMessage 206 | * @return mixed 207 | */ 208 | abstract protected function processReceive($rawMessage); 209 | } 210 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/TwilioSMS.php: -------------------------------------------------------------------------------- 1 | twilio = $twilio; 56 | $this->authToken = $authToken; 57 | $this->url = $url; 58 | $this->verify = $verify; 59 | } 60 | 61 | /** 62 | * Sends a SMS message. 63 | * 64 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 65 | * @return void 66 | */ 67 | public function send(OutgoingMessage $message) 68 | { 69 | $from = $message->getFrom(); 70 | $composeMessage = $message->composeMessage(); 71 | 72 | foreach ($message->getTo() as $to) { 73 | $this->twilio->account->messages->create([ 74 | 'To' => $to, 75 | 'From' => $from, 76 | 'Body' => $composeMessage, 77 | 'MediaUrl' => $message->getAttachImages(), 78 | ]); 79 | } 80 | } 81 | 82 | /** 83 | * Processing the raw information from a request and inputs it into the IncomingMessage object. 84 | * 85 | * @param $raw 86 | * @return void 87 | */ 88 | protected function processReceive($raw) 89 | { 90 | $incomingMessage = $this->createIncomingMessage(); 91 | $incomingMessage->setRaw($raw); 92 | $incomingMessage->setMessage($raw->body); 93 | $incomingMessage->setFrom($raw->from); 94 | $incomingMessage->setId($raw->sid); 95 | $incomingMessage->setTo($raw->to); 96 | } 97 | 98 | /** 99 | * Checks the server for messages and returns their results. 100 | * 101 | * @param array $options 102 | * @return array 103 | */ 104 | public function checkMessages(array $options = []) 105 | { 106 | $start = array_key_exists('start', $options) ? $options['start'] : 0; 107 | $end = array_key_exists('end', $options) ? $options['end'] : 25; 108 | 109 | $rawMessages = $this->twilio->account->messages->getIterator($start, $end, $options); 110 | $incomingMessages = []; 111 | 112 | foreach ($rawMessages as $rawMessage) { 113 | $incomingMessage = $this->createIncomingMessage(); 114 | $this->processReceive($incomingMessage, $rawMessage); 115 | $incomingMessages[] = $incomingMessage; 116 | } 117 | 118 | return $incomingMessages; 119 | } 120 | 121 | /** 122 | * Gets a single message by it's ID. 123 | * 124 | * @param string|int $messageId 125 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 126 | */ 127 | public function getMessage($messageId) 128 | { 129 | $rawMessage = $this->twilio->account->messages->get($messageId); 130 | $incomingMessage = $this->createIncomingMessage(); 131 | $this->processReceive($incomingMessage, $rawMessage); 132 | return $incomingMessage; 133 | } 134 | 135 | /** 136 | * Receives an incoming message via REST call. 137 | * 138 | * @param mixed $raw 139 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 140 | */ 141 | public function receive($raw) 142 | { 143 | if ($this->verify) { 144 | $this->validateRequest(); 145 | } 146 | 147 | $incomingMessage = $this->createIncomingMessage(); 148 | $incomingMessage->setRaw($raw->get()); 149 | $incomingMessage->setMessage($raw->get('Body')); 150 | $incomingMessage->setFrom($raw->get('From')); 151 | $incomingMessage->setId($raw->get('MessageSid')); 152 | $incomingMessage->setTo($raw->get('To')); 153 | 154 | return $incomingMessage; 155 | } 156 | 157 | /** 158 | * Checks if a message is authentic from Twilio. 159 | * 160 | * @throws \InvalidArgumentException 161 | * @return void 162 | */ 163 | protected function validateRequest() 164 | { 165 | //Twilio requires that all POST data be sorted alpha to validate. 166 | $data = $_POST; 167 | ksort($data); 168 | 169 | // append the data array to the url string, with no delimiters 170 | $url = $this->url; 171 | foreach ($data as $key => $value) { 172 | $url = $url . $key . $value; 173 | } 174 | 175 | //Encode the request string 176 | $hmac = hash_hmac("sha1", $url, $this->authToken, true); 177 | 178 | //Verify it against the given Twilio key 179 | if (base64_encode($hmac) != $_SERVER["HTTP_X_TWILIO_SIGNATURE"]) { 180 | throw new \InvalidArgumentException('This request was not able to verify it came from Twilio.'); 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/Drivers/EmailSMS.php: -------------------------------------------------------------------------------- 1 | mailer = $mailer; 33 | } 34 | 35 | /** 36 | * Sends a SMS message. 37 | * 38 | * @param \SimpleSoftwareIO\SMS\OutgoingMessage $message 39 | * @return void 40 | */ 41 | public function send(OutgoingMessage $message) 42 | { 43 | $this->outgoingMessage = $message; 44 | $me = $this; 45 | 46 | $this->mailer->send($this->outgoingMessage->getView(), $this->outgoingMessage->getData(), function ($email) use ($me) { 47 | foreach ($me->outgoingMessage->getToWithCarriers() as $number) { 48 | $email->to($me->buildEmail($number)); 49 | } 50 | 51 | if ($me->outgoingMessage->getAttachImages()) { 52 | foreach ($me->outgoingMessage->getAttachImages() as $image) { 53 | $email->attach($image); 54 | } 55 | } 56 | 57 | $email->from($me->outgoingMessage->getFrom()); 58 | }); 59 | } 60 | 61 | /** 62 | * Builds the email address of a number. 63 | * 64 | * @param array $number The number and carrier to look up. 65 | * @return string 66 | */ 67 | protected function buildEmail($number) 68 | { 69 | if (!$number['carrier']) { 70 | throw new \InvalidArgumentException('A carrier must be specified if using the E-Mail Driver.'); 71 | } 72 | 73 | return $number['number'] . '@' . $this->lookupGateway($number['carrier'], $this->outgoingMessage->isMMS()); 74 | } 75 | 76 | /** 77 | * Finds the gateway based on the carrier and MMS. 78 | * 79 | * @param string $carrier The desired carrier to look up. 80 | * @param boolean $mms If the Message is an MMS. 81 | * @return string 82 | */ 83 | protected function lookupGateway($carrier, $mms) 84 | { 85 | if ($mms) { 86 | switch ($carrier) { 87 | case 'att': 88 | return 'mms.att.net'; 89 | 90 | case 'airfiremobile': 91 | throw new \InvalidArgumentException('Air Fire Mobile does not support Email Gateway MMS messages.'); 92 | 93 | case 'alaskacommunicates': 94 | return 'msg.acsalaska.com'; 95 | 96 | case 'ameritech': 97 | throw new \InvalidArgumentException('Ameritech does not support Email Gateway MMS messages.'); 98 | 99 | case 'assurancewireless': 100 | return 'vmobl.com'; 101 | 102 | case 'boostmobile': 103 | return 'myboostmobile.com'; 104 | 105 | case 'cleartalk': 106 | throw new \InvalidArgumentException('Clear Talk does not support Email Gateway MMS messages.'); 107 | 108 | case 'cricket': 109 | return 'mms.mycricket.com '; 110 | 111 | case 'metropcs': 112 | return 'mymetropcs.com'; 113 | 114 | case 'nextech': 115 | throw new \InvalidArgumentException('NexTech does not support Email Gateway MMS messages.'); 116 | 117 | case 'rogerswireless': 118 | return 'mms.rogers.com'; 119 | 120 | case 'unicel': 121 | return 'utext.com'; 122 | 123 | case 'verizonwireless': 124 | return 'vzwpix.com'; 125 | 126 | case 'virginmobile': 127 | return 'vmpix.com'; 128 | 129 | case 'tmobile': 130 | return 'tmomail.net'; 131 | 132 | default: 133 | throw new \InvalidArgumentException('Carrier specified is not found.'); 134 | } 135 | } else { 136 | switch ($carrier) { 137 | case 'att': 138 | return 'txt.att.net'; 139 | 140 | case 'airfiremobile': 141 | return 'sms.airfiremobile.com'; 142 | 143 | case 'alaskacommunicates': 144 | return 'msg.acsalaska.com'; 145 | 146 | case 'ameritech': 147 | return 'paging.acswireless.com'; 148 | 149 | case 'assurancewireless': 150 | return 'vmobl.com'; 151 | 152 | case 'boostmobile': 153 | return 'sms.myboostmobile.com'; 154 | 155 | case 'cleartalk': 156 | return 'sms.cleartalk.us'; 157 | 158 | case 'cricket': 159 | return 'sms.mycricket.com'; 160 | 161 | case 'metropcs': 162 | return 'mymetropcs.com'; 163 | 164 | case 'nextech': 165 | return 'sms.ntwls.net'; 166 | 167 | case 'rogerswireless': 168 | return 'sms.rogers.com'; 169 | 170 | case 'unicel': 171 | return 'utext.com'; 172 | 173 | case 'verizonwireless': 174 | return 'vtext.com'; 175 | 176 | case 'virginmobile': 177 | return 'vmobl.com'; 178 | 179 | case 'tmobile': 180 | return 'tmomail.net'; 181 | 182 | default: 183 | throw new \InvalidArgumentException('Carrier specified is not found.'); 184 | } 185 | } 186 | } 187 | 188 | /** 189 | * Checks the server for messages and returns their results. 190 | * 191 | * @param array $options 192 | * @return array 193 | */ 194 | public function checkMessages(array $options = []) 195 | { 196 | throw new \RuntimeException('Receive methods are not support with the E-Mail driver.'); 197 | } 198 | 199 | /** 200 | * Gets a single message by it's ID. 201 | * 202 | * @param string|int $messageId 203 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 204 | * @throws \RuntimeException 205 | */ 206 | public function getMessage($messageId) 207 | { 208 | throw new \RuntimeException('Receive methods are not support with the E-Mail driver.'); 209 | } 210 | 211 | /** 212 | * Receives an incoming message via REST call. 213 | * 214 | * @param mixed $raw 215 | * @return \SimpleSoftwareIO\SMS\IncomingMessage 216 | * @throws \RuntimeException 217 | */ 218 | public function receive($raw) 219 | { 220 | throw new \RuntimeException('Receive methods are not support with the E-Mail driver.'); 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/SimpleSoftwareIO/SMS/SMS.php: -------------------------------------------------------------------------------- 1 | driver = $driver; 75 | } 76 | 77 | /** 78 | * Changes the set SMS driver 79 | * 80 | * @param $driver 81 | */ 82 | public function driver($driver) 83 | { 84 | $this->container['sms.sender'] = $this->container->share(function ($app) use ($driver) { 85 | return (new DriverManager($app))->driver($driver); 86 | }); 87 | 88 | $this->driver = $this->container['sms.sender']; 89 | } 90 | 91 | /** 92 | * Send a SMS. 93 | * 94 | * @param string $view The desired view. 95 | * @param array $data The data that needs to be passed into the view. 96 | * @param \Closure $callback The methods that you wish to fun on the message. 97 | * @return \SimpleSoftwareIO\SMS\Message The outgoing message that was sent. 98 | */ 99 | public function send($view, $data, $callback) 100 | { 101 | $data['message'] = $message = $this->createOutgoingMessage(); 102 | 103 | //We need to set the properties so that we can later pass this onto the Illuminate Mailer class if the e-mail gateway is used. 104 | $message->view($view); 105 | $message->data($data); 106 | 107 | call_user_func($callback, $message); 108 | 109 | if (!$this->pretending) 110 | { 111 | $this->driver->send($message); 112 | } 113 | elseif (isset($this->logger)) 114 | { 115 | $this->logMessage($message); 116 | } 117 | 118 | return $message; 119 | } 120 | 121 | /** 122 | * Logs that a message was sent. 123 | * 124 | * @param $message 125 | */ 126 | protected function logMessage($message) 127 | { 128 | $numbers = implode(" , ", $message->getTo()); 129 | 130 | $this->logger->info("Pretending to send SMS message to: $numbers"); 131 | } 132 | 133 | /** 134 | * Creates a new Message instance. 135 | * 136 | * @return \SimpleSoftwareIO\SMS\Message 137 | */ 138 | protected function createOutgoingMessage() 139 | { 140 | $message = new OutgoingMessage($this->container['view']); 141 | 142 | //If a from address is set, pass it along to the message class. 143 | if (isset($this->from)) { 144 | $message->from($this->from); 145 | } 146 | 147 | return $message; 148 | } 149 | 150 | /** 151 | * Returns if the message should be faked when sent or not. 152 | * 153 | * @return boolean 154 | */ 155 | public function isPretending() 156 | { 157 | return $this->pretending; 158 | } 159 | 160 | /** 161 | * Fake sending a SMS 162 | * 163 | * @param $view The desired view 164 | * @param $data The data to fill the view 165 | * @param $callback The message callback 166 | */ 167 | public function pretend($view, $data, $callback) 168 | { 169 | $this->setPretending(true); 170 | $this->send($view, $data, $callback); 171 | } 172 | 173 | /** 174 | * Sets if SMS should be fake send a SMS 175 | * 176 | * @param bool $pretend 177 | */ 178 | public function setPretending($pretend = false) 179 | { 180 | $this->pretending = $pretend; 181 | } 182 | 183 | /** 184 | * Sets the IoC container 185 | * 186 | * @param Container $container 187 | */ 188 | public function setContainer(Container $container) 189 | { 190 | $this->container = $container; 191 | } 192 | 193 | /** 194 | * Sets the number that message should always be sent from. 195 | * 196 | * @param $number 197 | */ 198 | public function alwaysFrom($number) 199 | { 200 | $this->from = $number; 201 | } 202 | 203 | /** 204 | * Set the log writer instance. 205 | * 206 | * @param \Illuminate\Log\Writer $logger 207 | * @return $this 208 | */ 209 | public function setLogger(Writer $logger) 210 | { 211 | $this->logger = $logger; 212 | 213 | return $this; 214 | } 215 | 216 | /** 217 | * Queues a SMS message. 218 | * 219 | * @param string $view The desired view. 220 | * @param array $data An array of data to fill the view. 221 | * @param \Closure|string $callback The callback to run on the Message class. 222 | * @param null|string $queue The desired queue to push the message to. 223 | * @return void 224 | */ 225 | public function queue($view, $data, $callback, $queue = null) 226 | { 227 | $callback = $this->buildQueueCallable($callback); 228 | 229 | $this->queue->push('sms@handleQueuedMessage', compact('view', 'data', 'callback'), $queue); 230 | } 231 | 232 | /** 233 | * Queues a SMS message to a given queue. 234 | * 235 | * @param null|string $queue The desired queue to push the message to. 236 | * @param string $view The desired view. 237 | * @param array $data An array of data to fill the view. 238 | * @param \Closure|string $callback The callback to run on the Message class. 239 | * @return void 240 | */ 241 | public function queueOn($queue, $view, array $data, $callback) 242 | { 243 | $this->queue($view, $data, $callback, $queue); 244 | } 245 | 246 | /** 247 | * Queues a message to be sent a later time. 248 | * 249 | * @param int $delay The desired delay in seconds 250 | * @param string $view The desired view. 251 | * @param array $data An array of data to fill the view. 252 | * @param \Closure|string $callback The callback to run on the Message class. 253 | * @param null|string $queue The desired queue to push the message to. 254 | * @return void 255 | */ 256 | public function later($delay, $view, array $data, $callback, $queue = null) 257 | { 258 | $callback = $this->buildQueueCallable($callback); 259 | 260 | $this->queue->later($delay, 'mailer@handleQueuedMessage', compact('view', 'data', 'callback'), $queue); 261 | } 262 | 263 | /** 264 | * Queues a message to be sent a later time on a given queue. 265 | * 266 | * @param null|string $queue The desired queue to push the message to. 267 | * @param int $delay The desired delay in seconds 268 | * @param string $view The desired view. 269 | * @param array $data An array of data to fill the view. 270 | * @param \Closure|string $callback The callback to run on the Message class. 271 | * @return void 272 | */ 273 | public function laterOn($queue, $delay, $view, array $data, $callback) 274 | { 275 | $this->later($delay, $view, $data, $callback, $queue); 276 | } 277 | 278 | /** 279 | * Builds the callable for a queue. 280 | * 281 | * @param \Closure|string $callback The callback to be serialized 282 | * @return string 283 | */ 284 | protected function buildQueueCallable($callback) 285 | { 286 | if (! $callback instanceof Closure) { 287 | return $callback; 288 | } 289 | return (new Serializer)->serialize($callback); 290 | } 291 | 292 | /** 293 | * Handles a queue message. 294 | * 295 | * @param \Illuminate\Queue\Jobs\Job $job 296 | * @param array $data 297 | * @return void 298 | */ 299 | public function handleQueuedMessage($job, $data) 300 | { 301 | $this->send($data['view'], $data['data'], $this->getQueuedCallable($data)); 302 | 303 | $job->delete(); 304 | } 305 | 306 | /** 307 | * Gets the callable for a queued message. 308 | * 309 | * @param array $data 310 | * @return mixed 311 | */ 312 | protected function getQueuedCallable(array $data) 313 | { 314 | if (Str::contains($data['callback'], 'SerializableClosure')) { 315 | return unserialize($data['callback'])->getClosure(); 316 | } 317 | return $data['callback']; 318 | } 319 | 320 | /** 321 | * Set the queue manager instance. 322 | * 323 | * @param \Illuminate\Queue\QueueManager $queue 324 | * @return $this 325 | */ 326 | public function setQueue(QueueManager $queue) 327 | { 328 | $this->queue = $queue; 329 | } 330 | 331 | /** 332 | * Receives a SMS via a push request. 333 | * 334 | * @return IncomingMessage 335 | */ 336 | public function receive() 337 | { 338 | //Passes all of the request onto the driver. 339 | $raw = $this->container['Input']; 340 | return $this->driver->receive($raw); 341 | } 342 | 343 | /** 344 | * Queries the provider for a list of messages. 345 | * 346 | * @param array $options The options to pass onto a provider. See each provider for a list of options. 347 | * @return array Returns an array of IncomingMessage objects. 348 | */ 349 | public function checkMessages(Array $options = array()) 350 | { 351 | return $this->driver->checkMessages($options); 352 | } 353 | 354 | /** 355 | * Gets a message by it's ID. 356 | * 357 | * @param $messageId The requested messageId. 358 | * @return IncomingMessage 359 | */ 360 | public function getMessage($messageId) 361 | { 362 | return $this->driver->getMessage($messageId); 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /docs/laravel4.md: -------------------------------------------------------------------------------- 1 | Simple SMS 2 | ========== 3 | 4 | [![Build Status](https://travis-ci.org/SimpleSoftwareIO/simple-sms.svg?branch=master)](https://travis-ci.org/SimpleSoftwareIO/simple-sms) 5 | [![Latest Stable Version](https://poser.pugx.org/simplesoftwareio/simple-sms/v/stable.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 6 | [![Latest Unstable Version](https://poser.pugx.org/simplesoftwareio/simple-sms/v/unstable.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 7 | [![License](https://poser.pugx.org/simplesoftwareio/simple-sms/license.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 8 | [![Total Downloads](https://poser.pugx.org/simplesoftwareio/simple-sms/downloads.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 9 | 10 | ## This package is no longer actively developed for Laravel 4. 11 | 12 | * [Introduction](#docs-introduction) 13 | * [Requirements](#docs-requirements) 14 | * [Configuration](#docs-configuration) 15 | * [Call Fire Driver](#docs-call-fire-driver) 16 | * [EZTexting Driver](#docs-ez-texting-driver) 17 | * [Email Driver](#docs-e-mail-driver) 18 | * [Mozeo Driver](#docs-mozeo-driver) 19 | * [Twilio Driver](#docs-twilio-driver) 20 | * [Driver Support](#docs-driver-support) 21 | * [Usage](#docs-usage) 22 | * [Outgoing Message Enclosure](#docs-outgoing-enclosure) 23 | * [Incoming Message](#docs-incoming-message) 24 | 25 | 26 | ## Introduction 27 | Simple SMS is an easy to use package for [Laravel](http://laravel.com/) that adds the capability to send and receive SMS/MMS messages to mobile phones from your web app. It currently supports a free way to send SMS messages through E-Mail gateways provided by the wireless carriers. The package also supports four paid services; [Call Fire,](https://www.callfire.com/) [EZTexting,](https://www.eztexting.com) [Mozeo,](https://www.mozeo.com/) and [Twilio.](https://www.twilio.com) 28 | 29 | 30 | ## Requirements 31 | 32 | #### Laravel 4 33 | * PHP: >= 5.4 34 | 35 | 36 | ## Configuration 37 | 38 | #### Composer 39 | 40 | First, add the Simple SMS package to your `require` in your `composer/json` file: 41 | 42 | "require": { 43 | "simplesoftwareio/simple-sms": "~1" 44 | } 45 | 46 | Next, run the `composer update` command. This will install the package into your Laravel application. 47 | 48 | #### Service Provider 49 | 50 | Once you have added the package to your composer file, you will need to register the service provider with Laravel. 51 | 52 | Add `'SimpleSoftwareIO\SMS\SMSServiceProvider'` in your `app/config/app.php` configuration file within the `providers` array. 53 | 54 | #### Aliases 55 | 56 | Finally, register the Facade. 57 | 58 | Add `'SMS' => 'SimpleSoftwareIO\SMS\Facades\SMS'` in your `app/config/app.php` configuration file within the `aliases` array. 59 | 60 | #### API Settings 61 | 62 | You must run the following command to save your configuration files to your local app: 63 | 64 | php artisan config:publish simplesoftwareio/simple-sms 65 | 66 | This will copy the configuration files to your `app/config/simplesoftwareio/simple-sms` folder. 67 | 68 | >Failure to run the `config:publish` command will result in your configuration files being overwritten after every `composer update` command. 69 | 70 | #### Driver Configuration 71 | 72 | 73 | ###### Call Fire Driver 74 | 75 | This driver sends and receives all messages through the [Call Fire](https://www.callfire.com/) service. It is a very quick and reliable service provider that includes many features such as drip campaigns and voice services. 76 | 77 | Fill in the `config` file with the correct settings to use this driver. You can find these settings under your CallFire account and then selecting [API Access.](https://www.callfire.com/ui/manage/access) 78 | 79 | return [ 80 | 'driver' => 'callfire', 81 | 'from' => 'Not Use For Call Fire', 82 | 'callfire' => [ 83 | 'app_login' => 'Your App Login', 84 | 'app_password' => 'Your App Password' 85 | ], 86 | ]; 87 | 88 | >Note: All messages from CallFire come from the same short number (67076) 89 | 90 | 91 | ###### EZTexting 92 | 93 | This driver sends all messages through the [EZTexting](https://www.eztexting.com) service. EZTexting has many different options that have proven to be reliable and fast. 94 | 95 | Fill in the `config` file with the correct settings to enable EZTexting. 96 | 97 | return [ 98 | 'driver' => 'eztexting', 99 | 'from' => 'Not Use For EZTexting', 100 | 'eztexting' => [ 101 | 'username' => 'Your Username', 102 | 'password' => 'Your Password' 103 | ], 104 | ]; 105 | 106 | To enable `receive()` for this service, you must visit the [EZTexting settings page.](https://app.eztexting.com/keywords/index/format/apist) Enable the `Forwarding API` and `Keyword API` for the messages that you would like forwarded to your web application. 107 | 108 | >Note: All messages from EZTexting come from the same short number (313131) 109 | 110 | 111 | ###### E-mail Driver 112 | 113 | The E-Mail driver sends all messages through the configured e-mail driver for Laravel. This driver uses the wireless carrier's e-mail gateways to send SMS messages to mobile phones. The biggest benefit to using the e-mail driver is that it is completely free to use. 114 | 115 | The only setting for this driver is the `from` setting. Simply enter an email address that you would like to send messages from. 116 | 117 | return [ 118 | 'driver' => 'email', 119 | 'from' => 'example@example.com', 120 | ]; 121 | 122 | >If messages are not being sent, ensure that you are able to send E-Mail through Laravel first. 123 | 124 | The following are currently supported by using the e-mail gateway driver. 125 | 126 | | Country | Carrier | Carrier Prefix | SMS Supported | MMS Supported | Tested? | 127 | | --- | --- | --- | --- | --- | --- | 128 | | USA | AT&T | att | Yes | Yes | Yes | 129 | | USA | Air Fire Mobile | airfiremobile | Yes | No | No | 130 | | USA | Alaska Communicates | alaskacommunicates | Yes | Yes | No | 131 | | USA | Ameritech | ameritech | Yes | No | No | 132 | | USA | Boost Mobile | moostmobile | Yes | Yes | No | 133 | | USA | Clear Talk | cleartalk | Yes | No | No | 134 | | USA | Cricket | cricket | Yes | No | No | 135 | | USA | Metro PCS | metropcs | Yes | Yes | No | 136 | | USA | NexTech | nextech | Yes | No | No | 137 | | Canada | Rogers Wireless | rogerswireless | Yes | Yes | No | 138 | | USA | Unicel | unicel | Yes | Yes | No | 139 | | USA | Verizon Wireless | verizonwireless | Yes | Yes | No | 140 | | USA | Virgin Mobile | virginmobile | Yes | Yes | No | 141 | | USA | T-Mobile | tmobile | Yes | Yes | Yes | 142 | 143 | >You must know the wireless provider for the mobile phone to use this driver. 144 | 145 | >Careful! Not all wireless carriers support e-mail gateways around the world. 146 | 147 | >Some carriers slightly modify messages by adding the `from` and `to` address to the SMS message. 148 | 149 | >An untested gateway means we have not been able to confirm if the gateway works with the mobile provider. Please provide feedback if you are on one of these carriers. 150 | 151 | 152 | ###### Mozeo Driver 153 | 154 | This driver sends all messages through the [Mozeo](https://www.mozeo.com/) service. These settings can be found on your [API Settings](https://www.mozeo.com/mozeo/customer/platformdetails.php) page. 155 | 156 | return [ 157 | 'driver' => 'mozeo', 158 | 'from' => 'Not Used With Mozeo', 159 | 'mozeo' => [ 160 | 'companyKey' => 'Your Company Key', 161 | 'username' => 'Your Username', 162 | 'password' => 'Your Password' 163 | ] 164 | ]; 165 | 166 | >Note: All messages from Mozeo come from the same short number (24587) 167 | 168 | 169 | ###### Twilio Driver 170 | 171 | This driver sends messages through the [Twilio](https://www.twilio.com/sms) messaging service. It is very reliable and capable of sending messages to mobile phones worldwide. 172 | 173 | return [ 174 | 'driver' => 'twilio', 175 | 'from' => '+15555555555', //Your Twilio Number in E.164 Format. 176 | 'twilio' => [ 177 | 'account_sid' => 'Your SID', 178 | 'auth_token' => 'Your Token', 179 | 'verify' => true, //Used to check if messages are really coming from Twilio. 180 | ] 181 | ]; 182 | 183 | It is strongly recommended to have the `verify` option enabled. This setting performs an additional security check to ensure messages are coming from Twilio and not being spoofed. 184 | 185 | To enable `receive()` messages you must set up the [request URL.](https://www.twilio.com/user/account/phone-numbers/incoming) Select the number you wish to enable and then enter your request URL. This request should be a `POST` request. 186 | 187 | 188 | ##Driver Support 189 | 190 | Not all drivers support every method due to the differences in each individual API. The following table outlines what is supported for each driver. 191 | 192 | | Driver | Send | Queue | Pretend | CheckMessages | GetMessage | Receive | 193 | | --- | --- | --- | --- | --- | --- | --- | 194 | | Call Fire | Yes | Yes | Yes | Yes | Yes | No | 195 | | EZTexting | Yes | Yes | Yes | Yes | Yes | Yes | 196 | | E-Mail | Yes | Yes | Yes | No | No | No | 197 | | Mozeo | Yes | Yes | Yes | No | No | No | 198 | | Twilio | Yes | Yes | Yes | Yes | Yes | Yes | 199 | 200 | 201 | 202 | ## Usage 203 | 204 | #### Basic Usage 205 | 206 | Simple SMS operates in much of the same way as the Laravel Mail service provider. If you are familiar with this then SMS should feel like home. The most basic way to send a SMS is to use the following: 207 | 208 | //Service Providers Example 209 | SMS::send('simple-sms::welcome', $data, function($sms) { 210 | $sms->to('+15555555555'); 211 | }); 212 | 213 | //Email Driver Example 214 | SMS::send('simple-sms::welcome', $data, function($sms) { 215 | $sms->to('+15555555555', 'att'); 216 | }); 217 | 218 | The first parameter is the view file that you would like to use. The second is the data that you wish to pass to the view. The final parameter is a callback that will set all of the options on the `message` closure. 219 | 220 | #### Send 221 | 222 | The `send` method sends the SMS through the configured driver using a Laravel view file. 223 | 224 | SMS::send($view, Array $data, function($sms) { 225 | $sms->to('+15555555555'); 226 | } 227 | SMS::send('simple-sms::welcome', $data, function($sms) { 228 | $sms->to('+15555555555'); 229 | }); 230 | 231 | #### Queue 232 | 233 | The `queue` method queues a message to be sent later instead of sending the message instantly. This allows for faster respond times for the consumer by offloading uncustomary processing time. Like `Laravel's Mail` system, queue also has `queueOn,` `later,` and `laterOn` methods. 234 | 235 | SMS::queue('simple-sms::welcome', $data, function($sms) { 236 | $sms->to('+15555555555'); 237 | }); 238 | 239 | >The `queue` method will fallback to the `send` method if a queue service is not configured within `Laravel.` 240 | 241 | #### Pretend 242 | 243 | The `pretend` method will simply create a log file that states that a SMS message has been "sent." This is useful to test to see if your configuration settings are working correctly without sending actual messages. 244 | 245 | SMS::pretend('simple-sms::welcome', $data, function($sms) { 246 | $sms->to('+15555555555'); 247 | }); 248 | 249 | You may also set the `pretend` configuration option to true to have all SMS messages pretend that they were sent. 250 | 251 | `/app/config/simplesoftwareio/simple-sms/config.php` 252 | return array( 253 | 'pretend' => true, 254 | ); 255 | 256 | #### Receive 257 | 258 | Simple SMS supports push SMS messages. You must first configure this with your service provider by following the configuration settings above. 259 | 260 | Route::post('sms/receive', function() 261 | { 262 | SMS::receive(); 263 | } 264 | 265 | The receive method will return a `IncomingMessage` instance. You may request any data off of this instance like: 266 | 267 | Route::post('sms/receive', function() 268 | { 269 | $incoming = SMS::receive(); 270 | //Get the sender's number. 271 | $incoming->from(); 272 | //Get the message sent. 273 | $incoming->message(); 274 | //Get the to unique ID of the message 275 | $incoming->id(); 276 | //Get the phone number the message was sent to 277 | $incoming->to(); 278 | //Get the raw message 279 | $incoming->raw(); 280 | } 281 | 282 | The `raw` method returns all of the data that a driver supports. This can be useful to get information that only certain service providers provide. 283 | 284 | Route::post('sms/receive', function() 285 | { 286 | $incoming = SMS::receive(); 287 | //Twilio message status 288 | echo $incoming->raw()['status']; 289 | } 290 | 291 | The above would return the status of the message on the Twilio driver. 292 | 293 | >Data used from the `raw` method will not work on other service providers. Each provider has different values that are sent out with each request. 294 | 295 | #### Check Messages 296 | 297 | This method will retrieve an array of messages from the service provider. Each message within the array will be an `IncomingMessage` object. 298 | 299 | $messages = SMS::checkMessages(); 300 | foreach ($messages as $message) 301 | { 302 | //Will display the message of each retrieve message. 303 | echo $message->message(); 304 | } 305 | 306 | The `checkMessages` method supports has an `options` variable to pass some settings onto each service provider. See each service providers API to see which `options` may be passed. 307 | 308 | More information about each service provider can be found at their API docs. 309 | 310 | * [Call Fire](https://www.callfire.com/api-documentation/rest/version/1.1#!/text/QueryTexts_get_1) 311 | * [EZTexting](https://www.eztexting.com/developers/sms-api-documentation/rest) 312 | * [Mozeo](https://www.mozeo.com/mozeo/customer/Mozeo_API_OutboundSMS.pdf) 313 | * [Twilio](https://www.twilio.com/docs/api/rest/message#list-get) 314 | 315 | #### Get Message 316 | 317 | You are able to retrieve a message by it's ID with a simply call. This will return an IncomingMessage object. 318 | 319 | $message = SMS::getMessage('aMessageId'); 320 | //Prints who the message came from. 321 | echo $message->from(); 322 | 323 | 324 | ## Outgoing Message Enclosure 325 | 326 | #### Why Enclosures? 327 | 328 | We use enclosures to allow for functions such as the queue methods. Being able to easily save the message enclosures allows for much greater flexibility. 329 | 330 | #### To 331 | 332 | The `to` method adds a phone number that will have a message sent to it. 333 | 334 | //Service Providers Example 335 | SMS::send('simple-sms::welcome', $data, function($sms) { 336 | $sms->to('+15555555555'); 337 | $sms->to('+14444444444'); 338 | }); 339 | //Email Driver 340 | SMS::send('simple-sms::welcome', $data, function($sms) { 341 | $sms->to('15555555555', 'att); 342 | $sms->to('14444444444', 'verizonwireless); 343 | }); 344 | 345 | >The carrier is required for the email driver so that the correct email gateway can be used. See the table above for a list of accepted carriers. 346 | 347 | #### From 348 | 349 | The `from` method will set the address from which the message is being sent. 350 | 351 | SMS::send('simple-sms::welcome', $data, function($sms) { 352 | $sms->from('+15555555555'); 353 | }); 354 | 355 | #### attachImage 356 | 357 | The `attachImage` method will add an image to the message. This will also convert the message to a MMS because SMS does not support image attachments. 358 | 359 | //Email Driver 360 | SMS::send('simple-sms::welcome', $data, function($sms) { 361 | $sms->attachImage('/local/path/to/image.jpg'); 362 | }); 363 | //Twilio Driver 364 | SMS::send('simple-sms::welcome', $data, function($sms) { 365 | $sms->attachImage('/url/to/image.jpg'); 366 | }); 367 | 368 | >Currently only supported with the E-Mail and Twilio Driver. 369 | 370 | 371 | ## Incoming Message 372 | 373 | All incoming messages generate a `IncomingMessage` object. This makes it easy to retrieve information from them in a uniformed way across multiple service providers. 374 | 375 | #### Raw 376 | 377 | The `raw` method returns the raw data provided by a service provider. 378 | 379 | $incoming = SMS::getMessage('messageId'); 380 | echo $incoming->raw()['status']; 381 | 382 | >Each service provider has different information in which they supply in their requests. See their documentations API for information on what you can get from a `raw` request. 383 | 384 | #### From 385 | 386 | This method returns the phone number in which a message came from. 387 | 388 | $incoming = SMS::getMessage('messageId'); 389 | echo $incoming->from(); 390 | 391 | #### To 392 | 393 | The `to` method returns the phone number that a message was sent to. 394 | 395 | $incoming = SMS::getMessage('messageId'); 396 | echo $incoming->to(); 397 | 398 | #### Id 399 | 400 | This method returns the unique id of a message. 401 | 402 | $incoming = SMS::getMessage('messageId'); 403 | echo $incoming->id(); 404 | 405 | #### Message 406 | 407 | And the best for last; this method returns the actual message of a SMS. 408 | 409 | $incoming = SMS::getMessage('messageId'); 410 | echo $incoming->message(); 411 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Simple SMS 2 | ========== 3 | 4 | [![Build Status](https://travis-ci.org/SimpleSoftwareIO/simple-sms.svg?branch=master)](https://travis-ci.org/SimpleSoftwareIO/simple-sms) 5 | [![Latest Stable Version](https://poser.pugx.org/simplesoftwareio/simple-sms/v/stable.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 6 | [![Latest Unstable Version](https://poser.pugx.org/simplesoftwareio/simple-sms/v/unstable.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 7 | [![License](https://poser.pugx.org/simplesoftwareio/simple-sms/license.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 8 | [![Total Downloads](https://poser.pugx.org/simplesoftwareio/simple-sms/downloads.svg)](https://packagist.org/packages/simplesoftwareio/simple-sms) 9 | 10 | * [Introduction](#docs-introduction) 11 | * [Requirements](#docs-requirements) 12 | * [Configuration](#docs-configuration) 13 | * [Call Fire Driver](#docs-call-fire-driver) 14 | * [E-mail Driver](#docs-e-mail-driver) 15 | * [EZTexting Driver](#docs-ez-texting-driver) 16 | * [LabsMobile Driver](#docs-labsmobile-driver) 17 | * [Mozeo Driver](#docs-mozeo-driver) 18 | * [Nexmo Driver](#docs-nexmo-driver) 19 | * [Twilio Driver](#docs-twilio-driver) 20 | * [Infobip Driver](#docs-infobip-driver) 21 | * [Driver Support](#docs-driver-support) 22 | * [Usage](#docs-usage) 23 | * [Outgoing Message Enclosure](#docs-outgoing-enclosure) 24 | * [Incoming Message](#docs-incoming-message) 25 | 26 | 27 | ## Introduction 28 | Simple SMS is an easy to use package for [Laravel](http://laravel.com/) that adds the capability to send and receive SMS/MMS messages to mobile phones from your web app. It currently supports a free way to send SMS messages through E-Mail gateways provided by the wireless carriers. The package also supports 6 paid services, [Call Fire,](https://www.callfire.com/) [EZTexting,](https://www.eztexting.com) [LabsMobile,](http://www.labsmobile.com) [Mozeo,](https://www.mozeo.com/) [Nexmo,](https://www.nexmo.com/) and [Twilio.](https://www.twilio.com) 29 | 30 | 31 | ## Requirements 32 | 33 | #### Laravel 5 34 | * PHP: >= 5.5 35 | * Guzzle >= 6.0 36 | 37 | 38 | ## Configuration 39 | 40 | #### Laravel 4 41 | 42 | Please read the Laravel 4 [documentation.](https://github.com/SimpleSoftwareIO/simple-sms/blob/master/docs/laravel4.md) 43 | 44 | #### Composer 45 | 46 | First, add the Simple SMS package to your `require` in your `composer/json` file: 47 | 48 | `composer require mrabbani/laravel_infobip` 49 | 50 | Next, run the `composer update` command. This will install the package into your Laravel application. 51 | 52 | #### Service Provider 53 | 54 | Once you have added the package to your composer file, you will need to register the service provider with Laravel. 55 | 56 | Add `SimpleSoftwareIO\SMS\SMSServiceProvider::class` in your `config/app.php` configuration file within the `providers` array. 57 | 58 | #### Aliases 59 | 60 | Finally, register the Facade. 61 | 62 | Add `'SMS' => SimpleSoftwareIO\SMS\Facades\SMS::class` in your `config/app.php` configuration file within the `aliases` array. 63 | 64 | #### API Settings 65 | 66 | You must run the following command to save your configuration files to your local app: 67 | 68 | php artisan vendor:publish 69 | 70 | This will copy the configuration files to your `config` folder. 71 | 72 | >Failure to run the `vendor:publish` command will result in your configuration files being overwritten after every `composer update` command. 73 | 74 | #### Driver Configuration 75 | 76 | 77 | ###### Call Fire Driver 78 | 79 | This driver sends and receives all messages through the [Call Fire](https://www.callfire.com/) service. It is a very quick and reliable service provider that includes many features such as drip campaigns and voice services. 80 | 81 | Fill in the `config` file with the correct settings to use this driver. You can find these settings under your CallFire account and then selecting [API Access.](https://www.callfire.com/ui/manage/access) 82 | 83 | return [ 84 | 'driver' => 'callfire', 85 | 'from' => 'Not Use For Call Fire', 86 | 'callfire' => [ 87 | 'app_login' => 'Your App Login', 88 | 'app_password' => 'Your App Password' 89 | ], 90 | ]; 91 | 92 | >Note: All messages from CallFire come from the same short number (67076) 93 | 94 | 95 | ###### E-mail Driver 96 | 97 | The E-Mail driver sends all messages through the configured e-mail driver for Laravel. This driver uses the wireless carrier's e-mail gateways to send SMS messages to mobile phones. The biggest benefit to using the e-mail driver is that it is completely free to use. 98 | 99 | The only setting for this driver is the `from` setting. Simply enter an email address that you would like to send messages from. 100 | 101 | return [ 102 | 'driver' => 'email', 103 | 'from' => 'example@example.com', 104 | ]; 105 | 106 | >If messages are not being sent, ensure that you are able to send E-Mail through Laravel first. 107 | 108 | The following are currently supported by using the e-mail gateway driver. 109 | 110 | | Country | Carrier | Carrier Prefix | SMS Supported | MMS Supported | Tested? | 111 | | --- | --- | --- | --- | --- | --- | 112 | | USA | AT&T | att | Yes | Yes | Yes | 113 | | USA | Air Fire Mobile | airfiremobile | Yes | No | No | 114 | | USA | Alaska Communicates | alaskacommunicates | Yes | Yes | No | 115 | | USA | Ameritech | ameritech | Yes | No | No | 116 | | USA | Boost Mobile | moostmobile | Yes | Yes | No | 117 | | USA | Clear Talk | cleartalk | Yes | No | No | 118 | | USA | Cricket | cricket | Yes | No | No | 119 | | USA | Metro PCS | metropcs | Yes | Yes | No | 120 | | USA | NexTech | nextech | Yes | No | No | 121 | | Canada | Rogers Wireless | rogerswireless | Yes | Yes | No | 122 | | USA | Unicel | unicel | Yes | Yes | No | 123 | | USA | Verizon Wireless | verizonwireless | Yes | Yes | No | 124 | | USA | Virgin Mobile | virginmobile | Yes | Yes | No | 125 | | USA | T-Mobile | tmobile | Yes | Yes | Yes | 126 | 127 | >You must know the wireless provider for the mobile phone to use this driver. 128 | 129 | >Careful! Not all wireless carriers support e-mail gateways around the world. 130 | 131 | >Some carriers slightly modify messages by adding the `from` and `to` address to the SMS message. 132 | 133 | >An untested gateway means we have not been able to confirm if the gateway works with the mobile provider. Please provide feedback if you are on one of these carriers. 134 | 135 | 136 | ###### EZTexting 137 | 138 | This driver sends all messages through the [EZTexting](https://www.eztexting.com) service. EZTexting has many different options that have proven to be reliable and fast. 139 | 140 | Fill in the `config` file with the correct settings to enable EZTexting. 141 | 142 | return [ 143 | 'driver' => 'eztexting', 144 | 'from' => 'Not Use For EZTexting', 145 | 'eztexting' => [ 146 | 'username' => 'Your Username', 147 | 'password' => 'Your Password' 148 | ], 149 | ]; 150 | 151 | To enable `receive()` for this service, you must visit the [EZTexting settings page.](https://app.eztexting.com/keywords/index/format/apist) Enable the `Forwarding API` and `Keyword API` for the messages that you would like forwarded to your web application. 152 | 153 | >Note: All messages from EZTexting come from the same short number (313131) 154 | 155 | 156 | ###### LabsMobile Driver 157 | 158 | This driver sends all messages through the [LabsMobile](http://www.labsmobile.com/) service. These settings can be found on your [API Settings](https://www.labsmobile.com/es/login) page. 159 | 160 | return [ 161 | 'driver' => 'labsmobile', 162 | 'from' => 'Sender', 163 | 'labsmobile' => [ 164 | 'client' => 'Your Client Key', 165 | 'username' => 'Your Username', 166 | 'password' => 'Your Password', 167 | 'test' => '1 for simulate mode; 0 for real sendings' 168 | ] 169 | ]; 170 | 171 | 172 | ###### Mozeo Driver 173 | 174 | This driver sends all messages through the [Mozeo](https://www.mozeo.com/) service. These settings can be found on your [API Settings](https://www.mozeo.com/mozeo/customer/platformdetails.php) page. 175 | 176 | return [ 177 | 'driver' => 'mozeo', 178 | 'from' => 'Not Used With Mozeo', 179 | 'mozeo' => [ 180 | 'companyKey' => 'Your Company Key', 181 | 'username' => 'Your Username', 182 | 'password' => 'Your Password' 183 | ] 184 | ]; 185 | 186 | >Note: All messages from Mozeo come from the same short number (24587) 187 | 188 | 189 | ###### Nexmo Driver 190 | 191 | This driver sends messages through the [Nexmo](https://www.nexmo.com/product/messaging/) messaging service. It is very reliable and capable of sending messages to mobile phones worldwide. 192 | 193 | return [ 194 | 'driver' => 'nexmo', 195 | 'from' => 'Company Name', 196 | 'nexmo' => [ 197 | 'key' => 'Your Nexmo API Key', 198 | 'secret' => 'Your Nexmo API Secret' 199 | ] 200 | ]; 201 | 202 | To enable `receive()` messages you must set up the [request URL.](https://docs.nexmo.com/index.php/sms-api/handle-inbound-message) 203 | 204 | 205 | ###### Twilio Driver 206 | 207 | This driver sends messages through the [Twilio](https://www.twilio.com/sms) messaging service. It is very reliable and capable of sending messages to mobile phones worldwide. 208 | 209 | return [ 210 | 'driver' => 'twilio', 211 | 'from' => '+15555555555', //Your Twilio Number in E.164 Format. 212 | 'twilio' => [ 213 | 'account_sid' => 'Your SID', 214 | 'auth_token' => 'Your Token', 215 | 'verify' => true, //Used to check if messages are really coming from Twilio. 216 | ] 217 | ]; 218 | 219 | It is strongly recommended to have the `verify` option enabled. This setting performs an additional security check to ensure messages are coming from Twilio and not being spoofed. 220 | 221 | To enable `receive()` messages you must set up the [request URL.](https://www.twilio.com/user/account/phone-numbers/incoming) Select the number you wish to enable and then enter your request URL. This request should be a `POST` request. 222 | 223 | 224 | ###### Infobip Driver 225 | 226 | This driver sends messages through the [Infobib](http://www.infobip.com/en) messaging service. It is very reliable and capable of sending messages to mobile phones worldwide. 227 | 228 | return [ 229 | 'driver' => 'infobip', 230 | 'from' => 'InfoSMS', 231 | 'infobip'=> [ 232 | 'username' => 'username of infobip', 233 | 'password' => 'password of infobip' 234 | ] 235 | ]; 236 | For more information see [Infobip API Developer Hub](https://dev.infobip.com/) 237 | 238 | 239 | ##Driver Support 240 | 241 | Not all drivers support every method due to the differences in each individual API. The following table outlines what is supported for each driver. 242 | 243 | | Driver | Send | Queue | Pretend | CheckMessages | GetMessage | Receive | 244 | | --- | --- | --- | --- | --- | --- | --- | 245 | | Call Fire | Yes | Yes | Yes | Yes | Yes | No | 246 | | E-Mail | Yes | Yes | Yes | No | No | No | 247 | | EZTexting | Yes | Yes | Yes | Yes | Yes | Yes | 248 | | LabsMobile | Yes | Yes | Yes | No | No | No | 249 | | Mozeo | Yes | Yes | Yes | No | No | No | 250 | | Nexmo | Yes | Yes | Yes | Yes | Yes | Yes | 251 | | Twilio | Yes | Yes | Yes | Yes | Yes | Yes | 252 | 253 | 254 | ## Usage 255 | 256 | #### Basic Usage 257 | 258 | Simple SMS operates in much of the same way as the Laravel Mail service provider. If you are familiar with this then SMS should feel like home. The most basic way to send a SMS is to use the following: 259 | 260 | //Service Providers Example 261 | SMS::send('simple-sms::welcome', $data, function($sms) { 262 | $sms->to('+15555555555'); 263 | }); 264 | 265 | //Email Driver Example 266 | SMS::send('simple-sms::welcome', $data, function($sms) { 267 | $sms->to('+15555555555', 'att'); 268 | }); 269 | 270 | The first parameter is the view file that you would like to use. The second is the data that you wish to pass to the view. The final parameter is a callback that will set all of the options on the `message` closure. 271 | 272 | #### Send 273 | 274 | The `send` method sends the SMS through the configured driver using a Laravel view file. 275 | 276 | SMS::send($view, Array $data, function($sms) { 277 | $sms->to('+15555555555'); 278 | } 279 | SMS::send('simple-sms::welcome', $data, function($sms) { 280 | $sms->to('+15555555555'); 281 | }); 282 | 283 | It is possible to send a simple message without creating views by passing a string instead of a view. 284 | 285 | SMS::send($message, [], function($sms) { 286 | $sms->to('+15555555555'); 287 | } 288 | SMS::send('This is my message', [], function($sms) { 289 | $sms->to('+15555555555'); 290 | }); 291 | 292 | #### Driver 293 | 294 | The `driver` method will switch the provider during runtime. 295 | 296 | //Will send through default provider set in the config file. 297 | SMS::queue('simple-sms::welcome', $data, function($sms) { 298 | $sms->to('+15555555555'); 299 | }); 300 | 301 | SMS::driver('twilio'); 302 | 303 | //Will send through Twilio 304 | SMS::queue('simple-sms::welcome', $data, function($sms) { 305 | $sms->to('+15555555555'); 306 | }); 307 | 308 | #### Queue 309 | 310 | The `queue` method queues a message to be sent later instead of sending the message instantly. This allows for faster respond times for the consumer by offloading uncustomary processing time. Like `Laravel's Mail` system, queue also has `queueOn,` `later,` and `laterOn` methods. 311 | 312 | SMS::queue('simple-sms::welcome', $data, function($sms) { 313 | $sms->to('+15555555555'); 314 | }); 315 | 316 | >The `queue` method will fallback to the `send` method if a queue service is not configured within `Laravel.` 317 | 318 | #### Pretend 319 | 320 | The `pretend` method will simply create a log file that states that a SMS message has been "sent." This is useful to test to see if your configuration settings are working correctly without sending actual messages. 321 | 322 | SMS::pretend('simple-sms::welcome', $data, function($sms) { 323 | $sms->to('+15555555555'); 324 | }); 325 | 326 | You may also set the `pretend` configuration option to true to have all SMS messages pretend that they were sent. 327 | 328 | `/app/config/simplesoftwareio/simple-sms/config.php` 329 | return array( 330 | 'pretend' => true, 331 | ); 332 | 333 | #### Receive 334 | 335 | Simple SMS supports push SMS messages. You must first configure this with your service provider by following the configuration settings above. 336 | 337 | Route::post('sms/receive', function() 338 | { 339 | SMS::receive(); 340 | } 341 | 342 | The receive method will return a `IncomingMessage` instance. You may request any data off of this instance like: 343 | 344 | Route::post('sms/receive', function() 345 | { 346 | $incoming = SMS::receive(); 347 | //Get the sender's number. 348 | $incoming->from(); 349 | //Get the message sent. 350 | $incoming->message(); 351 | //Get the to unique ID of the message 352 | $incoming->id(); 353 | //Get the phone number the message was sent to 354 | $incoming->to(); 355 | //Get the raw message 356 | $incoming->raw(); 357 | } 358 | 359 | The `raw` method returns all of the data that a driver supports. This can be useful to get information that only certain service providers provide. 360 | 361 | Route::post('sms/receive', function() 362 | { 363 | $incoming = SMS::receive(); 364 | //Twilio message status 365 | echo $incoming->raw()['status']; 366 | } 367 | 368 | The above would return the status of the message on the Twilio driver. 369 | 370 | >Data used from the `raw` method will not work on other service providers. Each provider has different values that are sent out with each request. 371 | 372 | #### Check Messages 373 | 374 | This method will retrieve an array of messages from the service provider. Each message within the array will be an `IncomingMessage` object. 375 | 376 | $messages = SMS::checkMessages(); 377 | foreach ($messages as $message) 378 | { 379 | //Will display the message of each retrieve message. 380 | echo $message->message(); 381 | } 382 | 383 | The `checkMessages` method supports has an `options` variable to pass some settings onto each service provider. See each service providers API to see which `options` may be passed. 384 | 385 | More information about each service provider can be found at their API docs. 386 | 387 | * [Call Fire](https://www.callfire.com/api-documentation/rest/version/1.1#!/text/QueryTexts_get_1) 388 | * [EZTexting](https://www.eztexting.com/developers/sms-api-documentation/rest) 389 | * [LabsMobile](http://www.labsmobile.com/en/api-sms) 390 | * [Mozeo](https://www.mozeo.com/mozeo/customer/Mozeo_API_OutboundSMS.pdf) 391 | * [Nexmo](https://docs.nexmo.com/index.php/developer-api/search-message) 392 | * [Twilio](https://www.twilio.com/docs/api/rest/message#list-get) 393 | * [Infobip](https://dev.infobip.com/) 394 | 395 | #### Get Message 396 | 397 | You are able to retrieve a message by it's ID with a simply call. This will return an IncomingMessage object. 398 | 399 | $message = SMS::getMessage('aMessageId'); 400 | //Prints who the message came from. 401 | echo $message->from(); 402 | 403 | 404 | ## Outgoing Message Enclosure 405 | 406 | #### Why Enclosures? 407 | 408 | We use enclosures to allow for functions such as the queue methods. Being able to easily save the message enclosures allows for much greater flexibility. 409 | 410 | #### To 411 | 412 | The `to` method adds a phone number that will have a message sent to it. 413 | 414 | //Service Providers Example 415 | SMS::send('simple-sms::welcome', $data, function($sms) { 416 | $sms->to('+15555555555'); 417 | $sms->to('+14444444444'); 418 | }); 419 | //Email Driver 420 | SMS::send('simple-sms::welcome', $data, function($sms) { 421 | $sms->to('15555555555', 'att); 422 | $sms->to('14444444444', 'verizonwireless); 423 | }); 424 | 425 | >The carrier is required for the email driver so that the correct email gateway can be used. See the table above for a list of accepted carriers. 426 | 427 | #### From 428 | 429 | The `from` method will set the address from which the message is being sent. 430 | 431 | SMS::send('simple-sms::welcome', $data, function($sms) { 432 | $sms->from('+15555555555'); 433 | }); 434 | 435 | #### attachImage 436 | 437 | The `attachImage` method will add an image to the message. This will also convert the message to a MMS because SMS does not support image attachments. 438 | 439 | //Email Driver 440 | SMS::send('simple-sms::welcome', $data, function($sms) { 441 | $sms->attachImage('/local/path/to/image.jpg'); 442 | }); 443 | //Twilio Driver 444 | SMS::send('simple-sms::welcome', $data, function($sms) { 445 | $sms->attachImage('/url/to/image.jpg'); 446 | }); 447 | 448 | >Currently only supported with the E-Mail and Twilio Driver. 449 | 450 | 451 | ## Incoming Message 452 | 453 | All incoming messages generate a `IncomingMessage` object. This makes it easy to retrieve information from them in a uniformed way across multiple service providers. 454 | 455 | #### Raw 456 | 457 | The `raw` method returns the raw data provided by a service provider. 458 | 459 | $incoming = SMS::getMessage('messageId'); 460 | echo $incoming->raw()['status']; 461 | 462 | >Each service provider has different information in which they supply in their requests. See their documentations API for information on what you can get from a `raw` request. 463 | 464 | #### From 465 | 466 | This method returns the phone number in which a message came from. 467 | 468 | $incoming = SMS::getMessage('messageId'); 469 | echo $incoming->from(); 470 | 471 | #### To 472 | 473 | The `to` method returns the phone number that a message was sent to. 474 | 475 | $incoming = SMS::getMessage('messageId'); 476 | echo $incoming->to(); 477 | 478 | #### Id 479 | 480 | This method returns the unique id of a message. 481 | 482 | $incoming = SMS::getMessage('messageId'); 483 | echo $incoming->id(); 484 | 485 | #### Message 486 | 487 | And the best for last; this method returns the actual message of a SMS. 488 | 489 | $incoming = SMS::getMessage('messageId'); 490 | echo $incoming->message(); 491 | --------------------------------------------------------------------------------