How do I get Google Drive access for a desktop app? - google-drive-api

I'm trying to write a Python program that uses Google Drive to do some custom backup and sync work from my Linux desktop.
I started using the PyDrive2 library, and followed its recommendations on how to sign up for Drive API access. When I run my program, it accesses Drive as I'd expect it to, but my authorization expires after a few hours, which is not going to work for a program that runs in cron. I thought this might be because my app is not verified, so I looked into verification, but it's asking for things like a my application's home page. Mine isn't a web-based application, so I don't have one.
Is there a good way to access Google Drive APIs from a non-web application?

if your access is expireing after only a few hours it sounds like you are not requesting offline access and storing the refresh token for later use.
If you followed Quickstart pyton You may have noticed this section. The users credetinals that being the refresh otken and the access token are stored in token.json for future use by your application.
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
I thought this might be because my app is not verified, so I looked into verification, but it's asking for things like a my application's home page.
Your application only really needs to be verified if you are going to have other uses using it. If your only using it yourself then you really only need to remove it from testing phase and put it into production then your refresh tokens will last longer then seven days.
You could try to use a service account but i don't know of anyone who has gotten service account authorization to work with curl.

Related

Library with identifier tmplib is missing (perhaps it was deleted, or maybe you don't have read access?)

I am using Legacy free edition of G Suite account to run my web application. What I want to achieve is to force users to log in. So I deployed the web application with these settings
Execute as User accessing the web app
Who has access Anyone with Google account
Now I was able to identify the user accessing the web application - I got their email from Session.getActiveUser().getEmail(); perfect. Then I want to save all their "data" in 'their own' spreadsheet. When I save a file using DriveApp.createFile(fileName, 'Hello, world!') the file is save on their Google disc. I want all the application data to be on my disc.
So I created a new project - library - and deployed as library and passed it the email because it will be the file name. It works if I access the web as me - owner of both projects. If I access the web as someone else I got this error We're sorry, a server error occurred while reading from storage. Error code NOT_FOUND.
Then I deployed the library as a web application with these settings
Execute as Me
Who has access Anyone or Anyone with Google account
again if I access the web as the owner it works but someone else gets an error Library with identifier tmplib is missing (perhaps it was deleted, or maybe you don't have read access?)
Also there is no log. Just error. Actually there are no logs from the library - I used Logger.log() and console.log()
I tried to add the library from the old editor as there was some error reported in past that might cause such error.
Is there any way I can use an web app and library intended way so the file is always saved as me?
UPDATE
If I share the library using share button and anyone is Editor then the web user needs to give permission to the web application to access their Drive and the file is saved in their Drive. I want ALWAYS the file to be saved in my Drive.
This appears to be a bug!
There is already a report on Google's Issue Tracker which detail the same kind of behaviour:
Error when including library
You can also hit the ☆ next to the issue number in the top left on the aforementioned pages which lets Google know more people are encountering this and so it is more likely to be seen to faster.

Access to Restricted data types and implement in development environment

We are developing application that needs write access to restricted data types. And looks like Google has stopped taking new request for whitelisting apps.
https://developers.google.com/fit/android/data-types#restricted_data_types
Note: Google has temporarily stopped taking new requests to write to restricted data types. We are updating our policy and process for reviewing requests and will update this documentation again when we resume.
Does anyone from Google have any idea when they will resume it?
Also: Is there a way to implement/write restricted data in development environment or debug build without whitelisting, and whitelist app before going to production?
There is no timeline yet for when this will be available.
(Source: I work on Google Fit)

Accessing web app developement URL from UrlFetch service

I'm trying to develop a simple web app using google script web app service and access it from another script using the UrlFetch service.
My problem is that in order to try the code on my web app I have to publish a new version every time because trying to access to the dev URL returns returns and HTML file telling me to sign in even though I've set the permissions for the web app to everyone, including anonymous (if I hit the production URL it does work, though).
I'm assuming that Google is limiting the access to the dev URL for security reasons but can someone shed a light on that assumption?
PS: I don't know if this is relevant but my google account is in a Google Apps for Education domain
Edit
I've found a method to avoid publishing the application for each code change: instead of calling it from the UrlFetch service, I've created a function in the web App code that does call the doPost or the doGet method (I've to create the request param, but that's easy) and I've changed the end of the script to log the result insted of returing it to the client. When the application will be ready, I can publish and develop the client using the UrlFetch.
Anyhow, if anyone knows about the limitation of the dev URL that would be great!
your assumption is correct, the dev url ignores your publishing permissions on purpose, only the developer has access to that url.
you could accomplish what you want using libraries. move the code in your called script to a library and add it to that script as "development mode" and publish your script service.
changing library code should also change your service because its on development mode.
Note that this can easily break your app if you save partial code changes, and makes it hard to test your changed code unless you make all changes and tests in a separate script copy. Making several changes at once in multiple apps script editor files is possible with their "Save all" File menu command (after manually pasting all code changes from your tested copy).

User disconnecting app in Drive causes loss of data under FILE scope

I've run into this issue a few times, but could never point my finger on it, attributing it to GDAA's latency, my buggy code, etc... I finally managed to come up with a scenario where I can safely reproduce it, so I would like to ask people who know if it is a feature I don' understand or a plain bug. If latter is the case, please point me to the place where I can nag about it.
I will discuss it on the REST API's background for simplicity.
1/ Let's have a Drive API authenticated app that runs under DRIVE_FILE scope
com.google.api.services.drive.Drive svc =
new Drive.Builder(
AndroidHttp.newCompatibleTransport(),
new GsonFactory(),
GoogleAccountCredential
.usingOAuth2( context, Collections.singletonList(DriveScopes.DRIVE_FILE))
).build();
2/ create a file (files/folders) in Google drive using
svc.files().insert([METADATA], [CONTENT]).execute();
3/ search for the objects you've created using
svc.files().list().setQ([QUERY]).setFields([FIELDS]).execute();
When the app is run, user goes through the usual Account-Pick / Drive-Authorize routine and everything works as expected. Files are created, visible, can be found ... until a user revokes the authorization by means of
Settings > Manage Apps > Disconnect From Drive
in drive.google.com.
After that, if the Android app is restarted (and re-authorized), none of the objects created prior the revocation is visible.
It may be by design, I don't know. If this is the case, I can't find a way how the Android app can get to anything it created before. I could certainly create another 'maintenance' app with DRIVE scope to fix this, but...
Now, in case of GDAA, it gets even worse. Not only GDAA does not have the DRIVE scope to fix it, but if the same sequence of steps is done and the app creates a file/folder immediately after revocation, GDAA does not complain, but the file/folder is not created at all. After a while (minutes), the re-authorization pops-up, but still, the files created meanwhile are nowhere to be found and everything pre-dating the revocation is lost to the (creator) app as well (it certainly is visible in the web app that obviously has DRIVE like scope).
Thank you for you patience.
The first issue is:
A user revokes authorization via: Settings > Manage Apps > Disconnect From Drive
Then reauthorizes that App
Files this App was authorized to see with DRIVE_FILE scope are no longer authorized.
This is the expected behavior of the REST and Android APIs.
We don't think users would intuitively expect all previously authorized files to be re-authorized. The user may not remember the files that were previously authorized, and informing users that these files are going to be authorized again will likely cause confusion.
The second issue is GDAA's behavior for folder creation in this situation. We don't currently support CompletionEvents for folder creations, but this is something we'll look into.

Accessing the Administrator Audit Log via Google Script

Despite fervent searches, I don't believe I have come up with quite the results I am needing. Within the Google Apps for Business Administrator console, under "Reports" there is the "Audit Log." This audit log nearly displays everything I need; however, I am needing the actual name of the file instead of the fileID provided in the report.
The ultimate endgame is to generate, via Google Script, an automated daily report that gives this same data to a few users daily. Is there any means by which I may access this data? I have been pouring over the APIs, and perhaps I've missed something, but I don't feel that I've found what I needed.
Any thoughts and help would be greatly appreciated. Thank you for your time and considerations.
This is possible using the Google Apps Admin Audit API. This uses OAuth and that is a bit tricky to setup sometimes. You can see the set up process in this video that we did. Except as the example shows, instead of the YouTube APIs enable the Apps Reporting and Audit APIs in the API Console.
I built out a simple example of this that you can see in operation. Access this URL after having been logged in as the domain admin. It will automatically create a Spreadsheet in your Drive with the latest Audit logs exported. This is a web app that is deployed as "Run as user".
I've open sourced this Github here. You should substitute in the right OAuth2 Client ID/Secret. The code is pretty rough so you'll want to clean it up. I am selectively logging a few columns but if you look at the API docs, there are other things you can log as well.
Once the OAuth token is set up you can have this run on a trigger as well as long as you refresh the token.
Hope this helps.