Send a mail inside botman (laravel 5.7) - laravel

I struggle to send a mail inside a botman reply.
I use mailhog, with botman 2.0 and laravel 5.7.
I've tested mailhog with simple php code , it work.
Here my env file config :
MAIL_DRIVER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
The conversation start here :
<?php
namespace App\Conversations\SASI\CreationTicket;
//use Validator;
use Illuminate\Support\Facades\Validator;
use BotMan\BotMan\Messages\Incoming\Answer;
use BotMan\BotMan\Messages\Conversations\Conversation;
use App\Conversations\SASI\CreationTicket\EndTicketResume;
class EndTicket extends Conversation
{
public function askProblem()
{
$this->ask('Décrivez succintement votre problème :', function(Answer $answer) {
$this->bot->userStorage()->save([
'problem' => $answer->getText(),
]);
$this->askEmail(); //passe à la fonction suivante
});
}
public function askEmail()
{
$this->ask('Quel est votre email?', function(Answer $answer) {
$validator = Validator::make(['email' => $answer->getText()], [
'email' => 'email',
]);
if ($validator->fails()) {
return $this->repeat('Cette email ne semble pas valide. Entrez un email valide.');
}
$this->bot->userStorage()->save([
'email' => $answer->getText(),
]);
$this->askMobile();
});
}
public function askMobile()
{
$this->ask('Quel est votre numéro pro?', function(Answer $answer) {
$this->bot->userStorage()->save([
'mobile' => $answer->getText(),
]);
$this->say('Merci');
//renvoi a une autre conversation app\Conversations\SelectServiceConversation.php
$this->bot->startConversation(new EndTicketResume());
});
}
public function run()
{
$this->askProblem();
}
}
As you can see the bot say "Merci" (thanks) and go to another conversation. If add my mail code the bot stop before he say "Merci"
So the next conversation :
<?php
namespace App\Conversations\SASI\CreationTicket;
use Illuminate\Support\Facades\Mail;
use BotMan\BotMan\Messages\Conversations\Conversation;
class EndTicketResume extends Conversation
{
public function confirmTicket()
{
$user = $this->bot->userStorage()->find();
$message = '------------------------------------------------ <br>';
$message .= 'Probleme : '.$user->get('problem').'<br>';
$message .= 'Email : '.$user->get('email').'<br>';
$message .= 'Tel : '.$user->get('mobile').'<br>';
$message .= '------------------------------------------------';
$this->say('Votre demande va être envoyé. <br><br>'.$message);
$email = $user->get('email');
$data = [
'first' => 'test',
'last' => 'TEST'
];
// send email with details
Mail::send('emails.justshoot', $data, function($message) use ($email) {
$message->subject('Welcome');
$message->from($email, 'Just Shoot Upload');
$message->to('myemail#gmail.com')->cc('test#gmail.com');
});
}
/**
* Start the conversation.
*
* #return mixed
*/
public function run()
{
$this->confirmTicket();
}
}
If I remove this
Mail::send('emails.justshoot', $data, function($message) use ($email) {
$message->subject('Welcome');
$message->from($email, 'Just Shoot Upload');
$message->to('myemail#gmail.com')->cc('test#gmail.com');
});
The bot say his last message, all is ok. But if I add this code , as I said previously, the bot won't even go to another conversation.
What I am doing wrong ?

Try to put the mail in a seperate function and different controller
you can debug using network tab in the console

Related

send an email in Laravel on a create function

send an email in Laravel on a create function but not able to do
this is my store function
public function store()
{
$input = $request->all();
$user = \AUTH::guard()->user();
$input['created_by'] = $user->id;
\Log::info('$input'.json_encode([$input]));
$bulkLabSample = $this->bulkLabSampleRepository->create($input);
Flash::success(__('messages.saved', ['model' => __('models/bulkLabSamples.singular')]));
return redirect(route('bulkLabSamples.index'));
}
// use this
use Illuminate\Support\Facades\Mail;
// send mail via mail
Mail::send('your-view-blade', ['extraInfo' => $extraInfo], function ($message) {
$message->to('email#email.com');
$message->subject('your subject here');
});
By extraInfo you can pass values to the mail template as you want.
// for your code
public function store()
{
$input = $request->all();
$user = \AUTH::guard()->user();
$input['created_by'] = $user->id;
\Log::info('$input'.json_encode([$input]));
$bulkLabSample = $this->bulkLabSampleRepository->create($input);
Mail::send('your-view-blade', ['extraInfo' => $extraInfo], function ($message) {
$message->to('email#email.com');
$message->subject('your subject here');
});
Flash::success(__('messages.saved', ['model' => __('models/bulkLabSamples.singular')]));
return redirect(route('bulkLabSamples.index'));
}

Limit Queued Job in Laravel

I have an email service that allows me to send only 60 emails per hour (1/minute).
So that is why i m trying to write an application that respect the service provider's restrictions,
I m dispatching emails to bulk users at once via queue jobs,Please take a look at the code
public function sendEmails(CreateEmailRequest $request)
{
$data = [];
$users = User::find($request->to);
$subject = $request->subject;
$body = $this->fileUpload($request->body);
foreach ($users as $user) {
$vars = array(
"{{name}}" => $user->name,
"{{email}}" => $user->email,
);
$body = strtr($body, $vars);
$data['body'] = $body;
$data['user'] = $user;
$data['subject'] = $subject;
dispatch(new SendEmailJob($data))->onQueue('mail');
}
Flash::success('Email sent successfully.');
return redirect(route('emails.index'));
}
here is SendEmailJob Class code
public function handle()
{
$data = $this->data;
$body = $data['body'];
$user = $data['user'];
$subject = $data['subject'];
// list($body, $user, $subject) = $this->data;
Mail::send('mail.email', ['body' => $body], function ($m) use ($user, $subject) {
$m->to($user->email)->subject($subject);
});
}
public function middleware()
{
return Limit::perMinute(1);
}
when I run php artisan queue:work it process all jobs at once..
can you please tell me how can I achieve this?
I can not use spatie/laravel-rate-limited-job-middleware because my server does not support Redis.
Can you please tell me i m doing wrong ?
You can use Job Middleware with a rate limiting
in the boot method of your AppServiceProvider
RateLimiter::for('emails', function($job) {
return Limit::perMinute(1);
});
and add middleware to the job:
use Illuminate\Queue\Middleware\RateLimited;
public function middleware()
{
return [new RateLimited('emails')];
}

Mailtrap does not show the body of the message

The function here is to send a six digit pin to email so as to recover password. Mailtrap inbox does not show the six digit pin, just a "button text". How do you send the recovery code /pin to the recovery mail.
class UserPasswordPin extends Mailable {
use Queueable, SerializesModels;
public $pin;
public function __construct($pin)
{
$this->pin = $pin;
}
public function build()
{
return $this->markdown('emails.userpin')->with([
'pin' => $this->pin,
]);
}
}
The recover password controller send the six digit code. it works in postman but when it send email to mailtrap its blank. And also is there an algorithm for the method unwantedPin, like it selects a six digit conbination and prevents sending digits which are predictable?
class RecoverPasswordController extends Controller{
private $unwantedPins = [
111111,222222,333333,444444,555555,666666,777777,888888,999999
];
private function inUnWanted($pin)
{
return in_array($pin,$this->unwantedPins);
}
public function recover(RecoverPasswordRequest $request){
//check if email exist
$user = DB::table('users')->where([
'email' => $request->email
])->first();
if (is_null($user)){
return response([
'errors'=>'The email entered is not registered'
],404);
}
//send a six digit code/pin to the recovery email
$pin = rand( 111111,999999);
foreach ($this->unwantedPins as $unwantedPin){
if ($pin == $unwantedPin){
$pin = rand(111111,999999);
}
}
Mail::to($user)->queue(new UserPasswordPin($pin));
return response([
'pin'=>$pin,
'message'=>'a six digit code has been sent to your email'
],200);
}
}
the problem was in userpin.blade.php
#component('mail::message')
# Introduction
This is your six digit number.
#component('mail::button', ['url' => ''])
{{$pin}}
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent

Sending Mail with Laravel

i'am trying to send a Mail with laravel after the registration , basically it's working , but when i added the name of the doctor into the Mail i got this error : Trying to get property 'Nom' of non-object , probably it doesn't know the "Name" of the doctor.
Thank you for your Help
The Doctor Controller :
public function ajouter (Request $request) {
$this->validate($request, [
'n' => 'required',
'p' => 'required' ,
'adresse' => 'required',
'mail' => 'required|email',
'mdp' => 'required|min:4',
'spec' => 'required',
'region' => 'required',
'ville'=>'required',
'photo'=> 'image|nullable|max:3999'
]);
$medecin= new doc() ;
$medecin->Nom= $request->input('n');
$medecin->Prénom =$request->input('p');
$medecin->Spécialité=$request->input('spec');
$medecin->Adresse_Cabinet=$request->input('adresse');
$id_ville=$request->input('region');
$medecin->Ville=vil::find($id_ville)->Ville;
$medecin->Délégation=$request->input('ville');
if($request->hasFile('photo')){
// Get filename with th extension
$file = $request->file('photo');
$extension=$file->getClientOriginalExtension();
$fileNameToStore=time().'.'.$extension;
$file->move('assets/img/uploads/',$fileNameToStore);
}
else {
$fileNameToStore =('noimage.png');
}
$medecin->photo=$fileNameToStore;
$medecin->Login=$request->input('mail');
$medecin->Password=Hash::make($request->input('mdp'));
$medecin->save();
Mail::to($request->input('mail'))->send(new WelcomeDoctorMail($medecin));
return redirect()->back()->withSuccess('medecin ajouter' ) ;
}
The Mail controller :
public $medecin;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(doc $medecin)
{
$this->doc = $medecin ;
}
public function build()
{
return $this->markdown('emails.welcome-doctor');
}
}
The Mail view :
#component('mail::message')
# Bienvenue
Merci {{$medecin->Nom}} de vous etes inscrit sur notre application.
Cordialement
Thanks,<br>
{{ config('app.name') }}
#endcomponent
You can use the with() function with an array as the first argument to specify what you want to access in the mail markup when returning from the build() function.
Like this:
public function build()
{
return $this->markdown('emails.welcome-doctor')
->with([
'medecin' => $this->doc
]);
}
EDIT: According to the documentation (https://laravel.com/docs/7.x/mail#view-data) you can access the variable directly if it's set to public in the class that extends Mailable. So you should be able to access $doc within the markup (not $medecin).
EDIT 2: I now see that you have defined public $medecin but you are trying to save the constructors parameter value in $this->doc which is not defined in the class that extends Mailable class nor used in the markdown. You could solve all your problems according to the documentation, by just changing $this->doc = $medecine to $this->medecine = $medecine.
first make sure the name inserted correctly into database ,
if it's correct try to access it like an array
#component('mail::message')
# Bienvenue
Merci {{$medecin['Nom']}} de vous etes inscrit sur notre application.
Cordialement
Thanks,<br>
{{ config('app.name') }}
#endcomponent

BadMethodCallException Call to undefined method App\AskQuestion::email()

I am trying to insert the data in database while using Laravel. I am getting the error
BadMethodCallException Call to undefined method
App\AskQuestion::email()
While create.blade.php is my view and respones is the name of my table. The controller name is ResponesContoller and its code is given.
public function create()
{
abort_if(Gate::denies('respone_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$categories = Category::all()->pluck('name', 'id')->prepend(trans('Sélectionnez la thématique'), '');
$author_emails = User::all()->pluck('email', 'id')->prepend(trans('Choisissez votre email'), '');
$ask_questions = AskQuestion::all();
return view('admin.respones.create', compact('categories', 'author_emails', 'ask_questions'));
}
public function store(StoreResponeRequest $request)
{
$respone = Respone::create($request->all());
return redirect()->route('admin.respones.index')->with('success', 'Réponse enregistrée avec succès!');
}
public function edit(Respone $respone)
{
abort_if(Gate::denies('respone_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$categories = Category::all()->pluck('name', 'id')->prepend(trans('Sélectonnez la thématique'), '');
$author_emails = User::all()->pluck('email', 'id')->prepend(trans('Choisissez votre email'), '');
$ask_questions = AskQuestion::all()->pluck('text_question', 'id')->prepend(trans('Choisissez la question posée'), '');
$respone->load('category', 'author_email', 'ask_question');
return view('admin.respones.edit', compact('categories', 'author_emails', 'ask_questions', 'respone'));
}
The code of web.php is given and it works correctly, before I have checked as a test.
Please if anyone can help me!
Here was the problem i solve it.
public function created(Respone $model)
{
$data = ['action' => 'Une réponse est apportée à votre question!', 'model_name' => 'Respone',
'respone' => $model ];
$askQuestions = \App\AskQuestion::WhereHas('respones', function($q) {
return $q->where('objet_question', 'email', 'text_question');
})->get();
Notification::send($askQuestions, new ResponeEmailNotification($data));
}

Resources