Connecting Google add-on to google vm instance

Viewed 76

I am developing an add-on for google drive.

As a part of the functionality of this add-on, I would like to incorporate a google vm server that performs some processing on a user's google drive files (i.e. you click on a file through the add-on, send a request with a download link to the server, the server downloads the file, then finally responds to the request with some helpful information about the file). Both the apps script for the add-on and the vm instance are connected to the same google "project."

I am struggling with google's OAuth2.0 system and how I can connect the authorization of the add-on and the vm instance together.

Currently, when users open the add-on for the first time, they are brought to the authorization screen like so Authorization Image.

Once they authorize, my add on has access to all the expected scopes, including read access to google drive files.

Now I want my server to have access to them as well. Unfortunately, I do not understand how to do this.

I have tried simply requesting the url returned from file.getDownloadUrl() in python. While the request returns a status code of 200, I cannot seem to get the file to download.

I have also looked into the Google Drive API for python (I am running a flask server). Unfortunately, it appears that I need an entirely new authorization flow to make it work.

Any clarity on this issue would be greatly appreciated. Frankly, I find google's documentation on this matter very scattered and confusing. So, even knowing the right place to look would extremely helpful.

Much Thanks!

EDIT

I am adding some additional code to help provide some clarity. This is currently how I make a request to my server from the add-on:

 var route = http://exampleurl.com/process
  

  var data = {
    'oAuthToken': ScriptApp.getOAuthToken(),
    'stateToken': ScriptApp.newStateToken().withTimeout(120).createToken(),
    'fileId': e.parameters.fileId,
    'fileType': e.parameters.fileMimeType
  };
  
  var options = {
    'method' : 'post',
    'payload' : data
  };
 
  
  var response = UrlFetchApp.fetch(route, options);

This code successfully sends information to my vm instance running my server.

Now, I need to authorize the server to download the file specified by fileId.

When developing, I closely followed this tutorial to set up OAuth2.0 access to the Drive API. Here are two key routes:

@app.route('/google/login')
@no_cache
def login():
    session = OAuth2Session(CLIENT_ID, CLIENT_SECRET,
                            scope=AUTHORIZATION_SCOPE,
                            redirect_uri=AUTH_REDIRECT_URI)
  
    uri, state = session.create_authorization_url(AUTHORIZATION_URL)

    

    flask.session[AUTH_STATE_KEY] = state

    
    flask.session.permanent = True

    return flask.redirect(uri, code=302)

@app.route('/google/auth')
@no_cache
def google_auth_redirect():

    req_state = flask.request.args.get('state', default=None, type=None)
    
    if req_state != flask.session[AUTH_STATE_KEY]:
        response = flask.make_response('Invalid state parameter', 401)
        return response
    
    session = OAuth2Session(CLIENT_ID, CLIENT_SECRET,
                            scope=AUTHORIZATION_SCOPE,
                            state=flask.session[AUTH_STATE_KEY],
                            redirect_uri=AUTH_REDIRECT_URI)

    oauth2_tokens = session.fetch_access_token(
                        ACCESS_TOKEN_URI,            
                        authorization_response=flask.request.url)

    flask.session[AUTH_TOKEN_KEY] = oauth2_tokens

    return flask.redirect(BASE_URI, code=302)

Is there a way to plug in the two tokens I generate from the add-on into this Oauth flow? It appears that Google isn't anticipating this setup given that I am required to provide a redirect URL, which wouldn't make much sense in the case of my add-on/server tech stack.

1 Answers

Currently, you can successfully send the access token from the Apps Script project (retrieved with getOAuthToken()), to the flask server.

Since you already got the access token, you don't need to go through all the OAuth process as defined here (use the application credentials to request the access token, provide user consent, redirect, etc.). Sending the access token through the API request is actually the last step in the OAuth flow.

You just need to use the token to build the service, and the server will be able to access the file.

Using access token to build service:

from googleapiclient.discovery import build
import google.oauth2.credentials

ACCESS_TOKEN = requestBody['oAuthToken'] # Data coming from Apps Script via UrlFetch
creds = google.oauth2.credentials.Credentials(ACCESS_TOKEN)
drive_service = build('drive', 'v3', credentials=creds) # Build Drive service

Using Drive service to download files:

After you've build the Drive service to access the API, you can use this code sample to download Google Documents, or this one for other files (both examples include a tab with a Python sample).

Note:

Reference:

Related