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.