Time based notifications service - node.js

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.

Related

What is the best way to notify users that document expired in database?

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.

NodeJs - setTimeout() for delete user subscription from db

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.

Getting notification of sales/refunds done through Square POS/Connect

I would like to integrate my web application with the Square POS.
The goal would be to be notified each time a transaction (sale/refund/etc) is processed by Square for an account so that I can update inventory levels etc, ultimately so I can update inventory levels as transactions occur.
From what I can tell, it seems that the Square API's seem to be designed around my application initiating the transaction, then handing off to Square to process the payment. I simply want to be notified that a transaction has happened so that I can update inventory.
Is it possible to do this? Or is the Square API just for processing payments?
edit: After some more reading, I still haven't found a webhook to be notified, but it looks like I can ListTransactions, and RetrieveTransaction, so if I poll I should be ok.
You’re correct. Square’s API Webhooks will be what you’ll use to be notified each time a transaction is created or updated. We have a quick setup guide available in Square’s Developer Doc (https://docs.connect.squareup.com/api/connect/v1/?q=webhooks#setupwebhooks).
The PAYMENT_UPDATED webhook will alert you every time a payment is made, so that you can update your inventory.

Azure Notification Hub: How to handle registration for a million devices?

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

Use the Twitter API to run a script every time I post a new tweet

I have a PHP script on my server that I want to run every time I post a new tweet to Twitter. Is there a way to automate this?
I could of course set up a cron job to run the script every five minutes, or run the script manually every time after tweeting, but neither of those is instant — and that’s exactly what I’m looking for.
Is it possible to use the Twitter API to run a script / get a URL every time my timeline is updated?
No, it is not possible.
The twitter API, as well as more or less every other web site API, do not allow you to set up such a feature. They only let you request data. It is up to you to request this data regularly and do something with it.
In theory, twitter could allow you to set up a command to be run when you do make a tweet, but bear in mind that it is free.
The only way I can think of you getting this sort of set us, is to use the twitter API to send an update to twitter, and then at the same time do what ever else you want to do. This will still let you get away with just tweeting from the one place, but you will have to always use that one other place.
Wouldn't it be better to just poll twitter for updates every few minutes?
Running a script every time you tweet is going to be a pain, and what if update it from a mobile device or something?

Resources