How to architect an Express route that knows time of the day - node.js

I am trying to create a route that functions as the following:
The mobile app will make a request: GET /ballots/today, which should return the ballot for "today" ONLY if the time is between 6:00pm EST - 10:00pm EST.
If the request is made before OR after that period of time, it should not return anything.
I am considering using moment library's isBetween method inside the express route to check if the current time is between 6:00pm and 10:00pm of that specific day.
However, the problem I have trouble understanding is how make sure the server has the correct time at all times (if that should even be a concern) as well as being agnostic to timezones.
If it matters, I am planning on deploying on Heroku.

Moment will always use the server time when running it on express. Most cloud providers have their server time set to UTC. You will have to provide the timezone using Moment Timezone. Here is an example of how to achieve it.
//set the start and end times for today EST
const start = moment.tz("America/New_York").format("YYYY-MM-DD") + " 18:00";
const end = moment.tz("America/New_York").format("YYYY-MM-DD") + " 22:00";
//convert the times to moments so we can do a compare
const startMoment = moment.tz(start, "America/New_York");
const endMoment = moment.tz(end, "America/New_York");
const isBetween = moment.tz("America/New_York").isBetween(startMoment, endMoment);
if (isBetween) {
//return ballot
}

Related

Timestamp For Discord Bot Status

I am using Discord.js Node V12 I am currently trying to find out how to say time elapsed in the status to show how long the bot has been playing game or any activity. But i cannot find anyone who has asked or answered any of these questions.
#client.event
async def on_connect():
await client.change_presence(status=discord.Status.dnd,activity = discord.Game(name = "VALORANT"))
I would like to break this answer into a few significant points:
• The sample code provided is from discord.py ( a discontinued python based library to interact with the API ) which is totally out of context of the whole question itself since you're asking it for discord.js
• There is no actual way to find the time elapsed since a particular activity as of now but you may resort to this:
var uptime = client.uptime; // returns uptime in milliseconds
var hours = uptime / 1000 / 60 / 60 // converts it to hours
/*
Then you may apply the following approach to change your status every hour passes
*/
setInterval(() => {
client.user.setActivity(`Valorant since ${hours} hour(s)`);
}, 3600000); // this would show up as Playing Valorant since 1 hour(s) and subsequently would change every hour if your bot isn't being restarted continuously.
I took a look at the discord.js documentation to examine setting activities and found no such information about timestamps. However, there was a section in the ActivityType that led me to the discord developers documentation and it indicates:
Bots are only able to send name, type, and optionally url.
So it doesn't seem as though you will be able to set the start or end timestamps for an activity as a bot.

How do I get the current time zone where my app resides

I've been having this issue for months and I've finally made some headway. I'm writing an app the sends me a message at specific times, 9 am and 9 pm eastern time. When I ran it locally it worked perfectly but when I deploy it, I get nothing. I was messing around and then I saw this Heroku Logs. My guess is that my app is located on a server that is in a different time zone and when this code below runs. The conditions are never met and nothing gets sent. My question now is, is there a way I can get the current time of and compare regardless of what time zone the server is located?
const sendMessage = require('./sms-api.js');
const send = () =>{
setInterval(()=>{
var x = new Date().toLocaleTimeString();
console.log(x);
if(x === '11:00:10 AM')
{
console.log('match');
return sendMessage('6178032176', 'Good Morning');
}
else if(x === '9:50:20 PM')
{
console.log('match');
sendMessage('6178032176', 'Good Evening');
}
},1000)
}
send();
When working with different timezones, it is better to work in UTC and then offset it according to required timezone.
Get the time in UTC and then offset it according to required timezone.
You can also use dedicated libraries like moment-timezone.
https://momentjs.com/timezone/docs/
Like Suyash said above, your best option is to work entirely in UTC, and only convert when displaying times to users. Rather than dealing with offsets, you can append your dates and times with a 'Z' to indicate they are universal.
The best way I've found to do that is with moment.js and moment-timezone.js. Here is an example of an implementation that will allow you to convert times and dates: https://github.com/aidanjrauscher/browser-timezone-conversions. These libraries also make it very convenient to convert any date or time related user input back from their local time zone to UTC.
thank you for your help. I ended up figuring it out. I used this instead const time = new Date().toLocaleTimeString('en-US', { timeZone: 'America/New_York' });.

setinterval Stops Working After 540 seconds (time limit in Firebase hosting), How to Solve this?

I've been using NodeJS running on Firebase hosting to monitor sensor values
(through dedicated hardware). I simply use function setinterval to check
the sensor values via API that I wrote. The system reads from sensor
successfully for every minutes (for just testing) but it stops reading
after 9 minutes (or 540 seconds according to google document here ??). The reading sensor function is working, only the loop in setinterval that stops working as I've mentioned. My simple code looks like this:
var intervalObj = setinterval(function(sensor_id){
var val = readSensorValue(sensor_id);
var d = new Date();
console.log("reading from sensor[" + sensor_id + "] => " + val + "#" + d);
}, 60000);
However, I have to monitor the sensor all day long. How can I fix this??
Or there's any other better approach??
Thank you for your time,
JJ
:D:D:D
I've decided not to use Firebase function hosting for now, so I run the project on the VM and everything's been working fine. Just a simple setInterval... even though I'm still wonder whether it is a design by Firebase for such limitation or there should be other approach for doing this on Firebase.
Thanks for all the comment.
:D:D:D

How can I use Node.js to get the value of a child under random USERid and keys

It's a simple concept but yet finding the right answer is ridiculously stressing. Use Firebase Functions w/ Node.js to pull the "itemsExpires" (date) from the Firebase database. The parent node is the userId (random string) and each item is stored under a key node (another random string).. So, here's what the firebase database looks like:
firebase-database-name
+ 82hfijcbwjbjfbergjagbk_USERID
+ "My Stuff"
+ gnjfgsdkfjsdf_ITEMkey
-- "item name": whatever
-- "itemExpires": 05-01-2017
-- "itemType": whatever too
+ an3jeejwiag_ITEMkey
-- "item name": whatever
-- "itemExpires": 06-01-2017
-- "itemType": whatever too
+ zzzndjgabblsbl_ITEMkey
-- "item name": whatever
-- "itemExpires": 07-01-2017
-- "itemType": whatever too
I'm not asking for someone to write the code, a good reference will do but there are so many ways to call data and all I'm finding are the ways to Call using a structured tree and not one with random id's and keynumbers.
*** Basically, my goal here is to run a 3rd party cron job through Firebase Functions that runs through each item entry and checks the expiration date against today's date. This is the wall I'm against.
Bradley I am yet unclear as to what you want to do exactly. I suppose you intend on having multiple users (not just one as in the example) with multiple Items and compare the current date against the expiration date of all items for every user at a specified time (using cron). There are some considerations you should take into account here :
Do you really need cron ? ( or can you solve your problems more easily and natively with a javascript plain setInterval() ? )
How often are you going to check your entire database and how big is that database?
OK. So to explain, the first consideration is just a thought and the logic behind it should be pretty obvious. The second consideration takes some explaining. Since I believe your firebase data will NOT be static and will constantly change you need to find a way to get these changes inside you node script.
If you do not intend on calling your scheduled task too often and the database is not a mammoth (taking ages to load) you could just do the following :
const firebase = require('firebase-admin');
const serviceAccount = require('yourServiceAccountPath.json');
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
databaseURL: "youDatabaseURL"
});
setInteval(function(){ // or cron schedule
firebase.database().ref().once('value',function(snapshot){
let allYourUsers = snapshot.val();
// iterate through them all
// and do what you gotta do
});
},10000); // your interval in milliseconds
However this approach just loads once all your database each time you want to check all items. If you have other data in the database, consider adding users to a seperate path and load just that path. This approach is not recommended if your users are quite many and/or you want them to be checked very often. If such is the case and your data does not change very often you could consider this alternative:
Here you use the on function to update your data as it is edited and set the checking part seperate like so :
const firebase = require('firebase-admin');
const serviceAccount = require('yourServiceAccountPath.json');
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
databaseURL: "youDatabaseURL"
});
const databaseRef=firebase.database().ref();
let allYourUsers;
let allYourUsersStaticCopy;
databaseRef.on('value',function(snapshot){
allYourUsers = snapshot.val();
});
setInteval(function(){ // or cron schedule
if ( allYourUsers ) { // to ensure that data has loaded at least once
// (startup considerations)
allYourUsersStaticCopy = Object.assign({},allYourUsers);
// iterate through the static copy in order to avoid
// you data changing while you are accesing it
// and do what you gotta do
}
},10000); // your interval in milliseconds
The upside with the second piece of code is that your data is loaded every time there is a change and not every time your check runs. If however your data changes very often (additions,deletions and edits) this approach might not be optimum.
In the case that your script runs often enough, the database is big enough, and the changes are often enough to prevent any of the above to be efficient, you might want to consider the optimum solution : loading your users once and then attaching listeners for the child added,removed and changed to update your existing users object. Thus you receive only changes and not a whole snapshot. If such is the case you can read about the mentioned listeners in the firebase docs and I can squeeze in some extra code. Just let me know.
Hope this long post helps!
Assuming you have Firebase set up properly within your node project, you can do a one time read for your ITEMkey entries. Something like this:
var db = admin.database();
var ref = db.ref("82hfijcbwjbjfbergjagbk_USERID").child("My Stuff");
ref.once("value", function(snapshot) {
var contents = snapshot.val();
// Data returned here will be an object with all children
// nodes under "My Stuff". You can access it by calling
// snapshot.val() like I did above.
}

Looking for a way to retrieve timezones in which the current time is x

I am looking for a way to obtain a list of timezones in which the current time is a variable (it has to be DST dependant as well).
For example I need to push messages to users for which the local time is 18:45. I can fetch from our database a list of users by timezone. So I plan a scheduled event that would wake up at every 15 minutes, it will need to check in which timezones it is currently 18:45 in order to be able to retrieve the right users.
Our environment is node js.
The way I am thinking about is preferably a web service or some utility that does it all for me including the updates from iana timezones database. But I can handle less convenient ways if there's no such alternative.
Thanks in advance.
Here is one simple way to do it with moment-timezone (I believe it handles things like daylight savings time etc., not 100% sure -- but certainly will do it better than one could do starting from scratch alone.. see their github repo for issues -- its a complex topic):
var moment = require('moment-timezone');
var tm = moment();
var toFind = tm.format('h:mm a');
var userZones = ['America/Los_Angeles', 'America/New_York'];
for (var i=0; i<userZones.length; i++) {
var fmt = tm.tz(userZones[i]).format('h:mm a');
if (fmt === toFind) console.log('matched zone: ' + userZones[i]);
}

Resources