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.
Related
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
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.
I'm using the Google Calendar API to programmatically create calendar events for users. I want to give users the option to include a Zoom meeting while creating their event (assuming they have the Zoom add-on for Gcal).
However, I get the following error when I try to create the event:
"Invalid conference type value."
Here is the body of my request (using the REST API):
data = {
summary: ...,
start: {...},
end: {...},
conferenceData: {
createRequest: {
requestId: uuid4().toString(),
conferenceSolutionKey: {
type: "addOn"
}
}
}
}
I used the type "addOn" per the allowed key types defined in the docs.
Another weird observation is that, when I pull my calendar metadata using the CalendarList API, under allowedConferenceSolutionTypes, only "hangoutsMeet" is listed. However, I double-checked in the Google Calendar client and I definitely have the Zoom add-on enabled.
Is this a bug in the Google Calendar API? Anyone have any pointers on how to create 3rd party conferencing meetings while creating GCal events?
This is currently not possible as confirmed by those two issues:
https://issuetracker.google.com/issues/167461857
https://issuetracker.google.com/issues/158019329
Even though the documentation of conferenceData seems to suggest that it is possible:
The conference solution, such as Hangouts or Google Meet. Unset for a conference with a failed create request. Either conferenceSolution and at least one entryPoint, or createRequest is required.
However the API returns an error if someone tries to do exactly that:
Cannot have multiple conferences of type Hangout and NamedHangout
I created a feature request, so I would suggest to go there and "vote" for it:
https://issuetracker.google.com/issues/167533577
Does Google Calendar API provide an endpoint for getting all of the meeting invites that a given user has yet to respond to? I'm familiar with the responseStatus field in the Event API so one way I imagine doing this is simply looking through all events on the calendar for which responseStatus == 'needsAction' but I'm hoping there's an easier way.
Any suggestions much appreciated!
I think the only way to do this is to get the Event and loop through the attendees to check the status. You can give that a try here, so you can immediately see the results.
I coach a sports team and set up a website for it. I would like to add a button to an admin page which I can click to quickly send an email to everyone on the team. This email will say something like: "Today's schedule has changed, please visit the website for more info."
I am sure this could be achieved easier though a distribution list in outlook or something, but I want to use, and get a better understanding of, Google Apps Script.
I have a Google Spreadsheet with the email addresses and a simple script function which sends the email.
This works great when I click to run it inside the script editor, but is there a way to call this from an external website with a button and some JavaScript?
You need to create a Google UI object that you can embed in your site - you'll do this by creating a Script that you will deploy as a web app. (Refer to Google Apps Script - Web Apps.) That object will contain a button that will invoke your existing script function to send the email.
Publish your web app to execute as you. For your specific situation, you will also want to have access to the app limited to you. That will mean that the UI Blob you create will not function for the general public. This is very incomplete, but produces a blob with a single button that will trigger your script:
function doGet() {
var app = UiApp.createApplication();
var button = app.createButton('Send Schedule Change Email');
app.add(button);
var handler = app.createServerHandler('myClickHandler');
button.addClickHandler(handler);
return app;
}
function myClickHandler(e) {
var app = UiApp.getActiveApplication();
// Call your library function, e.g.
TeamSpreadsheet.sendScheduleChanged();
var label = app.createLabel('Message Sent')
.setId('statusLabel')
.setVisible(false);
label.setVisible(true);
app.close();
return app;
}
Your web app will need to have access to your existing script, which I assume is embedded in your spreadsheet. This is accomplished by first saving a version of your existing script (File - Manage Versions), then adding it as a library to your new web app script (Resources - Manage Libraries). Read more about libraries here. Since your web app will run as you, you can keep your spreadsheet private.
Caveats
The utility script in your library will need to open your spreadsheet in a way that will work from outside of the sheet; use SpreadsheetApp.openById(), rather than SpreadsheetApp.getActiveSpreadsheet(). Unfortunately, openById pukes when you use it to open the host spreadsheet, so you'll want something like this:
var ss = null;
try {
// This works for scripts running in the host spreadsheet
ss = SpreadsheetApp.getActiveSpreadsheet();
} catch(err) {
try {
// This works for web apps
ss = SpreadsheetApp.openById("SPREADSHEET ID");
} catch(err) {
Logger.log("Could not open source spreadsheet.");
// Well, then, not much sense carrying on, is there?
return;
}
}
SpreadsheetApp.setActiveSpreadsheet(ss);
...
In fact, watch for any reliance on calls to get info from "active" objects. You may need to do some gymnastics to get around them.
I've found debugging this type of arrangement to be painful, since the app-script debugger often reports "Server Errors" when you try to trace into a library routine.
I hope that helps gets you started!
As a complement to Mogsdad's answer (that was quite complete and interesting) I'd say that your case could be a bit simpler since you have already a working script.
Take your script and add a doGet() function like in Mogsdad example, define a handler on the button that will call your existing function you wrote to send mails, in this function replace the getActiveSpreadsheet() by SpreadsheetApp.OpenById("the ID of the SS") and the getActiveSheet() by OpenByName() and you're done with the modifications.
After that follow Mogsdad instructions : deploy the script as a webapp running as you and use the provided url to access it from a link on your site.
If you want not to take any risk, do all these changes on a copy of your original spreadsheet so you always keep a working model at hand.
If you want more accurate advice (or if you meet some difficulties) feel free to show your existing script to get some help with the modifications.
PS : please consider this as a simple comment, written in an answer for the comfort of formating
Just publish your script as web application and upon a button click, excecute:
window.open("https://script.google.com/macros/s/<id>/exec");
Don't know if this was possible a year ago.