Laravel 5.5 email setup using Mailgun and Bogardo - php

I am attempting to setup automated email notification in my Laravel 5.5 app using Mailgun. I have the Mailgun SDK installed along with the recommended Laravel library - Bogardo. The reason I am using the Bogardo library instead of just using the Mailgun SDK or built in Laravel email functionality is neither of these allow for click tracking, bounces and other analytic functionality (that I know of). I am able to send emails just fine using Tinker. However, I am not 100% sure how to properly call my new mailable to send an email that way. Here is my mailable class:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class BaseEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$data = ['This is a message from Mailgun!'];
return Mailgun::raw($data, function($message) {
$message
->to('email#domain.com', 'Name Name')
->subject('Yoohoo!')
->from('otheremail#domain.com', 'Name')
->tag(['tag','tag2']);
});
}
}
When I call:
$mail = new App\Mail\BaseEmail();
$mail->send();
I get the following error
TypeError: Too few arguments to function Illuminate\Mail\Mailable::send(), 0 passed in /web/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php(90) : eval()'d code on line 1 and exactly 1 expected
and
$mail->send('this');
I get
TypeError: Argument 1 passed to Illuminate\Mail\Mailable::send() must be an instance of Illuminate\Contracts\Mail\Mailer, string given on line 1
Sorry if this is trivial, but I have been following their docs and have Googled everything that I can think of with no luck.
Any direction would be fantastic!
Thanks!

It appears that the Bogardo package does not support Laravel Mailables...
https://github.com/Bogardo/Mailgun/issues/72

You don't need to use the send() method when you're using raw().This code will send an email:
Mailgun::raw($data, function($message) {
$message->to('email#domain.com', 'Name Name')
->subject('Yoohoo!')
->from('otheremail#domain.com', 'Name')
->tag(['tag','tag2']);
});
You also don't need to use Mailable when you're using the package.

Related

'Undefined variable' in Laravel 8 blade template on sending email

In my Laravel 8 project I try to send HTML e-mail, but get Undefined variable error.
I have this code in my controller:
// here the $client has a model value
Mail::to($client)->send(new ClientCreated($client));
In my app/Mail/ClientCreated.php file:
<?php
namespace App\Mail;
use App\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ClientCreated extends Mailable
{
use Queueable, SerializesModels;
private $client;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
// here the $this->client has a model value
return $this->view('emails.client.created');
}
}
Finally in my resources/views/emails/client/created.blade.php I have this code:
<p>Dear{{ $client->name }}!</p>
And I got this error message:
Undefined variable: client (View: /home/vagrant/Code/myproject/laravel/resources/views/emails/client/created.blade.php)
I read the docs and search on the Stackoverflow, but not found any help.
Any idea what I made wrong?
If you passed the variable to the view properly, but it still does not work, try to restart the queue in the console:
php artisan queue:restart
You should make $client public not private:
public $client;
"There are two ways you may make data available to your view. First, any public property defined on your mailable class will automatically be made available to the view"
Laravel 8.x Docs - Mail - Writing Mailables - View Data - Via Public Properties
The other method would be calling with:
$this->view(...)->with('client', $this->client);
"If you would like to customize the format of your email's data before it is sent to the template, you may manually pass your data to the view via the with method."
Laravel 8.x Docs - Mail - Writing Mailables - View Data - Via the with Method
If you do not want to change $client to public then use the second method.
You should make $client public
public $client;
Once the data has been set to a public property, it will automatically be available in your view, so you may access it like you would access any other data in your Blade templates.
https://laravel.com/docs/8.x/mail#view-data

Laravel Mailer queue with Redis showing error "The script tried to execute a method or access a property of an incomplete object."

This is the complete error.
Illuminate\Mail\SendQueuedMailable::handle(): The script tried to
execute a method or access a property of an incomplete object. Please
ensure that the class definition "Security\Mail\WelcomeMail" of the
object you are trying to operate on was loaded before unserialize()
gets called or provide an autoloader to load the class definition in
/var/www/html/vendor/laravel/framework/src/Illuminate/Mail/SendQueuedMailable.php
We are using Laravel 5.5. And executing the following code
Mail::to($customer)->queue(new WelcomeMail($customer));
The mailer is the default mailer that comes with laravel, but we're queueing jobs to redis. Customer is a User object. The WelcomeMail is the following
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class WelcomeMail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('security::emails.welcome');
}
}
I figured out what was my problem. It was more than one server (localhost, staging etc... ) had a queue listener on the same Redis instance.

How can I send Email in Laravel command instead of controller

I'm working on a project using Laravel where I want to be able to send an email when it is scheduled to send.
So far I've only found solutions to send a mail through a Route but I want to be able to send the mail when cron activates my self made command. I've already made a view of the mail that should be sent and made a page sendMail with php artisan make:mail sendMail that returns the mail view.
sendMail.php
<?php
namespace App\Mail;
use Illuminate\Support\Facades\DB;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class sendMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
$winnersposts = DB::select('select post_id from winners group by post_id');
$posts = DB::select('select * from posts ');
$this->winnerposts =$winnersposts;
$this->posts=$posts;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this ->from('ivanrompa#gmail.com')
->view('emails.template');
}
}
mailAdmin.php
public function handle()
{
}
My command handle is still empty but I previously tried to implement to logic from my controller above in my command but it didn't work.
Am I writing the wrong code and is that the reason it just doesn't work or should I approach it in a different way? It is maybe good to know that I am still learning Laravel and I have never sent an email before through code. Any tips or solutions are welcome.
Assuming you have set your email configuration correctly.
Add this in your mailAdmin.php
use Mail;
use App\Mail\sendMail
public function handle()
{
Mail::to('recipient#gmail.com')->send(new sendMail);
}
Then run the command

Send notification to email

I work on a website project with the laravel framework and I want when I click on the button send a notification either send to the user's email
$invite = Invite::create([
'name' => $request->get('name'),
'email' => $request->get('email'),
'token' => str_random(60),
]);
$invite->notify(new UserInvite());
tnx to help me
What you are using is mail notification, Here is the answer but you can refer to notification section of laravel docs for more information:
https://laravel.com/docs/5.4/notifications
first generate the notification using your terminal in project folder:
php artisan make:notification UserInvite
Then in generated file specify your driver to be 'Mail'. byr default it is. Also laravel has a nice sample code there. And it is better you inject your $invite to the notification so you can use it there. here is a quick sample code. You can find the notification generated under App\Notifications.
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\Invite;
class UserInvite extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct()
{
//
}
public function via($notifiable)
{
return ['mail']; // Here you specify your driver, your case is Mail
}
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Your greeting comes here')
->line('The introduction to the notification.') //here is your lines in email
->action('Notification Action', url('/')) // here is your button
->line("You can use {$notifiable->token}"); // another line and you can add many lines
}
}
now you can call your notification:
$invite->notify(new UserInvite());
since you are notifying on invite, your notifiable is the same invite. As a result in your notification you can use $notification->token to retrieve the token of invite object.
Please let me know if I can be of any help.
regards.

Sending a mail without `to` method in Laravel

I want to send a mail via laravel. For some reason, I only want to set the cc before calling the send method:
Mail::cc($cc_mail)->send(new MyMailAlert());
Then I define the recipient (to) directly in the build method of my Mailable class:
$this->subject($subject)->to($to_email)->view('my-mail');
But it fails:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method Illuminate\Mail\Mailer::cc()
How can I send a mail without knowing the recipient before sending it in the build method? In other word I want to set the recipient (to) directly in the build method and I don't know how to do this.
cc is documented in Laravel Docs, but I can't find the method or property in the Illuminate\Mail\Mailer source code, neither in the Laravel API Documentation. So you can't use it this way.
But Illuminate\Mail\Mailable has the cc property. So, if you want to add the cc before sending and add the to on the build method, you need something like this:
MyMailAlert.php
class MyMailAlert extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->subject($this->subject)->to($this->to)->view('my-mail');
}
}
In your controller:
$myMailAlert = new MyMailAlert();
$myMailAlert->cc = $cc_mail;
// At this point you have cc already setted.
Mail::send($myMailAlert); // Here you sends the mail
Note that the build method uses subject and to properties of the mailable instance, so you have to set it before sending.
I'm not sure from where are you retrieving your $subject and $to_email in your build method example, but for my example you have to give these values to $myMailAlert->subject and $myMailAlert->to. You can use your custom variables in the build method, but given that the class already has these properties, custom variables aren't needed.
Here is a hack to deal with this problem:
Mail::to([])->cc($cc_mail)->send(new MyMailAlert());
So just add a to() method with an empty array and it works. It's still a hack, I'm not really sure it will work in the future.

Categories