Gmail Configuration in .env

Are You Using 2-Step Authentication

If your Gmail account uses 2-Step Authentication then the password required
will not be the same one you log into Gmail with. You’ll need to set up an
App Password. See Google Help
for instructions on how to do this.

The section after the next one (Testing Mail with Tinker) will explain how you can test your mail configuration.

Configuring for Mailgun

Another popular option is to use Mailgun to send your email. I use Mailgun. It’s completely free for the first 10,000 emails you send each month. After that it’s a penny for every 20 emails.

To configure to send through mailgun, first edit config/services.php to match what’s below.

The first argument is the view. The second is an array of any variables the view requires (and emails.test requires testVar). The third is a closure to do additional processing on the message. Here we just set the to address and the subject line.

Changes to routes.php

// After the following line
get('blog/{slug}', 'BlogController@showPost');
// Add these two lines
$router->get('contact', 'ContactController@showForm');
Route::post('contact', 'ContactController@sendContactInfo');

Notice we used $router directly instead of the get() function. Then instead of the post() function, the Route facade was used. This is simply to illustrate there’s multiple ways to set up the routes. Normally, I just use the helper functions directly, but some people prefer the $router variable or the Route facade.

Routing Shortcut Functions

Laravel 5.1 also provides the following shortcut functions for routing.
Any of these can be used directly on the $router variable or with the
Route facade.

When you group routes together, there’s no short helper function so
either Route::group() or $router->group() must be used.

Creating the FormRequest

We know the contact form will contain a name, email address, and a message. The Laravel “way” to validate forms is through FormRequest objects which we used quite a bit in the administration area of our blog.

Let’s create the FormRequest now, so it’s all ready when we build the controller. First use artisan to create the skeleton.

In the sendContactInfo() method, we use the ContactMeRequest to validate. Then we fill $data with the form fields. For the message field, we break the message into individual lines to pass to the view as messageLines.

Then we use the Mail facade to send the message. You could optionally have the sendContactInfo() method take an Illuminate\Mail\Mailer object as an argument (Laravel 5.1 is smart enough to automatically inject it) and use this object to send mail.

See the Official Documentation for a list of facades and the equivalent class to use if you want to access the instance directly.

After the message is sent, we redirect back to the contact page, passing a success message.

ADD contact_email to your blog config file. It is needed in the controller just created (config('blog.contact_email')). It’s easy to add this configuration value, just edit config/blog.php and add an additional option.

Creating the Views

Two views need to be created for the contact form. The one which will display the form and the one that formats the email to be sent.

Running Artisan queue:work

As you can see here it handled the queued email message. Now the email should arrive in your inbox within moments.

Automatically Processing the Queue

Of course, having to manually log into our server and run the artisan queue:work each time we want to process the next item on the queue is ridiculous.

There’s a few options to automate this.

One is load up artisan queue:listen in the startup scripts of your server. This command automatically calls artisan queue:work when items appear in the queue.

The problem with this technique is something will invariably happen. The queue:listen command will hang. Or it will stop running. A better way to run queue:listen is with supervisord.

Running queue:listen with supervisord

supervisord is a *nix utility to monitor and control processes. We’re not delving into how to install this utility, but if you have it and get it installed, below is a portion of /etc/supervisord.conf that works well.

This will run the queue:work command once a minute. You can change this frequency in many ways.

Various Run Frequencies in Console Kernel

// Run every 5 minutes
$schedule->command('queue:work')->everyFiveMinutes();
// Run once a day
$schedule->command('queue:work')->daily();
// Run Mondays at 8:15am
$schedule->command('queue:work')->weeklyOn(1, '8:15');

The second step in setting up the scheduled command is to modify your machine’s crontab. Edit crontab and add the following line.

Crontab Line for Artisan Scheduler

* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1

This will call artisan to run anything currently scheduled, sending any output to the null device.

Queing Jobs

Another great use for queues are asynchronous jobs. These are jobs you execute as normal with $this->dispatch(new JobName) from your controller, but they’ll simply be placed in the queue to be run later by queue:work or whatever method is processing queue items in your application.

Example of a Queued Job

Now, if you examine the template Laravel 5.1 created for TestJob you’ll notice few small changes at the top.

Difference in Queued Jobs

// These three use statements are new
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
// The class will also implement ShouldQueue
class TestJob extends Job implements SelfHandling, ShouldQueue
{
// And the class uses two traits
use InteractsWithQueue, SerializesModels;

ShouldQueue

By having the TestJobclass implement ShouldQueue, the handle() method won’t be called. Instead, TestJob will be constructed and the instance will be pushed onto the queue. When the item is processed from the queue, then the handle() method will be called..

InteractsWithQueue

This will make several queue interaction methods available such as $this->delete() to delete the item from the queue or $this->release() to release the item back onto the queue. Normally you won’t need these methods.

SerializesModels

When the job is serialized to be placed on the queue, this Trait will look for properties of the Job that are models and serialize them correctly.

Queued Jobs are an excellent way to run time consuming processes which you don’t want the user to have to wait for.

Recap

The main thing accomplished in this chapter was adding a Contact form to the blog, but we covered several interesting topics to do it. We talked about sending mail with Mailgun and testing mail with Tinker. Several alternative routing methods were presented. And we discussed queues, set up a database queue, and sent any contact emails through the queue.