How to refresh appmaker table on change in calendar event of a calendar(dynamic) on current day? - google-apps-script

I have created a app in appmaker. In that there is a table which should get refreshed (i.e a particular appscript function (client-side function)should run to refresh the table) whenever any change in calendar events of a particular calendar on the current day takes place.
How to set such type of trigger?
I did some R&D and found that there is something called watch function in calendar API but I'm not sure if it is useful for my problem.
By table I am referring to appmaker table widget.
If setting the appscript calendar trigger, Client refresh may be a problem. Because in my ui above the table there is a dropdown to select the calendarId which refreshes the table by running the below code:
var calendarId=app.pages.Events.descendants.Dropdown1.value;
google.script.run.withSuccessHandler(function() {
app.datasources.Events.load();
}).getTodayEvents(calendarId);
/* In getTodayEvents() current day events of the calendarId are
fetched from that calendar and stored in DB */
Can this happen from server side through trigger?
Also trigger should be based on the calendarId currently selected in dropdown.
So the calendarId needs to be dynamic in the trigger.

A calendar watch requires an webhook that will process some logic when there is an event modification(create, update, delete). Unfortunately, App Maker does not yet support such a thing and here is a discussion about it Calling App Maker server scripts from outside of App Maker UI. On top of that, you would require to interact with the client side rather than the server, so definitely not.
In this case, the best thing you can do is set an interval that will refresh the ui every certain seconds or minutes.
setInterval(function(){
app.datasources.myDatasource.load();
},60000); //60 seconds
A more advanced way of approaching this would be using firebase and cloud functions. I have implemented firebase on some projects with reliable results. You can read more about firebase and cloud functions on the below links:
https://firebase.google.com/docs/web/setup
https://cloud.google.com/functions/docs/

This may or may not be applicable to your use case but for non-app-maker script projects I'd do the following:
Go to your GSuite Developer Hub via https://script.google.com/home/my
Select the desired script project
On the right is a box titled "Project Details", click the menu icon (top-right) and select "Triggers"
Click the "Add trigger" button (bottom-right)
In the pop-up modal select the function you wish to run, and set the event source to "Calendar".
Note that this "Calendar" trigger can only detect updates to your primary calendar. Changes to secondary calendars you create will not be tracked.

Related

How to implement? Spreadsheet with link - Go To Link Grab Data - Update Spreadsheet Row

I am looking for technology suggestions. Or if this can be done in native google sheets (note the site I am looking to access is behind a username and password).
I have a google sheet that looks like this
birth date
link
data_element_from_website
12/31
https://something.com/3920230
1/31
https://something.com/1920238
lets say on https://something.com/3920230 there is a HTML element 123
Twice a day I want to be able to refresh the data, this could be done by going into the spreadsheet and clicking/doing something.
Can this be done?
What if https://something.com/3920230 is behind a login (authentication). Note: I could be logged in to the website in a different tab... I don't think that would make a difference though...
Assuming you have a script that you would like to run twice a day, you can use Apps Script Time-driven triggers:
A time-driven trigger (also called a clock trigger) is similar to a cron job in Unix. Time-driven triggers let scripts execute at a particular time or on a recurring interval, as frequently as every minute or as infrequently as once per month. (Note that an add-on can use a time-driven trigger once per hour at most.)
If it's just some formulae, you can change the recalculation settings to be either On change, On change and every minute or On change and every hour under the File > Spreadsheet settings menu item and clicking on the Calculation tab.
If you want to get data from public site(no login) you can use ImportXML. You can google a lot about it, for example
https://answerbun.com/personal-finance-money/get-revenue-details-in-google-sheets-using-google-finance/
If the page you want can only be accessed using login, this becomes a rather complicated task, especially using only apps script libraries (not much scraping lib support here)

g-suite Google Calender Apps script On Event Save/Update

First of all, i am new to Google Workspace and this is the first time i am developing an addon.
I am trying to develop a Google Workspace(gsuite) Addon using Google Apps Script,
My main objectives are:
Whenever i create/save/update an event in Google Calender, i want to make an alert asking for ok and cancel, if i click cancel the event should not be created and if i click ok then the event should be created and the script function should call my API endpoint with the following parameters:
{
summary: summary_of_the_event,
created: event_created_or_updated_date,
googleCalendarId: calender_id
}
Here is the reference to Apps script Google calender:
https://developers.google.com/apps-script/reference/calendar/calendar-app
I appreciate the help.
Some thoughts about calendar add-ons
CalendarApp features the installable calendar trigger with the specification:
Calendar triggers fire when a user's calendar events are updated (created, edited, or deleted).
Installble triggers can be used in Google Workspace add-ons
Howver, this installable trigger only fire after the event has been created / updated, so it can help you to cancel event creation, but rather no manually delete the event a posteriori.
Mind also that the when the trigger fires, it does not give you any information about the created / updated event - you have to manually find this event e.g. by querying for the least created / updated event in user's calendar.
Google Workspace Calendar add-ons feature the manifest trigger for updating calendar events calendar.eventUpdateTrigger
Thereby:
This trigger only fires if the user makes one or more of the following edits:
Adds one or more attendees.
Removes one or more attendees.
Adds or switches to a different conferencing solution.
Google Workspace Calendar add-ons also feature the manifest trigger calendar.eventOpenTrigger
It fires when you open an event (this is what you want!).
However, this work only for already existing events - not when a user opens the Calendar UI interface to create a new event
Instead of letting a user create / update events through the regular Calendar UI, you can use Card Service to create a custom add-on interface where the user can specify that he wants to create an event
Within the card interface, it is easier to implement an ok / cancel functionality (as a card) and then (in case "ok" is clicked) create an event for the user programmatically.

Google Calendar Trigger Does Not Fire

The objective is to transfer data from Google Calendar to a Google Sheet whenever the calendar is edited. For this we need a script that transfers the data, and need to set up the Calendar trigger.
Thanks to Oleg Valter and his excellent and exhaustive explanation how to create the script on this page:
Google calendar events to Google spreadsheet automatic refresh onEdit
the data transfer already works fine when the script is started from the Google sheets. I use a modified version of Oleg's script, which works well, and I am not sure if it would make sense to re-post it here (since that is not the problem).
I have tried to create the trigger with Oleg's funtion first:
/**
* Installs Calendar trigger;
*/
function calendarTrigger() {
var trigger = ScriptApp.newTrigger('callback name here')
.forUserCalendar('calendar owners email here')
.onEventUpdated()
.create();
}
but the trigger did not fire when I have added a new event on the calendar. Checked the triggers connected to the project, and the trigger created by the above function was there. Checked the Executions and nothing showed up.
Then I have manually deleted the trigger, and manually crated a new one following the instructions under "Managing triggers manually" section of this page:
https://developers.google.com/apps-script/guides/triggers/installable#google_apps_triggers
The trigger was created again, which basically looked the same as the one created by the above function, but it still did not fire when tested.
Now I am stuck and have no idea what else to try. It supposed to work, but it is possible that I have missed setting up something else that might be required for this to work.
I am using a simple Google account connected to a single email address (not a business suite). Never had any problems with the other triggers related to the sheets before that I could not resolve (sometimes the platform refuses to work as it should, but then later things get back to normal).
I would highly appreciate any advice about what else to try, or if you know what the problem is, even better.
Thanks in advance,
Zoltan
Well, after some trial and error based on ziganotschka's kind answer (thanks again) found the problem. It is caused by a bit of confusion about what the
.forUserCalendar('calendar owners email here') and the
Calendar ID supposed to be.
On my Calendar account there are several calendars, but two are of interest for us here:
"Main Calendar" which is the default calendar associated with the account. If everything else is deleted, then this will remain.
another calendar that I have added for the very purpose to be connected to the spreadsheet, and named it "Auto Billing" (only this is checked and displayed).
The Main Calendar has this on the Settings page (changed my email address):
Integrate calendar
Calendar ID
myAddress#yahoo.com
The Auto Billing calendar has this on the
Settings page (changed the ID):
Integrate calendar
Calendar ID
svj8tu1o458a9s1488xxxxxxxx#group.calendar.google.com
My intent was to use a custom created calendar for this purpose instead of using the default Main Calendar, because this might be full with all kinds of events.
Therefore when the trigger is created manually
svj8tu1o458a9s1488xxxxxxxx#group.calendar.google.com
should be added in the field "Calendar owner email" instead of the calendar owner's email address.
When the trigger is created from script using the above snippet, then
.forUserCalendar("svj8tu1o458a9s1488xxxxxxxx#group.calendar.google.com")
should be used.
In the script that transfers the data from the Calendar to the sheet the
var Calendar = CalendarApp.getCalendarById("svj8tu1o458a9s1488xxxxxxxx#group.calendar.google.com");
should be used. This way the trigger will work when events are edited on the Auto Billing calendar.
Thanks for the guidance Ziganotschka, and also big thanks to Oleg for the original script. Hope this debugging will help others as well.
Google Calendar trigger is a feature for the Google Calendar
It does not work for "myaddress#yahoo.com" calendars

Apps Script Making onEdit and onOpen triggers work only for the current user

Probably the answer to this is simple but I am having a tough time getting my head around it.
I have a spreadsheet used by many users. I want custom onEdit and onOpen functions to run only for the user who triggers then. For example - if person B opens the spreadsheet, then only his custom onOpen trigger should run, not the custom onOpen triggers for the other users. Likewise if the user edits a cell only his custom onEdit should run.
Currently how I have set it up everyone has his own triggers but they all run the same script every time there is a trigger by any user, meaning the trigger runs 4x for no reason and it's slowing down the spreadsheet, and it also wastes script time usage for the other users who are not opening or editing the sheet.
You can have separate functions for each user and have code dynamically check for current user and run the function of current user only.
See here for getting current user. Link
Assuming the functions are the same but you just aren't wanting it to run for some users, you could use PropertiesService to store a user property to identify if it should run or not. You have to make some UI method to set the property and then you would check for the property at the beginning of each of your functions. Technically the functions would run but you could return out of them if you don't want to finish the logic.

Installable OnEdit not being called in Stock spreadsheet

I have a function (in a Google Apps Script), not called onEdit(), but something else and this has been set up to be called from any on edit events via in the Installable onEdit on a Google Spreadsheet.
The spreadsheet is around stocks and monitors a portfolio and the purpose of the function is to send an email as soon as a stop loss is hit on a stock, i.e. the price of a stock falls to a certain price. The price of the stock is retrieved and updated via the Google Finance API in a column in the spreadsheet.
Now, when running the function from the script or locally editing the spreadsheet, the function is called successfully. However, I am finding that as the stock price is updating automatically throughout the day on Google Drive and falling to the stop loss price, the on edit function is not being called. I read somewhere about it not being called by an "anonymous" user? I know it's not being called as I have an "email counter" column, which decreases every time the function is called, and once at 0 no more mails will be sent to avoid spamming. This not decreasing via the Google Finance API automatic price updates.
Can someone advise what is causing this and if this there is any workaround?
A list of things-that-don't-trigger-onEdit, along with their issue tracking ids, were provided in a previous answer.
Content of a spreadsheet changed by scripts does not trigger onEdit.
A work-around might be to use a time-based trigger, and in the call-back scan for and react ti changes. (Could the updater set a trigger to fire in the near future, perhaps?) Challenges for this will be around balancing responsiveness vs trigger limits.