Keeping a Google Doc (Sheet, etc.) last update time - google-docs-api

I need to put (among other things) the time of the last update of a Google Document (Doc, Sheet, etc.) in a footer, so that if the document is printed it is possible to distinguish which printed copy is the latest. This needs to be a script so it is done automatically for users without requiring them to do anything special. I have a script that does this (at least for Docs), but there are some issues:
In a Doc there is no onEdit trigger, so I can't determine automatically when the document is updated in order to update the footer. (I am aware that I would need to prevent my own update from triggering this by ignoring the change I make)
onOpen can only update the document if the user has edit access to the document. So if somebody opens the document, edits it, and closes the window, and then another user opens it without edit access, they would see the next to last update time instead of the last update time.
The current version of my script must be manually bound to each document when it is created. Is there some way to have it automatically get bound when new documents are created? Would an add-on work?
Is it possible to use the "Detect Changes" API somehow? I'm not sure this is even going to do what I want, and it seems like it might be complicated to do it this way.
Would a time-driven trigger make sense? The only problem with this is that time driven triggers don't seem to be able to run more than once per minute (unless in an add-on, which can only run once per hour), so that last update time could be off by up to this much. This probably wouldn't be a big problem, but could occasionally cause some issues. Also, would running code every minute cause any kind of quota issues?
I tried using ClockTriggerBuilder with a delay of 1000ms, but it wasn't updating. Then I noticed that the after function says it will run the trigger after the specified number of milliseconds plus or minus 15 minutes!

Related

All time based triggers seem to run at the same time

I have multiple time based triggers in a google sheet (most of which are supposed to run every 15 minutes and one of which is supposed to run once a day). These scripts that the triggers run simply generate random numbers in specific cells (one per each script/trigger). These cells changing then triggers a script that pulls from an API. The issue is that I can only pull so much from the site's API before it locks me out (60/pulls per minute is the limit). The scripts seems to all run at the same time on occasion (including the one thats supposed to only run once a day) which results in me being locked out of the API and receiving no data. Does anyone know why everything would be running at the same time? This happens when the once a day trigger shouldn't be active too.
For this use case you might be better off chaining your functions.
So you would only schedule functionA(), and at the end of it you call functionB(), and so on.
That also allow you to put a Sleep() function between them if your API requires it.
If every function are in the same project that's straightforward, but if they are in different project you will need to publish your projects as libraries.
It's not pretty but it will do the tricky.

How to announce to user when a Google Script is completed

On a Google Sheet, I have an extensive OnOpen script (viewable here) to refresh data on several sheets within the workbook. It all takes a while for all script lines to execute, i.e. to import new raw data and to then perform five different Unique Queries against that new data and thus update data on five sheets. When the Google Sheet is opened the user does see two successive pop-up yellow "Working" boxes, then five subsequent progress bars (while each of the queries do their thing). This all takes quite a while. I'd like to make an addition to the script routine to announce to the user that "all data is now refreshed and ready to view." A simple MessageBox ("Data now refreshed') placed at the end of the scripts seems to pop up before all script commands are actually completed. Thus the message box gives misleading info and I think it also interrupts some script lines from executing until "OK" is checked. So, MessageBox doesn't seem to work. So, I'm looking for a way to confirm that all script line (and all unique queries) are, in fact, complete before informing the user that it's OK to start viewing the data. Thanks.
Place a SpreadsheetApp.flush() before the "finished" alert box; the flush() method:
Applies all pending Spreadsheet changes. Spreadsheet operations are sometimes bundled together to improve performance, such as when doing multiple calls to Range.getValue(). However, sometimes you may want to make sure that all pending changes are made right away, for instance to show users data as a script is executing.

Firebase observing adding new records

Before you link me to a duplicate, please read what I'm asking..
I'm building an app which basically has a list of about 5000 teams. These teams are fairly static (they don't change very often). I would like to observe any time one is changed though as it's essential it get's updated in the app ASAP.
If I include dbTeams.ref.observe(.childAdded, with: {}), it runs each time the app starts, loading over all 5000 records despite having them in the persistent storage already (I have enabled persistence).
Now the documentation says this will happen, I know, but with 5000 records (and potentially way more in the future), I can't have this happen.
My options so far (from what I've found and tried) are:
Add a timestamp to each record and create a custom query to call .childAdded after the last timestamp... This is inefficient. Storing a timestamp for soccer teams which will hardly ever change, is silly. It also means keeping a copy of the last time it was checked.
Create a sub-list within the Teams list. This too is silly as you may as well call .value and get the whole bunch of data in one go.
Just live with it... Fine - until it scales to tens of thousands of records. Not clever either.
It just seems weird that all the other event listeners only fire when they are "supposed to" except this one.
Any help would be appreciated - how do I achieve what I need?

Suggestion for trigger that sends email if threshold is broken

This is quite a broad question but ill try and summarise it as best I can.
I have an MVC front end which displays/allows processing of records which are classed as outstanding. I also have a scheduled console app which runs nightly and attempts to resolve each of these records using some logic I wrote.
I have a new requirement, which is to have an email sent every time the total number of outstanding records exceeds a certain amount, this amount needs to be configurable.
The table will contain every record with a flag to say if they have been resolved or not, so I will need to count the outstanding's then fire an email to notify if the threshold is broken.
I initially thought about adding a SQL Server trigger on insert however I soon realised that if no more records were added for a few days but the total number stayed above the threshold because nobody resolved them, then no further email would be sent.
I need the email to send every day on a schedule independently of insert/update.
So now I'm thinking possibly a SQL Server job, or an SSIS package or even a service which runs, but I'm aware this threshold number needs to be configurable.
So what would be the quickest simplest solution to my requirements, I'm open to any suggestion as long as it ticks all the boxes.
Given that the OP already has a console app running on a schedule, the most logical choice would be to simply add this check to the console app along with the email sending logic. It will be much easier to send emails that way, anyways, especially if you employ something like Postal, which will let you use MVC-style views to create your emails.
An SQL Server scheduled job seems to me to be the simplest way to go.
you can add a table to your database that will hold the threshold number and read it's value from there.
In many cases a GeneralParams table is a good thing to have anyway.
The other option you mentioned (windows service) is also configurable in many ways: you can use a GeneralParams table, or the App.Config file of the service (but you will have to restart it every time you change the app.config), or even a simple text file. anything goes. the downside is that it's outside of your sql server, but the upside is that it is probably easier to send emails from.

Letting something happen at a certain time with Rails

Like with browser games. User constructs building, and a timer is set for a specific date/time to finish the construction and spawn the building.
I imagined having something like a deamon, but how would that work? To me it seems that spinning + polling is not the way to go. I looked at async_observer, but is that a good fit for something like this?
If you only need the event to be visible to the owning player, then the model can report its updated status on demand and we're done, move along, there's nothing to see here.
If, on the other hand, it needs to be visible to anyone from the time of its scheduled creation, then the problem is a little more interesting.
I'd say you need two things. A queue into which you can put timed events (a database table would do nicely) and a background process, either running continuously or restarted frequently, that pulls events scheduled to occur since the last execution (or those that are imminent, I suppose) and actions them.
Looking at the list of options on the Rails wiki, it appears that there is no One True Solution yet. Let's hope that one of them fits the bill.
I just did exactly this thing for a PBBG I'm working on (Big Villain, you can see the work in progress at MadGamesLab.com). Anyway, I went with a commands table where user commands each generated exactly one entry and an events table with one or more entries per command (linking back to the command). A secondary daemon run using script/runner to get it started polls the event table periodically and runs events whose time has passed.
So far it seems to work quite well, unless I see some problem when I throw large number of users at it, I'm not planning to change it.
To a certian extent it depends on how much logic is on your front end, and how much is in your model. If you know how much time will elapse before something happens you can keep most of the logic on the front end.
I would use your model to determin the state of things, and on a paticular request you can check to see if it is built or not. I don't see why you would need a background worker for this.
I would use AJAX to start a timer (see Periodical Executor) for updating your UI. On the model side, just keep track of the created_at column for your building and only allow it to be used if its construction time has elapsed. That way you don't have to take a trip to your db every few seconds to see if your building is done.

Resources