Slow Sending Mail On Laravel 6 - php

I have setting on .env mail like this :
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=******#gmail.com
MAIL_PASSWORD=******
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
Then, i have class Sendemail extends mailables like this :
class Sendemail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public function build()
{
return
$this->from('*****#gmail.com')->subject('Penugasan')->view('Email/mail')->with('data',
$this->data);
}
}
Here is the view Email/mail :
Dengan Hormat,
Nama : {{ $data['nama'] }}
NIP : {{ $data['nip'] }}
Pangkat/Golongan : {{ $data['pangkat'] }}
The controller is like this :
foreach($rekantugas as $val)
{
$data = array(
'nama' =>$val->nama,
'nip' =>$val->nip,
'pangkat' =>$val->pangkat.' / '.$val->golongan,
);
Mail::to($val->email)->queue(new Sendemail($data));
}
My question is, when i executed the function to sending email, it's so slow about 10-15 seconds. Im still develop it in my localhost and im using Laravel 6 and postgresql.
How can i solve this ?
Note : All email has been success to delivered, but it just take a long time (slow) to sending email. I want to send an email by an form action.

Related

Send email and link to Auth Users once Job has completed

I'm using laravel/dompdf to generate a 30+ page PDF and using a Laravel Job and php artisan queue:work to complete the task so it will run in the background.
I want the "Job" to email the Auth user that selected the job to run. It should email once it has completed, with a link to the PDF.
Example:
John is logged in and presses the button to start the PDF job.
The PDF job runs in the background
The PDF job finishes
Once finished, the PDF job script emails John the link to the PDF
This is how my code is laid out:
View to start job
Hits the controller
Dispatch to the Job
Passes info to Mail
Sends mail
The main thing I'm looking for is help getting the Auth users email
and first_name passed to the email I'm trying to send once the job is
complete.
1. Start Job
Create PDF
2. Controller
use Auth;
use App\User;
use PDF;
use App\Jobs\ProcessPdfHaiti;
...etc
public function createPdf(){
$haitiKids = Kid::
whereRaw('sponsors_received < sponsors_needed')
->where('current_country', 'Haiti')
->orderBy('sponsors_received', 'ASC')
->get();
ProcessPdfHaiti::dispatch($haitiKids);
return back()->with('info','This will take a minute. You\'ll receive an email when it\'s completed.');
}
3. Job (ProcessPdfHaiti)
namespace App\Jobs;
use Auth;
use App\User;
...etc
class ProcessPdfHaiti implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $haitiKids;
public function __construct($haitiKids)
{
$this->haitiKids = $haitiKids;
}
public function handle()
{
$haitiKids = Kid::
whereRaw('sponsors_received < sponsors_needed')
->where('current_country', 'Haiti')
->orderBy('sponsors_received', 'ASC')
->get();
$pdf = PDF::loadView('admin.cdp.haiti-kid-pdf-all', compact('haitiKids'))->setPaper('letter', 'landscape');
$pdf->save(storage_path('app/public') . '/images/cdp/pdf/haiti-kids'.'-'.date("mdyhis").'.pdf');
// ####THIS IS WHERE I GET THE ERROR! ####
$pdfUserName= Auth::user()->first_name;
$pdfUserEmail = Auth::user()->email;
Mail::to($pdfUserEmail)
->send(new PdfFinished(
$pdfUserName = $pdfUser->first_name,
$pdfpath = storage_path('app/public') . '/images/cdp/pdf/haiti-kids'.'-'.date("mdyhis").'.pdf'
));
}
}
This is the above error I'm getting Trying to get property 'first_name' of
non-object
4. Passes info to Mail
namespace App\Mail;
use ...etc
class PdfFinished extends Mailable
{
use Queueable, SerializesModels;
public $pdfUserName;
public $pdfpath;
public function __construct($pdfUserName,$pdfpath)
{
$this->pdfUserName =$pdfUserName;
$this->pdfpath =$pdfpath;
}
public function build()
{
return $this->subject('PDF Has Completed')->markdown('emails.staff.pdfcompleted');
}
}
5. Send email with users First Name and Link
#component('mail::message')
### Hello {{ ucwords(strtolower($pdfUserName)) }},<br>
The PDF has processed successfully and is ready to view.<br>
You can copy and paste this link into the browser {{ $pdfpath }} to download, or select the button below.
{{-- WAS TRYING TO USE A BUTTON, BUT COULDN'T FIGURE OUT HOW TO ADD THE LINK TO THE URL
#component('mail::button', ['url' => {{ $pdfpath }}, 'color' => 'green'])
Download PDF
#endcomponent --}}
...etc
#endcomponent
6. I make sure I have php artisan queue:work running on the server
This is my first time creating a Jobs and Queue in Laravel so any help would be appreciated.
Update (Based on porloscerros solution)
$pdfUser = Auth::user();
//GET ERROR HERE
$pdfUserEmail = $pdfUser->email;
$pdfUserName = $pdfUser->first_name;
Mail::to($pdfUserEmail)
->send(new PdfFinished(
$pdfUserName = $pdfUserName,
$pdfpath = storage_path('app/public') . '/images/cdp/pdf/haiti-kids'.'-'.date("mdyhis").'.pdf'
));
ERROR: Trying to get property 'email' of non-object

Authentication required message when sending email

I am trying send email verification links to user when they register but I get a message Authentication required and mail isn't sent. I tried using mailtrap for demo and sendgrid which I will be using in production but the message was the same. This is how I a going about it
After running composer require guzzlehttp/guzzle I updated my env file like this
# MAIL_DRIVER=smtp
# MAIL_HOST=smtp.mailtrap.io
# MAIL_PORT=2525
# MAIL_USERNAME=mailtrap_username
# MAIL_PASSWORD=mailtrap_password
# MAIL_ENCRYPTION=tls
MAIL_DRIVER=smtp
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=sendgrid_username
MAIL_PASSWORD=sendgrid_password
MAIL_ENCRYPTION=tls
In the controller, I want to send the mail after a user is successfully created like this
...
use App\Mail\VerifyEmail;
...
use Illuminate\Support\Facades\Mail;
public function register(Request $request)
{
// create and store new user record
$user = User::create([
'username' => $request->username,
'password' => bcrypt($request->password)
]);
// send user email verification link
Mail::to($user->username)->send(new VerifyEmail());
}
VerifyMail.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class VerifyEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$from = 'support#fromus.com';
$name = 'custom name';
$subject = 'Welcome! Confirm Your Email';
return $this->from($from, $name)
->subject($subject)
->view('auth.verify');
}
}
Following the documentation for email verification https://laravel.com/docs/5.8/verification#verification-routing I added the Auth::routes(['verify' => true]) to api.php file like this
<?php
// Register routes for email verification
Auth::routes(['verify' => true]);
Route::prefix('v1')->group(function () {
// protected routes
Route::middleware('auth:api')->group(function () {
Route::get('products', 'ProductController#index'); // get products
});
});
Route::fallback(function () {
return response()->json(['error' => 'Not Found'], 404);
});
Why am I getting the Authentication required error message and how can I fix it?
First i removed Auth::routes(['verify' => true]) from the api.php file and added it in the web.php.
Then I ran php artisan config:cache to cache changes made to the env file. Fixed

Laravel Notifications not sending

I set up a contact form which sends an email on completion using Laravel notifications, however it doesn't look like anything is being sent.
ROUTES
Route::post('/contact', 'ContactController#store');
CONTROLLER
public function store()
{
request()->validate([
'name' => 'required|max:255',
'email' => 'required|email|unique:contacts|max:255',
'message' => 'required|max:2000',
]);
$contact = Contact::create(
request()->only([
'name',
'email',
'message',
])
);
User::first()->notify(new SendContactNotification($contact));
return back()->with('success', 'Thank you, I will be in touch as soon as I can');
}
NOTIFICATION
protected $contact;
public function __construct($contact)
{
$this->contact = $contact;
}
public function toMail($notifiable)
{
return (new MailMessage)
->line($this->contact->name)
->line($this->contact->email)
->line($this->contact->message);
}
I do get the success message when I run it. However, nothing appears in my Mailtrap. Here's the mail section of the sanitised .env file:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=username
MAIL_PASSWORD=password
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS='admin#test.com'
MAIL_FROM_NAME='admin'
I can't see what I have done wrong. I also tried type hinting the contact in the notification like so:
public function __construct(Contact $contact)
{
$this->contact = $contact;
}
That didn't work unfortunately. I also thought it might be something to do with my computer not being set up to send emails using php, but I was under the impression that the env file would take care of that.
The contacts are being stored in the database ok, but no emails are being sent. Would anyone be able to help?
It was the port in the env file, I changed it to:
MAIL_PORT=465
and it worked!
I knew port 2525 wasn't working because of this answer: https://stackoverflow.com/a/45418259/5497241

Sending mail with lumen | Timeout

I have required composer require illuminate/mail,
.env looks fine :
MAIL_DRIVER=smtp
MAIL_HOST=smtp-mail.outlook.com
MAIL_PORT=587
MAIL_USERNAME=******#hotmail.com
MAIL_PASSWORD=*****
MAIL_ENCRYPTION=tls
Controller :
use Illuminate\Support\Facades\Mail;
....
....
....
$random = str_random(40);
Mail::send('email.verify', ['user' => $applicant_id, 'random'=>$random], function ($m) use ($findUser) {
$m->to($findUser->user->email)->subject('Account Verification');
});
It always gives me "message": "Maximum execution time of 30 seconds exceeded",, I tried it with zoho mail also.

Getting error: `Maximum execution time` when send Mail Queue in Laravel

I using Laravel Mail Queue to send quick mail.
I have an error like:
Maximum execution time of 60 seconds exceeded in SendWelcomeEmail.php
(line 38)
Difficult to describe my error because I don't have experience with Laravel. So, I tried to record step by step what I did.
My problem is: when user click Send information, Send Mail is activated and it using too much time to complete this work. This affect to the user experience.
I expect an answer or another method to resolve my problem.
My demo was make with step by step:
Step 1:
c:\xampp\htdocs\laravel-test>php artisan queue:table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan queue:failed-table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2017_04_03_144759_create_jobs_table
Migrated: 2017_04_03_150557_create_failed_jobs_table
Step 2: update my .env file and setting email:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:beQGwYyUPOTMtkbzDhft7swh68UJW7RqwAGwhELUfLI=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dongxanh
DB_USERNAME=admin
DB_PASSWORD=euEW12il
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=database
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=myemail#gmail.com
MAIL_PASSWORD=yxpszfarmxoperew
MAIL_ENCRYPTION=tls
Step 3:
php artisan make:mail EmailCustomer
At function __contruct():
protected $content;
public function __construct($content)
{
$this->content = $content;
}
Function build():
public function build()
{
return $this->view('emails.contact')
->with('content',$this->content);
}
Step 4: In views/emails/contact.blade.php is:
Name: {{ $content['name'] }} <br>
Title: {{ $content['title'] }} <br>
Email: {{ $content['email'] }} <br>
Phone number: {{ $content['phonenumber'] }} <br>
Body:
{{ $content['body'] }}
Step 5: Create Job SendWelcomeEmail:
php artisan make:job SendWelcomeEmail
It will create SendWelcomeEmail.php look like this:
use Mail;
use App\Mail\EmailCustomer;
class SendWelcomeEmail implements ShouldQueue
{
protected $content;
public function __construct($content)
{
$this->content = $content;
}
public function handle()
{
sleep(60);
$receiverAddress = 'myemail#gmail.com';
$email = new EmailCustomer($content);
Mail::to($receiverAddress)->queue($email);
}
}
Finally: Send Job to Queue when user click submits form in app\Http\Controllers\RegisterForm.php:
public function storeCustomer(Request $request) {
Customer::create($request->all());
$content = [
'name'=> $request->input('name'),
'title'=> $request->input('title'),
'email'=> $request->input('email'),
'phonenumber' => $request->input('phonenumber'),
'body' => $request->input('body')
];
dispatch(new SendWelcomeEmail($content));
return view('partials.success-mail');
}
I run two commands:
php artisan serve
php artisan queue:work
And tested. It's show error like the question.
You should not use sleep here , Remove this to make queue work .
If need it try like this to increase time limit
php artisan queue:work --timeout=0
Or you can use Task Schedule : https://laravel.com/docs/5.4/scheduling
Also Use $this->content not $content.
$email = new EmailCustomer($content);
You missing this :
QUEUE_CONNECTION=database

Categories