Calling a Web Service from Blogger using JSON-P and Google Apps Script
This article will give a simple example of how to write a web app with Google Apps Script, and then make a call to this from a page posted on your blog at Blogger. Since you can't host web apps on the same domain as your Blogger blog, you would normally be restricted from doing this by the same origin policy enforced by javascript. That is, javascript in a page on one domain cannot make remote calls to services running on another domain. This policy is enforced to prevent vulnerabilities called cross-site scripting.
But if you control both the content in your Blogger page, as well as the code of the web service, then there is a way to get around this using an approach called JSON with padding or JSONP. In this article I'll share a simple example which you can modify to solve more complex problems where you want to execute some server side function in Google Apps Script without the user leaving the page of your blog.
Example Scenario
We will present a form into which a visitor will type a stock ticker symbol. The visitor will then click a button to get the stock price. The page will call to the Google Apps Script web app to get the stock price, and display this in an alert to the visitor. In this way you'll see how parameters can be passed to and responses captured from a web service.
How we will do this
There are two parts to getting this scenario to work
Let's start by creating the web app with Google Apps Script. Create a spreadsheet and go to the Script Editor. Create a blank project and replace the empty function with the following code
function doGet(request) {
Logger.log(request.queryString);
var ticker = request.parameters.ticker;
var info = FinanceApp.getStockInfo(ticker);
return ContentService.createTextOutput(
'returnStock(' + JSON.stringify(info) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Now you need to publish the web app, so click Publish and Deploy as web app. You'll need to save a new version from the dialog that appears. And in the field "Who has access to the app" make sure to select "Anyone, even anonymous". Once you've published it, make a copy of the web app URL, because you'll need that when we edit the page on Blogger. At this point you can test the web app by pasting the URL into your browser bar and appending "?ticker=TDC" to the end. You should get a response something like the following (with a lot more info).
returnStock({"priceopen":58.81999969482422, ... ,"price":57.7400016784668, ...})
You'll notice that this looks like a call to a javascript function "returnStock" passing all the information about the stock in json. This is the code that will be injected into the page in blogger. So now let's create the page in Blogger which will execute this web app.
Creating the Blogger Page or Post
This will work from either a page or a post, or even a JavaScript/HTML Gadget. Basically anywhere that you can inject JavaScript into your blog. It will also work on any platform, and not just Blogger. So go ahead and create a page or a post and switch the editor into html mode. Then paste in the following
<script>
function returnStock(info) {
alert("The latest price is " + info.price);
}
function sendStock() {
var form = document.forms["ticker-form"];
var ticker = form["ticker"].value;
var script = document.createElement('script');
script.src = '[INSERT_YOUR_URL]?ticker='
+ encodeURIComponent(ticker);
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>
<form name="ticker-form" onsubmit="sendStock(); return false;">
Ticker: <input name="ticker" type="text" required/>
<input name="submit" type="submit" value="Get Info" />
</form>
We have two javascript functions. The first is "returnStock" which you'll recall from above is the function returned by the Google Apps Script web app. This is the function which will be called with the stock info returned from the web app. The next function is "sendStock" which takes the ticker symbol entered into the form and forms the URL to call your web app and pass the ticker symbol. You'll need to replace the [INSERT_YOUR_URL] bit with the URL that you got when you published your web app.
Test It!
That's it. Now visit the page or post that you just created in your browser and type a ticker symbol like TDC into the form and press Get Info. In a few moments you should see an alert popup with the current price.
Conclusion
Obviously this is a fairly trivial example. You can have the "call back" function (returnStock in this example) do anything that JavaScript can do. So it could update the page content with the response rather than display it in an alert. And the web app can do anything that Google Apps Script can do.
It's also worth mentioning that the more typical approach with JSON-P is for the calling page to pass the name of the callback function to the web app, and for the web app to use it. In the example above I hardcoded the name of the callback function to just simplify things a little.
Before using JSON-P I thought I could accomplish this same scenario by just making the form action point at the web app URL directly (without an onclick), and then have the web app redirect the user to another page on my blog. But you can't inject http headers from a Google Apps Script web app, so there was no way to issue a location redirect. And in addition to this, Google Apps Script inspects and modifies any javascript that your web app returns, and attempts to force an equivalent redirect through JavaScript are caught and stripped from the code. I could have just had the web app output the results web page. But I wanted to keep the visitor on the blog, so, as far as I can tell, this approach with JSON-P is the only one that works.
But if you control both the content in your Blogger page, as well as the code of the web service, then there is a way to get around this using an approach called JSON with padding or JSONP. In this article I'll share a simple example which you can modify to solve more complex problems where you want to execute some server side function in Google Apps Script without the user leaving the page of your blog.
Example Scenario
We will present a form into which a visitor will type a stock ticker symbol. The visitor will then click a button to get the stock price. The page will call to the Google Apps Script web app to get the stock price, and display this in an alert to the visitor. In this way you'll see how parameters can be passed to and responses captured from a web service.
How we will do this
There are two parts to getting this scenario to work
- Create a web app which looks up a stock price and returns it
- Create a page or post in Blogger that calls this web app
Creating the Web App
Let's start by creating the web app with Google Apps Script. Create a spreadsheet and go to the Script Editor. Create a blank project and replace the empty function with the following code
function doGet(request) {
Logger.log(request.queryString);
var ticker = request.parameters.ticker;
var info = FinanceApp.getStockInfo(ticker);
return ContentService.createTextOutput(
'returnStock(' + JSON.stringify(info) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Now you need to publish the web app, so click Publish and Deploy as web app. You'll need to save a new version from the dialog that appears. And in the field "Who has access to the app" make sure to select "Anyone, even anonymous". Once you've published it, make a copy of the web app URL, because you'll need that when we edit the page on Blogger. At this point you can test the web app by pasting the URL into your browser bar and appending "?ticker=TDC" to the end. You should get a response something like the following (with a lot more info).
returnStock({"priceopen":58.81999969482422, ... ,"price":57.7400016784668, ...})
You'll notice that this looks like a call to a javascript function "returnStock" passing all the information about the stock in json. This is the code that will be injected into the page in blogger. So now let's create the page in Blogger which will execute this web app.
Creating the Blogger Page or Post
This will work from either a page or a post, or even a JavaScript/HTML Gadget. Basically anywhere that you can inject JavaScript into your blog. It will also work on any platform, and not just Blogger. So go ahead and create a page or a post and switch the editor into html mode. Then paste in the following
<script>
function returnStock(info) {
alert("The latest price is " + info.price);
}
function sendStock() {
var form = document.forms["ticker-form"];
var ticker = form["ticker"].value;
var script = document.createElement('script');
script.src = '[INSERT_YOUR_URL]?ticker='
+ encodeURIComponent(ticker);
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>
<form name="ticker-form" onsubmit="sendStock(); return false;">
Ticker: <input name="ticker" type="text" required/>
<input name="submit" type="submit" value="Get Info" />
</form>
We have two javascript functions. The first is "returnStock" which you'll recall from above is the function returned by the Google Apps Script web app. This is the function which will be called with the stock info returned from the web app. The next function is "sendStock" which takes the ticker symbol entered into the form and forms the URL to call your web app and pass the ticker symbol. You'll need to replace the [INSERT_YOUR_URL] bit with the URL that you got when you published your web app.
Test It!
That's it. Now visit the page or post that you just created in your browser and type a ticker symbol like TDC into the form and press Get Info. In a few moments you should see an alert popup with the current price.
Conclusion
Obviously this is a fairly trivial example. You can have the "call back" function (returnStock in this example) do anything that JavaScript can do. So it could update the page content with the response rather than display it in an alert. And the web app can do anything that Google Apps Script can do.
It's also worth mentioning that the more typical approach with JSON-P is for the calling page to pass the name of the callback function to the web app, and for the web app to use it. In the example above I hardcoded the name of the callback function to just simplify things a little.