Google Calendar API get Event details - javascript

I tried to get the event from Google Calendar of the specific date
function testing(){
var cal = CalendarApp.getCalendarById('moses#gmail.com');
var events = cal.getEvents(new Date("7/11/2022 07:30 AM"),new Date("7/12/2022 10:00 AM"));
for (var i=0;i<events.length;i++){
var title = events[i].getTitle();
var start_time = events[i].getStartTime();
var end_time = events[i].getEndTime();
}}
But I don't know how to get the same detail from Calendar when I schedule any meeting without specifying any date range.
My request is, I need to get the Title, Organizer Name, Start and End Time of the meeting when I schedule any meeting in Google Calendar.
Moment I press Save in the Calendar, My script needs to trigger and get the details of the meeting I scheduled in calendar.

This can get complicated and you won't be able to only use Google Apps Script for it.
I believe your question boils down to two requirements:
Knowing when a new event has been created.
Getting the details of this newly created event to use as you see fit.
For #1, you can know when a calendar gets modified by using push notifications. The way this works is that you send a POST request to the Calendar's watch endpoint, with headers specifying the URL of a server that you want to set up as a webhook. This server will receive POST notifications when the Calendar gets updated and you can then handle them. A few caveats:
There are no native Apps Script functions that can use this, so you need to create your own GCP project, and generate the Authorization token to include in your request to create the webhook.
You will need to set up your own server to handle the callbacks. You cannot use Apps Script as a Web App because the callbacks contain all their information in their HTTP headers, and the doPost() method does not contain the headers, as explained in this question. Since the notifications work by sending POST messages, Apps Script won't work here.
The notifications are not 100% reliable. A small percentage of messages may get dropped so you won't always know that there was a change.
As for #2, the problem here is that the push notifications are only meant to notify your app that a change was made so it can handle the syncing on its own. This means that they don't include any details about what exactly changed, so you cannot know which event was created or changed, you only know that the calendar was somehow changed, and it's up to you to figure out what it was.
Google recommends using incremental sync, which means that you first sync all events, then use the syncToken they provide to get only changed events. You can use this to figure out which events changed since you got the notification, but you may have to refresh a full sync sometimes, so rather than just picking up new events, your app is now in charge of fully syncing the Calendar.
If this is all too much work you can still try to list events using the updatedMin parameter to only list events more recently modified than a specific date/time. You can use this with Apps Script's Advanced Calendar Service. You could do this periodically, but you won't have the instant trigger you're looking for.
Sources
Node.js sample of how to use webhooks
Push Notifications
Advanced Calendar Service
Synchronizing calendars

Related

How to create Custom Dimension & get Unique PageView with GA4?

We're not sure if this is the right place for us to obtain the answers of such. We've contacted the Firebase Support Team but did not get the answers that we want except a few links to the online documentation that we've mostly been through before. After further clarifying our requests, we've not been receiving any response from them for 5 days; therefore we might as well try our luck here.
1. How to create a Custom Dimension in GA4?
As we understand, GA4 are all events now, including the Hit in Universal Analytics (UA), but how can we map from our UA custom dimensions to the GA4 model as shown below?
When we tried to create the AccCode custom dimension in GA4, we have no idea what to enter under the Event parameter dropdown list as it also cannot be dropped down whatsoever:
May I know how can we proceed from here and what should we enter for the Event parameter value?
2. How to get Unique PageView (UPV) in Firebase GA4 API?
In UA or GA v3, this is how we get our Page View and Unique PageView:
return jwt.authorize()
.then((response) => {
return google.analytics('v3').data.ga.get({
'auth': jwt,
'ids': 'ga:' + gaConfig.ViewerID,
'start-date': validatedDateRange.strStartDate,
'end-date': validatedDateRange.strEndDate,
'metrics': 'ga:pageviews,ga:uniquepageviews',
"dimensions": gaConfig.AccCodeDimension,
'filters': ${gaConfig.PageUrlDimension}!#googleusercontent.com;${gaConfig.PageUrlDimension}!#blogspot.com${!accCode ? "" : ";" + gaConfig.AccCodeDimension + "==" + accCode}`,
'sort': `${gaConfig.AccCodeDimension},-ga:pageviews,-ga:uniquepageviews`
}).then((gaQuery) => {
// Do something here
});
Below is the sample code that we found from the Firebase GA4 documentation:
import firebase from "firebase/app";
import "firebase/analytics";
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Initialize Analytics and get a reference to the service
const analytics = firebase.analytics();
analytics.logEvent('select_content', {
content_type: 'image',
content_id: 'P12453',
items: [{ name: 'Kittens' }]
});
But the above sample code seems to be far from giving us an idea on how to achieve the same result as did in GA v3. It's more like logging of event data, potentially for our custom dimensions as what we did in the UA's tracking code. Examples for data pulling don't seem to be available in the documentation here. We need an equivalent example on how we can achieve the same result with Firebase GA4 API so that we can quickly migrate over to GA4 before July 2023.
We hope that someone here can help us to resolve the above two issues as quickly as possible because they involve changing the core engine of our app, which requires vast amount of development time and testing while the clock is ticking. Thank you so much in advance!
After so much of the studies and R&D, we realized that for what we're trying to achieve has nothing to do Firebase at all -- we can purely focus on GA and its latest API, which is still on Beta while some are on Alpha. But for the custom dimension creation, below is the answer:
Creating Custom Dimensions in GA4
As per the question described, the custom dimension creation process can be very confusing, especially to the UA users due to the change of data model and concepts. But what you need to know is that, you need to finalize your event parameters before mapping them over to the custom dimensions on GA console because the event parameter cannot be edited once the custom dimension is created on GA console:
So what you need to do is to extend your existing UA tracking code as shown below before creating your custom dimensions on GA console:
gtag('event','page_view', { // the page_view event is for web
"acc_code": "{{{AccCode}}}", // acc_code is your event parameter
"acc_name": "{{{AccName}}}", // This is another event parameter
"viewer_id": "{{{ViewerID}}}",
"viewer_title": "{{{ViewerTitle}}}",
"viewer_url": "{{{gaUrl}}}"
});
gtag('config', 'G-XXXXXXXX'); // This is your GA4 MEASUREMENT_ID
Data Query in GA4
For data query in GA4 that is equivalent to the given example in the question, please refer to the GA4 Data API here.
What about the Unique Pageview metric?
According to the GA documentation here, looks like Unique Pageview is no longer available in GA4:
I'm not sure if this is still subject to change, but you may need to write your own code, perhaps using sessionStorage or session cookies to track your own unique pageviews per user session for every page viewed.

Firebase real-time efficiency question: How to set up listeners for a chat app

I have a chat app using Firebase as a realtime database and React Native. I'm trying to figure out the most efficient way to set up the listener for chat messages from Firebase in terms of minimizing read operations and transferring data. Here is my data structure:
- messages
- chatId
- messageId
- sentBy
- timestamp
- text
As I see it I have 2 options, either ref.on("child_added) or ref.on("value")
If I use ref.on("child_added"), the advantage is that when a new message is sent then only the newest message is retrieved. The problem though is that when the conversation is loaded the read operation is called for each message in the chat. If a conversation is hundreds of messages long, then that's hundreds of read operations.
The other option is to use ref.on("value"). The problem here is that on every new message added, the entire conversation is resent instead of just the most recent message. The advantage is that when the conversation is loaded, only one read operation is called to transfer the entire conversation to the screen.
I want some combination of the two of these in which when the conversation is loaded, there is one read operation that brings the entire contents of the conversation, AND when a new child node is added (a new message) only that message is transmitted to the listener. How can I achieve this?
firebaser here
There is no difference between the wire traffic for a value listener and child_ listeners on the same location/query. If you check the Network tab of your browser, you can see exactly what is sent retrieved, and you'll see that it's exactly the same between the listener types.
The difference between value and child_* events is purely made client-side to make it easier for you to update the UI. In fact, even when you attach both value and child_* listeners to the same query/location, Firebase will only retrieve the data only once.
The common way to do what you want is to attach both child_* and value listeners to the query/location. Since the value listener is guaranteed to be fired last, you can use that fact to detect when the initial load is done.
Something like:
var chatRef = firebase.database().ref("messages/chatId");
var initialLoadDone = false;
chatRef.on("child_added", (snapshot) => {
if (initialLoadDone) {
...
}
});
chatRef.once("value", (snapshot) => {
snapshot.forEach((messageSnapshot) => {
...
});
initialLoadDone = true;
});
Suggestion: Use Firestore. It maintains a cache of your data and efficiently handles such scenarios.
You can use ref.once('value') to get current nodes only once and then ref.on('child_added') for subsequent additions. More performance notes.
Edit: I believe Firebase Database handles this efficiently by just ref.on('value'). On checking the network tab after adding a new node to my database, I notified the amount of data that got transferred was very low. This might mean that firebase by default caches your previous data. Would recommend you to look at your network tab and take decisions as such or wait from someone from their team show directions.

Can I Send a Web Notification on a Specific Time?

I am trying to implement notifications that do not need the interaction of the backend to be shown. The use of this is to put a remind me button, that would send a notification on certain time of the day (that the user specified). I am pretty new to service workers but I understand that they work asynchronously. That being said, is there any way in which I could do something like the following pseudocode?
function timeLeft(time){
setTimeout(() => showNotification(), time);
}
This would work if I put it on a regular javascript file and the user has the browser still open.
It does not need to be exactly like that, it just needs to solve my problem. Thank you un advance.
First you need to have an ID for each browser. If you use the Push API, then you can use the browser endpoint.
When a user adds a reminder, you must store the tuple (endpoint, send_at, reminder) in your database on your server
Run a cron job on your server (or create a scheduled job with Sidekiq, etc.) in order to send the reminder at the correct time (using the Push API)
Otherwise you can use a service which allows you to create scheduled notifications: see this example on my blog.

Retrieve single Calendar Event using API v3 in javascript

I have modified the script found here Retrieve Google Calendar events using API v3 in javascript to display a page of upcoming events over the next 30 days which summarizes each event.
I would like to create a link provided with each event summary on the above page to another page that would show more details for a specific single event.
I cannot seem to write the code that will successfully take the eventId and query the Google Calendar API to retrieve the resources for that single event.
I apologize in advance as I am trying to learn Javascript as I go so I suspect this is something rather simple that I'm stuck on.
I am of the belief that in the makeApiCall() function I would desire to change the lines that start with:
var request = gapi.client.calendar.events.list({
to:
gapi.client.load('calendar', 'v3', function () {
var request = gapi.client.calendar.events.get({
'calendarId' : userEmail,
'eventId': eventIDstr});
I can get a valid answer when using Google's APIs Explorer pages so I know I have the correct Calendar and Event IDs. Just cannot seem to apply that to the correct javascript to get the results I am looking for.
I have searched high and low for samples of javascript that will retrieve a single Event's data from Google Calendar using v3 of their API and have come up with nothing useful. Any help would be greatly appreciated.
Thanks in advance.
Yes, you're on the right path. Use Events:get. Events provides different flavors of event resources.
HTTP request
GET https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId
If successful, method returns an event resource in the response body.
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
// ...
// Initialize Calendar service with valid OAuth credentials
Calendar service = new Calendar.Builder(httpTransport, jsonFactory, credentials)
.setApplicationName("applicationName").build();
// Retrieve an event
Event event = service.events().get('primary', "eventId").execute();
System.out.println(event.getSummary());
You can use singleEvents=true parameter in the list request to avoid the second call. This will ask the server to do the recurring event expansion for you right away.

Auto detect if DB table changes

I have a small application where a users can drag and drop a task in an HTML table.
When user drops the task, I call a javascript function called update_task:
function update_task(user_id, task_id, status_id, text, uiDraggable, el) {
$.get('task_update.php?user_id='+user_id+'&task_id='+task_id+'&status_id='+status_id+'', function(data) {
try {
jsonResult = JSON.parse(data);
} catch (e) {
alert(data);
return;
};
In task_update.php I GET my values; user_id, task_id & status_id and execute a PDO UPDATE query, to update my DB. If the query executes correctly, I
echo json_encode ( array (
'success' => true
) );
And then I append the task to the correct table cell
if(typeof jsonResult.success != 'undefined') {
$(uiDraggable).detach().css({top: 0,left: 0}).appendTo(el);
}
This has all worked fine. But, I'm starting to realize, that it's a problem when 2 or more people are making changes at the same time. If I'm testing with 2 browsers, and has the site opened on both for example: Then, if I move a task on browser1, I would have to manually refresh the page at browser2 to see the changes.
So my question is; How can I make my application auto-detech if a change to the DB-table has been made? And how can I update the HTML table, without refreshing the page.
I have looked at some timed intervals for updating pages, but that wouldn't work for me, since I really don't want to force the browser to refresh. A user can for example also create a new task in a lightbox iframe, so it would be incredibly annoying for them, if their browser refreshed while they were trying to create a new task.
So yeah, what would be the best practice for me to use?
Use Redis and its publish/subscribe feature to implement a message bus between your PHP app and a lightweight websocket server (Node.js is a good choice for this).
When your PHP modifies the data, it also emits an event in Redis that some data has changed.
When a websocket client connects to the Node.js server, it tells the server what data it would like to monitor, then, as soon as a Redis event was received and the event's data matches the client's monitored data, notify the client over the websocket, which then would refresh the page.
Take a look at this question with answers explaining all of this in detail, includes sample code that you can reuse.
I would use ajax to check the server at a reasonable interval. What's reasonable depends on your project - it should be often enough that it changes on one end don't mess up what another user is doing.
If you're worried about this being resource intensive you could use APC to save last modified times for everything that's active - that way you don't have to hit the database when you're just checking if anything has changed.
When things have changed then you should use ajax for that as well, and add the changes directly in the page with javascript/jquery.
If you really need to check a db changes - write a database triggers.
But if nobody, except your code, change it - you can to implement some observation in your code.
Make Observation(EventListener) pattern imlementation, or use one of existed.
Trigger events when anything meaningful happened.
Subscribe to this events

Categories