I am new to nodeJs.
I am developing a platform where users can subscribe in trial or pro version. I would like to know if I can use the setTimeout method to delete a user's info from db after the subscription expiration date. if this is not possible is there a way to do it or a library that allows you to manage subscriptions?
You can, but it would not be a good approach since you be manging that on memory and if your server restarts you will lose this subscription status.
Why don't you just save on database the subscription date and on user login verify if the subscription date difference from the now is greater than the period of free subscription?
A solution to your problem is to run a CRON job. That may run once every 24 hours to check user's subscription's and if trial has expired then delete the user. You can use the cron npm package to achieve this.
setTimeout is not reliable, service can go up or down and your request should be persistent.
You need an offline job manager, DB-based, like agenda or similar.
Question is also discussed widely here: I need a Nodejs scheduler that allows for tasks at different intervals
Other solution: create TTL Index. Mongodb periodically checks and remove expired users.
You don't need to write any extra code / logic.
Related
Hi I want to create a payment plan expiry reminder using django
Current Solution
Create a management command
Run the management command as a cron job
Problems with the Current sollution
in windows cron job doesn't work
it will run at particular time for all the users
I don't want to run cron for every minute
But i want to notify the user when 50%,30%,20%,10% and 5% time is remaining.
What I'm looking for
I'm trying to do something that can be done using the expiry_date ('available in the membership model of user and plan ')
using which we can just look at the membership which are expiring and notify them only.
final and most important i don't want to run a cron job every minute , but want to achieve a functionality which lets the user even remind that you have just 10mins remaining ,5 mins remaining kind of notifications.
as the process is for learning I'm not looking for any paid API's
In my application users create documents which are then saved in the database. The document has expireAt field which is set to 30 days ahead from the date it is created. After the expiration date the document is considered as inactive.
So, what I want is to send an email to the user after expiration date to notify him that his document is now inactive. The only solution I see is to create a cron job and periodically poll the database for expired documents.
But I'm not sure if periodical polling is a good approach and would like to know if there are other ways of doing this.
P.S. The app is built with nodejs + mongoDB
If your use case is just removing the expired doc, you could use TTL feature of mongodb.
Since you need to send an email, the best option is cron job as you already thought of. Yes, periodically polling is a good option and works in most of the use cases and you do have control over it.
As per your requirement, you could poll once per day. If you are still need to care till minute level of expiry, you could do that by subtracting 24 hours from your actual query and send an alert for user convenience.
Tykaty, you can try to use 2 features of mongodb:
Expire data https://docs.mongodb.com/manual/tutorial/expire-data/
Change events https://docs.mongodb.com/manual/reference/change-events/ https://docs.mongodb.com/manual/changeStreams/#watch-a-collection--database--or-deployment
The idea is simple. You store the documents as before. Add a collection that you will watch and add there objects which should expire, link each document in your original collection to a corresponding object to be expired(1 to 1 link). When the object is deleted by mongo engine(expired), you get a notification with it's _id. Find this _id in your original collection of documents to understand which doc was expired. Here you are.
Of course, you can start with polling, final solution depends on the data and it's usage, the load as well.
I'd like to be able to test locally that the correct actions are taken when the trial period for a user ends.
I set up the Stripe CLI, and start listening:
stripe listen --forward-to http://localhost:8000/api/stripe-webhook
When a trial comes to an end, the customer.subscription.updated event will occur.
I trigger this event using the Stripe CLI:
stripe trigger customer.subscription.updated
On my server side I can see that payload['data']['previous_attributes'] contains a metadata array with foo = null. When a trial ends, we should get previous_attributes containing something like: { "status": "trialing"...
I'm wondering if it's possible to trigger an event using the Stripe CLI that mimics a user trial ending (or maybe even just a way to set the previous_attributes to similar values that'd occur in a live environment when a trial ends)? If it's possible to do that then it'd be a little easier to test locally that the appropriate action occurs when a trial ends without pushing to a prod-like environment.
The easiest way is probably to just use trial_end to set a very short trial period either when creating a subscription, or on an existing subscription, and wait a couple of minutes for it to end, at which point it will generate the appropriate events.
stripe subscriptions update sub_HpOl9vDMzIEfGf --trial-end=`date -v +5M +%s`
https://stripe.com/docs/billing/testing#trials
https://stripe.com/docs/api/subscriptions/update#update_subscription-trial_end
Requirement-
The requirement is to send notifications to devices on specific times. That is, if a user has setup a schedule at 07:00 AM for breakfast, he'll get a notification for the same like 'Its time for breakfast, blah blah blah!'.
However, if the user has already had his breakfast before 07:00 AM, he'll make his diary entry on what he had etc. and then the notification must not be sent to him.
This is a recurring schedule and the user will only change this if he needs to, otherwise, the schedule will mostly be the same.
What we have achieved?-
So, for now what we do is to register devices with tags like '{TimeZone:EST},{Breakfast:07:00:00}' on the app's launch.
In case, the user has already had his breakfast, we update his registration on notification hub to also contain a tag like '{HadBreakfast}' - So, the set of tags user's device is registered to becomes - '{TimeZone:EST},{Breakfast:07:00:00},{HadBreakfast}'
What are we stuck at?-
This approach will work very well because, when sending notifications, we use tag expression like - '{TimeZone:EST} && {Breakfast:07:00:00} && !{HadBreakfast}'
So, this will send a notification to all users that wants a notification for breakfast at 07:00:00 AM for EST timezone but not to the ones who already had their breakfast.
However, if the user is registered with a tag like {HadBreakfast}, then the next day, he might not get the notification based on the logic just described.
So, we came up with the workaround to de-register only the {HadBreakfast} tag at the end of day for all the devices which has that tag by running a scheduler.
But, somewhere in our mind, we think that is not the best solution for this problem.
Other Alternative-
We also thought of another alternative that we can run a scheduler for every hour within which, it will do the same thing of removing such tags for the past hour for all the user devices which has that tag - and this process seems to be effective than running it once in a day.
But we wanted to know thoughts from the community on what I can try out? If the method that we use is correct or not? What else could be done to do this more simply OR smoothly? What if we have a million plus devices? Will this work?
I would suggest exploring the option for modifying registration in bulk and using the Azure Scheduler for the reaccuring task
I am dealing with subscriptions where a user is subscribed to a plan and it has an expiration.
So basically each user store has an expiration field.
I want to be able to get notified when a user plan is expired as soon as it is actually expired.
Right now, I have a job that runs on all users once a day and check if anyone has expired but ideally I would like to get a server postback or some sort of event whenever a user is expired without running this each day.
Can you think of any third party service / database / other tool that deals with these sort of things ?
A lot of services, Stripe for example, notify you with a webhook whenever a user's subscription is renewed / expired. Are they just running a job repeatedly like I am ?
Hope I made myself clear enough, would appreciate help in how to focus my search in Google as well.
My current stack is Mongodb, Node.js, AWS
Thanks
We do not know for sure, how Stripe handles it.
There are two solutions coming to my mind. Let's start with the simple one:
Cronjob
As you mentioned, you already have a Cronjob solution, but you can instead make it run each hour, or each 10 minutes. Just ensure you optimize your query to the maximum, so that it is not super-heavy to run.
It is attractive, easy to implement, very few edge cases, but as you might have though can be a performance drag once you reach millions of clients.
Timers
Implementation varries, and you need to worry about the edge cases, but the concept:
On day start* (00:00) query for all clients who are set to expire today, save them into array (in-memory). Sort the array by time (preferably descending).
Create timer to execute on last array's element time.
Function: If Client X expires now, query database to ensure subscription was not extended. Notify if it wasn't.
Remove Client X from the tracked array. Repeat step 2.
On day start* - Also run it on script launch.