Google fit API script needs constant authorisation when trying to run automatically & how to extract additional info - google-fit

I have a script that exports data from the Google Fit API to Google Spreadsheets. The script was found here - https://ithoughthecamewithyou.com/post/export-google-fit-daily-steps-to-a-google-sheet and works.
When I run the script daily manually, it works. However, when I have it set up to run automatically and scrape the data each morning, I get an email saying that it failed to run as authorisation was required.
I'm sure it's something simple, but how can I have it set up so that authorisation isn't required?
Additionally, the ultimate goal is to build some form of dashboard from the data stored on that spreadsheet. Is it possible to scrape additional information, such as what the exercise was? I know that info is stored there, but I'm just not sure how to access it.
For example, I'd like to scrape the data that has been identified as a run on Google Fit.

Google fit Access OAuth token are process short-lived, and they do not last for long period. So you will be required to identify yourself with credentials on every instance request or after 60 mins per documentation for security reasons.

Related

how to store the email of the google app script installing users

I have google sheets addon in Google Workspace Marketplace. I want to store the emails of the users installing the addon. I'm thinking of three possible ways.
Write to private spreadsheet under the addon account (different than the user's). Addon is running under user's so the question is, is this even possible - accessing the addon account (specifically writing to a spreadsheet) from within the user google account context?
using PropertiesService - Write the user to script properties using PropertiesService class.
One problem with this one is the limitations as explained in Quotas for Google Services.
for me, at lease for now, this is enough.
However the question is how to access those script properties programmatically.
Of course I can access the data from the script editor, but this is not practical if I want for example to send mail to all the users.
adding code to the addon that will be available only for specific users (admin). In this case since I can read the users from the script properties, and maybe write them to spreadsheet to be used later. This looks ugly, I admit.
I'm not asking for code solutions, but suggestions for the right or best approach.
The easiest solution is to create a database
Create a spreadsheet located on your Drive, shared as "Everyne can edit".
Implement a flow where after Add-n installation data containing the user"s email will be appended to the spreadsheet.
This request will take place on user's beahlf, however given that the spreadsheet is shared publicly, there won't be any access permission issues
Even if the spreadsheet is shred publicly - given that the spreadsheet id is not known by anyone other than the Add-on code, you do not need to worry about undesired access to the database.

How to link a Project Number to a Script dynamically?

I'm creating forms on demand and i need to be able to set up the triggers. If i do it on the main AppsScript script that is handling the forms creation, i'll hit the 20 triggers max quota pretty soon. So i decided to add a dedicated script to every form (associating with parentID) so i won't hit the quota.
My problem is that when i try to add the triggers i'm getting permission denied since the scripts created for each form are using a default GCP project and it needs to be a standard GCP project due to OAuth.
I can add the project number manually, but that kind of defeats the idea of being able to generate google forms on demand.
I want to be able to link the script created with the standard GCP project that is already configured, but i just can't find anything on Google's documentation, i know its a long shot but i've decided to post here in hopes that someone that had the same problem managed to do so.
As requested on the comments below, the triggers that i'm using are:
onFormSubmit - get the response and send it to my endpoint in the backend server
onOpen - ensures that the editor hasn't removed anything default (this only works when an editor opens the form in edit mode)
This is the project number im referring to.
Thanks

Apps Script Activity Reporting/Visualization

I've been developing an apps script project for my company that tracks our time/expenses. I've structured the project like so:
The company has a paid Gsuite account that owns all the spreadsheets hosted on the company's google drive.
Each employee has their own "user" spreadsheet which is shared from the company Gsuite account with the employee's personal gmail account.
Each of the user spreadsheets has a container-bound script that accesses a central library script.
The library script allows us to update the script centrally and the effects are immediate for each user. It also prevents users from seeing the central script and meddling with it.
Each of the user container-bound scripts have installable triggers that are authorized by the company account so that the code being run has full authority to do what it needs to to the spreadsheets.
This setup has been working quite well for us with about 40 users. The drawback to this setup is that since all the script activity is run by the company account via the triggers, the activity of all our users is logged under the single company account and therefore capped by the apps script server quotas for a single user. This hasn't been much of an issue for us yet as long as our script is efficient in how it runs. I have looked into deploying this project as a web-app for our company, but there doesn't seem to be a good way to control/limit user access to the central files. In other words, if this project was running as a web app installed by each user, each user would need to have access to all the central spreadsheets that the project uses behind the scenes. And we don't want that.
SO with that background, here is my question. How do I efficiently track apps script activity to see how close we are to hitting our server quota, and identify which of my functions need to be optimized?
I started doing this by writing a entry into a "activity log" spreadsheet every time the script was called. It tracked what function was called, and who the user was and it had a start time entry and and end time entry so I can see how long unique executions took and which ones failed. This was great because I had a live view into the project activity and could graph it using the spreadsheet graphs tools. Where this began to break down was the fact that every execution of the script required two write-actions: one for initialization and another for completion. Since the script is being executed every time a user made an edit to their spreadsheet, during times of high traffic, the activity log spreadsheet became inaccessible and errors would be thrown all over the place.
So I have since transitioned to tracking activity by connecting each script file to a single Google Cloud Platform (GCP) project and using the Logger API. Writing logs is a lot more efficient than writing an entry to a spreadsheet, so the high traffic errors are all but gone. The problem now is that the GCP log browser isn't as easy to use as a spreadsheet and I can't graph the logs or sum up the activity to see where we stand with our server quota.
I've spent some time now trying to figure out how to automatically export the logs from the GCP so I can process the logs in real-time. I see how to download the logs as csv files, which I can then import into a google spreadsheet and do the calcs and graphing I need, but this is a manual process, and doesn't show live data.
I have also figured out how to stream the logs from GCP by setting up a "sink" that transfers the logs to a "bucket" which can theoretically be read by other services. This got me excited to try out Google Data Studio, which I saw is able to use Google Cloud Storage "buckets" as a data source. Unfortunately though, Google Data Studio can only read csv files in cloud storage, and not the json files that my "sink" is generating in my "bucket" for the logs.
So I've hit a wall. Am I missing something here? I'm just trying to get live data showing current activity on our apps script project so I can identify failed executions, see total processing time, and sort the logs by user or function so I can quickly identify where I need to optimize my script.
You've already referenced using GCP side of your Apps Script.
Have a look at Metric explorer, it lets you see quota usage per resource and auto generates graph for you.
But long term I think re-building your solution may be a better idea. At minimum switching to submitting data via Google Forms will save you on operation.

Google Apps Script - communication between script

HiMy problem is following: I would like to create small web page, on which it will be possible to create event in Google Calendar, but with some restrictions. In my case this calendar could be edited by my flatmates to reserve washing machine. This reservation cannot overlap and also all of us has limited number of days when we can use it. I have created private calendar, and I have created script which validate requests, and if everything is ok add event to calendar. This script is executed as me (because only I have permission to edit this calendar).
But I have problem with fetching information which user execute this script (me or one of my flatmate). Class Session contains 2 methods getActiveUser() and getEffectiveUser() but active user does not work (I guess because privacy protection policy). But if I create another script which is executed as user accessing the web I can get active user.
Does anybody know if is it possible to communicate somehow between this 2 scripts embedeed on the same site? I want to pass email of active user from one script to another. Or maybe do you know better solution how to solve this problem?
Regards
Adam
As you noticed, you need to set the script to run as the user accessing it to get his email. Then, instead of accessing the calendar directly (which you obviously can't) you can call another script published, but running as yourself allowing anonymous access that will receive this request from the "viewing" script and create the calendar events for it.
After you publish this "background" script, get its url and use it on a UrlfetchApp.fetch call to it. Then pass the parameters as url paremeters (or on payload if you prefer to use post instead of get).
The background script may even use ContentService to give nice return values to the calling script.
Sure, you can do so, but it's not as simple as you'd like. Make your admin level script run a web service that responds to the other script. It can probably be hacked as you can't authenticate the users, but comon, this is a washing macine!

Security issue concerning apps scripts inserted in google site

I inserted a google apps script as a gadget in a google Site. This GAS implements a page on html service and is intended to capture user data and store it in the ScriptDb of another script. Playing around, I noticed that viewing the source code of the google site any user could access directly to the GAS via an url displayed on the source of the Google site. I followed this link, and there was the GAS! From this link, I tried to save new data to ScriptDb, and I found that fortunately this was not possible. Doesn't this behaviour represent a security issue? Can I be sure that It is not possible to modify the ScriptDb data from this embedded link?
The ScritpDb your script creates can only be accessed accessed by that script's code - just because you have the URL to the published script or even if you have code in some form DOES NOT give you access to the ScriptDb.
However, lets say if in your doGet if you are blindly dumping out all the data to HTML output if a certain predictable parameter is passed in, then that is bad. But that would be considered a programming error.
So in short - if your ScriptDb is properly wrapped with the appropriate Apps Script, then access to that ScriptDb is secure.
I can clarify more if you share some code around what you worry might be insecure.