I have a Google Spreadsheet that IFTTT adds a line to when particular events occur. I would like a Google script to run each time a line is added. Currently, the script has an installed onEdit trigger but it isn't triggered unless I manually edit the spreadsheet.
This thread and this thread describe similar issues but I lack the knowledge to try out their proposed solutions. The first suggests using a webapp and the second suggests using a time based trigger and checking for changes in the spreadsheet.
Any guidance would be greatly appreciated.
Further Details
Each row that comes in via IFTTT represents a purchase of a random prize. One column contains the price of the purchase, another column contains the date of the purchase, and another contains purchase details. When the total amount spent changes, the spreadsheet fetches a random number and the prize associated with the number. I want those details emailed to me when a prize is bought (more specifically, I want them emailed to IFTTT so it can SMS me the details). The email and email address are generated by formulae in spreadsheet cells. A script grabs the email and address from the spreadsheet and sends the email. Currently, the email is successfully triggered when the spreadsheet is manually edited but not via the IFTTT log entry.
Most of this project is achieved via formulae in the spreadsheet, rather than scripts, as I am much more confident using them.
The onEdit() trigger only fires on user input.
You should see if you can use onFormSubmit if IFTTT sends form-info?
My workable but untidy and unsatisfying solution is as follows.
The following functions are used to record the time and date that the Total Spent cell was updated.
function timestamp() {
var d = new Date()
return d.toLocaleTimeString();
}
function datestamp() {
return new Date()
}
SPLIT() and INT() are used to manipulate the date and timestamps into usable formats that can be compared with the current date and time. The datestamp() function always gives the date in PST so I've had to add the appropriate number of hours to convert it.
One IF() cell checks whether the date is today and another IF() cell checks whether the time has a value that is less than the time 5 minutes ago.
If the conditions are satisfied (total spent was edited today and less than 5min ago) the email cell is given the value of IFTTT's email address. If not the cell gets a space.
My sendEmails script is triggered every 5 minutes by an installable time based trigger. It will send an email to the valid address if the conditions are met and a blank email address if they are not.
One workaround could be the following:
You could make a script in this spreadsheet, and save the getLastRow() value in scriptproperties.
Compare them every minute or so via a timed trigger, and when it had increased, do your thing ;)
just change the trigger to be select event type to be "On Change". This will run the script whenever you edit it and also whenever IFTTT adds the row.
Related
the sheet I'm working on generates a request number on the very first submission a user makes of a google form based off of information the user inputted in the form and a timestamp. Now, because I need for the user to be able to edit their response later which causes the form to be re-submitted, I want the request number not to be regenerated, and to stay the same as when it was initially generated. Is there any way to prevent a cell from changing from its initial value when it contains a formula that references a cell that updates?
Here is the formula contained in the cell I don't want to update with alongside its references:
=ARRAYFORMULA(ARRAY_CONSTRAIN(if(ROW(A:A)=1, "Request ID", if(D1:D="", "",C1:C&"-"&G1:G&"-"&N1:N)), MAX(if(D1:D="",0,ROW(D1:D)))-ROW()+1,1))
The formula appends different values received from the form together to create a request number (formatted as essentially C1:C-G1:G-N1:N, timestamp-System-initials) and the arrayformula and constraint ensures the formula is copied to each row in the sheet that contains a form response so far. I want this request number to stay the same as it's initial value, even as columns C, G, and N change.
Edit: Not really sure how I can provide a search history on what I've tried so far because I've been searching for anything I can to fix this problem because it's important. I've looked into indirect referencing, absolute references, considered using PropertiesService (Google Apps Script) in order to store whether the request number has been initiated before and got stuck there, considered copying the value into another column to store it but again the autoupdating feature that accompanies linking cells of course still remains an issue. I'm stuck on what kind of function/workaround I could use to achieve this. Look forward to your thoughts. I've also tried a number of other strategies as well.
Since formulas recalculate each time the spreadsheet is recalculated using a formula is not the right way to keep the original value on the current spreadsheet version. The way to achieve this is by using a script to log those values.
There are already a lot of questions about using a script to log values from one sheet to another. Here are few examples
How to Get (& Set) cell values from one sheet to another in Google Sheets?
I want to write a script to read and log values of a specific row and copy them to a new sheet
I am making a status tracker sheet that has a column for the status of each task. Right now, Column D is has the status for each task and is set up with a drop down menu:
No action needed
Needs attention
In progress
Complete
Column E has the due date for each task.
Is there a way to write a script for the drop down menu that will change the status of cells that say "No Action Needed" to "Needs attention" once the due date is within a week of the current date?
Also, what's the best way to incorporate email notifications into the script so that any time a status changes to "Needs attention", an email is sent to the owner in Column F?
This would definitely be possible through the built-in script editor.
Overall you would want to be able to interact with the sheet that this is data is stored in. The easiest way to do this is through the SpreadsheetApp class and methods.
For the first step, you would want to set up a script that checks whether the due date is within a week of the current date. This can be done using the Javascript Date Methods which can easily be compared using regular number operations such as subtraction and addition.
The second part of the script would be possible using the built-in apps script functions of MailApp.
When you have both of these parts of the scripts down, you should tie it to a trigger to ensure that the script will trigger at either given times (time-driven triggers) or at given events (event-triggers).
I have a google spreadsheet which we use to feed inventory purchase and issue data. The only problem is my staff can manipulate purchased quantity, prices and other variables at a later date. I want that if they enter data in a cell, they cannot edit it post-midnight but I can.
Also, I have filled most of the cells with formula, for example- there is formula in A1:H999, so that when they enter data, it calculates the values in other cells, and suppose my staff has entered data till A1:H500. In this case, the script should work On A1:H500, it should not consider the whole range just because i have filled it with formula. Thanks
If you want to limit access to the script to particular hours it's fairly simple. This can be done with one function if written in a clever way or with 2 functions.
Function1 will simply lock the spreadsheet and allow only you to edit by using the protection class, then use function2 (or write function1 in a clever way to do different things depending on when it starts) that is triggered at a different time to remove that protection.
if I get a timestamp for a Google Form submit event, using for example:
var timestamp = event.response.getTimestamp();
a time is returned e.g.
Fri Sep 26 17:54:02 GMT+12:00 2014
and in the linked spreadsheet the timestamp
is displayed in column one.
Are both timestamps always identical (i.e. is the event timestamp passed to the spreadsheet) or can they be different and the timestamp on the spreadsheet is actually the timestamp of the write to the spreadsheet?
Background: I'm making an application where when a form is submitted an email is sent to the person who has filled in the form with a confirm link. Using a query url and a webapp on the form's linked spreadsheet I can get the parameters from the query url. I now need to have a unique id to find the entry in the spreadsheet in order to to mark it as 'confirmed'. Timestamps seem a suitable way of doing this, but better ways may exist.
Thanks in advance,
Trevor
There doesn't appear to be any documentation or confirmation on this, but from my experience, the timestamp is not the time that the sheet is written to. I believe it's the form submit time, but I can't confirm that for you.
From reading your requirements however, it sounds as though there's the potential for failure as the timestamps won't be unique, and it's possible two people will submit the form simultaneously (though depending on the popularity of the form, this may be slim).
If you need a Unique ID for each entry to just confirm it was submitted, but don't need it for anything else, have you considered logging the 'Edit response URL'? That's unique to each submission, so there's no danger in mixing up submissions.
Thanks for the suggestion. Further experimentation showed that occasionally the timestamps were different at most by a second. I suspect that the event times are for submitting the form and writing to the sheet.
I've found a more elegant solution that works well. The form has a field for last name. I've attached the onformsubmit trigger to the spreadsheet that receives the form responses. By getting the current unix time in milliseconds and concatenating it to the lastname (eg.storr1411790175312) I have a unique ID to pass to the query string that is a link in the email. Further, I write the unique ID value to the correct row in the receiving spreadsheet by using the event range method, e.range, which will always return the range that triggered the current event. As the unique ID is generated once and used in both the email and the spreadsheet it is internally consistent.
Cheers
Trevor
I figured it out.
The value of event.response.getTimestamp() is same as the timestamp in linked spreadsheet.
This is because...
It seems that spreadsheet also stores timestamp in milliseconds.
If you set custom cell format to
yyyy"/"mm"/"dd" "hh":"mm":"ss":"000
you can finally make milliseconds to appear.
If you don't explicitly display milliseconds, spreadsheet automatically round it.
Ex)
Here is my issue. I have a spreadsheet with multiple sheets, and each sheet has about 300-500 rows. I am using ScriptDb to store the data for each sheet.
What I am currently doing is calling a custom function in 300-500 cells in each sheet to populate certain cells with data, and what happens is that some will populate and the rest will error out saying i've queried the database too many times in a short period. Obviously having to query the database for each cell isn't the best solution.
How would I go about querying all the data for the current sheet and then having that data available to grab for each cell. What I've read is that you can't really have "global" variables in GAS, but have to use things such as CacheService or ScriptDB, which is what i'm trying to do. I'm just querying it too much.
Is there some way to populate all the cells from 1 function call instead of 1 call for each cell? What am I missing or what other solutions are there?
Just realized a similar question was asked earlier today: Google Spreadsheet Script invoked too many times per second for this Google user account
Yes its possible. Simply return an array from your function. It will work like an arrayformula.
Of course your cells would need to be contiguous.