Giter Site home page Giter Site logo

thomasjohnkane / snooze Goto Github PK

View Code? Open in Web Editor NEW
846.0 12.0 88.0 218 KB

A package to simplify automating future notifications and reminders in Laravel

License: MIT License

PHP 100.00%
laravel laravel-package laravel-framework notifications scheduled-notifications delayed-queue delayed-notifications drip-campaigns onboarding-emails reminders

snooze's Introduction

Laravel Snooze

Schedule future notifications and reminders in Laravel

Build Status styleci

Latest Stable Version Total Downloads License

Why use this package?

  • Ever wanted to schedule a future notification to go out at a specific time? (was the delayed queue option not enough?)
  • Want a simple on-boarding email drip?
  • How about happy birthday emails?

Common use cases

  • Reminder system (1 week before appt, 1 day before, 1 hour before, etc)
  • Follow-up surveys (2 days after purchase)
  • On-boarding Email Drips (Welcome email after sign-up, additional tips after 3 days, upsell offer after 7 days)
  • Short-Term Recurring reports (send every week for the next 4 weeks)

Installation

Install via composer

composer require thomasjohnkane/snooze
php artisan migrate

Publish Configuration File

php artisan vendor:publish --provider="Thomasjohnkane\Snooze\ServiceProvider" --tag="config"

Usage

Using the model trait

Snooze provides a trait for your model, similar to the standard Notifiable trait. It adds a notifyAt() method to your model to schedule notifications.

use Thomasjohnkane\Snooze\Traits\SnoozeNotifiable;
use Illuminate\Notifications\Notifiable;

class User extends Model {
    use Notifiable, SnoozeNotifiable;

    // ...
}

// Schedule a birthday notification
$user->notifyAt(new BirthdayNotification, Carbon::parse($user->birthday));

// Schedule for a week from now
$user->notifyAt(new NextWeekNotification, Carbon::now()->addDays(7));

// Schedule for new years eve
$user->notifyAt(new NewYearNotification, Carbon::parse('last day of this year'));

Using the ScheduledNotification::create helper

You can also use the create method on the ScheduledNotification.

ScheduledNotification::create(
     Auth::user(), // Target
     new ScheduledNotificationExample($order), // Notification
     Carbon::now()->addHour() // Send At
);

This is also useful for scheduling anonymous notifications (routed direct, rather than on a model).

$target = (new AnonymousNotifiable)
    ->route('mail', '[email protected]')
    ->route('sms', '56546456566');

ScheduledNotification::create(
     $target, // Target
     new ScheduledNotificationExample($order), // Notification
     Carbon::now()->addDay() // Send At
);

An important note about scheduling the snooze:send command

Creating a scheduled notification will add the notification to the database. It will be sent by running snooze:send command at (or after) the stored sendAt time.

The snooze:send command is scheduled to run every minute by default. You can change this value (sendFrequency) in the published config file. Available options are everyMinute, everyFiveMinutes, everyTenMinutes, everyFifteenMinutes, everyThirtyMinutes, hourly, and daily.

The only thing you need to do is make sure schedule:run is also running. You can test this by running php artisan schedule:run in the console. To make it run automatically, read here.

Note: If you would prefer snooze to not automatically schedule the commands, you can set the scheduleCommands config value to false

Setting the send tolerance

If your scheduler stops working, a backlog of scheduled notifications will build up. To prevent users receiving all of the old scheduled notifications at once, the command will only send mail within the configured tolerance. By default this is set to 24 hours, so only mail scheduled to be sent within that window will be sent. This can be configured (in seconds) using the SCHEDULED_NOTIFICATION_SEND_TOLERANCE environment variable or in the snooze.php config file.

Setting the prune age

The package can prune sent and cancelled messages that were sent/cancelled more than x days ago. You can configure this using the SCHEDULED_NOTIFICATION_PRUNE_AGE environment variable or in the snooze.php config file (unit is days). This feature is turned off by default.

Detailed Examples

Cancelling Scheduled Notifications

$notification->cancel();

Note: you cannot cancel a notification that has already been sent.

Rescheduling Scheduled Notifications

$rescheduleAt = Carbon::now()->addDay(1)

$notification->reschedule($rescheduleAt)

Note: you cannot reschedule a notification that has already been sent or cancelled. If you want to duplicate a notification that has already been sent or cancelled, pass a truthy second parameter along with the new send date; reschedule($date, true), or use the scheduleAgainAt($date) method shown below.

Duplicate a Scheduled Notification to be sent again

$notification->scheduleAgainAt($newDate); // Returns the new (duplicated) $notification

Check a scheduled notification's status

// Check if a notification is already cancelled

$result = $notification->isCancelled(); // returns a bool

// Check if a notification is already sent

$result = $notification->isSent(); // returns a bool

Conditionally interrupt a scheduled notification

If you'd like to stop an email from being sent conditionally, you can add the shouldInterrupt() method to any notification. This method will be checked immediately before the notification is sent.

For example, you might not send a future drip notification if a user has become inactive, or the order the notification was for has been canceled.

public function shouldInterrupt($notifiable) {
    return $notifiable->isInactive() || $this->order->isCanceled();
}

If this method is not present on your notification, the notification will not be interrupted. Consider creating a shouldInterupt trait if you'd like to repeat conditional logic on groups of notifications.

Scheduled Notification Meta Information

It's possible to store meta information on a scheduled notification, and then query the scheduled notifications by this meta information at a later stage.

This functionality could be useful for when you store notifications for a future date, but some change in the system requires you to update them. By using the meta column, it's possible to more easily query these scheduled notifications from the database by something else than the notifiable.

Storing Meta Information

Using the ScheduledNotification::create helper

ScheduledNotification::create(
     $target, // Target
     new ScheduledNotificationExample($order), // Notification
     Carbon::now()->addDay(), // Send At,
     ['foo' => 'bar'] // Meta Information
);

Using the notifyAt trait

  $user->notifyAt(new BirthdayNotification, Carbon::parse($user->birthday), ['foo' => 'bar']);

Retrieving Meta Information from Scheduled Notifications

You can call the getMeta function on an existing scheduled notification to retrieve the meta information for the specific notification.

Passing no parameters to this function will return the entire meta column in array form.

Passing a string key (getMeta('foo')), will retrieve the specific key from the meta column.

Querying Scheduled Notifications using the ScheduledNotification::findByMeta helper

It's possible to query the database for scheduled notifications with certain meta information, by using the findByMeta helper.

  ScheduledNotification::findByMeta('foo', 'bar'); //key and value

The first parameter is the meta key, and the second parameter is the value to look for.

Note: The index column doesn't currently make use of a database index

Conditionally turn off scheduler

If you would like to disable sending of scheduled notifications, set an env variable of SCHEDULED_NOTIFICATIONS_DISABLED to true. You will still be able to schedule notifications, and they will be sent once the scheduler is enabled.

This could be useful for ensuring that scheduled notifications are only sent by a specific server, for example.

Enable onOneServer

If you would like the snooze commands to utilise the Laravel Scheduler's onOneServer functionality, you can use the following environment variable:

SCHEDULED_NOTIFICATIONS_ONE_SERVER = true

Running the Tests

composer test

Security

If you discover any security related issues, please email instead of using the issue tracker.

Contributing

  1. Fork it (https://github.com/thomasjohnkane/snooze/fork)
  2. Create your feature branch (git checkout -b feature/fooBar)
  3. Commit your changes (git commit -am 'Add some fooBar')
  4. Push to the branch (git push origin feature/fooBar)
  5. Create a new Pull Request

Credits

This package is bootstrapped with the help of melihovv/laravel-package-generator.

snooze's People

Contributors

atymic avatar azarzag avatar colq2 avatar cristiancalara avatar danielsimkus avatar elishaukpong avatar ettiennelouw avatar gborcherds avatar gpanos avatar joe-pritchard avatar laravel-shift avatar pxlrbt avatar ricuss avatar thdebay avatar thomasjohnkane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

snooze's Issues

Reference to $notification for canceling/reschedule

I'm having this scenario:

  1. User needs to set targetDay
  2. In model I'm listening for "created" event
  3. $user->notifyAt(new TargetDayReminder, $targetDay);
    Along with that I'm scheduling some more events for the same entry/user - for example BirthdayReminder ...

This works.

But I'm having problem when user change $targetDay.
I'm listening to models "updated" event and I know there is "reschedule" method available in ScheduledNotifications.

But to call "reschedule", I need to have reference to $notification.
From your example: $notification->reschedule($rescheduleAt)

What would be the best way to get that reference?

I guess I should be able to get reference from this 3 parameters:

  • Class name of notifiable class "TargetDayReminder"
  • User
  • SendAt

Or should I use completely different approach to handle situations like this?

findByMeta with target

Hello,
great package!
But is it possible to get the scheduled_notification by the meta tag but also eager load the target?

Use case:
I have tasks
The task has reminder notifications
The target is the selected user of the task notification
The task is stored in the meta data
I get all reminders / notificaitons for a task with findByMeta as a task attribute

Now a solution could be iterating with a foreach through every notification of the getRemindersAttribute function.
But is it build in and i couldnt figure it out?

Add a way to retrieve underlying Notification

It would be useful if we had a way to retrieve the underlying Illuminate\Notifications\Notification from the ScheduledNotification class. It's already part of the Eloquent model so it'd be handy to have a getNotification() method. There's already functionality for unserializing it.

How get ID after sending scheduled notification

how i can get id after send notification $user->notifyAt(some_notification_class)
i want stored in my table to cancel specific notification for user.
for cancel notification i use
$scheduledNotification= ScheduledNotification::find(scheduled_notification_id); $scheduledNotification->cancel();

Prune send/cancelled notifications

There's currently no mechanism to clean up send/cancelled notifications. Over time the table will grow and grow, so we should probably have some way of cleaning up old entries.

[BUG] QueryException: Incorrect table name while running migrate command

After installing the package when I was going to run php artisan migrate .
It shows me
Illuminate\Database\QueryException
SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name '' (SQL: create table `` (idint unsigned not null auto_increment primary key,target_idvarchar(255) null,target_typevarchar(255) not null,targettext not null,notification_typevarchar(255) not null,notificationtext not null,send_atdatetime not null,sent_atdatetime null,rescheduled_atdatetime null,cancelled_atdatetime null,created_attimestamp null,updated_at timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

I have published the config file.
Versions:
Laravel Framework 7.30.4
PHP 7.4.15

Please check your example #3

Hi!

I tried use your package but I can't understand how use this in controllers. Please public more examples for controllers. Thank you!

Cancel notifications by target

I think we should add a way to cancel all future notifications for a target. For example, if they unsub we don't want to continue sending.

Possible implementation:
Add a target_type column to the migration, and method to cancel outstanding notifications for a target.

Switch flags to be datetime fields

I think having the flags (sent, rescheduled, cancelled) as datetime fields would be useful. It would help with debugging to know when the action happened.

Scheduled notification events

I think we should add an event dispatched before and after a notification is sent.

It would allow the application to do some checks before the notification is sent (ie, ensure that the user is still active, etc) and after (record that x email was sent)

There are no commands defined in the "snooze" namespace

Hi
I'm getting the following error in my schedule:run cron job

[2020-08-06 13:56:02] local.ERROR: There are no commands defined in the "snooze" namespace. {"exception":"[object] (Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException(code: 0): There are no commands defined in the \"snooze\" namespace. at /home2/foldernamechanged/public_html/testing/vendor/symfony/console/Application.php:597)
[stacktrace]
#0 /home2/foldernamechanged/public_html/testing/vendor/symfony/console/Application.php(650): Symfony\\Component\\Console\\Application->findNamespace('snooze')
#1 /home2/foldernamechanged/public_html/testing/vendor/symfony/console/Application.php(235): Symfony\\Component\\Console\\Application->find('snooze:send')
#2 /home2/foldernamechanged/public_html/testing/vendor/symfony/console/Application.php(147): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#3 /home2/foldernamechanged/public_html/testing/vendor/laravel/framework/src/Illuminate/Console/Application.php(90): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#4 /home2/foldernamechanged/public_html/testing/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(133): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#5 /home2/foldernamechanged/public_html/testing/artisan(36): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#6 {main}
"} 

sendFrequency is set to everyMinute so I'm getting this error every minute now.

When I manually run schedule:run or snooze:send in console it works fine. The issue seems to occur only in the cron job.
Running php artisan shows

 snooze
  snooze:prune                  Prune scheduled notifications that have been sent or cancelled
  snooze:send                   Send scheduled notifications that are ready to be sent.

Searching the web, most answers were to run config:clear , cache:clear, composer dump-autoload, but no luck doing that.

Any ideas on what could be wrong?

System Details

php: 7.2.32
laravel: 5.8.38
snooze: 1.0.3
os: CentOS Linux release 7.8.2003 (Core)

How to get notifications data from scheduled message

I want to show all scheduled message by authenticate user. But I did not find any documentation about it.
I've look through the source code and found method findByTarget(). Is that related method to get all scheduled notifications by current authenticated user?

And I saw at table, especially notification column. I wonder how I get my custom data because it's like a pattern right there (not the same like notifications data on default laravel notifications table)

V2 Roadmap

  • Fix #52 issues with psql
  • Fix #60 by publishing migrations
  • Fix #47 by adding a tries column to migration
  • Clean up code issues
  • Drop old laravel version support

Missed notifications improvements

I think it'd be a good idea to have an event or notification in the case that we have a large backlog of unsent notifications (snooze was not running for x days).

Otherwise it could just go unnoticed by the developer unless they checked the table.

Also, adding a command to cancel one that were missed (or doing this when the above notification is sent?)

unserialize(): Error at offset

in laravel version "version": "v7.14.1", i got this error, i found databse notification field data is not right,
O:41:"App\Notifications\AppointmentNotification":10:{s:11:"
it's missing something. Why?
i have a Appointment model to store user's appoinment,
and how can i get the notification by Appointment id? if user change the appointment time, i need to reschedule the notification, i only can get the notification by user id / notification type

Admin UI &/Or Nova Package

Just moving this from the readme so we can discuss ๐Ÿ˜„

  • Show tab for past notifications
  • Show tab for scheduled notifications
  • Give CRUD options for scheduled notifications
  • Create as a Nova Package

Publish migrations

Great job on the package!
I would like to add some additional fields on the migration - therefore it would be great if the migration wouldn't get loaded automatically from the service provider, but if I could just publish and modify it instead.
Would you accept a PR with that change?

Laravel 9 Support?

Is the package still maintained? Will there be an update for Laravel 9?

Notifications Event : NotificationSent should fire after commits

I have a case when I've created a listener when notification is sent on laravel that have a simple task which is check if current scheduled notification is sent. I know it's weird because it's actually/already sent but I've check it again on that events.
But from the case, I know that method $notification->isSent() is always false.

I've looked at the code and found this line from this closed issue.

From that logic then I know that the result will always false because
event(new NotificationSent($this));
is firing before

$this->sent_at = Carbon::now();
$this->save();

I think it will be good to put it after update event so method like isSent() still return true in notificationsSent listener.

Tag v1.0

I think we are ready to tag the first version of the package.
Is there anything else we need to do before then?

cc @thomasjohnkane

unserialize(): Error at offset

Hey @thomasjohnkane ,

Thanks for the wonderful package.

I am having the following issue often while unserialize the content. it clearly shows couldn't unserialize data but serialize & unserialize are via the package.

when unserialize fails it's crashing, and unserialize has no way to catch the exception as well.
It automatically retries N times based on tolerance time and it crashes N times.

Please let me know is there any work around for this?

domain/username/Message
unserialize(): Error at offset 6079 of 18968 bytes
Level
ERROR
Exception

   "class": "ErrorException",
   "message": "unserialize(): Error at offset 6079 of 18968 bytes",
   "code": 0,
   "file": "/username/web/domain/vendor/thomasjohnkane/snooze/src/Serializer.php:34",
   "trace": [
       "/username/web/domain/vendor/thomasjohnkane/snooze/src/Serializer.php:34",
       "/username/web/domain/vendor/thomasjohnkane/snooze/src/Models/ScheduledNotification.php:66",
       "/username/web/domain/vendor/thomasjohnkane/snooze/src/Console/Commands/SendScheduledNotifications.php:58",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Support/Collection.php:475",
       "/username/web/domain/vendor/thomasjohnkane/snooze/src/Console/Commands/SendScheduledNotifications.php:63",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Container/Container.php:576",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Console/Command.php:183",
       "/username/web/domain/vendor/symfony/console/Command/Command.php:255",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Console/Command.php:170",
       "/username/web/domain/vendor/symfony/console/Application.php:1001",
       "/username/web/domain/vendor/symfony/console/Application.php:271",
       "/username/web/domain/vendor/symfony/console/Application.php:147",
       "/username/web/domain/vendor/laravel/framework/src/Illuminate/Console/Application.php:90",
       "/username/web/domain/โ€ฆ

Is there any way to schedule notifications for them to happen daily?

I'm trying to make for my backend to send a notification each day that that comes closer to an indicated date.

For example, if my user adds the date "16-07-2020", he should be getting a notification "your deadline is in 1 day!" (as today is 15).

How is it possible to make it with this package?

Update Email only

Hello,

I have an AnonymousNotifiable and want to change the email only. For example the user changes his email so I want to update the notification. Otherwise it will be send to the old one.

How can I do that?

Thanks

it's possible to preview?

it's possible to preview scheduled notifications?

i.e. in Laravel 8 I can do something like to preview notifications:

Route::get('/preview', function () {
  $admin = User::find(1);
  $company = Company::find(1);
   return (new CompanyRegistration($company))->toMail($admin);
});

I.e. its possible to do something like...:

$notification = ScheduledNotification::find(1);
return $notification->getPreview();

?
thnks

Add `shouldRescheduleFor` method (similar to `shouldInterrupt`)

I'm creating a zip in AWS that might take as long as 15m. I'd like to send the notification as soon as possible, so ideally I'd check every minute, and then if it's ready I send the notification, if not, I reschedule.

I've done this by extending the custom model and overwriting the send method.

public function send(): void
{
    // ...
    if ($this->shouldInterrupt($notification, $notifiable)) {
        $this->cancel();
        event(new NotificationInterrupted($this));

        return;
    }

    if($sendAt = $this->shouldRescheduleFor($notification, $notifiable)) {
        $this->reschedule($sendAt);

        return;
    }
    // ...

}

public function shouldRescheduleFor(?object $notification = null, ?object $notifiable = null):
\DateTimeInterface|string|null
{
    if (! $notification) {
        $notification = $this->serializer->unserialize($this->notification);
    }

    if (! $notifiable) {
        $notifiable = $this->serializer->unserialize($this->target);
    }

    if (method_exists($notification, 'shouldRescheduleFor')) {
        return $notification->shouldRescheduleFor($notifiable);
    }

    return null;
}

Created the issue mainly to ask if you think this might be a useful feature for the package. If that's the case, I can create a PR for this.

Thanks for the package! :)

No scheduled notifications need to be sent

I have done all the configuration and the notifications are being stored in the scheduled notifications table but when I run the "php artisan snooze:send" command it says no scheduled notifications need to be sent.

Custom Data

Is there a way to add custom data to a notification? For example, writing an email or SMS and then scheduling that notification ? I can see there is a link in the documentation for support custom data, however it no longer exists, and the custom code example files are no longer in the documentation. Currently, when trying to do this, the notification just doesn't send.

Limit tries sending email before cancellation

I had a bug where one of the notifications was updated, but the previously serialized version had some invalid data in it.

This caused problems because snooze tries (and fails) to send it every minute.
We should have some kind of 'try' limit, to make sure we don't keep trying (and failing) to send the same notification.

image

How do I get notification type to cancel?

I am trying to do this but I get a json error. Is there an easier way to cancel a notification by findyByTargetAndType?

`

   $scheduledNotification=ScheduledNotification::findByTarget($user);
   foreach ($scheduledNotification as $key ) {
            print_r('yes');
   if($key->getType() == 'App\Notifications\BookAMassageReminderNotificationApp')

   {
    print_r('yes');
   }
   else{
    print_r('no');
   }
   }`

Multi-Tenancy

Hello,
first of all thank you so much for creating this package.. How do I implement multitenancy into this package?

I am currently creating an application that uses the multitenancy feature with the archtechx/tenancy package. I have already created a duplicate of the scheduled_notifications table in the tenant database, but I am unable to perform the php artisan snooze:send command because this actions will trigger to the central database while the notification data is located in the tenant database.

Report caught exceptions when sending

Currently we just log an errors that happen when sending scheduled emails (to avoid breaking future sends in that batch).

justaphpguy on reddit raised that we should use the report hepler instead, which means it's passed onto things like Sentry, etc.

Ref: https://laravel.com/docs/5.7/errors#report-method

Pretty cool! ๐Ÿ‘

I wonder though if the error handling in the console is a good idea => https://github.com/thomasjohnkane/snooze/blob/master/src/Console/Commands/SendScheduledNotifications.php#L55-L64

php try { $notification->send(); } catch (\Exception $e) { $this->error($e->getMessage()); Log::error(sprintf('Failed to send notification: %s', $e->getMessage())); }

Since the command is the primary way this is used with the scheduler, I believe this should be improved.

Sending to $this->error() and Log::error() is nice, but in reality you want to funnel this through the application exception handler so you can have proper reporting.

This removes the need for Log:error, not sure about $this->error().

php try { โ€ฆ } catch (\Throwable $t) { report($e); $this->error($e->getMessage()); } Just my 2c ;)

Question:how you check the notification entries in table is due?

Very great package i would say!

This is not really an issue, but rather a question of my curiosity. May i know, how you check the notification entries in table is due, let say when after running snooze:send command?

Appreciate for the clarification!

Thanks

How can I cancel the notification

Hi, I did create a notification from a model:

$finance->notifyAt(new ThreeConsecutiveNsfsDayOneEmail(), $this->due);

Now, I need to cancel this notification, the documentation is saying $notification->cancel(); but how can I have the notification. I tried the following but didn't work.

$notification = new ThreeConsecutiveNsfsDayOneEmail();
$notification->cancel();

So, what is the solution to do so, can you update the documentation.

Thank you,

Detect duplicate notifications

For example, when a job fails part way through and is retried it's possible to end up with a bunch of duplicate scheduled notifications.

Detecting this and throwing an exception or maybe silent fail?
Should be behind a config option

Bulk/Multiple notifiables

Hi,

first of all thank you so much for creating this package.. does this package support bulk, multiple notifiables? just like laravel Notification::send()

if($request->schedule && !empty($request->scheduled_at))
{
    $enrolledUsers = User::whereRelation('enrolledCourses', 'course_id', $course_id)->get();

    ScheduledNotification::create(
        $enrolledUsers, // Target
        new NewLessonNotification($lesson), // Notification
        Carbon::createFromFormat('d/m/Y h:i a', $request->scheduled_at) // Send At
   ); // gives me error: Collection is not notifiable..

} else {

    $enrolledUsers = User::whereRelation('enrolledCourses', 'course_id', $course_id)->get();
    
    Notification::send($enrolledUsers, new NewLessonNotification($lesson));
}

Type error: Argument 1 passed to Thomasjohnkane\Snooze\ScheduledNotification::create() must be an instance of Thomasjohnkane\Snooze\object

Hi. We used this good package at our stage server, at local version it is also works fine, but today we are added it to the production server (master branch is equal to stage branch) and got an error:

Type error: Argument 1 passed to Thomasjohnkane\Snooze\ScheduledNotification::create() must be an instance of Thomasjohnkane\Snooze\object, 
instance of App\Models\VideoCall given, called in [...]/public/vendor/thomasjohnkane/snooze/src/Traits/SnoozeNotifiable.php on line 23
{"userId":40,"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Type error: Argument 1 passed
to Thomasjohnkane\\Snooze\\ScheduledNotification::create() must be an instance of Thomasjohnkane\\Snooze\\object,
instance of App\\Models\\VideoCall given, called in [...]/public/vendor/thomasjohnkane/snooze/src/Traits/SnoozeNotifiable.php
on line 23 at [...]/vendor/thomasjohnkane/snooze/src/ScheduledNotification.php:37)
[stacktrace]

#0 [...]/public/vendor/thomasjohnkane/snooze/src/Traits/SnoozeNotifiable.php(23):
Thomasjohnkane\\Snooze\\ScheduledNotification::create(Object(App\\Models\\VideoCall), Object(App\\Notifications\\VideoCallsNotice), Object(Carbon\\Carbon))

#1 [...]/public/app/Observers/VideoCallObserver.php(21):
App\\Models\\VideoCall->notifyAt(Object(App\\Notifications\\VideoCallsNotice), Object(Carbon\\Carbon))

#2 [internal function]: App\\Observers\\VideoCallObserver->created(Object(App\\Models\\VideoCall))

Our model VideoCall uses Notifiable and SnoozeNotifiable traits.

And we are calling it:

$call->notifyAt(new VideoCallsNotice(), $startDate->subMinutes(30));

Laravel 5.6
PHP 7.2.33

Maybe some PHP extension needs to be enabled, or something else?

Unable to retrieve parameters in notification

Hello,

I am a little confused by the following behaviour.

// this is working
Notification::send(
    $event->user, // Target
    new DripMarketingNotification($rule)
);

// this is not
ScheduledNotification::create(
    $event->user, // Target
    new DripMarketingNotification($rule),
    Carbon::now()->addSeconds($rule->delay) // Send At
);

The scheduled notification appears in the DB table, but when I run artisan schedule:run I get the following error in the logs:

Undefined property: $dripRule {"exception":"[object] (ErrorException(code: 0) at .../src/Notifications/DripMarketingNotification.php:43)

But the regular Notification facade works perfectly. Is there something I am missing?

This is the code from DripMarketingNotification.php

public function toMail($notifiable)
{
    return (new DripMarketingMail($notifiable, $this->dripRule))->to($notifiable->email);
}

You don't pass the $notifiable to the shouldInterrupt() method ?

If I understand the docs, I should be able to add a public function shouldInterrupt($notifiable) to my class MyCoolNotification extends Notification, something like:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class MyCoolNotification extends Notification 
{
    use Queueable;

    public function shouldInterrupt($notifiable) {
        return $notifiable->my_bool_value;
    }
}

but I get an exception: Too few arguments to function App\Notifications\MyCoolNotification::shouldInterrupt(), 0 passed in ..............\vendor\thomasjohnkane\snooze\src\Models\ScheduledNotification.php on line 95 and exactly 1 expected

in that line 95 you call: return (bool) $notification->shouldInterrupt();

I think you are missing passing the $notifiable ??

[URGENT ACTION REQUIRED] StyleCI Payment Details

StyleCI is migrating to a new payment system, and you must re-enter your payment information as soon as possible to continue using the StyleCI Monthly Solo plan. Please re-enter your payment details on the StyleCI account settings page, or directly by clicking here.

nothing to migrate in production server

Hi, thanks for this amazing package

in my local environment i used composer require thomasjohnkane/snooze and php artisan migrate
which works perfectly fine and the local database migrated successfully

BUT
when i pushed updates to private git repo and then pull them in prod server
but i used composer install --no-scripts --no-dev commend to install the package then
when i tried php artisan migrate i get Nothing to migrate. message

Workaround
that i'm using right now is copying the migration file from snooze/migrations/2019_02_25_231036_create_scheduled_notifications_table.php to the local env under database/migrations folder than pushing changes to prod env than running php artisan migrate

The script tried to call a method on an incomplete object...

Hello,
thank you for amazing package.
I have started getting lots of sentry errors with internal exceptions. Here is the trace:

Error: The script tried to call a method on an incomplete object. Please ensure that the class definition "App\Notifications\ReminderOnboard" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide an autoloader to load the class definition
#19 /vendor/thomasjohnkane/snooze/src/Models/ScheduledNotification.php(103): method_exists
#18 /vendor/thomasjohnkane/snooze/src/Models/ScheduledNotification.php(103): Thomasjohnkane\Snooze\Models\ScheduledNotification::shouldInterrupt
#17 /vendor/thomasjohnkane/snooze/src/Models/ScheduledNotification.php(73): Thomasjohnkane\Snooze\Models\ScheduledNotification::send
#16 /vendor/thomasjohnkane/snooze/src/Console/Commands/SendScheduledNotifications.php(58): Thomasjohnkane\Snooze\Console\Commands\SendScheduledNotifications::Thomasjohnkane\Snooze\Console\Commands\{closure}
#15 /vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(244): Illuminate\Support\Collection::each
#14 /vendor/thomasjohnkane/snooze/src/Console/Commands/SendScheduledNotifications.php(63): Thomasjohnkane\Snooze\Console\Commands\SendScheduledNotifications::handle
#13 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}
#12 /vendor/laravel/framework/src/Illuminate/Container/Util.php(40): Illuminate\Container\Util::unwrapIfClosure
#11 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\BoundMethod::callBoundMethod
#10 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::call
#9 /vendor/laravel/framework/src/Illuminate/Container/Container.php(653): Illuminate\Container\Container::call
#8 /vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Illuminate\Console\Command::execute
#7 /vendor/symfony/console/Command/Command.php(298): Symfony\Component\Console\Command\Command::run
#6 /vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Illuminate\Console\Command::run
#5 /vendor/symfony/console/Application.php(1015): Symfony\Component\Console\Application::doRunCommand
#4 /vendor/symfony/console/Application.php(299): Symfony\Component\Console\Application::doRun
#3 /vendor/symfony/console/Application.php(171): Symfony\Component\Console\Application::run
#2 /vendor/laravel/framework/src/Illuminate/Console/Application.php(94): Illuminate\Console\Application::run
#1 /vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\Foundation\Console\Kernel::handle
#0 /artisan(37): null

UPDATE:
Found the problem. The notification file was moved to another folder, but the records in scheduled_notifications database table had old file path.
How this case could be solved?

"App\Models\User is not notifiable" error

Hi,

thanks a lot for your amazing work.

I would like to understand the given error. According to the documentation in the README file, I should have a Model like this:

class User extends Model {
    use SnoozeNotifiable;

    // ...
}

that sadly fires the error in the issue subject.

If look closer, the error is thrown in lines 46-48 of ScheduledNotification.php:

if (! method_exists($notifiable, 'notify')) {
        throw new SchedulingFailedException(sprintf('%s is not notifiable', get_class($notifiable)));
}

if fact, looking at Traits/SnoozeNotifiable.php I see that only the notifyAt method is declared, but not notify.

The error disappear if I declare the Model as

    use Notifiable, SnoozeNotifiable;

    // ...
}

Anyway I would like to know if there's a mistake somewhere in my code, or "simply" something to add in the README.

version "1.0.5"
Laravel "v6.20.27"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.