How to handle callback when mail is sent in laravel 4 - php

I wonder how to handle the callback when mail is sent? I want to do some action when the mail is sent. I know the code below is wrong, let's say $callbackOnSend is called before the mail is send and $callbackAfterSent is called after the mail is sent.
Mail::send(array('text' => 'view'), $data, $callbackOnSend, $callbackAfterSent);
I wonder how can I achieve the $callbackAfterSent?

If the mail is sent, the Mail::send() method will return true.
$mailVariables = ['from' => 'abc#abc.com'. 'fromName' => 'abc', 'to' => '123#123.com', 'cc' => 'xyz#xyz.com', 'attachment' => 'file1'];
Mail::send('emails.welcome', $data, function($message) use ($mailVariables)
{
$message->from($mailVariables['from'], $mailVariables['fromName']);
$message->to($mailVariables['to'])->cc($mailVariables['cc']);
$message->attach($mailVariables['attachment']);
});
If you need to do something if/after the mail is sent, you can wrap the whole Mail::send() in an if statement, however, from what I've read, it won't work if you have 'pretent' set to true in your config as with 'pretend' set to true, mail::send() will always return false.
if(Mail::send('emails.welcome', $data, function($message) use ($mailVariables)
{
$message->from($mailVariables['from'], $mailVariables['fromName']);
$message->to($mailVariables['to'])->cc($mailVariables['cc']);
$message->attach($mailVariables['attachment']);
})) {
// do something
}

Related

Send massive emails in laravel

Goodnight
Porblem 1.-
I need to send more than 1000 emails for each event created, and for this I use queue (as Laravel's documentation says), but when sending the emails I have to wait until all the emails are sent to return to the view of control Panel
this is my "store" function in NewsEvents.php controller that sends the emails
public function store(Request $request)
{
$attributes = request()->validate(News::$rules, News::$messages);
$news = $this->createEntry(News::class, $attributes);
//queue for sending emails
$this->dispatch(new Nevent($news));
return redirect_to_resource();
}
the "handle" function of job "Nevent.php"
public function handle()
{
//
$users=User::where('tipo_user','user')->get();
foreach($users as $user)
{
$user->notify(new EventCreated($this->news));
echo 'enviado correo';
Informe::create([
'event_id' => $this->news->id,
'total' => '1',
'tipo' => 'invitacion',
'dst_id' => $user->id,
'estado' => 'correcto',
]);
}
}
What could be the problem?
problem 2.-
How could I send an email for every minute?
since when sending all emails my server responded with this message:
Domain mu.edu.fi has exceeded the max emails per hour (100/100 (100%)) allowed. Message will be reattempted later
If u are using Redis server for managing jobs, Laravel provides a simple
API for Rate Limiting API's
Redis::throttle('your job id')->allow(10)->every(60)->then(function () {
// Job logic...
}, function () {
return $this->release(10);
});
Hope this helps.

Laravel: Use Email and Name in Mail::to

I have a contact form where someone provides his name and email. I want to send him an email now with Laravel.
I found in the docs
To send a message, use the to method on the Mail facade. The to method
accepts an email address, a user instance, or a collection of users.
and in fact
\Mail::to('example#gmail.com')->send(new \App\Mail\Hello);
works. But is it also possible to provide the name for the email receipt?
I wanted to look that up in the Laravel API for the Mail Facade but to my surprise the facade has no to function?
So how can I find out what the to function really does and if I can pass a name parameter as well?
In laravel 5.6, answer to your question is: use associative array for every recpient with 'email' and 'name' keys, should work with $to, $cc, $bcc
$to = [
[
'email' => $email,
'name' => $name,
]
];
\Mail::to($to)->send(new \App\Mail\Hello);
You can use the Mail::send() function that inject a Message class in the callable. The Message class has a function to($email, $name) with the signature you're searching, i.e.:
Mail::send($view, $data, function($message) use ($email, $name) {
$m->to($email, $name);
$m->from('youremail#example.com', 'Your Name');
$m->subject('Hi there');
})
The $view could be a string (an actual view) or an array like these:
['text'=> 'body here']
['html'=> 'body here']
['raw'=> 'body here']
The $data argument will be passed to the $view.
For Laravel < 5.6 one can use this:
$object = new \stdClass();
$object->email = $email;
$object->name = $user->getName();
\Mail::to($object)->queue($mailclass);
see here
I prefer this solution as more readable (no need to use arrays and static string keys).
\Mail::send((new \App\Mail\Hello)
->to('example#gmail.com', 'John Doe');
You can use Mailable class in Laravel:
https://laravel.com/docs/5.5/mail
php artisan make:mail YouMail
These classes are stored in the app/Mail directory.
In config/mail.php you can configue email settings:
'from' => ['address' => 'example#example.com', 'name' => 'App Name'],
for Laravel 8 is like this:
$user = new User;
$user->email = 'example#example.com';
Mail::to($user)->send(new YourMail);
YourMail is Mailable class created by php artisan make:mail YourMail

Debug why a Queue failed on Laravel 5.2

I'm trying to dispatch Welcome Email on Laravel 5.2 but the job is failing and I have no idea how to figure out why.
Here is what I have so far:
public function test(Request $request) {
$email = $request->get('email');
$subject = $this->word('emails.welcome.subject');
// Mail::send # I use this to Send it synchronously
// $this->mailQueue->queue # I use this to Queue
('emails.welcome', ['domain' => 'blablabla', 'name' => 'Marco Aurélio Deleu', 'date' => Carbon::now(),
'total' => 100, 'pretext' => '', 'score' => '', 'surtext' => '', 'password' => 'blabla', 'shop' => ''],
function ($message) use ($email, $subject) {
$message->to($email);
$message->subject($subject);
}, true);
return 'queued';
}
I noticed that Jobs can easily fail when any kind of exception is thrown, so I figured that I could use Mail::send to find out which exception was being thrown / what was the problem and then use the $this->mailQueue->queue() when I had it sorted out.
I managed to use this strategy to find out that I can't use function calls inside the closure, but now I just don't know what else to do in order to find where the problem lies. The synchronous method of sending the email directly works just fine and the email arrives, but the job will fail at a queue.
The last piece of evidence that I have is that the problem is in the $data array, because if I use it without any $data, the job will be processed and the email arrives.
...
// If I use it like this, it will work perfectly.
$this->mailQueue->queue
('emails.welcome', [ /* empty array */ ], function ($message) use ($email, $subject) {
$message->to($email);
$message->subject($subject);
}, true);
Here is the Queue Listener:
// --> This is the job failing with $data array <--
[06:34 PM]-[root#local]-[/project/]-[git sign-up-with-email]
# php artisan queue:listen --timeout=30 --tries=1
[2016-06-28 21:34:29] Failed: mailer#handleQueuedMessage
^C
// --> This is the job working with empty $data array <--
[06:35 PM]-[root#local]-[/project/]-[git sign-up-with-email]
# php artisan queue:listen --timeout=30 --tries=1
[2016-06-28 21:44:31] Processed: mailer#handleQueuedMessage

PHP Laravel 5 User class properties not accessible for sending Email after account creation

I have a problem where I can't put in the variables into the Mail::send() function in laravel. Please see the following code:
$first_name = $request->input('first_name'),
$email = $request->input('email'),
//Create account
User::create([
'first_name' => $first_name,
'last_name' => $request->input('last_name'),
'email' => $email,
'password' => bcrypt($request->input('password')),
]);
//Send email to user
Mail::send('emails.test', ['fname' => $first_name], function($message)
{
$message->to($email)
->subject('Welcome!');
});
return redirect()
->route('home')
->with('info', 'Your account has been created and an authentication link has been sent to the email address that you provided. Please go to your email inbox and click on the link in order to complete the registration.');
For some reason the code breaks when it gets to the send email because I receive the error and the data is sent to the database. Why is the variable no longer accessible afterwards?
Any help would be greatly appreciated. Thank you
Closures may also inherit variables from the parent scope. Any such variables must be passed to the use language construct.
Source: http://php.net/manual/en/functions.anonymous.php
In other words, $email has to be inherited like this:
Mail::send('emails.test', ['fname' => $first_name], function($message) use ($email)
{
$message->to($email)
->subject('Welcome!');
});
Note: use ($email) in the first line.

"async" Parameter using Mandrill API with laravel

This is my code:
$email = "email#gmail.com";
$data = array(
'email' => $email,
'async' => false,
);
Mail::queue('user.mails.welcome', $data, function($message) use ($email) {
$message
->to($email, $email)
->subject('Welcome to the Laravel 4 Auth App!');
});
And this is what shows on my Mandrill account API log:
Full Request {
"key": "x",
"raw_message": "y",
"async": "1"
}
Full Response {
"email": "xy",
"status": "queued",
"_id": "z"
}
As you can see, emails are being queued by default. Why? And how can I change that?
Per the Mandrill docs:
Async: enable a background sending mode that is optimized for bulk sending. In async mode, messages/send will immediately return a status of "queued" for every recipient. To handle rejections when sending in async mode, set up a webhook for the 'reject' event. Defaults to false for messages with no more than 10 recipients; messages with more than 10 recipients are always sent asynchronously, regardless of the value of async.
Basically, it's something that Mandrill is doing on their end is is unrelated to whether you use Mail::send or Mail::queue in Laravel.
All emails sending through Mandrill are queued and sent out in accordance with the parameters defined for your account. In other words: They decide when your emails eventually get sent.
Edit: Laravel's Mandrill Mail Transport is always going to send with async mode enabled. There's no way to configure that without editing the class: MandrillTransport
I am not sure I understand. Your emails are being queued because you are using the queue() method:
Mail::queue('user.mails.welcome', $data, function($message) use ($email) {
If you want to not queue, then use the send() method:
Mail::send('user.mails.welcome', $data, function($message) use ($email) {
I had to set a "from" email to have this work.
The 'async' parameter of the mandrill api isn't exposed to the Laravel mail closure. I just extended the MandrillTransport class and passed a Swift_Mime_Message into it so that I could capture the response, it will be 'sent' or 'rejected' (and reject_reason will be populated with something like "hard/soft bounce") which I can store in my application:
class Mandrill extends MandrillTransport
{
public function send(\Swift_Mime_Message $message, &$failedRecipients = null)
{
$client = $this->getHttpClient();
$response = $client->post('https://mandrillapp.com/api/1.0/messages/send-raw.json', [
'body' => [
'key' => $this->key,
'raw_message' => (string)$message,
'async' => false,
],
]);
return $response->json();
}
}

Categories