javascripthtmlgoogle-apigoogle-calendar-api

Google calendars requires authentication to showcase my own calendar


IS there a way that I can showcase my personal calendar in my website so people can see my availability. So i've dwelled on this for some hours now, i was able to do it if I did google authentication but the thing is i dont want to access other peoples calendar data, i just want to read mine to showcase them. I did the setup on google console cloud with the apikey , client_id , but through that route I've only found ways where I ask for "visitors" to authenticate their account. I've done the iframe method , but i just want to fetch the calendar data to "design" it after. Summarizing , Want to setup my own calendar in my website without needing to authenticate on google everytime i enter the website. Sorry if this might be confusing , i can post some code that i got and answer anything. PLS HELP

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"],
        });
        gisLoaded();
    } catch (error) {
        console.error('Error initializing Google Calendar API client:', error);
       
    }
}

function gisLoaded() {
    const tokenClient = google.accounts.oauth2.initTokenClient({
        client_id: CLIENT_ID,
        scope: 'https://www.googleapis.com/auth/calendar.readonly',
        callback: handleAuthResponse,
    });
    tokenClient.requestAccessToken();
}

function handleAuthResponse(response) {
    if (response.error) {
        console.error('Error authenticating:', response);
        
        return;
    }
    loadCalendarEvents();
}

async function loadCalendarEvents() {
    try {
        const response = await gapi.client.calendar.events.list({
            'calendarId': CALENDAR_ID,
            'timeMin': (new Date()).toISOString(),
            'showDeleted': false,
            'singleEvents': true,
            'maxResults': 10,
            'orderBy': 'startTime'
        });

        const events = response.result.items;
        const calendarDiv = document.getElementById('calendar');
        calendarDiv.innerHTML = ''; // Clear loading message

        events.forEach(event => {
            const eventDiv = document.createElement('div');
            eventDiv.className = 'event';

            const titleDiv = document.createElement('div');
            titleDiv.className = 'event-title';
            titleDiv.textContent = event.summary;
            eventDiv.appendChild(titleDiv);

            const timeDiv = document.createElement('div');
            timeDiv.className = 'event-time';
            const start = event.start.dateTime || event.start.date;
            timeDiv.textContent = new Date(start).toLocaleString();
            eventDiv.appendChild(timeDiv);

            calendarDiv.appendChild(eventDiv);
        });
    } catch (error) {
        console.error('Error fetching calendar events:', error);
        
    }
}

window.onload = function() {
    console.log('window.onload: Page fully loaded');
    
    gapiLoaded();
};

Now the html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>St. Patrick's Irish Pub - Menu</title>
    <link rel="stylesheet" href="calendar.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    <script src="https://apis.google.com/js/api.js"></script>
</head>
<body>
    <div class="calendar" id="calendar"></div>
    <script src="calendar2.js"></script>
</body>
</html>

the js i have here is the one where it asks for authentication , and it works... but as i said , i dont want to ask visitors to authenticate...

I'm probably being dumb , and i hope i am . Thank you in advance cause i know you're machines!


Solution

  • OAuth-using consent screens were designed in order to allow access to the APIs for any user that uses the application. However, in your use case you only want this for one user. The simplest method is to generate the access and refresh tokens beforehand using the OAuth Playground, and then use those 2 in order to call the API.

    By using the refresh token, you no longer need to request an access token with a consent screen, as the API is called for your user just save the refresh and access token generated, and then using the refresh token you get a new access token each time you need to make an API call. This will allow you to ignore the consent screen for this combination.

    In order to get the refresh and access token, please follow the steps below:

    1. Open the GCP Console.
    2. Go to “APIs & Services”.
    3. Click “Credentials” from the left pane.
    4. Select “OAuth client ID” from the “Create credentials” tab.
    5. Next, for “Application type” choose the “Web application”.
    6. Click “Create”, and a message will appear, showing “OAuth client created”.
    7. Next, open a new browser tab and go to OAuth Playground, and choose “Google 8. Calendar API v3”.
    8. Select “https://googleapis.com/auth/calendar.events”.
    9. Click “Authorize APIs”.
    10. Next, click on the wheel icon in the upper right corner, and make sure that “Use your own OAuth credentials” is selected.
    11. Go back to the Cloud Console tab in your browser and from the API Keys copy the “Client ID” and paste it in the “OAuth Client ID” field in the OAuth Playground tab.
    12. Do the same for the “Client secret” and copy it in the “OAuth Client secret” field in the OAuth Playground tab.
    13. Go to the GCP Console tab, and from the API Keys menu select the Client ID you have just created.
    14. Under the “Authorized redirect URIs”, paste the following URI: “https://developers.google.com/oauthplayground” and click on “Save”.
    15. Finally, go one last time to the OAuth Playground tab, and click again on “Authorize APIs”.
    16. The consent screen should appear; select the desired user, then click “Allow”.
    17. Select “Exchange authorization code for tokens”

    For a comprehensive guide on how to implement OAuth, please check this article. If you are a Google Workspace user, another solution would be to use a service account with impersonation, this is documented here. This way, you can set the user that will give access to the api directly from code. For a more explicit example you can check this article.