Session.getActiveUser().getEmail() workaround for distributing grades from a spreadsheet - google-apps-script

My students all have a Google account, but use different emails (like john#hotmail.com).I tried to write a webapp that would get from my grade spreadsheet the row with the webapp's user's email address, so that each student would only see his or her grades. That webapp uses: Session.getActiveUser().getEmail()
This only works for users in the same domain as the script, I have to run the script as the webapp user (which is ok -- my students trust me that far!). Here is that restriction:
Returns a User object describing the current user. In
limited-privilege executions (such as in response to onOpen or
onEdit), we only return the identity of the active user if both the
user and the script owner are part of the same domain. This is to
protect the privacy of consumer users, who may not want their email
address exposed.
My script works, but I have to put the table of grades directly in the script and update the webapp each time I update my spreadsheet. Yeck!
I can't share my grade spreadsheet because then they would see each other's grades. So now I am brainstorming other workarounds.
Here is one example:
Share a second spreadsheet, copy the grades from my spreadsheet with an update function that encrypts the grades. The webapp sucks up the data from the shared spreadsheet and decrypts. Now a simple update of a spreadsheet is all that is needed -- the webapp doesn't need to be republished. (There are some simple encryption options, like base64encode with maybe a little scrambling...?)
Find a way to automatically update the webapp and republish. (Don't know how to do that.)
????
Any suggestions?
PS: if 1 seems feasible, some suggestions for simple encryption code?

There are some simple encryption options, like base64encode with maybe a little scrambling...?
Yes, the GAS has functions to encode/decode using the Base64 algorithm - Utilities.base64Encode, Utilities.base64Decode, but I think, it is not an option even with a little scrambling. Students are very clever. My opinion is to use a JavaScript implementation of a encryption algorithm, for instance the Blowfish. There are a number of its implementations on JavaScript (here and here). These implementations should work in the GAS environment without any changes or with small modifications. It is should be sufficient to copy and paste the source code to the GAS Editor.

I dont understand why you say "My script works, but I have to put the table of grades directly in the script and update the webapp each time I update my spreadsheet"
It is very easy to create a webapp that shows a part of a spreadsheet using a flextable for example. Each instance of the app will have a user related content automatically and you will only have to update your master spreadsheet to get what you want. I don't know why you want to encode data for this... I think the user identification through the google login should be enough, don't you ?
Here is an example of such a webapp, the numbers you see are taken from a specific column in a master spreadsheet (for this public copy I set the app as running as "me" to avoid the authorization process but in real every user is identified and sees only his data).
The Spreadsheet itself and the code are viewable here, do not hesitate to come back if you need further information.

Is it an option to sync your sheet with a scriptDB?
And then query the DB where user=loginID

Related

Best way to share inside my domain a script embedded in a spreadsheet

I have a spreadsheet, with 2 scripts embedded, that monthly is sent to some accounts (teachers) inside my domain. One script reads a form (exam) and write the results in the spreadsheet, the second script transfer the final evaluation (the teacher must add other info to the exam scores) to another public spreadsheet where the people can see the results.
Everything works fine, except that the first run of one of the scripts, asks for Authorization. I'd like to avoid that and I read many articles about Authorize scripts, but I couldn't find the solution.
I don't need to Publish an App, that is far away from my needs and my abilities.
I explored Add-on feature, but in some forums I read that there are limits for the Add-on capabilities and possibly it doesn't work between forms and spreadsheets.
So, is there any option to distribute a script inside my domain and the people are not required to Authorize it?
You can add an installable onEdit trigger from your account, trigger script function if specific cell is updated by the rest of the user.

Pulling data from Sheets into Gmail template - one email at a time, not a bulk mail merge

I'm trying to come up with a solution that will allow me to (1) pull data from Sheets for only ONE of the rows into a Gmail template and (2) allow for modifying the template with additional information that's not in the spreadsheet before sending it off.
Context: My organization uses an intake/referral log to track key information about referrals. Once info is in the Sheet, they manually send an email assigning the referral to an employee for follow-up. Much of the info in the Sheet is retyped...which initially made me think of automating this fully with AppsScript, so that all the standard info (case #, case type, due dates, etc) is included in that email. However, the emails sometimes have a paragraph or three of contextual information that we don't want to store in the spreadsheets and have pulled into the automated email.
So my goal is to pull the data from the spreadsheet into the email where I can (vs having to retype it) AND allow the addition of contextual info before sending it off to the assigned employee.
Any thoughts on how to accomplish this? I haven't found a mail merge add-on or Apps Script solution that allows doing this one row at a time and adding in extra custom info into the email.
Thanks in advance!
So this question, as currently written, could clearly be accomplished a whole bunch of different ways. With that in mind, here is one quick and dirty way in which it might be accomplished:
On the spreadsheet where the data is stored, create a script via tools>script editor.
Using that script, create a menu which runs a function that does the following, perhaps in an endless loop:
a. Prompt the user for the email address of where to send the email if it isn't in the spreadsheet or a token value, such as an empty string, to end the script.
b. Prompt the user for the number of the row where the info is stored.
c. Prompt the user for any extra contextual information to add to the email.
d. Get the info from the applicable row in the spreadsheet.
e. Create a nicely formatted email and send it off.
From there, the person in charge of doing the referrals would simply run the script and feed it the required information. Clearly human error could fowl things up here, but without more details of exactly how you want this to work, it isn't really possible to define exactly how to best protect against human error. Reading up on Data Validation might give you a start on that front.
And if you are still completely lost, I happen to be a Google Apps Script tutor/consultant who often gives away free tutoring/consulting. See tutoringbyroger.com for more on that.
I hope that helps.

Gathering user data on a Google Add-on to determine usage levels appropriate for monetization

I have a Google Sheets Add-on about which I'd like to determine feasibility of monetizing. To do this I'd like to see frequency level of users; users per domain as well as how often they use the add-on.
I've read a bit about properties in the documentation, and I'm pretty sure that is at the heart of what I need to work on to start getting this data. My question is about routing that to a form I can use to crunch numbers.
I have considered just having the Properties Service send the user's email and date generated in the Add-on (not the current date, but the date for the content generated). Once that gets sent to a spreadsheet in my drive, I can use a script bound to the spreadsheet to determine if the user has been logged yet. If so, we move the date to the row for that user. If not, we create a new entry. I can also have the script order users based on domain so I can see domains with heavier usage.
I've never done this before, so I'm looking to see if I'm thinking in the right direction or if I'm overlooking something.

Allow other users within domain to use google apps scripts

I have written some code within my Master spreadsheet, and then added the script ID to the library on other spreadsheets owned by me. I am able to run the scripts on those other spreadsheets. However, when I share Edit level access to other users and the scripts don't run when they log in. I have to share each spreadsheet on an individual basis, as they contain confidential information (e.g., payroll info).
Here is the process I used.
Get the script ID from the Master spreadsheet.
On each individual's payroll spreadsheet I added the script ID as an included Library. There is a toggle for Development Mode, set to ON (although, I'm not clear on what that is).
Add references to call code from Master.
Again, everything works as expected when I'm logged in, but not when the users are. First of all, the onOpen trigger doesn't work (it should make a menu and then jump to the current month's sheet.) If that user opens Script Editor and attempts to run the script, it says something like, "User doesn't have access to library Master or it has been deleted."
Hopefully I'm just such a noob that there is an obvious oversight. If you notice it, please let me know how to correct this!
Thank you in advance,
Neill

Google Apps Script - get/assign user unique identifier

I am developing a Google Docs Add-on and need to know if the user currently using the add-on has used it before in the current document or any document. I can't figure out which service gives me some kind of unique identifier for the current user that I can use to identify the current user.
The base service's User.getEmail is not good enough as it doesn't give access to the email under certain conditions and is not reliable.
Thoughts on best way to do this?
Unfortunately, there is no such service. Google wants users' personal information to remain private, so AFAIK you won't usually get even user's email, unless your script is written for Google Apps domain and the user is in the same domain as the script's author.
The only thing you can do in the situation is use something like DocumentApp.getActiveDocument().getId() and check if the script was used in this document, but of course this won't give you an idea if user has used your script in other documents or not.
Also you can show a Prompt Dialog to user, asking him to enter email, but of course there is no way you can check if he entered his real email.
Unique user identifier you can get for apps script is Session.getEffectiveUser().getEmail()
This will return the email of user for which the script run. This is better than ActiveUser because if you use trigger EffectiveUser will well return the email of the user who install the script.
I use that for several apps to identify license assignment and it works great.
It looks like the best solution is to roll your own solution using the following to set the userId at an appropriate time:
PropertiesService.getUserProperties().setProperty("userId",<someGeneratedUId>)
then whenever you want to look up if this user is a recognizable user,
var userId = PropertiesServices.getUserProperties().getProperty("userId")
Looks like once set, the UserProperties thus set is available to this particular user (per user) running this add-on everywhere (i.e. all docs, not just the current on) that have this particular add-on enabled/running.
I'll validate this further but seems like this works in my tests.