Posted on Leave a comment

Writing Your Own Personal Cloud Music Player – Part 1

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Cloud Based Music Storage

Wouldn’t it be great if you had your own cloud based music player that played all of your music from your server? It’s surprisingly simple to get a basic version of that up with Lumen and Ionic, which I will now show you.
Getting Started
As before I am going to assume you have the environment set up to being development, if not take a moment and read this post. Start with creating a new project


lumen new MusicStorage

Next we need to add a dependency for CORS, if you have followed any of my previous posts this will look familiar


composer require "palanik/lumen-cors:dev-master"

This app will need to provide CORS on all requests so we need to register a global middleware, open up bootstrap/app.php and in the Register Middleware section uncomment the $app->middleware block and make it look like this:


$app->middleware([
// // IlluminateCookieMiddlewareEncryptCookies::class,
// // IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
// // IlluminateSessionMiddlewareStartSession::class,
// // IlluminateViewMiddlewareShareErrorsFromSession::class,
// // LaravelLumenHttpMiddlewareVerifyCsrfToken::class,
palaniklumenMiddlewareLumenCors::class,]);

Since we are here anyway, might as well configure some things. Uncomment these two lines Dotenv::load(DIR.’/../’);
and $app->withFacades(); this will allow us to use the .env file to set app variables and allow us to use some useful Facades that we are definitely going to need.
Migrations
Luckily this app only has one migration, and that is for a files table that only holds id, name, and timestamps. Nice and smooth like. issue this command in your terminal


php artisan make:migration add_files_table --create=files

now open up your newly created migration and paste in the following code:


public function up() {
Schema::create('files', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('files');
}
}

  • Don’t forget to run your migrations with the command php artisan migrate:install
    Controllers

Like our migration we only have one controller, add a new file in your app/Http/Controllers folder called FileController.php and add the following contents


<?php namespace AppHttpControllers;
use LaravelLumenRoutingController as BaseController;
use IlluminateSupportFacadesStorage;
use IlluminateSupportFacadesFile;
use DB;
use Request;
class FileController extends BaseController { public function saveFile() { $file = Request::file('file'); $name = $file->getClientOriginalName();<br ?--> $name = str_replace(' ', '_', $name);
Storage::put('music/'.$name, file_get_contents($file->getRealPath()));
DB::table('files')->insert(
['name' => $name ]
);
return response()->json('success');
}
public function deleteFile($name)
{
Storage::delete('music/'.$name);
return response()->json('success');
}
public function getFileList(){
$files = Storage::files('music');
$response = [];
foreach($files as $file){
$file = str_replace('music/', '', $file);
array_push($response,[
'file' =>$file
]);
}
return response()->json($response);
}
public function viewFile($name){
$name = 'music/'.$name;
return response()->make(Storage::get($name), 200, [
'Content-Type' => Storage::mimeType($name),
'Content-Disposition' => 'inline; '.$name,
]);
}
}

The methods should be pretty self-explanatory. Let’s map these to some routes, open up app/Http/routes.php and copy:


<?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It is a breeze. Simply tell Lumen the URIs it should respond to | and give it the Closure to call when that URI is requested. | */ $app->get('/', 'FileController@getFileList');<br ?--> $app->get('{name}', 'FileController@viewFile');
$app->post('add','FileController@saveFile');
$app->get('delete/{name}', 'FileController@deleteFile');

Your backend is complete, soon I will upload part 2 – The Ionic App. Stay tuned!

Posted on 2 Comments

Creating A POS System With Lumen and Ionic – Part 2

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Before We Begin

Have you already have the Lumen back end micro service up and running? If not head over to part 1 and write your own implementation. Alternatively you can clone the repository from GitHub. Now with that working, let us begin!

Ionic

As with part 1 I will assume you already have the environment set up to begin Ionic development. If you don’t, please head over and read my previous Ionic tutorial. Otherwise let’s create a new project

ionic start ParkerPay

cd into the new application and install the dependencies

bower install ngCordova  

cordova plugin add https://github.com/Paldom/SpinnerDialog.git


cordova plugin add cordova-plugin-dialogs

This will install ngCordova which will allow us to access native APIs via plugins, the two plugins are for accessing native spinner dialogs and alert dialogs. Now let’s edit the application logic, head over to www/js/app.js and paste the following code:


angular.module('parker-pay', ['ionic','ngCordova'])


.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})


.controller('HomeCtrl', function($scope,$http,$cordovaSpinnerDialog,$cordovaDialogs){
$scope.charge = {};
$scope.createToken = function(){
$cordovaSpinnerDialog.show("Processing Payment","Please wait....", true);
Stripe.setPublishableKey('STRIPE PUBLISHABLE KEY');
Stripe.card.createToken({
number: $scope.charge.number,
cvc: $scope.charge.cvc,
exp_month: $scope.charge.exp_month,
exp_year: $scope.charge.exp_year
}, $scope.stripeResponseHandler);
};


$scope.stripeResponseHandler = function(status, response){
if (response.error) {
// Show the errors on the form
$cordovaSpinnerDialog.hide();
$cordovaDialogs.alert('There was an error', 'Alert', 'OK')
.then(function() {
// callback success
});


} else {
// response contains id and card, which contains additional card details
var token = response.id;
//console.log()
// Insert the token into the form so it gets submitted to the server
var data = {token:token,amount:$scope.charge.amount,description:$scope.charge.description}
// and submit


$http.post('http://payment.jyroneparker.com/charge',data).success(function(dta){
console.log(dta);
$cordovaSpinnerDialog.hide();
// beep 1 time
$cordovaDialogs.beep(1);
$cordovaDialogs.alert('Payment was a success.', 'Alert', 'OK')
.then(function() {
// callback success
});

}).error(function(dta){
console.log(dta);
$cordovaSpinnerDialog.hide();
alert('There was an error.');


$cordovaDialogs.alert('There was an error', 'Alert', 'OK')
.then(function() {
// callback success
});


//$cordovaSpinnerDialog.hide();
});
}
}
})

Be sure to put your Stripe key in. Last thing to do programmatically speaking, is to edit the index.html file. Paste the following code:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>

<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->


<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>


<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>


<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="parker-pay" ng-controller="HomeCtrl">


<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Parker Pay</h1>
</ion-header-bar>
<ion-content
<div class="list list-inset">
<label class="icon icon-left ion-pricetag item item-input">
<input ng-model="charge.amount" type="text" placeholder=" Amount">
</label>
<label class="icon icon-left ion-card item item-input">
<input ng-model="charge.number" type="text" placeholder=" Card Number">
</label>
<label class="ion-calendar icon icon-left item item-input">
<input ng-model="charge.exp_month" type="text" placeholder=" Exp. Month">
</label>
<label class="icon icon-left ion-calendar item item-input">
<input ng-model="charge.exp_year" type="text" placeholder=" Exp Year">
</label>
<label class="icon icon-left ion-card item item-input">
<input ng-model="charge.cvc" type="text" placeholder=" CVC">
</label>
<label class="icon icon-left ion-edit item item-input">
<input ng-model="charge.description" type="text" placeholder=" Description">
</label>
</div>
<div class="row">
<button ng-click="createToken()" class="col-offset-33  icon icon-left ion-social-usd button button-positive">
Charge
</button>
</div>
</ion-content>
</ion-pane>
</body>
</html>

Next add your preferred platform by running

ionic platform add <PLATFORM> 

, connect your device and run ionic run <PLATFORM> , THAT’S IT YOU ARE NOW TAKING PAYMENTS!! See how easy that was? You are on your way to being an Artisan! Be sure to check the code out on GitHub

Posted on Leave a comment

Creating A POS System With Lumen and Ionic – Part 1

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Your Very Own POS

I use Stripe all the time in my web and mobile applications to accept payments. It’s great I love it, I don’t have to worry about PCI compliance and they have a kick ass API. In this new programming series I will be showing you how to create your own full stack solution for accepting payments with Stripe. In order to accomplish this it requires a Lumen back end micro service, and an Ionic mobile app, ready? Good! LET’S GET STARTED!!
 

Part 1 – Lumen Back End

If you haven’t read my past Lumen tutorial take the time to read it….or not completely up to you, in either case I am assuming you have the environment to run the following command:

 lumen new StripeServer

before we do anything else, we need to install our dependencies. Kindly input the following commands into your terminal:

composer require stripe/stripe-php palanik/lumen-cors illuminate/mail guzzlehttp/guzzle

The first dependency is for Stripe (So we can take payments), the other is for CORS (we will need this for our mobile app consumption), the last two are for email alerts.
Next we need to create controllers to handle our requests create two controllers: ChargeController.php and WebHookController.php. Inside of ChargeController.php paste the following code:


<?php

namespace AppHttpControllers;

 

use IlluminateHttpRequest;


class ChargeController extends Controller
{
public function charge(Request $request){
StripeStripe::setApiKey(env('STRIPE_KEY'));
StripeCharge::create(array(
"amount" => $request->input('amount'),
"currency" => "usd",
"source" => $request->token,
"description" => $request->input('description')
));
return response()->json(['success'=>'true']);
}}

This controller only has one method. See? It’s not that scary. We are making use of the Stripe Charge API to create a credit card charge, then returning a json response letting us know everything is ok. Now let’s move on to the WebHookController :


<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use IlluminateSupportFacadesMail;
class WebHookController extends Controller
{
public function handleStripe(Request $request){
switch($request->type){
case 'charge.succeeded':
$number = $request->data['object']['amount'] / 100;
Mail::raw('Charge succeeded in amount of $'. money_format('%i', $number) . "n",
function($msg) {
$msg->to([env('PHONE_ADDRESS')]);
$msg->from([[env('MAIL_FROM_ADDRESS')]);
});
break;
case 'charge.failed':
$number = $request->data['object']['amount'] / 100;
Mail::raw('Charge failed in amount of $'. money_format('%i', $number) . "n",
function($msg) {
$msg->to([[env('PHONE_ADDRESS')]);
$msg->from([[env('MAIL_FROM_ADDRESS')]);
});
break;
}
}
}

Here we are sending text message alerts when we get pinged by one of Stripe’s webhook events. Here we are only looking for 2 Stripe events but feel free to add whatever you want. For a more in depth tutorial on sending text messages with Laravel click here. Lastly we need edit the routes file, open routes.php and add the following routes:


$app->post('stripe', 'WebHookController@handleStripe');
$app-> post('charge',['middleware' => 'cors', 'uses' => 'ChargeController@charge']);

Back end is finished, just be sure to edit your .env file. You can view the source code here.

Posted on 1 Comment

Creating A Todo App With SMS Alerts In Laravel 5 – Part 3

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Delayed Responses

So now we have Facebook integration in our Laravel app, but there is one problem, the Laravel app sends the SMS alert right away. We want to give the users the option to select when the text message goes out. In order to do this we will implement Laravel queues to achieve this task. We will make a new job and move the TodoCreatedListener code into that new job. Let’s get started.
Enter this command into the terminal to create a new job


php artisan make:job SendText --queued

this scaffolds a new job class for you, open that class and copy the following code


 <? php
namespace AppJobs;
use AppJobsJob;
use Mail;
use IlluminateQueueSerializesModels;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsBusSelfHandling;
use IlluminateContractsQueueShouldQueue;
class SendText extends Job implements SelfHandling, ShouldQueue {
use InteractsWithQueue, SerializesModels;
 public $text;
public $phone;
/** * Create a new job instance.
 * * @return void */
public function __construct($text,$phone) {
//
$this->text = $text;
 $this->phone = $phone;
 }
/**
 * Execute the job.
 *
 * @return void
 */
 public function handle()
 {
Mail::raw($this->text, function ($message){
 $message->from(env('MAIL_USERNAME','john.smith@email.com'));
 $message->to($this->phone);
 //var_dump($this->phone); exit();
 });
 }
 }

Notice it’s the code from the TodoCreatedListener with a minor changes. Now you can go to that class and change the code to this:

<? php namespace AppListeners;
use Mail;
use AppEventsTodoCreatedEvent;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchesJobs;
use AppJobsSendText;
 class TodoCreatedListener implements ShouldQueue {
use DispatchesJobs;
/** * Create the event listener.
* * @return void */
public function __construct() { // }
/** * Handle the event.
* * @param TodoCreatedEvent $event
* @return void */
public function handle(TodoCreatedEvent $event) {
//set todo
$text = $event->todo->content;
$job = (new SendText($text,$event->phone))->delay($event->timer);
$this->dispatch($job);
}
 }

Notice the delay($event->timer)? That allows us to programmatically delay the job until the user’s desired time. Head over to the TodoController class and modify the store method to look like this:


/**
 * Store a newly created resource in storage.
 *
 * @param IlluminateHttpRequest $request
 * @return IlluminateHttpResponse
 */
 public function store(Request $request)
 {
 //create Todo Model and
 $todo = new Todo;
 if ($request->session()->has('user')) {
 $user = $request->session()->get('user');
 //var_dump($user); exit();
 $todo->facebook_id = $user[0]['id'];
 //var_dump($todo->facebook_id);exit();
 }
 $todo->content = $request->content;
 $todo->save();
 //var_dump($todo);exit();
 //launch event
$phone = $request->phone . $request->gateway;
 //dd($phone);
 $timer = $request->timer;
 event(new TodoCreatedEvent($todo,$phone,$timer));
 //(new SendText($todo->content,$phone))->delay(30);
 return redirect('/');
 }

That takes care of the backend, don’t forget to run a queue listener to handle the jobs. Now head over to the welcome view and in the forms add these fields (or whatever times you want):
Now
1 Minute
5 minutes
10 minutes
15 Minutes
30 Minutes
1 Hour
12 Hours
24 Hours
To see the live version of the Laravel click here, and don’t forget to check the Github.

Posted on Leave a comment

Create A Real-Time Chat App With Ionic

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Ionic

I figured Ionic would be a great choice for creating the mobile chat app. This chat app is dirt simple:

  1. Open up a websocket connection to the Lumen service and listen for messages
  2. Post messages to Lumen Service

Follow along, I won’t be adding any target platforms, just testing in browser. However if you want to port this that another platform just follow this guide. Let’s start! If you don’t already have the software installed type in this command npm -g install cordova ionic you may have to run this command as sudo. Afterwards cd into an empty directory and run this command

ionic start messenger-mobile blank

. It will go through the process of creating a new Ionic application, when complete cd into your new app.

Dependencies

Now we need to install our dependencies first off we need to install the socket.io-client to communicate with our real-time chat server. This is available via npm, type in this command

npm install socket.io-client

and copy the folder

node_modules/socket.io-client

to the lib folder (that’s where everything else is ionic related). Next type in this command

ionic plugin add cordova-plugin-whitelist

, this in needed because we have to access remote resources, and need to whitelist them.

Whitelisting

Open up the config.xml file at the root of your application and add this line

<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">

This allows us to go to any remote resource. Now we won’t get any errors trying to access our websocket. Now lets create our WebSocket factory.
 

WebSocket Factory

Create a seperate file in your www/js folder called services.js. Inside put the following code:


angular.module('services', [])
.factory('WebSocket', function($http) {
// Open a WebSocket connection
var dataStream = io('http://messenger.app:6001');
console.log(dataStream);

var messages = [];
dataStream.on('message',function(data) {
messages.push(data.message);
console.log(messages);
});
var methods = {
messages: messages,
send: function(message) {
$http.post('http://messenger.app/message',{ message:message}).success(function(data){
///messages.push(data);
//console.log(messages);
});
}
};

return methods;
});

Change http://messenger.app to the IP address of your microservice. Right now this code would break because we haven’t included the io dependecy but we will get to that.

App.js

Open www/js/app.js this is our main JS file, we are going to include our services file in here and access the WebSocket factory. Copy this code:

// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('real-time-messaging', ['ionic','services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('HomeController',function($scope,WebSocket){
$scope.socket = WebSocket;
console.log($scope.socket);
$scope.messageModel = {};
$scope.sendMessage = function(){
console.log('SEND MESSAGE PUSHED!');
console.log('Message Sent ' + $scope.messageModel.message);
$scope.socket.send($scope.messageModel.message);
console.log($scope.socket.messages);
};
});

The code is pretty self explanatory, we have a single function in our HomeController that sends a message to the microservice. We have all the real time logic encapsulated in the WebSocket factory, so we are complete here!
 

Index.html

Lastly we need to modify the index.html. For simplicity sake this page only has a list to hold messages and a form to post a message. Copy the following code:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<script src="lib/socket.io-client/socket.io.js"></script>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">

<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>

<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>

<!-- your app's js -->
<script src="js/app.js"></script>
<!-- your app's js -->
<script src="js/services.js"></script>

</head>
<body ng-app="real-time-messaging" ng-controller="HomeController">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Real Time Messaging</h1>
</ion-header-bar>
<ion-content>
<textarea ng-model="messageModel.message" placeholder="Enter Message"></textarea>
<br>
<button ng-click="sendMessage()" class="icon icon-left ion-paper-airplane button button-positive">
Send Message
</button>

<ion-list>
<ion-item ng-repeat="message in socket.messages track by $index">
Messages:  {{message}}
</ion-item>
</ion-list>
</ion-content>
</ion-pane>
</body>
</html>

 
The app is complete! You can test it in the browser by typing ionic serve in the terminal, or you can add a platform and test on an emulator or physical device. If you have any questions, or want to see some future enhancements, please comment below!

Posted on 6 Comments

Create A Real-Time Microservice With Lumen

Laravel 6 Is Out Which Means New Lumen!

When I was at Laracon 2019 I interviewed Taylor Otwell and one of the things we talked about was new Lumen updates. I have switched to a primarily micro service mentality and I’m excited to write up scalable robust production ready microservices.

Laracon 2019 I interviewed Taylor Otwell

What Is Lumen?

Lumen is microframework provided by Laravel. I use it all the time when I need to create standalone APIs and microservices. Today I will show you how to create a generic real time microservice that can be used for later mobile back end tutorials . The microservice will take messages and push them out to all clients listening setting the ground for push notifications. Without further ado, let’s get started!

Getting Started

Because I want to focus on development, and not system administration, please follow this guide to getting your environment up and running, after doing so, go to your terminal, cd into an empty directory and type in this command or clone the repo:

lumen new real-time-microservice-skeleton

cd into your newly created app. First thing we are going to do is define our events. This microservice will give us real-time updates from those who sent messages to it. In order to provide this, we will leverage the broadcasting paradigm included in the Event class. If you are interested in a deeper understanding on how broadcasting works check here, but in short you tell the event what channel to broadcast on and you give it a driver (Redis, Pusher, log). We will being using Redis with a Node.js implementation. Before we can do any of that, we have to add a dependency or two:

For Composer:

composer require predis/predis

For NPM:

npm install --save socket.io-client

Now open up app/Providers/EventServiceProvider.php and change  the array to this:

protected $listen = [
        'App\Events\NewMessageEvent' => [
            'App\Listeners\NewMessageListener',
        ],
    ];

Event & Listener

Lumen doesn’t have generators so we have to do things manually. Now create those corresponding classes in the app/Events and app/Listeners directories respectively. In the NewMessageEvent add this code:

<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class NewMessageEvent extends Event implements ShouldBroadcast
{
public $message;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($channel, $message)
{
//
$this->message = $message;
}
public function broadcastOn()
{
return new PrivateChannel('example-channel');
}
}

In the NewMessageListener it can just have the default listener code

<?php
namespace App\Listeners;
use App\Events\NewMessageEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class NewMessageListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    /**
     * Handle the event.
     *
     * @param  NewMessageEvent  $event
     * @return void
     */
    public function handle(NewMessageEvent $event)
    {
        //
    }
}

Routing

For the lumen skeleton I will just add two addition routes to the web.php file one GET and one POST that do the same thing. Pass a message parameter to a controller method.

<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/
$router->get('/', function () use ($router) {
    return $router->app->version();
});
$router->get('/message', 'MessageController@sendMessage');
$router->post('/message', 'MessageController@sendMessage');

Controller

The controller will have one method that calls a new event and passes the message as the parameter.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MessageController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    public function sendMessage(Request $request){
      event(new \App\Events\NewMessageEvent($request->message));
    }
    //
}

Socket-IO Client

We will use Laravel Echo to interact with out redis pub/sub mechanism. Create a new file called socket-client.js and input the following

import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});
Echo.private('example-channel')
    .listen('NewMessageEvent', (e) => {
        console.log(e.message);
    });

As you can see we are listening for a private channel with the same name that we broadcasted on in the Event class. Now the only thing needed is an actual socket.io server. I won’t get into that in this tutorial but the official Laravel documentation recommends that you use this github package. In the next step of the tutorial I will add authentication to secure channels.

Posted on 10 Comments

Creating A Todo App With SMS Alerts In Laravel 5

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

SMS Alerts In Laravel!

Today I am going to show you how easy it is to create a todo app with  SMS alerts in Laravel. Everything needed in including in the Laravel installation. I am using Laravel Homestead as my development machine image.
 

What Will We Be Building?

A canonical example to learn building web apps is creating a todo list app. I wanted to take the concept a step further. Wouldn’t it be nice to also receive a text message with the todo item? We will build exactly that. Building an SMS server is actually quite easy. It is as simple as sending an email to phonenumber@gateway.com a more comprehensive tutorial can be found here.  This example will also serve as an excellent use case for Laravel’s Event system. Let’s get started!
 

Steps

First thing is first, cd into an empty directory and start a new Laravel installation:

laravel new Todo

cd into your new application and lets create a new migration. We only need one model right now, a Todo model, run this command next.

php artisan make:model Todo --migration

This command not only creates our Model class for us, it also creates the db migration file too! Open your migration file @ database/migrations/MIGRATION.php and replace the old up() function with the following code.


public function up()
{
Schema::create('todos', function (Blueprint $table) {
$table->increments('id');
$table->string('content');
$table->timestamps();
});
}

Our model is extremely simple all we want to do is store a string containing our todo.
Next we are going to create a controller for our Todo model, in your terminal type in this command:
php artisan make:controller TodoController
Now open up the newly created controller file and copy this code in your store() method


//create Todo Model and
$todo = new Todo;
$todo->content = $request->content;
//$todo->save();
//launch event
event(new TodoCreatedEvent($todo));
return view('welcome');

Be sure to add

use AppTodo; and use AppEventsTodoCreatedEvent;

at the top of the page. Right now this function will break because we have not yet defined TodoCreatedEvent class, let’s create that and the TodoCreatedListener. Open up

App/Providers/EventServiceProvider.php and replace the protected $listen variable with this
protected $listen = [
'AppEventsTodoCreatedEvent' => [
'AppListenersTodoCreatedListener',
],
];

Laravel is pretty awesome about its CLI, head over to the terminal and cd into your project root and run this command

php artisan event:generate

This command will create all the events and listeners defined in the array above and scaffolds the code for you AWESOMESAUCE. Now head over to the newly created event class located at

App/Events/TodoCreatedEvent.php.

This event will do one thing, inject an Eloquent model, then pass to the listener. Laravel’s event system does an excellent job at decoupling tasks, all our our event logic will be contained in the TodoCreatedListener class. Replace the contents of your event with this:


<?php
namespace AppEvents;
use AppTodo;
use AppEventsEvent;
use IlluminateQueueSerializesModels;
use IlluminateContractsBroadcastingShouldBroadcast;

class TodoCreatedEvent extends Event
{
use SerializesModels;

public $todo;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Todo $todo)
{
//set variables
$this->todo = $todo;
}

/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}

See? Simple! Now let’s get into the meat over at

App/Listeners/TodoCreatedListener.php

. In this file we are only concerned with the handle() method which you can see injects an instance of our event for us! Here we are going to send an email to our cell phones (FREE TEXTS). Change your handle method to look like this:

<?php
namespace AppListeners;
use Mail;
.
.
.
.
public function handle(TodoCreatedEvent $event)
{
//set todo
$text = $event->todo->content;
Mail::raw($text, function ($message) {
$message->from(env('MAIL_USERNAME','john.smith@email.com'));
$message->to(env('PHONE','123-456-7890@gateway.com'));
});
}.

A couple things left on the backend, first off head over  to your routes file located at App/Http/routes.php add this route:


Route::post('addTodo','TodoController@store');.

Last thing to do now is edit your .env file and add all the necessary details about mail providers, as well as a phone variable to hold your number. That’s it for the backend!
All we have to do now is create a form to create the todos! Open up resources/views/welcome.blade.php and replace the contents with this:


<!DOCTYPE html>
<html>
<head>
<title>Todo SMS</title>

<link href="/css?family=Lato:100" rel="stylesheet" type="text/css">

<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
display: table;
font-weight: 100;
font-family: 'Lato';
}

.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}

.content {
text-align: center;
display: inline-block;
}

.title {
font-size: 96px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">

<form method="POST" action="/addTodo">
{!! csrf_field() !!}

<div>
Content
<input type="text" name="content" value="{{ old('content') }}">
</div>

<div>
<button type="submit">Add Todo </button>
</div>
</form>
</div>
</div>
</body>
</html>

Test it out and try for yourself! Enjoy guys! You can see the full repo here! You can view the live app here!