Content Service

When a script is published as a web app, the special callback functions doGet()and doPost() are invoked whenever a request is made to the script's URL. Instead of returning a user interface object created with the HTML service, the Content service can be used to return raw textual content. This allows you to write scripts that act as "services", responding to GET and POST requests and serving data of various MIME types.

The basics

Here is a simple example of the Content service:

function doGet() {
  return ContentService.createTextOutput('Hello, world!');
}

Deploy the script as a web app, using the same steps that you would if you were serving a user interface. When a GET request is made to the script's URL, the text Hello, world! will be returned. In addition to plain text, the service also supports returning ATOM, CSV, iCal, JavaScript, JSON, RSS, vCard, and XML content.

Serving RSS feeds

Let's try something slightly more complicated like filtering an RSS feed. The XKCD comics are always funny, but you can't get the full joke unless you hover over the comic strip to see the extra alt text. Unfortunately, you can't hover on a mobile browser, so this doesn't work.

Let's say we wanted to edit the feed so that the extra punchline was in the feed directly, and instead of hovering you just scrolled down a bit to see it. That would work fine on a mobile device. Here's the code:

function doGet() {
  var feed =  UrlFetchApp.fetch('http://xkcd.com/rss.xml').getContentText();
  feed = feed.replace(
    /(<img.*?alt="(.*?)".*?>)/g,
    '$1' + new Array(10).join('<br />') + '$2');
  return ContentService.createTextOutput(feed)
    .setMimeType(ContentService.MimeType.RSS);
}

That may look tricky, but it breaks down into simple parts. We use the URL Fetch service to fetch the original XKCD RSS feed. We then use a standard JavaScript regular expression to make the substitutions we need. Finally, we wrap the edited feed in a TextOutput object and set the MIME type to RSS.

To see this in action, publish the script as a web app, making sure to allow anonymous access (since your RSS reader will be visiting it as an anonymous user). Then add the URL of the service (not the original RSS feed) to your RSS reader or just visit it directly in a web browser. That's it!

Serving JSON from scripts

What else can we do with the Content service? How about serving up JSON to other scripts or other websites and services! Here's a simple script that implements a service that anyone can use to see if a calendar slot is open at a specific time.

function doGet(request) {
  var events = CalendarApp.getEvents(
    new Date(Number(request.parameters.start) * 1000),
    new Date(Number(request.parameters.end) * 1000));
  var result = {
    available: events.length == 0
  };
  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON);
}

As before, publish this as an anonymous web app to make it work. In this case, users of your new service can use it by adding URL parameters to the end of the service URL. The start and end parameters give a time range to check, specified in the standard Unix epoch.

curl -L URL_OF_YOUR_SCRIPT?start=1325437200&end=1325439000

The service will return JSON that reports whether you have anything in your calendar in that range.

{"available":true}

Serving JSONP in web pages

With a slight change, your JSON service can become JSONP, which means that it can be called from JavaScript in a browser. Here's the new script:

function doGet(request) {
  var events = CalendarApp.getEvents(
    new Date(Number(request.parameters.start) * 1000),
    new Date(Number(request.parameters.end) * 1000));
  var result = {
    available: events.length == 0
  };
  return ContentService.createTextOutput(
    request.parameters.prefix + '(' + JSON.stringify(result) + ')')
    .setMimeType(ContentService.MimeType.JAVASCRIPT);
}

To call this service from a browser, create a script tag whose src attribute is the URL of your service, with an additional parameter called prefix. This is the name of the function in your client-side JavaScript that will be called with the value returned by the service.

<script src="URL_OF_YOUR_SCRIPT?start=1325437200&end=1325439000&prefix=alert"></script>

This example will show a message box in the browser with the service output, since we specify the browser's built-in alert() function as our prefix. The JavaScript code returned will look like:

alert({"available":true})

Redirects

For security reasons, content returned by the Content service isn't served from script.google.com, but instead redirected to a one-time URL at script.googleusercontent.com. This means that if you use the Content service to return data to another application, you must ensure that the HTTP client is configured to follow redirects. For example, in the cURL command line utility, add the flag -L. Check the documentation for your HTTP client for more information on how to enable this behavior.