在 javascript 中使用 API v3 检索 Google 日历事件

Retrieve Google Calendar events using API v3 in javascript

去年我使用此处找到的代码 http://gdata-javascript-client.googlecode.com/svn/trunk/samples/calendar/simple_sample/simple_sample.html 从 public Google 日历的 "now" 检索所有事件,然后在网页中显示结果. 我修改了该代码以满足我的需要(参见下面的代码)。

现在,使用 API v3,代码不再有效,我无法理解代码的哪些行已弃用以及如何更新它们。 有人可以帮我处理这段代码吗?

非常感谢:-)

<body>

<script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_KEY_HERE"></script>
<script type="text/javascript">

/* Loads the Google data JavaScript client library */
google.load("gdata", "2.x");

function init() {
  // init the Google data JS client library with an error handler
  google.gdata.client.init(handleGDError);
  // load the code.google.com calendar
  loadMyCalendar();
}
/**
 * Loads the Google Event Calendar
 */
function loadMyCalendar() {
  loadCalendarByAddress('MY_ADDRESS@gmail.com'); /* address here
}

/**
 * Adds a leading zero to a single-digit number.  Used for displaying dates.
 */
function padNumber(num) {
  if (num <= 9) {
    return "0" + num;
  }
  return num;
}

/**
 * Determines the full calendarUrl based upon the calendarAddress
 * argument and calls loadCalendar with the calendarUrl value.
 *
 * @param {string} calendarAddress is the email-style address for the calendar
 */ 
function loadCalendarByAddress(calendarAddress) {
  var calendarUrl = 'https://www.google.com/calendar/feeds/' +
                    calendarAddress + 
                    '/public/full';
  loadCalendar(calendarUrl);
}

function loadCalendar(calendarUrl) {
  var service = new 
      google.gdata.calendar.CalendarService('gdata-js-client-samples-simple');
  var query = new google.gdata.calendar.CalendarEventQuery(calendarUrl);
  query.setOrderBy('starttime');
  query.setSortOrder('ascending');
  query.setFutureEvents(true);
  query.setSingleEvents(true);
  query.setMaxResults(100);
  service.getEventsFeed(query, listEvents, handleGDError);
}

    /**
 * Callback function for the Google data JS client library to call when an error
 * occurs during the retrieval of the feed. Details available depend partly
 * on the web browser, but this shows a few basic examples. In the case of
 * a privileged environment using ClientLogin authentication, there may also
 * be an e.type attribute in some cases.
 *
 * @param {Error} e is an instance of an Error 
 */
function handleGDError(e) {
  document.getElementById('jsSourceFinal').setAttribute('style', 
      'display:none');
  if (e instanceof Error) {
    /* alert with the error line number, file and message */
    alert('Error at line ' + e.lineNumber +
          ' in ' + e.fileName + '\n' +
          'Message: ' + e.message);
    /* if available, output HTTP error code and status text */
    if (e.cause) {
      var status = e.cause.status;
      var statusText = e.cause.statusText;
      alert('Root cause: HTTP error ' + status + ' with status text of: ' + 
            statusText);
    }
  } else {
    alert(e.toString());
  }
}

/**
 * Callback function for the Google data JS client library to call with a feed 
 * of events retrieved.
 *
 * Creates an unordered list of events in a human-readable form.  This list of
 * events is added into a div called 'events'.  The title for the calendar is
 * placed in a div called 'calendarTitle'
 *
 * @param {json} feedRoot is the root of the feed, containing all entries 
 */ 
function listEvents(feedRoot) {
  var entries = feedRoot.feed.getEntries();
  var eventDiv = document.getElementById('events');
  if (eventDiv.childNodes.length > 0) {
    eventDiv.removeChild(eventDiv.childNodes[0]);
                                        }   

  var ul = document.createElement('ul');
  /* set the calendarTitle div with the name of the calendar */
  /*document.getElementById('calendarTitle').innerHTML = 
    "Calendar: " + feedRoot.feed.title.$t + "<br/><br/>";*/
  /* loop through each event in the feed */
 var len = entries.length;
 for (var i = 0; i < len; i++) {
    var entry = entries[i];
    /* contenuto e titolo sono invertiti */
    var cont = entry.getTitle().getText();
    var title = entry.getContent().getText();  /* get description notes */
   /* only events containing WORD_1 &/or WORD_2 & not containing '?' */
       if(cont.indexOf('?') == -1 && (cont.indexOf('WORD_1') > -1 || cont.indexOf('WORD_2') > -1)){
    var whereIs = entry.getLocations()[0].getValueString();
    var startDateTime = null;
    var startJSDate = null;
    var times = entry.getTimes();
    if (times.length > 0) {
      startDateTime = times[0].getStartTime();
      startJSDate = startDateTime.getDate();
    }
    var entryLinkHref = null;
    if (entry.getHtmlLink() != null) {
      entryLinkHref = entry.getHtmlLink().getHref();
    }
    var day = padNumber(startJSDate.getDate());
    var month = padNumber(startJSDate.getMonth() + 1);
    var dateString = day + "/" + month + "/" + startJSDate.getFullYear();
    if (title.indexOf(' - ') > -1) {
      cont = title.substring(0, title.indexOf(' - ')+3) + cont + " @ " + whereIs;
      title = title.substring(title.indexOf(' - ')+3);
    } else cont = "h_:_ - " + cont + " @ " + whereIs;
    var li = document.createElement('li');

    /* if we have a link to the event, create an 'a' element */
    if (entryLinkHref != null) {
      entryLink = document.createElement('a');
      entryLink.setAttribute('href', entryLinkHref);
      li.appendChild(document.createTextNode(dateString + ' - '));
   entryLink.appendChild(document.createTextNode(title));
      li.appendChild(entryLink);
      
    } else {
      li.appendChild(document.createTextNode(dateString + ' - ' + title));
    }     

    var p = document.createElement("p");
    
    var lo = document.createElement('lo');
    lo.appendChild(document.createTextNode(cont));

 li.style.fontSize = "25px";
 lo.style.fontSize = "15px";


    /* append the list item onto the unordered list */
    ul.appendChild(li);
    ul.appendChild(lo);
    ul.appendChild(p);
    
  }
    eventDiv.appendChild(ul);
    }
}

google.setOnLoadCallback(init);
</script>

<p id="events">LOADING CALENDAR . . . . . . . . . .</p>
    </body>

已解决 :-) 这里是 javascript 代码,用于访问和显示 PUBLIC google 日历即将发生的事件,使用 Google 日历 API v3。

<html>
    <head>
    </head>
<body bgcolor="black" text="white" link="#00ffff" vlink="green" alink="yellow">
<script>
    
var clientId = 'YOUR_CLIENT_ID HERE'; //choose web app client Id, redirect URI and Javascript origin set to http://localhost
var apiKey = 'YOUR_APIKEY_HERE'; //choose public apiKey, any IP allowed (leave blank the allowed IP boxes in Google Dev Console)
var userEmail = "YOUR_ADDRESS@gmail.com"; //your calendar Id
var userTimeZone = "YOUR_TIME_ZONE_HERE"; //example "Rome" "Los_Angeles" ecc...
var maxRows = 10; //events to shown
var calName = "YOUR CALENDAR NAME"; //name of calendar (write what you want, doesn't matter)
    
var scopes = 'https://www.googleapis.com/auth/calendar';
    
//--------------------- Add a 0 to numbers
function padNum(num) {
    if (num <= 9) {
        return "0" + num;
    }
    return num;
}
//--------------------- end    
    
//--------------------- From 24h to Am/Pm
function AmPm(num) {
    if (num <= 12) { return "am " + num; }
    return "pm " + padNum(num - 12);
}
//--------------------- end    

//--------------------- num Month to String
function monthString(num) {
         if (num === "01") { return "JAN"; } 
    else if (num === "02") { return "FEB"; } 
    else if (num === "03") { return "MAR"; } 
    else if (num === "04") { return "APR"; } 
    else if (num === "05") { return "MAJ"; } 
    else if (num === "06") { return "JUN"; } 
    else if (num === "07") { return "JUL"; } 
    else if (num === "08") { return "AUG"; } 
    else if (num === "09") { return "SEP"; } 
    else if (num === "10") { return "OCT"; } 
    else if (num === "11") { return "NOV"; } 
    else if (num === "12") { return "DEC"; }
}
//--------------------- end

//--------------------- from num to day of week
function dayString(num){
         if (num == "1") { return "mon" }
    else if (num == "2") { return "tue" }
    else if (num == "3") { return "wed" }
    else if (num == "4") { return "thu" }
    else if (num == "5") { return "fri" }
    else if (num == "6") { return "sat" }
    else if (num == "0") { return "sun" }
}
//--------------------- end

//--------------------- client CALL
function handleClientLoad() {
    gapi.client.setApiKey(apiKey);
    checkAuth();
}
//--------------------- end

//--------------------- check Auth
function checkAuth() {
    gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
//--------------------- end

//--------------------- handle result and make CALL
function handleAuthResult(authResult) {
    if (authResult) {
        makeApiCall();
    }
}
//--------------------- end

//--------------------- API CALL itself
function makeApiCall() {
    var today = new Date(); //today date
    gapi.client.load('calendar', 'v3', function () {
        var request = gapi.client.calendar.events.list({
            'calendarId' : userEmail,
            'timeZone' : userTimeZone, 
            'singleEvents': true, 
            'timeMin': today.toISOString(), //gathers only events not happened yet
            'maxResults': maxRows, 
            'orderBy': 'startTime'});
    request.execute(function (resp) {
            for (var i = 0; i < resp.items.length; i++) {
                var li = document.createElement('li');
                var item = resp.items[i];
                var classes = [];
                var allDay = item.start.date? true : false;
                var startDT = allDay ? item.start.date : item.start.dateTime;
                var dateTime = startDT.split("T"); //split date from time
                var date = dateTime[0].split("-"); //split yyyy mm dd
                var startYear = date[0];
                var startMonth = monthString(date[1]);
                var startDay = date[2];
                var startDateISO = new Date(startMonth + " " + startDay + ", " + startYear + " 00:00:00");
                var startDayWeek = dayString(startDateISO.getDay());
                if( allDay == true){ //change this to match your needs
                    var str = [
                    '<font size="4" face="courier">',
                    startDayWeek, ' ',
                    startMonth, ' ',
                    startDay, ' ',
                    startYear, '</font><font size="5" face="courier"> @ ', item.summary , '</font><br><br>'
                    ];
                }
                else{
                    var time = dateTime[1].split(":"); //split hh ss etc...
                    var startHour = AmPm(time[0]);
                    var startMin = time[1];
                    var str = [ //change this to match your needs
                        '<font size="4" face="courier">',
                        startDayWeek, ' ',
                        startMonth, ' ',
                        startDay, ' ',
                        startYear, ' - ',
                        startHour, ':', startMin, '</font><font size="5" face="courier"> @ ', item.summary , '</font><br><br>'
                        ];
                }
                li.innerHTML = str.join('');
                li.setAttribute('class', classes.join(' '));
                document.getElementById('events').appendChild(li);
            }
        document.getElementById('updated').innerHTML = "updated " + today;
        document.getElementById('calendar').innerHTML = calName;
        });
    });
}
//--------------------- end
</script>
<script src='https://apis.google.com/js/client.js?onload=handleClientLoad'></script>
    <div id='content'>
    <h1 id='calendar' style="color:grey">LOADING . . . .</h1>
    <ul id='events'></ul>
    </div>
    <p id='updated' style="font-size:12; color:grey">updating . . . . .</p>
    </body>
</html>

这是一个基于 Max 的原始脚本的简化、注释和更新脚本,它使用了 Moment.js 和 JQuery。阅读 the full blog post here 了解详细信息(包括如何获取 API 密钥),或仅替换以下脚本中的 YOUR_CALENDAR_ID 和 YOUR_API_KEY:

<script>
    /* This solution makes use of "simple access" to google, providing only an API Key.
    * This way we can only get access to public calendars. To access a private calendar,
    * we would need to use OAuth 2.0 access.
    *
    * "Simple" vs. "Authorized" access: https://developers.google.com/api-client-library/javascript/features/authentication
    * Examples of "simple" vs OAuth 2.0 access: https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
    *
    * We will make use of "Option 1: Load the API discovery document, then assemble the request."
    * as described in https://developers.google.com/api-client-library/javascript/start/start-js
    */
    function printCalendar() {
        // The "Calendar ID" from your calendar settings page, "Calendar Integration" secion:
        var calendarId = 'YOUR_CALENDAR_ID@group.calendar.google.com';

        // 1. Create a project using google's wizzard: https://console.developers.google.com/start/api?id=calendar
        // 2. Create credentials:
        //    a) Go to https://console.cloud.google.com/apis/credentials
        //    b) Create Credentials / API key
        //    c) Since your key will be called from any of your users' browsers, set "Application restrictions" to "None",
        //       leave "Website restrictions" blank; you may optionally set "API restrictions" to "Google Calendar API"
        var apiKey = 'YOUR_API_KEY';
        // You can get a list of time zones from here: http://www.timezoneconverter.com/cgi-bin/zonehelp
        var userTimeZone = "Europe/Budapest";

        // Initializes the client with the API key and the Translate API.
        gapi.client.init({
            'apiKey': apiKey,
            // Discovery docs docs: https://developers.google.com/api-client-library/javascript/features/discovery
            'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'],
        }).then(function () {
            // Use Google's "apis-explorer" for research: https://developers.google.com/apis-explorer/#s/calendar/v3/
            // Events: list API docs: https://developers.google.com/calendar/v3/reference/events/list
            return gapi.client.calendar.events.list({
                'calendarId': calendarId,
                'timeZone': userTimeZone,
                'singleEvents': true,
                'timeMin': (new Date()).toISOString(), //gathers only events not happened yet
                'maxResults': 20,
                'orderBy': 'startTime'
            });
        }).then(function (response) {
            if (response.result.items) {
                var calendarRows = ['<table class="wellness-calendar"><tbody>'];
                response.result.items.forEach(function(entry) {
                    var startsAt = moment(entry.start.dateTime).format("L") + ' ' + moment(entry.start.dateTime).format("LT");
                    var endsAt = moment(entry.end.dateTime).format("LT");
                    calendarRows.push(`<tr><td>${startsAt} - ${endsAt}</td><td>${entry.summary}</td></tr>`);
                });
                calendarRows.push('</tbody></table>');
                $('#wellness-calendar').html(calendarRows.join(""));
            }
        }, function (reason) {
            console.log('Error: ' + reason.result.error.message);
        });
    };

    // Loads the JavaScript client library and invokes `start` afterwards.
    gapi.load('client', printCalendar);
</script>

您还需要在页面的某处包含 Moment.JS 和 Google JS API:

<script src="https://cdn.jsdelivr.net/npm/moment@2/moment.min.js"></script>
<script src="https://apis.google.com/js/api.js"></script>