I am using ""davibennun/laravel-push-notification": "dev-laravel5" " for sending push notification. What i want is delay in sending notification after hit but dont want to stop the process. Is there any idea how can i do this or is this possible?
Following is the code to send push notification:
$pushNotification = PushNotification::app('appNameAndroid')->to($token);
$pushNotification->adapter->setAdapterParameters(['sslverifypeer' => false]);
$pushNotification->send($message);
Thanks in advance.
I found how to do this.
Following are the steps.
Run the following command
php artisan queue:table
php artisan migrate
Change .env
QUEUE_DRIVER=database
Create a job
php artisan make:job JobName
//In Job file
I have mentioned 2 protected variable in my job file
$message,$deviceToken
In _construct i assigned a value to the above variables.
public function __construct($deviceToken, $message)
{
$this->deviceToken = $deviceToken;
$this->message = $message;
}
In handle method
$pushNotification = PushNotification::app('appNameAndroid')->to($this->deviceToken);
$pushNotification->adapter->setAdapterParameters(['sslverifypeer' => false]);
$pushNotification->send($this->message);
//In my controller
$job = (new JobName($deviceToken, $message))->delay(10);
$this->dispatch($job);
Related
I would like to send an email via task scheduler every minute using Laravel 8.
Below is my code on Kernel.php
$schedule->call(function () {
$adminController = new AdminController();
$adminController->test();
})->everyMinute();
On the Admin Controller I have a method called test
public function test()
{
try {
$fp = fopen('cronJobTest.txt', 'a');
fwrite($fp, "Testing Started. ");
fclose($fp);
$email = new \stdClass();
$email->subject = "Cron Job Test";
$email->greetings = "Hi, Tested";
$email->message1 = "This is a cron job tester";
$email->btn_text = 'Test';
$email->message2 = "";
$email->url = "dashboard/test";
\Illuminate\Support\Facades\Notification::route('mail', 'myemailaddressHere#gmail.com')->notify(new EmailNotification($email));
}catch (Exception $exception){
$fp = fopen('cronJobTest.txt', 'a');
fwrite($fp, "Failed with exception ".$exception->getMessage());
fclose($fp);
}
}
On my local machine I then run the command:
php artisan schedule:work
An email is sent to the provided email address as expected.
However, after uploading the source code to shared hosting cpanel and setting up the Cron Job, the scheduler does not send an email.
I am sure the method test() is fired because if you look at the test() method, I am creating a file 'cronJobTest.txt' everytime the method is called and appending the text 'Test Started'.
In my web routes I have created a route to direct to the test() method and if I call the method via the route, an email is sent. ie https://mylaraveldomain.com/test
Route::get("test", [AdminController::class, 'test']);
However the same same method does not send an email if fired from the scheduler.
What might be causing this?
Do you have a cron in your server? If not, then that is the problem. Refer to this page.
Edit: Have you confirmed that the cron is running properly? If not, put an everyMinute job that logs something first. Check first if the log shows up.
I can send email to all users after submitting the form but it takes some time. What I want to achieve is to skip that task(sending email) and run it in background after submitting the form. So, users can do other things asides waiting to finish the task(sending email).
I tried to look at https://laravel.com/docs/4.2/queues but I'm beginner in Laravel and I don't understand well the documentaion. by the way I'm using old laravel version which is laravel 4.2.
APKFileController.php
$users = User::All();
foreach($users as $user) {
$data = array(
'apk_name' => Input::get('name'),
'version' => $apk->version,
'download_link' => Input::get('remarks'),
'subject' => 'v' . $apk->version . ' is now available.',
'message' => 'A new version of APK has been released!',
);
$this->userMailer->sendToApp($user, compact('data'));
}
}
UserMailer.php
<?php namespace Sample\Mailers;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use User;
class UserMailer extends Mailer
{
public function sendToApp(User $user, $data)
{
$subject = $data['data']['subject'];
$view = 'emails.clients.apkInfo';
return $this->sendTo($user, $subject, $view, $data);
}
}
Mailer.php
<?php namespace Sample\Mailers;
use Illuminate\Mail\Mailer as Mail;
abstract class Mailer {
private $mail;
function __construct(Mail $mail) {
$this->mail = $mail;
}
public function sendTo($user, $subject, $view, $data = [] )
{
$this->mail->queue($view, $data, function ($message) use ($user, $subject) {
$message->to($user->email)->subject($subject);
});
}
}
You can create a artisan command, just as described here:
Building A Command
Generating The Class
To create a new command, you may use the command:make Artisan command, which will generate a command stub to help you get started:
Generate A New Command Class
php artisan command:make FooCommand
By default, generated commands will be stored in the app/commands
directory; however, you may specify custom path or namespace:
php artisan command:make FooCommand --path=app/classes --namespace=Classes
When creating the command, the --command option may be used to assign
the terminal command name:
php artisan command:make AssignUsers --command=users:assign
Then you create a crontab schedule to run your command as described here:
Add a Cron JobPermalink
Open a crontab for your user in a text editor (vi in most distributions):
crontab -e
Note:
To change the text editor used, add the environment variable to your ~/.bashrc file, exchanging vim for nano, or whatever other
terminal-based editor you prefer.
export EDITOR=vim
Add the Cron job, save, and exit. The crontab will be saved in /var/spool/cron/crontabsas a crontab specific to the user who created
it. To later remove a Cron job from it, delete the line from the
user’s crontab file.
Or you can simple put it in a Queuing system. Refer to this https://laravel.com/docs/4.2/queues
I have a question about how to method. I'm using Laravel
The goal :
Send an email the last day of month with a generated PDF.
How can you do to achieve this ?
I create my PDF in controller like this (with laravel-dompdf package)
$pdf = PDF::loadView('exportPDF.templatePDF', compact('data'));
return $pdf->stream('fileName'.pdf');
Should I use a notification file (php artisan make:notification ActionNotification) to add in my job queue ? A command file (php artisan make:command ActionCmd) ? Directly in the method in my Controller ? or other method ?
I'll appreciate that you give me the right way to develop this feature in Laravel.
Because I don't know how and where to start to do this.
Thank you very much.
You can create a Queued Job and call it via Task Scheduling.
Like so:
php artisan make:job SendMonthlyEmailWithPDF
Then edit the handle method in the created class to send the email.
And to call it at every end of a month:
$schedule->job(new SendMonthlyEmailWithPDF)->when(function () {
return \Carbon\Carbon::now()->endOfMonth()->isToday();
});
Below is what's happening when i run php artisan queue:listen and at my job table only have one job
and this is my code :
public function handle(Xero $xero)
{
$this->getAndCreateXeroSnapshotID();
$this->importInvoices($xero);
$this->importBankTransaction($xero);
$this->importBankStatement($xero);
$this->importBalanceSheet($xero);
$this->importProfitAndLoss($xero);
}
In order for a job to leave the queue, it must reach the end of the handle function -- without errors and exceptions.
There must be something breaking inside one or more of your functions.
If an exception is thrown while the job is being processed, the job will automatically be released back onto the queue so it may be attempted again. https://laravel.com/docs/5.8/queues
The same behavior can be achieved with
$this->release()
If you can't figure out what is breaking, you can set your job to run only once. If an error is thrown, the job will be considered failed and will be put in the failed jobs queue.
The maximum number of attempts is defined by the --tries switch used
on the queue:work Artisan command. https://laravel.com/docs/5.8/queues
php artisan queue:work --tries=1
If you are using the database queue, (awesome for debugging) run this command to create the failed queue table
php artisan queue:failed
Finally, to find out what is wrong with your code. You can catch and log the error.
public function handle(Xero $xero)
{
try{
$this->getAndCreateXeroSnapshotID();
$this->importInvoices($xero);
$this->importBankTransaction($xero);
$this->importBankStatement($xero);
$this->importBalanceSheet($xero);
$this->importProfitAndLoss($xero);
}catch(\Exception $e){
Log::error($e->getMessage());
}
}
You could also set your error log channel to be slack, bugsnag or whatever. Just be sure to check it. Please don't be offended, it's normal to screw up when dealing with laravel queues. How do you think I got here?
Laravel try to run the job again and again.
php artisan queue:work --tries=3
Upper command will only try to run the jobs 3 times.
Hope this helps
In my case the problem was the payload, I've created the variable private, but it needs to by protected.
class EventJob implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
// payload
protected $command;
// Maximum tries of this event
public $tries = 5;
public function __construct(CommandInterface $command)
{
$this->command = $command;
}
public function handle()
{
$event = I_Event::create([
'event_type_id' => $command->getEventTypeId(),
'sender_url' => $command->getSenderUrl(),
'sender_ip' => $command->getSenderIp()
]);
return $event;
}
}
The solution that worked for me to delete the job after pushing them into the queue.
Consider the e.g.
class SomeController extends Controller{
public function uploadProductCsv(){
//process file here and push the code inot Queue
Queue::push('SomeController#processFile', $someDataArray);
}
public function processFile($job, $data){
//logic to process the data
$job->delete(); //after complete the process delete the job
}
}
Note: This is implemented for laravel 4.2
I am using laravel 5.1 and i am using the dispatch method to push the job onto the queue.
But there are two kind of jobs and i have created and two queues for that in sqs.
How should i achieve this?
In order to specify the queue you need to call onQueue() method on your job object, e.g.:
$job = (new SendReminderEmail($user))->onQueue('emails');
$this->dispatch($job);
If you want to send the job to a connection other than default, you need to do fetch connection manually and send the job there:
$connection = Queue::connection('connection_name');
$connection->pushOn('queue_name', $job)
This worked for me.
//code to be used in the controller (taken from #jedrzej.kurylo above)
$job = (new SendReminderEmail($user))->onQueue('emails');
$this->dispatch($job);
I think this dispatches the job on to the queue named "emails".
To execute the job dispatched on 'emails' queue:
//Run this command in a new terminal window
php artisan queue:listen --queue=emails
I'd suggest this:
app('queue')->connection('connection_name')->pushOn('queue_name', $job);
From here: In Laravel how to create a queue object and set their connection without Facade