How to get Google Calendar events in the search results

Have you ever seen those event listings in the search results and wondered how you can get them? Do you organize events, either online or offline that you want to give extra exposure? Do you want to get more clicks, more visitors, more business by easily promoting your events?

Take a look at what we were able to do for our LocalSpark client Urban Air Trampoline Park. When you search for events in their city, their events show up in the search results:

Overland Park events SERP

 

Their event listings also show up on branded search terms:

 

Want to know how I did it? Read on for step-by-step instructions.

FREE implementation: Google to the rescue!

Depending on the platform you’re using there are a number of solutions. In case you’re using WordPress there are many plugins (both free and paid) to choose from, in order to get events in the search results. In most cases, you’ll have to pay for solutions which connect to Google Calendar.

How about a FREE solution, using Google’s own platform to generate the required code to import in your website to show the events from one or more Google Calendars?

To get Google Calendar events in the search results, follow these steps:

  1. Create (or assign) a Google Calendar, dedicated to your online events list.
  2. Open Google Script Editor and copy/paste the code from the bottom of this blog post.
  3. Run the Google Apps Script and grant the required privileges
  4. Get the public URL of your Calendar Script
  5. Import the content from the URL from the desired page(s) of your site and output it at the right place in the PHP code of the template within your CMS

Check out the video below to see how you can accomplish this for yourself, or follow the instructions underneath the video (HINT: watch the video fullscreen to see more detail):

 

This might sound more difficult than it actually is. Don’t worry, let me take you through the steps, one step at a time.

Prerequisite: From here on, you need a Google account…

 

Step 1: Create a dedicated Google Calendar

Steps to create a new Google Calendar:

  1. Login to your Google account and go to https://calendar.google.com
  2. Click the little triangle next to “My calendars” in the left sidebar
  3. Click “Create new calendar”
  4. Give the calendar a name, set the correct location and timezone
  5. Click “Create calendar” button at the bottom when done
  6. Add one or more (dummy) events to the calendar so you’re able to test it

Step 2: Create and modify the script

To copy the script, surf to https://script.google.com and perform these steps:

  1. Assign a name to your project
  2. Select and remove all code
  3. Copy the Calendar Events Google Apps Script (below) to the clipboard and paste it in the editor
  4. Get the calendar ID (see below) and paste it in place of the ‘#####’ (5 hash tags / pound signs)

To get the Calendar ID or ID’s, do the following:

  1. In Google Calendar, click the wheel on the right and select “Settings”
  2. Click on the top menu on “Calendars”
  3. Select the calendar you just created
  4. Copy the ID to the clipboard
Get Google Calendar ID

Step 3: Grant the required privileges to the script

Your script can not be used, until you:

  1. Save the script by clicking on the little disk
  2. Select “doGet” in the “Select Function” dropdown box
  3. Click the “Play”-button
  4. Select “Continue” in the popup window, titled “Authorization required”
  5. When the next window pops up, asking to “Manage your calendars”, click “Allow”

Congratulations, you’re almost there…

Step 4: Get the public URL of the script

Once you’ve granted the correct authorization and made sure the script doesn’t return an error, follow these steps:

  1. Click “Publish” and select “Deploy as web app”
  2. Give an initial description
  3. Leave your Google ID under “Execute the app as:”
  4. Under “Who has access to the app:”, select “Anyone, even anonymous”
  5. Click on “Deploy”

You’re then shown a window with the “Current web app URL”. Copy it to the clipboard and paste it in a new browser window. If you’ve performed all steps correctly, you’ll see the events code, which you can embed in the source of your PHP template(s).

Step 5: Get the events in your PHP code

In order to get the events embedded in the source code of your HTML-code, you’ll most likely need to modify the PHP template(s) of your CMS.

Since WordPress is the most widely used CMS, I only focus on WordPress from here on. But for any PHP-based CMS, the solution will be quite comparable..

Once you have the events listed on your screen in the previous step, create a custom field named “eventlisturl” in the page you want to have the events listed in the search results. Copy/paste the URL from your browser into this custom field.

NOTE: Make sure that you DO NOT USE the “Current web app URL” shown in the Google Script Editor, as this will NOT WORK!

Then in the template of your theme, add the following PHP code (typically in footer.php, just before </body>):

if ( ($eventlisturl = get_post_meta( $post->ID, 'eventlisturl', true ) )) {
$eventlistoutput = file_get_contents( $eventlisturl );

$search = array( "$location", "$url" );
$replace = array( get_the_title(), "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$eventlistoutput = str_replace( $search, $replace, $eventlistoutput );
echo $eventlistoutput;
}

This piece of PHP code assumes the following:

  • The custom field “eventlisturl” is set to the URL that you see when you view the script in your browser in step 6 above.
  • “$location” will be substituted by the HTML title of your page
  • “$url” will be set to the URL of the current page, so the event listing will link to the page containing the code

While any location in the code will be fine, I advise to place the code in the footer, just before the closing “</body>” tag.

Further customizations

It is also possible to customize the Location and URL fields by adding a bit of additional content to the event description in Google Calendar:

  • Add a line with e.g. “name: Whitespark HQ” (without the quotes) to have the location automatically set to “Whitespark HQ”
  • Add a line with ONLY a URL, e.g. “https://whitespark.ca/special-event” (without the quotes, but WITH http://) to link to the actual event page

Google Apps Script for Step 2:

function doGet() {

  var calIds = [ 
    "#####" // ID(s) of 1 or more Google Calendars
  ];

  var total = '';
  for ( var cal = 0; cal < calIds.length; cal++ ) {
    total = total + getEventsJSON( calIds[cal] );
  }

  return ContentService.createTextOutput().append(total);
}


function getEventsJSON( id ) {
  var now = new Date();
  var oneYearFromNow = new Date(now.getTime() + 1000 * 60 * 60 * 24 * 365); // 1 Year in advance

  var output = '<script type="application/ld+json">\n';

  var events = CalendarApp.getCalendarById(id).getEvents(now, oneYearFromNow, {search: '*'});

  if ( events.length > 1 ) {
    output += '[';
  }

  Logger.log('Number of events: ' + events.length + ' in calendar "' + id + '"' );

  for (var i=0 ; i < events.length && i < 7 ;i++) {

    output += '{\n"@context": "http://schema.org",\n"@type": "Event",\n';
    
    var title  = events[i].getTitle();

    var starttime = events[i].getStartTime();
    var tz    = CalendarApp.getDefaultCalendar().getTimeZone();
    var start = Utilities.formatDate(starttime, tz, "yyyy-MM-dd HH:mm");

    var endtime = events[i].getEndTime();
    var end = Utilities.formatDate(endtime, tz, "yyyy-MM-dd HH:mm");

    var descr  = events[i].getDescription();
    var sameas = '';
    var name   = '';
    
    if ( (name = descr.match(/name: (.*)/i)) == null ) {
      name = '$location';
    } else {
      descr = descr.replace( name[0], '');
      name = name[1];
    }
    
    if ( (sameas = descr.match(/https?:[^\s]+/)) == null ) {
      sameas = '$url';
    } else {
      descr = descr.replace( sameas[0], '');
    }

    // Strip any trailing whitespace
    descr = descr.replace( /[\s]+$/g, '');

    var loc    = events[i].getLocation();

    output += '"name": "' + title + '",\n';
    output += '"startDate": "' + start + '",\n';
    output += '"endDate": "' + end + '",\n';
    output += '"location": {\n"@type": "Place",\n"name": "' + name + '",\n"address": "' + loc + '",\n"sameAs": "' + sameas + '"\n},\n';

    output += '"description": "' + descr + '"\n';
    output += '}';
   
    if ( events.length > 1 && i < Math.min((events.length-1), 6) ) {
      output += ',\n';
    }
  }
  
  if ( events.length > 1 ) {
      output += ']\n';
  }
  
  output += '</script>\n';

  return output;
}

Conclusion

There you have it. Follow the instructions above to get your events listed in the search results.

I hope this solution is useful for you. If you have any comments or questions, feel free to post them below and I’ll do my best to reply to them.

AUTHOR

Eduard de Boer

Eduard started with hand-coding websites in 1993 and became immersed in SEO, reputation management and content marketing in the years thereafter. After almost two decades Eduard is still following his passion: consulting and helping companies to profile themselves better. Eduard is also a certified Google Maps Business Photographer.

Follow Me on Twitter

43 comments on “How to get Google Calendar events in the search results

  • Is this a working Jquery driven solution. It seems that this works (although I’m sure it could be optimized)

    the following code replaces step 5 above.

    the url inside the $(‘#loader’).load(‘your url goes here’); is the calendar’s unique url as stated in step 4.

    Google’s structured data testing tool doesn’t see the code, but if you inspect the page in chrome or firefox you can see the json-ld code right before the closing body tag. Google has claimed that it can crawl content that is loaded via ajax, so I’m wondering if this will work…

    You can see a test version at : http://learnerdesign.com/json-ld-test.html

  • Dude!

    Timely for sure.

    and Eduard… ask Darren about gravatar.

    and Kevin (other commenter), excellent domain name

  • @Noah: when Google Structured Data Testing Tool isn’t seeing the events, they won’t get indexed.

    @Wesley: I tried to make it as easy to follow as possible. If anything is unclear, feel free to ask.

    @Kevin: thanks! Did it work for you?

    @Rob: Thanks for pointing the Gravatar issue out to me. I do have my whitespark.ca address associated with it, but for one reason or the other, it doesn’t show my photo… (Have now used my primary address, though 😉

  • This is brilliant. Thank you so much for taking the time to outline all the steps (even for dummies like me). I’m close, but keep getting this error, “TypeError: Cannot call method “getEvents” of null. (line 22, file “Code”, project “NYC Calendar”)”. It then highlights this code:

    var events = CalendarApp.getCalendarById(id).getEvents(now, oneYearFromNow, {search: ‘*’});

    Any thoughts? I put in the correct ID where the hashtags were…what am I missing?

    Again, thank you so much.

  • I AM HAVING THE SAME EXACT PROBLEM. Tried to troubleshoot to no avail. Wish I could get this to work!

    Thanks for the info though!

  • Same Issue As Well;
    TypeError: Cannot call method “getEvents” of null. (line 22, file “Code”)

    var events = CalendarApp.getCalendarById(id).getEvents(now, oneYearFromNow, {search: ‘*’});

  • Hi Shanti, this solution is typically tailored to WordPress, as it’s by far the most use CMS on the planet.

    I don’t have experience with Wix, sorry. So I can’t say anything valid about that. Would have to look into it, to find out.

  • Hello,

    Thank you for taking the time to post all of this information, as I run an events directory I am keen to implement.
    I have been getting this error however (I see some others have also)
    Cannot call method “getEvents” of null. (line 22, file “Code”)

    Any ideas on how to fix this?
    Thanks!

  • HI, the script that generates the events from Google calendar, only outputs 7 events .
    sorry not I’m not much of script editor, I followed the blog instructions and is working well.. thanks 4 that
    but it only generates 7 events , see my script –> (I am using the EXACT script from the blog page)

    https://script.google.com/macros/s/AKfycbxPlRbojKEjLwX-mn1ISYdVE6phpo3EBkmilhxK9l-xQlEnEHJs/exec

    I thought changing this line –> for (var i=0 ; i < events.length && i < 7 ;i++) to <21 for no. events 21 ??
    does not seem to work …

  • Did everything correctly and got the Schema data displaying in a browser, however when I went to add the data to the head of my page using:

    $calendarthing = file_get_contents(‘https://script.googleusercontent.com/macros/echo?user_content_key=blahdeblahetc123456789dummykey’);
    echo $calendarthing;

    and uploaded the page to a server I got the Google login page (One account. All of Google. Sign in to continue to Google Drive.) I got this even if I was viewing with the same Google acount as I had used to create the script.

    I DID select the correct settings for access anyone even anonymous

    This pretty well makes your script unuseable – do you have an update, fix or workaround?

  • Further to my last, this will display the schema in the head of a web page that is .php
    If using Selerdeck or Actinic use a php block

    $eventlisturl =’https://script.googleusercontent.gobblydegookblahblahdummycode’;

    $eventlistoutput = file_get_contents( $eventlisturl );

    echo $eventlistoutput;

  • Further to my last again I used a different calendar and am back to the code displaying the goole login page! Please help?

    • Hi Jonathan,

      I think we’d need to get on a Skype call, so you can share your screen. Because trying to troubleshoot through these comments here, seems a bit too cumbersome.

      I’ve sent you my details per mail.

      • Hi Eduard. Thank you very much for coming back. I unticked the ‘make calendar public’ box and saved then ticked it again, saved again then generated the code and it seems to be ok! I will let you know if further problems.

        Thank you again.

        Best wishes

        Jonathan

  • Hi,
    I’m trying to do this for my website which is html/ css so cannot use the php code. Could you let me know if there’s a way that I can adapt this step for html?

    • Sure August. That is possible. Although I am not a Joomla crack, I might be able to help you in the right direction. Please contact me through Google+: +EduarddeBoer

  • Hi Eduard,

    Thanks so much for this guide! This is going to be super helpful.
    However, I got stuck at step 5: get the events in your PHP code. I have to say, I am a bit of a noob:)

    I have created the custom field and am about to add some PHP code to the footer.php. Do I have to change ANYTHING about the bit of code you provide?

    Thanks for your reply!
    Lieke

    • Hi Rob,

      The problem is that you don’t have the PHP code tags around your piece of code. That is why it is being displayed as text and not executed as PHP code.

      I recommend you put
      at the end.

      Google is now enforcing more rules before your events appear. Actually, they now also require the events to be shown on the page in regular HTML.

      – Eduard.

  • Hi Eduard! Thank you for this great article! I followed everything perfectly up to the click on “deploy”… I copied the code, but I don’t know what php is or where to find it to paste the code I copied? Sorry I’m new to this!

  • Hi,

    I have tried several times to implement this development on a WordPress site. Finally I see my events on Google Search, but sadly the URLs does not work pretty.

    When I see the code it gets the same url to all the events with php code on the footer. I mean, if a create several events on google Calendar and the code of the footer replace $url variable with the live URL of the post, all events get the same URL.

    There is any way to solve this?

    Thank you so much.

  • Hi Eduard
    This has all been going so well, now Google is reporting warnings with the events listing saying:
    Missing Field ‘image’
    Missing Field ‘performer’
    Missing Field ‘offers’
    These are optional, can we safely leave them or can te script be edited easily to include them?
    Thank you
    Jonathan

  • Hello! I’m new on creating public events and manage some pages…. and I’m so happy and grateful that you had spent your time in creating this detail process and share your knowledge.
    However I tried to follow everything and when I do “save” to the script, it gives me the error “Missing ] after element list. (line 4, file “Code”)” : |
    I have zero background on coding so I’m quite lost…. Thanks

  • Hi, I was excited to try this out and got TypeError: Cannot call method “getEvents” of null. (line 22, file “Code”)

    How to fix?

  • Hey, great post! I’m hoping now that I have this approach working it will improve visibility for my events.

    While I am here, I wish to comment on a problem several people mention encountering when implementing your script: the “getEvents of null error.” This error essentially means the script was unable to access the calendar either due to insufficient access privileges or a bad calendar ID. In my case, it was the latter situation.

    After wracking my brain for a couple of hours over this error, I discovered that I was mistakenly attempting to use Google-generated share link URL as the calendar ID. Some online posts incorrectly suggest the calendar ID and a share link URL are the same thing – they’re not. Once I figured this out, the script worked like a charm.

    If a person uses the default calendar, the calendar ID is likely the email address. This is a bad idea for obvious reasons. A better approach is to add a new calendar to the account, in which case the calendar ID will be formatted along the lines of “[unique value]@group.calendar.google.com.” This should resolve the null error situation AND avoid the problem of the account email address being shared.

    Thanks again.

Comments are closed.