1

I have hundreds of google spreadsheets which all have the same script in them. I'd like to execute a specific google spreadsheet by ID either from PostgreSQL or from Bash. Is there an easy way to execute scripts? I prefer not having to learn python.

For example, I have spreadsheet id 1HGo8V-P5S-z4oCUiAKULrkZRFlzRHEalJqUFLiP and I'd like to execute function Refresh() via Bash or Postgresql.

Is the API the only route? https://developers.google.com/apps-script/api/how-tos/execute

So far my consideration is to create a python executable and execute it from a postgresql function. https://developers.google.com/apps-script/api/quickstart/python

Edit: It looks like if I want to execute any app script, each spreadsheet would need a google project (manually created). There has to be an easier way to do this, manually creating a project for every spreadsheet doesn't make sense.

Reference: https://developers.google.com/apps-script/api/how-tos/execute

The script being called and the calling application must share a Cloud Platform project.

Solution: Deploy web apps is the solution I ended up going with thanks to @Tanaike

sojim2
  • 1,245
  • 2
  • 15
  • 38

1 Answers1

1
  • You want to execute the container-bound script of Spreadsheet.
  • You want to execute the script from local PC or outside of Google.
  • You want to execute the script from Spreadsheet ID.

If my understanding is correct, how about this answer?

Retrieving project IDs of container bound script:

I think that this is the difficult problem in your situation. In the current stage, there are no methods for retrieving the project ID of the container-bound script from the parent Google Docs (in this case, it's Spreadsheet.).

  • This has already been reported at https://issuetracker.google.com/issues/111149037 as a Feature Request. But unfortunately, this has not been achieved yet.
  • By this, the project IDs are required to be retrieved manually.
  • For example, you can retrieve the project IDs at Developer Hub.
    • When you select a project, you can see the project ID at the URL of https://script.google.com/home/projects/### projectId ###.

From above situation, the project IDs are required to be manually retrieved from each Spreadsheet you want to run the script. I apologize that I couldn't find a workaround for this situation.

Executing script:

I think that there are 2 patterns for executing the script. You can select from 2 patterns.

1. Use the method of scripts.run in Apps Script API

  • This is also mentioned in your question.
  • Function in the script is execute using API.
  • You are required to create only python script at local side.
  • In this case, the access token retrieved by the OAuth2 process is required at local side.

I think that in this pattern, the script can be simple.

2. Use Web Apps

  • By accessing to Web Apps, function in the script is execute.
    • In this case, in order to execute the script, it uses scripts.run in Apps Script API, because of large number of Spreadsheets in your situation. When user accesses to Web Apps, the script of Spreadsheet is executed by the script of Web Apps. Because Google Apps Script is used, the access token can be easily retrieved.
  • You are required to create a python script for accessing to Web Apps at local side, and Google Apps Script at Google Side (Web Apps).
  • In this case, you can run the script with and without the access token at local side.

I think that in this pattern, the method of access can be simple.

References:

If this was not what you want, I apologize.

Edit:

From the discussions, I thought that in the case of your script Refresh(), the following flow is suitable. 1. Deploy Web Apps using the script of Refresh() like an API. 2. Call the API using python script and curl. By this, the script of Web Apps is run and you can reflect the result of Refresh() for all Spreadsheets.

Sample script:

function doGet() {
  var spreadsheets = ["spreadsheetId1", "spreadsheetId2",,,]; // Please set spreadsheet ID here.
  for (var i = 0; i < spreadsheets.length; i++) {
    SpreadsheetApp.openById(spreadsheets[i])
      .getSheetByName("Sheet1") // If you want to also put values to other sheet, please modify this.
      .getRange(1, 1)
      .setValue(new Date());
  }
  return ContentService.createTextOutput("Done.");
}
  • When Web Apps is deployed, the authorization screen is opened. But this authorization is only one time.

Deploy Web Apps:

Before you request to Web Apps, please deploy Web Apps.

  • On the Script Editor
  • Publish -> Deploy as Web App
    1. Create new Project version
    2. At "Execute the app a"s, select "Me"
    3. At "Who has access to the app", select "Anyone, even anonymous"
    4. Click "Deploy"
    5. Copy "Current web app URL"
    6. Click "OK"

Curl sample:

If you use curl command, please use as follows.

$ curl -L "https://script.google.com/macros/s/#####/exec"

Note:

  • When you modified the script, please redeploy Web Apps as new version. By this, the latest script is reflected to Web Apps. This is an important point.

Note:

  • Also you can use the spreadsheet IDs for requesting and you can directly includ them in Web Apps. (In the sample script, the latter is used.)
    • If you want to use the spreadsheet IDs for requesting, please be careful. The number of workers for Web Apps is required to be less than 30. Ref
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thanks for taking the time! It looks like I'll need to create a project for each and every google spreadsheet regardless if I'm doing the scripts.run method or via the apps scripts api https://developers.google.com/apps-script/api/how-tos/execute google's requirement is `The script being called and the calling application must share a Cloud Platform project.` Why does google do this to us whyyyy. I'll leave the question open in case there's any other easy solution.. – sojim2 Feb 19 '19 at 03:53
  • @sojim2 Thank you for replying. And I apologize that I proposed the methods you don't want. Can I ask you about the detail situation you want? 1. You want to execute a script while the many Spreadsheets are not opened. Is my understanding correct? 2. Can you provide a sample script you want to execute? Also from the script, I would like to find a workaround. Because for example, I thought that Sheets API might be able to be used in your situation. – Tanaike Feb 19 '19 at 04:31
  • I think I have misunderstood.. creating the script would require creating a project already so all I would need to do is create python execute script per `https://developers.google.com/apps-script/api/how-tos/execute` and have the app ID & function name to execute it from the python script. Basically, I would like to run `Refresh()` remotely for this spreadsheet: https://docs.google.com/spreadsheets/d/1P-6Rjcl-cGFiH93RIf5TNqrw9eZpY6jcT3IYwSmDLFA/edit#gid=0 So the API would satisfy my requirements, I would just need to use python. – sojim2 Feb 19 '19 at 04:47
  • @sojim2 Thank you for the additional information. In the case of the script at the shared Spreadsheet, I think that it is not required to use Apps Script API and you can directly reflect the result of the script to such a lot of Spreadsheets by using Sheets API. In this case, you can run the script using Spreadsheet IDs and the bound script is not required in each Spreadsheet. Is my understanding correct? Of course, you can achieve it using a python script. – Tanaike Feb 19 '19 at 04:54
  • To be clear, the python referenced here would work and is probably the easiest route to manage hundreds of spreadsheets? https://developers.google.com/apps-script/api/how-tos/execute – sojim2 Feb 19 '19 at 05:37
  • @sojim2 I apologize for my poor English skill. In my latest comment, as other workaround, I proposed that it reflects the result of ``Refresh()`` using Sheets API without using Apps Script API, because I could know the script from your comment. Because if you want to run ``Refresh()`` to a lot of Spreadsheets using Apps Script API, I thought that the preparation for it will be much hard. Retrieving the project ID, deploying web execution, enabling Apps Script API and putting the script are required to be done for all Spreadsheets. – Tanaike Feb 19 '19 at 05:43
  • After looking into this further, It looks like a standalone script would be ideal since if I need to make changes for the script, I would only need to change one script instead of hundreds. – sojim2 Feb 19 '19 at 05:43
  • @sojim2 Also you can run the script using Web Apps. In this case, I think that a simple script can be used. This might be better. – Tanaike Feb 19 '19 at 05:45
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188649/discussion-between-tanaike-and-sojim2). – Tanaike Feb 19 '19 at 05:46