2

So I am trying to use an outside source (Zapier) to input values into my spreadsheet. These input values are then "transposed (formula wise)" into my spreadsheet to fit the cell coordinates with which they are to align.

I have the spreadsheet set to run 'onEdit' and when these incoming values arrive, it is supposed to cause the rest of the spreadsheet to change, but the function is not running.

However, if I were to edit the spreadsheet 'manually,' the onEdit function runs perfectly.

So why then would the spreadsheet not be running the function, when the outside source brings its input values?

UPDATE:

So I discovered that if I manually authorize an 'onChange' installable trigger, it will work. But if I create a copy of the same exact spreadsheet, the installable trigger will not exist in the copy. The copy needs to have the trigger without me having to do it manually. So I am trying to create a code inside of Google Script Editor that will either allow me to use the onChange function or install the onChange function in the Developer Hub. Any thoughts? Here is the code I tried but did not work:

var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("My 
     Sheet") 

var ssid = "My SpreadSheet ID"; 
     ScriptApp.newTrigger('My Sheet) 
    .forSpreadsheet(ss.getId()) 
    .onChange() 
    .create(); 

    myFunction()
    {

If there is an alternative for the onChange function, then I'm all ears. I just need a function that can run itself in my copies.

  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/194972/discussion-on-question-by-get-her-done-why-isnt-my-spreadsheet-changing-from-in). – Samuel Liew Jun 15 '19 at 04:57

1 Answers1

0

As a part of a collaborative effort, let me clarify the Zapier part (this answer does not concern the copy part).

Part 1. Zapier setup

Assuming you have a third-party application that you pull data from (btw, since you decided to use apps script, isn't it easier to drop the middleman like Zapier and connect to the 3P app API – if it has one, ofc – directly?), you created a Catch Hook and a POST Action.

The POST Action setup contains several fields:

  1. URL field - this is where your /exec URL goes (WebApp is deployed via Publish->Deploy as a WebApp). After you deploy your script as a WebApp, you will get a URL that users and scripts can make requests to (it is always of this format https://script.google.com/macros/s/{yourProjectId}/exec - with some slight diff. due to access permissions). To avoid permissions issue, set the Who has access to the app option to anyone or anyone, even anonymous (otherwise, you'll have to devise auth handling).
  2. Payload Type field is irrelevant here, but I suggest using JSON.
  3. Data field is required if you chose the POST Action and should contain key-value pairs of data you would like to transmit via Zapier (the data will be available in parameter/parameters property of the event object).

Part 2. WebApp setup

Published WebApps should have either a doGet() or doPost() function to be able to receive and process requests (or both). Each of them accepts one special argument, which is constructed each time a request to the WebApp is made – an event object.

The event object will contain all the data that you sent from Zapier. You can then use this data to conditionally trigger different functions, pass data to handlers, etc. So, instead of relying on triggers, you can create a function that is called inside the doGet / doPost that will a) populate your target sheet with new values; b) do anything else after that, thus acting as an analogue of onEdit / onChange.

Useful links

  1. Event object structure;
  2. Passing event objects around;
  3. Creating triggers on other documents;
  • NP, hope that this will work for you, tried to explain as much as possible in a short format ([guide](https://developers.google.com/apps-script/guides/web) on webapps and [guide](https://developers.google.com/apps-script/guides/triggers/installable) on installable triggers might be also helpful) – Oleg Valter is with Ukraine Jun 14 '19 at 20:47
  • 1
    Hey @Oleg Valter ! I'm going through your steps now, but I have one question regarding deploying my script as an webapp, particularly where you say: "To avoid permissions issue, set the Who has access to the app option to anyone or anyone, even anonymous (otherwise, you'll have to devise auth handling)." How safe does my spreadsheet become if I deploy my script this way? Does my spreadsheet become public for all to see? – Get Her Done Jun 14 '19 at 22:36
  • Hey! No, this does not change your spreadsheet permissions, it only controls if *the WebApp* itself can be accessed via the public URL (which is a point of deploying as WebApp) you provided (and, besides, you can create additional checks to verify requests if you are worried about WebApp security) If you don't want to trouble yourself with request verification, simply use the `/exec` url only in secure environments and you are all set! – Oleg Valter is with Ukraine Jun 14 '19 at 22:42
  • Ok. So far here is what I've done: As it regards the Zapier setup, first, I have deployed my script as an webapp and it generated a link. Second, I created a step called 'Webhook' inside of Zapier and chose the option called 'POST.' Third, where it says edit template, I placed the generated link that I got from my deployed webapp where it says: URL. I selected JSON as the payload type. Fourth, I see a section called 'Data,' but I don't know what to put there yet.... Next I will explain what I have as it regards the Webapp setup... – Get Her Done Jun 14 '19 at 23:29
  • Now as it regards Webapp setup, I only rewrote the function as: `function doPost(e) { ` in place of `onEdit(e){`. I also kept the set of code that says: `if(e.range.getA1Notation().indexOf("cell")` . I have the e.range.getA1Notation code written for various cells, so that it can be triggered to run the input values received in those cell ranges from Zapier. After trying to bring the input values from Zapier, nothing is still happening. I think I'm missing something somewhere. My sincerest apologies for the back and forth. I'm sincerely trying my hardest here and your help is truly appreciated. – Get Her Done Jun 14 '19 at 23:31
  • No problem, glad to help! The rewritten function fails because the event object of the `doGet()` / `doPost()` functions is different than the `onEdit()` one, thus `e.range` became `undefined` (and this is why it fails). If your Zapier connector passes range identifier as a parameter, it will be available in `e.parameters` / `e.parameter` object (btw, make use of `Logger.log(dataToLog)` and `console.log(dataToLog)` for debugging). Otherwise, either hardcode cells via `getRange` method or decide how to obtain them programm. (there are too many ways to address it to put in comment) – Oleg Valter is with Ukraine Jun 15 '19 at 00:13
  • Hey @Oleg Valter! Bro, I am almost there! When I 'manually' insert the URL of the Webapp inside of Zapier, it runs the code. But here is my problem. I have an original spreadsheet and I have the copies of the spreadsheets that will be made inside of Zapier. How do I get Zapier to find the Webapp URL of each copy that is made so that the webhook can run on those spreadsheets, not the original copy? (Zapier also cannot find the Webapp URL of the original spreadsheet either unless I actually copy and paste the URL there - In other words, I could not select the Webapp URL as an option in Zapier). – Get Her Done Jun 15 '19 at 14:26
  • Hi @GetHerDone! Glad to hear! Regarding your question, the idea is to have one *standalone* WebApp for every Spreadsheet (btw, can you clarify how the Zapier integration is *triggered*, that is - what initiates the copy process?) - if you can create copies inside the Zapier, you should also be able to a access a copy Id/Url, right (for example, as a separate step)? Just pass this Id with the return data and you can then access the copy in `doGet`/`doPost` with `openById()`/`openByUrl()` method and perform your changes. – Oleg Valter is with Ukraine Jun 15 '19 at 15:16
  • I think I see what you mean. Let me explain the order of my zaps: First, I have Zapier use my Google Drive to make a copy of the Spreadsheet that I want. When it does this, Zapier then gives me access to the copy's ID. Second, after the copy is made, Zapier triggers Google Sheets to import the data I want into that copied spreadsheet. It is after this step, I insert Webhook step. In the Webhook step, it asks for a URL. This is where I attempted to use the format `https://script.google.com/macros/s/"copied spreadsheet ID (not the webapp link"/exec` , but it did not work. – Get Her Done Jun 15 '19 at 15:41
  • In Google Script Editor, my code looks like this: `function doPost(e) {`. I don't have anything else special after that. Do I need to put something like `openById()` or `openByURL` into it as well? By the way, after the webhook finishes its step (if I manually insert the Webapp link), it generates a HTML text. Do I need to do anything with that? – Get Her Done Jun 15 '19 at 15:50
  • Hm, can you post in chat by any chance? I see what's the first issue - no, the apps script project has *separate* Id and you should use what's been provided to you on webapp setup (as I mentioned, you can pass the spreadsheet Id as a query string parameter or payload depending on request method), the second one warrants extended discussion – Oleg Valter is with Ukraine Jun 15 '19 at 16:03
  • Absolutely! I'll see you soon in the chatroom! – Get Her Done Jun 15 '19 at 16:04