Retrieve Google user and use it as data in Google Data Studio - google-apps-script

What I have now: I have a static HTML site where I'm creating a dashboard with Google Data Studio. The spreadsheet connected to Google Data Studio has sensitive data of 100s of different users, each identified by their e-mail address in the organization.
Goal: Display only the rows of a table where a user's e-mail is stated. I want to do it retrieving the user e-mail from session, passing it to Google Data Studio and automatically show rows corresponding to the address.
Code snippet:
- Retrieve the user's e-mail from session:
var email = Session.getActiveUser().getEmail();
But this is all I know. I don't know:
- Wether I have to make a connector, write it on Google Apps scripts then link it or write it in the Spreadsheets Apps Script (makes no sense for me).
- How to send the 'email' retrieved to Google Data Studio.
Any lights on this issue would be really useful. Thanks!

It's not possible to retrieve the active user's email unless there are certain conditions. From the documentation we can read that:
If security policies do not allow access to the user's identity,
User.getEmail() returns a blank string.
The circumstances in which the email address is available vary: for
example, the user's email address is not available in any context that
allows a script to run without that user's authorization...
...these restrictions generally do not apply if the developer runs the
script themselves or belongs to the same G Suite domain as the user.
This means you would need to deploy the script as a web app with the option:
Execute the app as: User accessing the web app

Steps:
Data Set: [Done] In the the spreadsheet, create a field (e.g. email) which includes an email address on each row.
Data Source: At the Data Source (editing an existing or creating a new one) the top left now includes an email filter where the field with the email address (email) can be selected as the field to filter the report by.

Edit: The Filter by email address feature was launched last week. This can be a much simpler solution to your requirements.
Original Answer: Implement Row level filtering with Data Studio. However, instead of using BigQuery as your source of data, fetch the data from the associated Sheet.

Related

Google Sheets - Multiple users platform - Cant have two or more users at a time

I have a google sheet that will serve as a platform for several users, the sheet allows the user to select several options to generate some statistics and comments. The issue is when I have multiple users connected at the same time, they might want to check different information, selecting different options, so lets say when user 'John' is checking his statistics, the user 'Steve' can go to options and change the inputs, generating a report that 'Steve' wants to check but overwriting 'John's information. :(
So this is a multiuser sheet but only works with 1 person connected at a time.
I can replicate the sheet for each user, so they would have their own sheet, but I can't image updating each copy when necessary.
Do you know any solution in Google Sheets that could address my issue?
Thanks!
A long-term solution would be building a report in Google Data Studio.
It's always recommended to have the frontend (User interface) with the backend (data).
After you create a report, you'll only be worried about the data you modify in the Spreadsheet and the users will filter it as they prefer.
You can connect your spreadsheet with the data and share the data studio link to your users

Do I need OAuth - Google Contact Form data (all) to Sheet then to Email

I want to use Google Form as a contact form on a website, and email the contents of the form (not just a notification) to a specified address.
I created a Google Form, embedded it on a website to use as a contact form for enquiries. Then created a Sheet to pull in the data from the Form. After that I created a Trigger for onFormSubmission which runs the following:
/**
* #OnlyCurrentDoc
*/
function onFormSubmission (e) {
var values = e.namedValues;
var htmlBody ='<ul>';
for (Key in values) {
var label = Key;
var data = values[Key];
htmlBody += '<li>' + label + ": " + data + '</li>';
Logger.log(label + ": " + data);
};
htmlBody += '</ul>';
GmailApp.sendEmail('me#gmail.com', 'Web Form Enquiry', '', {htmlBody:htmlBody})
}
Running this brings up a dialogue stating:
Authorization required.
'Send email' needs your permission to access your data on Google
Review Permissions or Cancel
['Send email' is my 'App' in G Suite]
Clicking Review Permissions opens a popup asking to choose an account to continue. Clicking on the account (the same account I'm logged in with and have created the form, etc with) brings up:
This app isn't verified. This app hasn't been verified by Google yet. Only proceed if you know and trust the developer.
Advanced or Back to safety
Clicking Advanced:
Google hasn't reviewed this app yet and can't confirm it's authentic. Unverified apps may pose a threat to your personal data.
Go to 'Send email' (unsafe)
It then states:
'Send email' wants to access your Google account
This will allow 'Send email' to Read, compose, send and permanently delete all your email from Gmail
Connect to an external service (Create a network connection to any external service (e.g. to read or write data)
Make sure that you trust Send emails
You may be sharing sensitive info with this site or app. Find out how Send emails will handle your data by reviewing its terms of service and privacy policies. You can always see or remove access in your Google Account.
Find out about the risks
Cancel or Allow
So, for testing purposes I clicked Allow. And it all worked beautifully! And I made the form responsive, and then I remembered I had to go back and review the permissions. After 4 hours I got lost down the rabbit hole, and crawled my way back up to here in confusion. So my questions are:
Do I need to implement OAuth?
Does Google need to verify the app?
If yes to 2, does this take weeks? (If yes, probably need to abandon this solution)
If I give the app 'permissive permissions' (as I did for testing) is there any security risk?
If I give the app 'permissive permissions' is Google going to review it and decide to stop it running?
The only reason I can imagine that OAuth is needed is that data is being taken from Sheets, an email is being created and the data is being passed to that. Is it because of the data being passed to a different 'service' than collected it? Or because a different service is instructing the creation of an email? (Or both?)
If OAuth is implemented does this mean that users will be asked to verify? Obviously, they will not require to be logged in to use a contact form on a website.
Is it possible to restrict the permissions eg to only compose emails, rather than have the ability to delete any or all emails in the account (manifest?)
Would it make any difference if I skipped the spreadsheet ie Form to email? (Can't see how, but asking just in case.)
This is my first time using these services, so hopefully, I've explained it ok.
Any advice gratefully received!
I want to use Google Form as a contact form on a website, and email the contents of the form (not just a notification) to a specified address.
Do I need to implement OAuth?
What you're doing is already OAuth flow. But it's managed by apps script. So, No.
Does Google need to verify the app?
Not for your use case.
If yes to 2, does this take weeks? (If yes, probably need to abandon this solution)
Maybe more
If I give the app 'permissive permissions' (as I did for testing) is there any security risk?
Anyone with access to your script(by implication, anyone with edit access to your spreadsheet) can change the script to send email from your account to any other website or Read or delete your email. So, Avoid providing edit permission to your Spreadsheet or script.
If I give the app 'permissive permissions' is Google going to review it and decide to stop it running?
Not if you're the only user.
The only reason I can imagine that OAuth is needed is that data is being taken from Sheets, an email is being created and the data is being passed to that. Is it because of the data being passed to a different 'service' than collected it? Or because a different service is instructing the creation of an email? (Or both?)
Yes.
If OAuth is implemented does this mean that users will be asked to verify? Obviously, they will not require to be logged in to use a contact form on a website.
You are the owner of the email, sheet and the form responses. Only you need to authorize the app/script to act on your behalf to do certain jobs like copy/paste.
Is it possible to restrict the permissions eg to only compose emails, rather than have the ability to delete any or all emails in the account
Yes.
You can use MailApp instead of GmailApp
OR Limit the scopes in apps script manifest file:
https://www.googleapis.com/auth/gmail.send
Would it make any difference if I skipped the spreadsheet ie Form to email? (Can't see how, but asking just in case.)
Reducing the number of hops it takes for the script flow is good for security. But doesn't make much difference in terms of oauth flow/permissions requested. You can use the formsubmission trigger in the form itself. Note however that you need to redesign the script according to the event object provided on formsubmit to the form. This is different from the event object provided to the spreadsheet onformsubmit.

How to connect an html form submission on an external web app to a user's google sheet?

There are plenty of examples on how to use an apps script web app to connect HTML forms to google sheets. However all these refer to a scenario where the owner of the spreadsheet/form is the developer, such as this method. The owner/creator of the spreadsheet/form is not dynamic in these cases as far as I can see.
In my use case I want users to create their own HTML Forms based off data from a spreadsheet in their drive and receive responses in that sheet. So we are talking about multiple users creating their own spreadsheet in their own google account/drive instance and connecting that to my external web app to display the form to the users who have the link.
The flow is like this:
User1 creates Google SpreadSheet in their drive
User1 uses our add on to create the form/link
User1 sends the links out
Receiving Users go to the link which leads to my external web app to fill out the form and submit a response
User1 receives responses in another sheet in the same spreadsheet in their drive.
This is repeated for x amount of users.
I'm thinking this will be done through a sheet add on, but I'm not sure how to connect the add on to the external web app. In the link above it is done by creating an apps script web app, but I can't ask the user to do that/programmatically do it for them.
What options do I have?
There needs to be a url to send data to, with a process listening for said data that I can then run a function on.
Hopefully there is some api for this, maybe for drive?
P.S In case anyone is suggesting that I use google forms for this, google forms is great but it is limited in UI options and to a question and answer format. I'm looking to include search/filter functionality for possibly hundreds of list items with a quantity field. So it can't be done in forms.
This should be possible given the following constraints: 1. The form "owner" would need to pass the Sheet IDs of the source and destination to you and, 2. both of those Sheets would need to be publicly readable and writeable.
AppScript is great for manipulating Docs and Sheets you own, but in your case you'll want to use the core Sheets API instead.
Your application which handles responses is probably best implemented using one of the SDKs depending on which language you write it in.

Gmail auto populate bcc field

Using Gmail, can I create a script that allows me to key off of an address in the To/Cc field to add an address to the BCC field using some browser-side code?
Ex:
Whenever an email with example#example.com is created in the TO/CC field (or created via a reply/reply-all etc) I want for the email address otherName#myCRM.com to be added to the BCC field.
I don't want this for a single address (or this would be much easier) I want to have a dictionary with many To/CC addresses that maps to many BCC addresses. I would also like to update the dictionary on a regular basis.
Here is a link to the API that I was planning on using to create this Google Apps Script: https://developers.google.com/apps-script/reference/gmail/
Is this possible? If so is there an example of doing it? I haven't been able to find one!
Because Google Apps Script runs server side, not client side, you can't do this in the way you have described.
While you can use Apps Script to access messages in the Drafts or Sent labels, it doesn't appear you can set the BCC value of those messages, only retrieve it.
One approach that might work is to poll the Draft or Sent messages folder on a fixed schedule, identify emails meeting your criteria, and then forward them to a given address (the one you wish to BCC). There are a number of challenges to this approach, such as determining how to avoid forwarding a given message multiple times, but it could be made to work.
See the docs on how to run your script on a schedule here:
https://developers.google.com/apps-script/guides/triggers/installable#time-driven_triggers
Edit, additional details in response to comment:
Setting up the triggers is very simple, I've used them many times in the past. You simply write a function that takes the actions you want, and once you have finished testing it manually, you can create the trigger via the "Resources" -> "Current Script's Triggers" menu options in the Script Editor.
You can't simply store processed id's in a variable, state is not shared between instances of the script. So you'll need to track them elsewhere, depending on volume you might want to look at the Properties Service, storing them in a spreadsheet, or my favorite would be to apply a label to processed emails and cross check the label in your script.
The label approach also lets you easily see which messages have been processed in the gmail interface.
If what you want is sending a copy of sent mail automatically to some address, that can be done with filters. I found the solution here:
http://markmail.org/message/nj46fcwlccd6asoj
"Configure the filter like this:
From: your email address
Forward: your email address
Enable never send to spam (IMPORTANT!)
"

Session.getActiveUser().getEmail() workaround for distributing grades from a spreadsheet

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