Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

error getting calendar events with google calendar API

I am developing a connection of my web application with the Google API related to the calendar allowing the user to see the events of their Google calendar.

My code allows you to log in from the navigation bar and redirect to the calendar page, but I have an error when rendering/loading the events, these errors appear in the console but it renders the empty calendar:

[GSI_LOGGER]: Failed to open popup window on url: . Maybe blocked by the browser?

GET https://content.googleapis.com/calendar/v3/calendars/primary/events?maxResults=100&orderBy=startTime... 404 (Not Found)

ai @ cb=gapi.loaded_0?le=scs:170

h @ cb=gapi.loaded_0?le=scs:170

bi @ cb=gapi.loaded_0?le=scs:171

(anonymous) @ cb=gapi.loaded_0?le=scs:171

d @ cb=gapi.loaded_0?le=scs:130

b @ cb=gapi.loaded_0?le=scs:126

calendarGoogle:944 Error fetching events: {result: {…}, body: '{\n "error": {\n "errors": [\n {\n "domain": "gl… ],\n "code": 404,\n "message": "Not Found"\n }\n}\n', headers: {…}, status: 404, statusText: null}

If I hit the custom refresh button that calls the loadCalendarEvents() function then the events are loaded.

This is my code:

calendarGoogle.php

<script>
    const HomeUrl = '<?php echo site_url('home'); ?>';

    let calendar;
    let calendarEl = document.getElementById('calendar');

    document.addEventListener('DOMContentLoaded', function() {
        calendar = new FullCalendar.Calendar(calendarEl, {
            initialView: 'dayGridMonth',
            headerToolbar: {
                left: 'prev,next today myCustomButton logout',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay'
            },
            events: async function(fetchInfo, successCallback, failureCallback) {
                try {
await ensureGapiInitialized();
                    const response = await gapi.client.calendar.events.list({
                        'calendarId': 'primary',
                        'timeMin': fetchInfo.startStr,
                        'timeMax': fetchInfo.endStr,
                        'showDeleted': false,
                        'singleEvents': true,
                        'maxResults': 100,
                        'orderBy': 'startTime'
                    });
                    const events = response.result.items.map(event => {
                        return {
                            title: event.summary,
                            start: event.start.dateTime || event.start.date,
                            end: event.end.dateTime || event.end.date,
description: event.description || '',
location: event.location || ''
                        };
                    });
                    successCallback(events);
                } catch (error) {
                    console.error('Error fetching events:', error);
                    failureCallback(error);
                }
            },
            customButtons: {
                myCustomButton: {
                    text: 'Refrescar',
                    click: function() {
                        Swal.fire({
                            title: 'Actualizando calendario...',
                            allowOutsideClick: false,
                            didOpen: () => {
                                Swal.showLoading();
                                loadCalendarEvents();
                            },
                        });
                    },
                },
                logout: {
                    text: 'Cerrar Sesión',
                    click: function() {
                        cierre();
                    }
                }
            },
            buttonText: {
                today: 'Hoy',
                month: 'Mes',
                week: 'Semana',
                day: 'Día',
                list: 'Lista'
            },
            locale: 'es',
            firstDay: 1,
            dayMaxEvents: true,
            eventClick: function(info) {
                const event = info.event;
                const title = event.title;
                const start = event.start;
                const end = event.end;
                const allDay = event.allDay;
                const description = event.extendedProps.description || '';
const location = event.extendedProps.location || '';
                const alert = event.extendedProps.alert || '';
                const task = event.extendedProps.task || '';

                let startFormatted, endFormatted;

                if (allDay) {
                    startFormatted = moment(start).format('Do MMM, YYYY');
                    endFormatted = end ? moment(end).format('Do MMM, YYYY') : 'Sin fecha de fin';
                } else {
                    startFormatted = moment(start).format('Do MMM, YYYY - h:mm a');
                    endFormatted = end ? moment(end).format('Do MMM, YYYY - h:mm a') : 'Sin fecha de fin';
                }
              
                document.querySelector('[data-kt-calendar="event_name"]').textContent = title;
                document.querySelector('[data-kt-calendar="all_day"]').textContent = allDay ? 'Todo el día' : '';
                document.querySelector('[data-kt-calendar="event_start_date"]').textContent = startFormatted;
                document.querySelector('[data-kt-calendar="event_end_date"]').textContent = endFormatted;
                // Mostrar si hay descripción
                const eventDescriptionContainer = document.querySelector('[data-kt-calendar="event_description"]');
                if (description.trim() !== '') {
                    eventDescriptionContainer.innerText = description;
                    eventDescriptionContainer.classList.add('scrollable-textarea');
                    eventDescriptionContainer.style.resize = 'vertical';
                    eventDescriptionContainer.style.display = 'block'; // Asegurarse de que el contenedor esté visible
                } else {
                    eventDescriptionContainer.innerText = '';
                    eventDescriptionContainer.classList.remove('scrollable-textarea');
                    eventDescriptionContainer.style.resize = 'none';
                    eventDescriptionContainer.style.display = 'none'; // Ocultar el contenedor si no hay descripción
                }

                // Mostrar si hay Localización
                const viewEventLocation = document.querySelector('[data-kt-calendar="event_location"]');
                if (viewEventLocation) {
                    const eventLocationContainer = viewEventLocation.closest('.d-flex.align-items-center');
viewEventLocation.innerHTML = '';
                    if (location.trim() !== '') {                        
                        const googleMapsUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(location)}`;
                        viewEventLocation.innerHTML = `<a href="${googleMapsUrl}" target="_blank">${location}</a>`;
                        eventLocationContainer.classList.remove('hidden');
                    } else {
                        eventLocationContainer.classList.add('hidden');
                    }
                } else {
viewEventLocation.innerHTML = '';
                    console.error('Elemento de ubicación no encontrado');
                }
                document.querySelector('[data-kt-calendar="event_alert"]').textContent = alert;
                document.querySelector('[data-kt-calendar="event_task"]').textContent = task;

                // Mostrar el modal de Bootstrap
                const modal = new bootstrap.Modal(document.getElementById('kt_modal_view_event'));
                modal.show();
            }
        });

        calendar.render();
ensureGapiInitialized().then(loadCalendarEvents).catch(handleError); // Load events when the calendar is rendered
    });

/*
    function gapiLoaded() {
        gapi.load('client', initializeGapiClient);
    }

    async function initializeGapiClient() {
        try {
            await gapi.client.init({
                apiKey: "api key",
                discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
            });
            gapiInited = true;
            // Load the calendar events after the client is initialized
            if (gisInited) {
                loadCalendarEvents();
            }
        } catch (error) {
            console.error('Error al inicializar gapi client:', error);
        }
    }

    function gisLoaded() {
        try {
            tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: "client id",
                scope: "https://www.googleapis.com/auth/calendar.readonly",
                callback: '', // defined later
redirect_uri: '<?php echo site_url('calendarGoogle'); ?>',
            });
            gisInited = true;
            // Load the calendar events after the client is initialized
            if (gapiInited) {
                loadCalendarEvents();
            }
        } catch (error) {
            console.error('Error: Configuración de Google no cargada correctamente.', error);
        }
    }
*/

async function ensureGapiInitialized() {
        return new Promise((resolve, reject) => {
            if (typeof gapi !== 'undefined' && gapiInited && gisInited) {
                resolve();
            } else {
                const checkInterval = setInterval(() => {
                    if (typeof gapi !== 'undefined' && gapiInited && gisInited) {
                        clearInterval(checkInterval);
                        resolve();
                    }
                }, 100);
                setTimeout(() => {
                    clearInterval(checkInterval);
                    reject(new Error('Google Calendar API no está inicializada.'));
                }, 5000); // Timeout after 5 seconds
            }
        });
    }

    function loadCalendarEvents() {
        tokenClient.callback = async (resp) => {
            if (resp.error !== undefined) {
                throw (resp);
            }
            calendar.refetchEvents();
Swal.close();
        };

        if (gapi.client.getToken() === null) {
            tokenClient.requestAccessToken({ prompt: 'consent', login_hint: 'user@example.com' });
        } else {
            tokenClient.requestAccessToken({ prompt: '' });
        }
    }

    function handleError(error) {
        console.error('Error:', error);
        Swal.fire({
            icon: 'error',
            title: 'Error',
            text: 'Ocurrió un error. Por favor, inténtalo de nuevo más tarde.',
        });
    }

    // LOG OUT
    async function cierre() {
        console.log('Cerrando sesión Google...');
        Swal.fire({
            title: 'Cerrando sesión...',
            allowOutsideClick: false,
            didOpen: () => {
                Swal.showLoading();
            },
        });
        try {
            const token = gapi.client.getToken().access_token;
            if (token) {
                await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${token}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                });

                console.log('Token revocado correctamente');

                gapi.client.setToken(null);
                localStorage.removeItem('googleAccessToken');
                localStorage.setItem('logoutCompletedG', 'true');
                console.log('Sesión Google cerrada correctamente');
                Swal.close();
                
                const logoutWindow = window.open(`https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue=${HomeUrl}`, '_blank', 'width=500,height=500');

                // Esperar unos segundos para asegurarse de que el cierre de sesión se complete
                setTimeout(() => {
                    if (logoutWindow) {
                        logoutWindow.close();
                    }
                    Swal.close();
                    window.location.href = HomeUrl;
                }, 3000);
            }
        } catch (error) {
            Swal.close();
            Swal.fire({
                icon: 'error',
                title: 'Error al cerrar sesión',
                text: 'Ocurrió un error al intentar cerrar sesión. Por favor, inténtalo de nuevo más tarde.'
            });
            console.log('Error al cerrar sesión Google', error);
        }
    }
</script>

navbar.php

<!-- Google API -->
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>

<script type="text/javascript">
        //#region GOOGLE
        const calendarGoogleUrl = '<?php echo site_url('calendarGoogle'); ?>';

        let tokenClient;
        let gapiInited = false;
        let gisInited = false;
        
        async function initializeGapiClient() {
            try {
                await gapi.client.init({
                    apiKey: "API KEY",
                    discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
                });
                gapiInited = true;
            } catch (error) {
                console.error('Error al inicializar gapi client:', error);
            }
        }

        function gapiLoaded() {
            gapi.load('client', initializeGapiClient);
        }

        function gisLoaded() {
            try {
                tokenClient = google.accounts.oauth2.initTokenClient({
                    client_id: "CLIENT ID",
                    scope: "https://www.googleapis.com/auth/calendar.readonly",
                    callback: '', // defined later
                    redirect_uri: '<?php echo site_url('calendarGoogle'); ?>',
                });
                gisInited = true;
            } catch (error) {
                console.error('Error: Configuración de Google no cargada correctamente.', error);
            }
        }

        function mostrarCalendarioGoogle() {
            if (!gapiInited || !gisInited) {
                console.error("El cliente API de Google aún no se ha inicializado.");
                return;
            }
            try {
                handleAuthClick();
            } catch (error) {
                handleError(error);
            }
        }

        function handleAuthClick() {
            tokenClient.callback = async (resp) => {
                try {
                    if (resp.error !== undefined) {
                        throw (resp);
                    }                                    
                    window.location.href = calendarGoogleUrl;
                } catch (error) {
                    handleError(error);
                }
            };

            if (gapi.client.getToken() === null) {
                tokenClient.requestAccessToken({
                    prompt: 'consent',
                    login_hint: 'user@example.com'
                });
            } else {
                tokenClient.requestAccessToken({
                    prompt: ''
                });
            }
        }

        //#endregion

        // BOTONES
        document.addEventListener('DOMContentLoaded', function() {                          document.getElementById('botonGoogle').addEventListener('click', function(event) {
                event.preventDefault(); // Previene el comportamiento por defecto del enlace
                mostrarCalendarioGoogle();
            });
        });

        // ERRORES
        function handleError(error) {
            const errorCode = error.errorCode || error.error;

            if (error.errorCode === "interaction_in_progress") {
                console.warn('Interaction in progress, waiting for it to complete.');
            } else if (error.errorCode === "consent_required" || error.errorCode === "interaction_required") {
                Swal.fire({
                    icon: 'error',
                    title: 'Permisos necesarios',
                    text: 'El administrador debe conceder los permisos necesarios para acceder a los calendarios. Contacta al administrador.'
                });
            } else if (error.errorCode === "access_denied") {
                Swal.fire({
                    icon: 'error',
                    title: 'Acceso denegado',
                    text: 'No se pudo acceder a los datos solicitados. Verifica los permisos y vuelve a intentarlo.'
                });
            } else if (error.errorCode === "user_cancelled") {
                Swal.fire({
                    icon: 'error',
                    title: 'Acción Cancelada',
                    text: 'Ha cancelado el inicio de sesión'
                });
            } else {
                Swal.fire({
                    icon: 'error',
                    title: 'Error de autenticación',
                    text: 'Ocurrió un error durante la autenticación. Por favor, inténtalo de nuevo más tarde.'
                });
                console.error('Error durante la autenticación:', error);
            }
        }

        function goToCalendarEvent(event) {
            localStorage.setItem('event', JSON.stringify(event));
            window.location.replace('<?= site_url('calendar') ?>')
        }
    </script>

If you need more information, do not hesitate to ask,

thank you very much!

0 0 188
0 REPLIES 0