1

I'm working on a Flutter app. And I've been trying to run my web-app Google Apps Script through http request since I'm required to use a Service Account and that access isn't supported in the Apps Script API. But I keep getting a 403/Forbidden response to the requests. I have the credentials for the Service Account and I am using its access token in my request but it still doesn't work.

I'm a novice at http requests and new to Google's authentication protocols so I'd appreciate some insight.

Thanks in advance.

Code:

    return await driveUtils.getCreds(context).then((creds) async {
      final drive_scopes = [drive.DriveApi.DriveReadonlyScope, "https://www.googleapis.com/auth/drive.file"];
      final script_scopes = [app_scripts.ScriptApi.ScriptDeploymentsScope];
      return await clientViaServiceAccount(creds, script_scopes+drive_scopes).then((AuthClient client) async {
        debugPrint("url = " + url);
        debugPrint("token = " + client.credentials.accessToken.data);
        return await client.get(url,
          headers: {
            "Authorization": "Bearer ${client.credentials.accessToken.data}"
          }
        );

      }, onError: onClientError);
    }, onError: onCredsError);

Background: The script creates a Form and sets it Destination to a Spreadsheet's ID. Hence, the app requires that anyone who runs it to have a Google account to become the owner of the new Form and obtain access to the Sheet.

Update: It seems that Service Accounts can only access scripts that are within the same Google Cloud Project. This is a big issue since the point of the script is to create a central place for acquiring Form creation functionality for my app. And the app is intended to be used by anyone.

Does anyone have any ideas? Assuming a Service Account is the right Google Credentials for my app, I essentially need the ability to:

  1. Create a Form that can be assigned to a user
  2. Designate a user's spreadsheet as the forms response location
  3. Retrieve the forms publishedURL
  • Unfortunately, the Apps Script API does not work with service accounts. [Ref](https://developers.google.com/apps-script/api/concepts) So, if you want to run the Google Apps Script, how about using Web Apps? [Ref](https://developers.google.com/apps-script/guides/web) In this case, the function of Google Apps Script can be run by HTML request. And also, the access token of the service account can be used for the authorization of Web Apps. If this was not the direction you expect, I apologize. – Tanaike Jan 10 '21 at 00:26
  • @Tanaike I tried all that. My current issue is that if I getting to the WebApp by means of a service account access token. I keep getting a 403 response. I'm currently under the impression that service accounts can only access WebApps in the GCP. Do you know anything about this? – Bernardin Dezius Jan 10 '21 at 02:03
  • Thank you for replying. From `My current issue is that if I getting to the WebApp by means of a service account access token. I keep getting a 403 response`, I cannot understand about the detail of your script and settings of Web Apps and the script of the client side. This is due to my poor skill. I apologize for this. About ` I'm currently under the impression that service accounts can only access WebApps in the GCP.`, I cannot understand it. Can I ask you about the detail of it? – Tanaike Jan 10 '21 at 02:13
  • By the way, although I'm not sure about your current situation, when you request to the Web Apps using the access token of service account, please include the scope of `https://www.googleapis.com/auth/drive.readonly` or `https://www.googleapis.com/auth/drive`. – Tanaike Jan 10 '21 at 02:20
  • @Tanaike My mistake. On the first part I meant to say I already tried and I am currently unable to send a request to the WebApp through a http request and using a Service Account access token (refer the cod in my original post). For the second part, I currently believe that it may not be possible for a Service Account to run a WebApp that isn't within the same Google Cloud Platform project. – Bernardin Dezius Jan 10 '21 at 02:22
  • Thank you for replying. A1: Web Apps can be accessed with the access token retrieved from the service account. In this case, please be careful the scope of the access token. A2: When I tested using the 2 different GCPs, I could confirm that the service account of GCP "A" can access to the Web Apps of GCP "B". But in this case, please share the email of service account with the Google Apps Script project. Please be careful this. – Tanaike Jan 10 '21 at 02:26
  • Thank you, thats great to hear. Could you share your project configuration? I'm am still not able to do the same. And if you could also share you implementation code that would be great as well. – Bernardin Dezius Jan 10 '21 at 02:43
  • Thank you for replying. I have to apologize for my poor English skill. About `project configuration`, can I ask you about the detail of your current situation including the settings of Web Apps and the script of Web Apps? From these information, I would like to confirm your current situation. By the way, can I think that you have already retrieved the valid access token from the service account? – Tanaike Jan 10 '21 at 02:50
  • My Web Apps `Deploy` setting are: `Execute as` >> "User accessing the web app", `Who has access` >> "Anyone with a Google account" – Bernardin Dezius Jan 10 '21 at 03:02
  • Thank you for replying. I think that your setting for Web Apps is fine. I think that this can be accessed with the access token of service account. Can you provide the current script of Web Apps? – Tanaike Jan 10 '21 at 03:06
  • https://script.google.com/d/1maVz8_kCMzsgArHEfxIFGZBLrpRQsjDjCwSVSUtKQs-hutPdo3jhkQ4P/edit?usp=sharing – Bernardin Dezius Jan 10 '21 at 03:18
  • Thank you for replying. In that case, at first, in order to test the request, how about using a simple script? Because when I saw your script, if the Google Apps Script has the issue, it is required to remove it. As the simple test sample for requesting to Web Apps, how about this? `const doGet = () => ContentService.createTextOutput("Done.");` In this case, when the request works, `Done` is returned. After this test, please use your script. When an error occurs, it is found that in that case, the script has the issue. If your script has the issue, please post it as new question. – Tanaike Jan 10 '21 at 03:27
  • 1
    By the way, when the script of Web Apps is modified, please redeploy it as new version. By this, the latest script is reflected to the Web Apps. Please be careful this. – Tanaike Jan 10 '21 at 03:28
  • I may have found the original problem. Thanks to you I realized I hadn't assign my WebApp to and project. Now I have added a project and I tried to run your simple script but when I run the http request I get a response of "[email] needs your permission to access your personal data". Did the same response happen for you? – Bernardin Dezius Jan 10 '21 at 04:27
  • 1
    Thank you for replying. In your case, please create new Google Apps Script project and put the simple script and test it again. Because I think that your script has already used several scopes because of your existing script. After you confirmed the test using the simple script worked, please got to the next step using your script. In that case, although I'm not sure about your actual script, the specific scopes might be required to be added. Please be careful this. – Tanaike Jan 10 '21 at 05:51
  • I did as you suggested and created a new WebApp to run the simple script. But the 403 response has returned when attempting to run the script with a Service Account access token. For the WebApp, I set `Execute as` to "User accessing the web app". And I set `Who has access` to Anyone with Google account". And I made sure to connect a GCP project to the WebApp. – Bernardin Dezius Jan 10 '21 at 19:40
  • After a closer inspection of the http response, it displays an html page saying "You need access" and "Ask for access, or switch to an account with access." That makes no sense to me since the WebApp setting is for it to be available to any Google account – Bernardin Dezius Jan 10 '21 at 19:57
  • Never mind. That error meant that I had to change the `Share` settings for the file to " Anyone with the link" – Bernardin Dezius Jan 10 '21 at 22:49
  • Thank you for replying. I'm glad your issue was resolved. – Tanaike Jan 11 '21 at 00:36

1 Answers1

0

@Tanaike helped me figure out the issue. In order to make the script visible and able to run with a Service Account I had to change the Share setting for viewing the script. Simple solution