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

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.

Related

How do I get Google Drive access for a desktop app?

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.

Google App Script not working in incognito mode

i've been learning with google app script, and tried to make a web form because of the limitation of google form. I tried making it by following this example, and it works. However when I tried using incognito or other browser without a google account log on to it, it failed, showing this error
"Maaf, terjadi error pada server saat membaca dari penyimpanan. Kode error INTERNAL."
Which is in Indonesian that basically states the server failed to read the file, and there is an internal error. This is the web app script.
Settings for the web app deployment
Also in the spreadsheet linked is set to anyone with link is able to edit. When this is changed to anyone with link is able to view only, causes a log in prompt to appear in incognito mode.
Any help is greatly appreciated. I also found out earlier that this problem occurred previously because of a bug by google, but it has been resolved. So did I do something wrong?
According to the Apps Script Web Apps documentation:
The first is labeled Current web app URL and ends in /exec. This URL is for the published version of your app, based on the last version you saved and deployed.
The second is the link labeled latest code and ends in /dev. This URL can only be accessed by users who have edit access to the script. This instance of the app always runs the most recently saved code — not necessarily a formal version — and is intended for quick testing during development.
Therefore, when sharing the web application, you should be sharing the /exec link.
There is an open bug for this: https://issuetracker.google.com/issues/160665120

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).

Directory sandboxed access for Google Drive / Dropbox API / RemoteStorage apps?

Is there a way to get sandboxed, user-selected directory access on any major file service without first getting read level access to their entire filesystem?
There's a lot of talk about "unhosted" static webapps that allow users to access their data from a 3rd party file service (Google Drive, Dropbox, their own server, etc.). The most notable effort I've found so far is remoteStorage.io, but there doesn't seem to be a way with any major provider to let the user select a directory and then use that as a sandbox without breaking their trust (i.e. getting read access to all their files first).
From the user's perspective, the webapp shouldn't have access to anything else on the remote file storage except the one folder the user grants it access to (for example, I might grant a text editor access to my FunnyJokes folder).
The current work around seems to be having the webapp force a specific folder name ahead of time ("this app wants access to /appname_notes"), but that rules out letting the user point it to where they may already have their notes.
Does anyone know of a nice way to do this with Google Drive, Dropbox, or the like?
The user experience that makes the most sense to me is something like...
User opens an unhosted webapp (for example, a basic text editor TextyApp). They click a button to connect with their data.
3rd party auth page appears (for example, Google Drive) and it says "The app TextyApp has requested read/write access to your files. Please select a directory to use."
Confirmation screen: "Grant read/write access to folder FunnyJokes for TextyApp?"
The page redirects back to the webapp with sandboxed accessed to the user-specified folder and the files within it.
This seems like how remote file storage should work, but I haven't found a way to do it yet. Any thoughts/suggestions would be great!
Cheers,
Adam
Edit: To clarify, I'm not talking about storing hidden "application data", but instead letting the user specify a particular directory to sandbox for use with a webapp that they may not want to give broader access to.
The Dropbox Apps API provides the ability to restrict any app using your API key to a single directory of your Dropbox account. So users could create an API key with access to a specific directory and then plug that into your app. However, that's not a user-friendly workflow.
I think the Dropbox Drop-Ins Chooser/Saver API might be close to what you want. The user is presented with a Dropbox file selection popup, and your app only gets access to the specific file(s) that the user selects.
With remoteStorage, sandboxed directory access is currently the default way for apps to request (and users to grant) access to the storage. However, users cannot manually select or enter custom directories during the connect phase.

How to make a copy of a file between users of different domains?

I would like to make a copy of a Google Spreadsheet file between users that are not on the same domain. The source file has a sharing setting of Anyone with the link can edit.
I created a Web App (with execution permissions set to User accessing the web app) that call an install function:
I was hoping the code would read the source file which is open to everybody and make a local copy to the Google Drive of the user running the Web App (of course assuming the user accept to run the script). The behavior works when it's me running it (because I am the owner of the source) but do not work if the user is from another domain.
Any suggestions on how to achieve this?
function doInstall() {
// The source file is readable by everybody with the link;
var file = DocsList.getFileById('0AlVPTKz1xoevdHc1ZTQ2OGFMXXXXXXXYYYYZZZZ');
file.makeCopy('Test Copy Spreadsheet');
}
I had a different but similar use case and problem. Like you, my source file was accessible to anyone with the link and my domain settings allowed users to share content outside my domain. It worked for me but not for them.
This might work for you, it has for me (so far):
Assuming you have your original script...
Create a separate script for 'Script as web app'.
Write a function (e.g. loadFileIds()) to store the necessary fileIds using ScriptDb. Run the loadFileIds() function.
Write another function (e.g. getFileId()) in the same project that returns your desired file Id from ScriptDb.getMyDb when called. Avoid using DocsList in this function. I originally thought that because getFileId() would 'run as me' that it would be OK but it was always the DocsList line that caused failures when other users triggered the script.
In File > Manage Versions: Save a version of the project.
Under Publish: Deploy that version of your project as a web app. Choose Execute the app as "me(me#mydomain.com)" and set Who has access to the web app to "Anyone".
In your original project go to Manage Resources and enter the Project Key of the web app, choose a version and copy the identifier.
Write a function that calls yourIdentifier.getFileId() and - hopefully - returns the fileId.
In my experience so far external users have been able to access files that they could not when DocsList methods returned null. But there is one more thing to add... You might find you have to share your web app script with your users. I haven't quite made certain that's necessary but I've encountered bugs when I don't. I untick the option to email them the link.
I learned how to do this from examples in the documentation, this video and of course StackOverflow.
As you can see, I'm still working this out myself and testing of the system has so far been just me simulating other users. So no promises. Good luck! I'll star your issue.