Connecting AdWords Scripts & The Advanced Calendar API

In this helpful how-to, columnist Russell Savage explains how to integrate Google Calendar with AdWords to monitor your campaign start and end dates.

Chat with SearchBot

events-calendar-schedule-ss-1920

AdWords scripts just got a lot more useful thanks to the recent rollout of Advanced APIs.

These additional APIs allow AdWords scripts to access other Google services like Google Analytics and Google Calendar. Anyone familiar with other Google Scripts will recognize these objects as the same ones available there.

Today we are going to focus on the Calendar API and build an integration that allows you to monitor campaign start and end dates via your Google calendar.

Many times, for meetings or reporting, it helps to see things laid out in a week or month view so that overlapping items stand out. This script will create entries on a separate calendar representing the duration of your campaigns.

The first thing I recommend doing is creating a new calendar in your Google account to hold the campaign start and end dates. This way, you can easily share the calendar with other team members or hide it to reduce clutter. I named mine “AdWords,” but you can name it whatever you like.

Create A New Google Calendar

Now that you have a place to put all your events, let’s start writing some code. When you open a new scripting window, you will notice a new button next to the Preview button titled “Advanced APIs.” This is where you will need to enable the use of the Calendar API before you continue.

You will also need to enable the API in the Developers Console. Just click the link at the bottom of the dialog box and follow the prompts.

Once everything is enabled, go back to your AdWords script window and complete the authorization process as normal. You will now have access to a new Calendar class in your scripts. You will need to follow this initial set up process for each new script you create.

Calendar API Enabled via Google Developers Console

The first thing we are going to need is a function that allows us to find the calendar id from the nice name (or summary) you entered earlier. This was adapted from some of the sample code on the AdWords Scripts developer site and does the job nicely.

// Lookup the calendar id given the summary
// If no calendar id is found, an error is raised
function getCalendarId(summary) {
  var calendarList = Calendar.CalendarList.list();
  for(var i in calendarList.items) {
    var cal = calendarList.items[i];
    if(cal.summary === summary) {
      return cal.id;
    }
  }
  throw "No calendar with the summary: '"+summary+"' found.";
}

 

Now that we have the id of the calendar, we can start updating it. This script is going to take the simple approach and clear all the entries from the calendar each time it is run.

Yeah, it is a little wasteful, but it shouldn’t matter as long as you have less than 2500 campaigns in your MCC. You can always call the delete function multiple times if you need to since it is pretty fast.

// Removes all the events from a given calendar
function blowAwayTheCalendar(calendarSummary) {
  var calendarId = getCalendarId(calendarSummary);
  var calendarEvents = Calendar.Events.list(calendarId, { maxResults: 2500 } );
  if (calendarEvents.items && calendarEvents.items.length > 0) {
    for(var i = 0; i < calendarEvents.items.length; i++) {
      var calendarEvent = calendarEvents.items[i];
      Calendar.Events.remove(calendarId, calendarEvent.id);
    }
  }
}

 

The script is going to run through each account we have, look at all the campaigns, and create calendar events reflecting the start and end dates of the campaign.

We will need some code to actually create the event. The most important things in a calendar event are the summary and the dates, so that’s all I’m going to care about here.

// Creates an event on the given calendar
function createEvent(calendarId,eventSummary,startDate,endDate) {
  var eventData = {
    'summary': eventSummary,
    'description': '', // You can add something here if you wish
    'start': { 'date': formatDate(startDate) },
    'end': { 'date': formatDate(endDate) }
  };
  var maxRetries = 3;
  while(maxRetries > 0) {
    try {
      var calendarEvent = Calendar.Events.insert(eventData, calendarId);
      Logger.log('New event with ID = %s was created.',calendarEvent.getId());
      return calendarEvent.getId();
    } catch(e) {
      maxRetries--;
      Utilities.sleep(1000);
    }
  }
  throw "Could not create calendar event: "+eventSummary;
}

// Helper function for formatting the date
function formatDate(theDate) {
  return Utilities.formatDate(theDate, 
                              AdWordsApp.currentAccount().getTimeZone(), 
                              'yyyy-MM-dd');
}

 

With only a few lines of code, we can now create events from our AdWords campaigns. This is going to create a new all-day event starting on the start date and ending on the end date. There are many other customizable parameters you can add if you like, but this will work for now.

You might notice the retry logic here when trying to create the event. If you are running this in parallel with other accounts, you will most likely run into the limits of five events per second. The retry logic captures that and retries after waiting a second.

This should help with any quota issues. Now we’re ready to put together the code to iterate through our accounts and add the events to our calendar. We can use a simple executeInParallel command to accomplish this.

// This is the nice name you used when
// creating your calendar.
var CALENDAR_SUMMARY = 'AdWords';

function main() {
  blowAwayTheCalendar(CALENDAR_SUMMARY); // remove all existing entries
  MccApp.accounts().executeInParallel('campaignsToCalender');
}

// Iterates through the campaigns in an account
// and adds a calendar event using the start and 
// optional end date of the campaign.
function campaignsToCalender() {
  var calendarId = getCalendarId(CALENDAR_SUMMARY);
  var accountName = AdWordsApp.currentAccount().getName();
  var campIter = AdWordsApp.campaigns().get();
  while(campIter.hasNext()) {
    var camp = campIter.next();
    var start = camp.getStartDate() ? awDateToDate(camp.getStartDate()) : null;
    if(!start) { continue; } // this shouldn't happen
    var end;
    if(camp.getEndDate()) {
      end = awDateToDate(camp.getEndDate());
    } else {
      // Default campaign length is a year
      // Maybe a few months is better?
      end = new Date(start);
      end.setFullYear(end.getYear()+1);
    }
    // Event name will be Account > Campaign
    var summary = [accountName,camp.getName()].join(' > ');
    var eventId = createEvent(calendarId,summary,start,end);
  }
}

// Helper function to transform AdWordsDate
// objects to normal Date objects.
function awDateToDate(awDate) {
  return new Date(awDate.year, 
                  awDate.month, 
                  awDate.day, 0, 0, 0);
}

 

Final Thoughts

Our main function becomes extremely simple because we have created functions for all the complicated stuff. One thing to notice is that while all campaigns will have a start date, not all of them require an end date.

In cases like these, you will have to decide what you want to do. In this code, I am setting the campaigns for a length of a year just so I can keep track of them, but you can do whatever makes sense for your account.

This is just a simple example of course; but hopefully, it sparks an idea for you to continue exploring these new APIs. For example, you could extend this code to allow you to change events on your calendar and have your campaigns automatically update.

There are plenty of other Advanced APIs that have recently been enabled, and I encourage you to check them out. It’s getting harder and harder to keep up with the momentum of AdWords Scripts, and I can’t wait to see what they have in store for us next.


Opinions expressed in this article are those of the guest author and not necessarily Search Engine Land. Staff authors are listed here.


About the author

Russell Savage
Contributor
Russell Savage is an Application Engineer for Cask Data and loves tinkering with marketing data and automation in his spare time. He is the creator of FreeAdWordsScripts.com, where he posts AdWords Scripts for anyone to use.

Get the must-read newsletter for search marketers.