How do get the url "https://script.google.com/macros/d/{SCRIPT ID}/usercallback" responding / up and running - google-apps-script

I'm a beginner in Google Apps Script.
I'm basically trying to use the OAuth service in a Google Apps Script to be able to connect a Google spreadsheet to Yahoo fantasy API.
I'm using the package you can found here:
https://github.com/googleworkspace/apps-script-oauth2
In the "read me" part you can see that oauth libraries will by default use the callback url https://script.google.com/macros/**d**/{SCRIPT ID}/usercallback
So I try to use this package in my script, but when I publish my script it creates the following url:
https://script.google.com/macros/**s**/{SCRIPT ID}/
Notice it's an "s" instead of the "d" in the url.
I can access properly to https://script.google.com/macros/**s**/{SCRIPT ID}/exec and so on but the url containing the "d", which is expected to be use by OAuth service, return an error.
When trying to access the url in a browser I got:
an error if I call ../usercallback
the message: "Sorry, the file you've asked doesn't exist", if I call the ../exec
.. is https://script.google.com/macros/**d**/{SCRIPT ID} in that case.
I've been looking on internet for having this url working but no success (it that so obvious that no one else had the issue except me?).
I tried several thing, i've created a project and linked my script to that project, i played a bit with the configuration in the project in regards to what i found on internet, like credential for API, but still can't have the url with a "/d/" responding.
I'm not sure of the meaning of the "s" (script?) or the "d" in the url.
I'm not sure if it has something to do with the way I publish my script or if I need to have specific function in my script or maybe some configuration of the script, maybe I need to persevere with the project thing...

I think that you should re-read the Readme.md file from the Google OAuth Sample GitHub repo. Also I think that d and s parts of Google Apps SCript URLs are irrelevant for using the "OAuth Service".
The .../exec URL is generated when making a new deployment. This URL doesn't contain the script Id... please bear in mind that a single Google Apps Script project might be deployed multiple times and have all or some deployments being live at the same time. Each web app deployment will have it's own URL... none of them have the script id. By the other hand, you might not need to make a deployment in order to be able to use "the OAuth service", this is needed only if the script will be receiving GET/POST HTTP requests.
You should not to access the ../usercallback in the browser, as you will be doing a GET request without proving the required data. This URL should be added when getting the credentials to be used with the "OAuth Service" from the OAuth provider, in this case Yahoo, as the redirect URI.
The referred repo includes multiple samples about how to use the "OAuth Service", one of the is Yahoo.gs
Resources
https://developers.google.com/apps-script/guides/web
https://developers.google.com/apps-script/concepts/deployments

Related

Read Gmail POST Notification using Standard Google Cloud Platform (GCP) Script

I am trying to create a subscribing webapp using Google Scripts App to receive and decode POST notifications from Gmail API whenever a new email is received. The new changes in the Google Cloud Platform (GCP) is making it very hard to work. All the documentation/videos I have found about this are obsolete.
I created a script with a doPost() function directly from Google Drive (not linked to Google Docs, Sheets or Forms) and deployed it as a webapp with a provided link. I had to link the script with a standard GCP project as the default GCP projects which are automatically created for any Google Scripts App are not accessible anymore. The next step was to go to PubSub API in GCP, created a topic. When I try to create a subscription to allow the webapp to receive the POST messages from Gmail API, and set its delivery type to PUSH, an Endpoint URL is required. When I use the webapp link, I get the error:
The supplied URL is not registered in the subscription's parent project. Please see documentation on domain ownership validation.
I went throug the domain ownership validation and tried all possible solutions I found online without success. Without the PUSH subscription, I am unable to receive the notification, decode its body, get the email id then retrieve and decode the email body. Any help is highly appreciated.

"Invalid legacy scope provided" error when attempting to access a Google API from web app?

Here's what I'm trying to do:
Remotely execute a Google Apps Script function from an online automation service (Zoho Flow, similar in purpose to Zapier.)*
This function that I am remotely executing is to add gmail labels to everyone in an organization.
In order to do this, I've done the following:
Created a service account with domain-wide-delegation in the same GCP project associated with the function that adds gmail labels.
Used the OAuth2 library for Google Apps Script to perpetuate JWT authorization for that service account in my script.
Verified that function works with service account functionality for all users in a Google oragnization within google apps script
Deployed this script as an API Executable to enable remote execution
Created authtokens authorized with the mail scope for the Apps Script API (https://mail.google.com/), as well as an additional scope required by the OAuth2 library in my script. This is done in the google developer playground, using OAuth2.0 Client ID credentials that are authorized as a part of that same GCP project.
Successfully executed the function remotely using the Google Apps Script API with Postman
Now, in order to actually make this functionality official, I now have to replace postman and the google developer console with the actual client, which is this Zoho Flow platform for api connections and process automation.
In order to make the switch I've done the following;
Added the authorized redirect URl for the client (Zoho Flow) under the same credentials that are used for the Google Developer Playground:
Utilized the credentials found from the JSON representation of those credentials** for creating what's called a "connection" in this software, which is basically an easy-to-use OAuth2.0 connection with a nice front-end that can be used for accessing API data (this is the part where I create this connection):
Entered the same scope for this connection that were authorized in the google developer playground, as well as that additional scope (https://www.googleapis.com/auth/script.external_request) that the OAuth2.0 library for Google Apps Script uses:
Lo and behold, I get the error below when attempting to gain access to Google API data from a web application, and the scopes that are said to cause the error is every scope except for the mail scope: https://mail.google.com/. I've done additional testing to verify that every other scope that is a part of the google apps script API also create this error, not just this external scope for the OAuth2 library.
Support said it was likely an issue with my credential permissions; is my line of logic for this correct? If it is, then it is an issue with their software that I will have them pursue further.
Some additional testing has been done on the software (Zoho Flow) to confirm whether or not it is a software error or not: I'm not certain if the process defined in my answer is best practices, or even 100% correct (other users can speak to it,) but I've confirmed that the error I am seeing is likely an error with the client.
Here's why:
When authorizing for multiple scopes, I get the error seen at the end of my question:
When changing that connection to utilize only one of my scopes instead, like so:
The connection proceeds properly, and I can remotely execute functions that utilize only that one scope successfully. This does work for any one scope that I authorize. The only problem is, it's a rare occurrence that a script only requires one scope. While this I can get around this major bug, I cannot remotely execute my function that adds gmail labels to all users in an organization because it requires two scopes. This will be mentioned to the development team and it should be fixed soon.

404 error when deploying a Google Apps script via the REST API

I'm trying to deploy a Google Apps script via the Google REST API, and I'm using the API Explorer to perform that.
This is the method I am testing:
https://developers.google.com/apps-script/api/reference/rest/v1/projects.deployments/create
Executing the method via the API Explorer returns a 404 error. I have verified that the scriptId in question does exist, and have tried several other scriptIds, to no avail. I have also made sure the permission scopes are properly set.
This is what the API Explorer gives me.
Worth mentioning that the same scriptId works when calling another method such as projects.get.
Is there anything I am missing, or is this an issue on Google's end?
In case of the latter, what are the steps to contact Google Apps Script's team and inform them of this issue?
Your versionNumber is incorrect. The Requested entity here refers to the version of your script. You need to go to File>Manage Versions>Save New version to create a new version(or create one with the api1) and use that version number in the request body.
Check your authorization scopes. You need to have the following scope enabled:
https://www.googleapis.com/auth/script.deployments
If its not in the list of available scopes in API Explorer then you'll need to add it manually (there is an area at the bottom of the authorization dialog where you can add scopes).
Google's API Explorer uses API keys to authorize requests. In some cases an API key is not sufficient and an OAuth2 (bearer) access token is required. As an alternative you can create an Apps Script project and add the appropriate scopes via the manifest file(appsscript.json). Then you can use UrlFetchApp.fetch() to test the API directly.

In Google Apps Script, avoid second 'Review Permissions' prompt, possibly by using approval_prompt

I have searched StackOverflow, etc. for a solution to this problem, and several answers 'point me in a direction' (mentioning approval_prompt = auto not approval_prompt = force), but none are applicable (as far as I can tell) to my situation.
I have a Web Application hosted at www.mjpanel.com that expects to use a Google Apps Script that I 'own', but the Javascript at www.mjpanel.com calls the Google Apps Script (deployed as a Web App with doGet()) as a Web Service. It expects the web service call to return various JSON objects.
If the user has not yet authorized my application, the call to the Google Apps Script Web App / Web Service will not return a JSON object, causing www.mjpanel.com Javascript code to fail saying "Invalid Request" (because it isn't a JSON object as my code expects).
To prevent this from happening, www.mjpanel.com uses gapi.auth2.init to get the permissions/scopes it needs. I'm developing everything now, so if/whenever the Google Apps Script evolve to use something (like sending GMail emails as the user) that is new, I have been figuring out the scope to request, adding it to the list of scopes in the gapi.auth2.init call, and everything is fine. The next time a user uses the app., they get initially prompted for the newly added scope, then everything proceeds fine.
However, now sometimes one of my test users has a Web Service call fail because Google Apps Script is returning another request for permissions for a 'new permission' of 'Have Offline Access'.
There's nothing about my script that would warrant the user needing to grant this permission.
When I research, a lot of stuff (mostly about requesting OAuth2 stuff in a 'structure' different than the way my app. is set up) says it has to do with submitting a 'approval_prompt=force' in my request URL.
However, the way I have my app set up, all the URLs I would use (aside from my 'custom stuff' in the query string) are dictated by Google Apps Script. And I can't find any place where any URL I use has an approval_prompt in it.
I can't figure out where I would need to configure that approval_prompt to be auto (as is recommended in the 'successful answers' I find).
Of if the idea of approval_prompt is 'on the wrong track', any information in general to help me solve this problem would be greatly appreciated.
Thanks in advance for any help you can give me.
Unfortunately the Google Apps Script native OAuth flow includes approval_prompt=force. This causes the following conditions:
If cookie exists in browser and has permission for this application the consent screen will not be displayed.
If cookie exists in browser but does not have permission for this application: consent screen will be displayed
If cookie does not exist in browser and the application has permissions: application will request 'Have offline access'.
The easiest way around this is to manage your own OAuth flow and use the Execution API. The following link will take you to the javascript quick start.
https://developers.google.com/apps-script/guides/rest/quickstart/target-script

Authenticate Google Apps Script user via HTTP

In the scenario of scripts that need authentication to run (run as service account, locked down sharing settings, etc) is there a way to authenticate as a Google user via an HTTP tool like cURL, UrlFetchApp, or even PowerShell scripts from Windows Server environments?
You are going to have to do a little leg work on this one.
Firstly, when you publish your apps script, make sure to change the "who has access to the app" to something like "only myself".
Then you need to see what happens when you try to hit that URL from an external service without authenticating. There may be some help from the error codes you are likely to receive.
I imagine you can then use the following documents to Authenticate for Google Services IN GENERAL. Then you will most likely have to pass a sessionID or Accesskey of some sort. I only have a brief understanding of OAuth, but I do imagine that you may be able to set up a more permanent connection between your other server and your particular Google Apps Script.
I hope this helps.
Jacob