Skip Navigation LinksHome > View Post

Making HTTP requests from Scripts in Mobile Services

It’s no secret that my favorite feature of our first release of Mobile Services is the ability to execute scripts on the server. This is useful for all kinds of scenarios from validation and authorization to sending push notifications. We made it very easy to send push notifications via WNS (Windows Notification Services), it’s basically a single code statement:

push.wns.sendTileWideImageAndText01(channelUrl, {
   text: "foo",
   imageSrc: "http://someurl/where/an/image/lives.jpg"
});

It’s amazing that this is all it takes to send a live tile update with an image to your windows 8 device. For more information on getting started with push – check out our tutorials:

HTTP with request

It’s also no secret that the Mobile Services runtime uses NodeJS to give you the power of JavaScript on the server – with the ability to require some of the best modules in Node, including my favorite: request from Mikeal. The request module makes http a doddle. Here’s what it looks like to make a simple request to twitter, for example, in a Mobile Services insert script.

function insert(item, user, request) {

var req = require('request'); req.get({ url: "http://search.twitter.com/search.json", qs: { q: item.text, lang: "en" } }, function(error, result, body) { var json = JSON.parse(body); item.relevantTweet = json.results[0].text; // now go ahead and save the data, with // the new property, courtesy of twitter request.execute(); }); }

The script above uses the text property of item being inserted and searches twitter for matching tweets. It then appends a property to the record containing the content of the first tweet and inserts everything to the database. Who wouldn’t want a tweet to accompany each and every item on your todolist? Here’s the exciting result in the Windows Azure Portal:

image

Now that we understand push and HTTP wouldn’t it be cool to pull the two together, and use the power of the internet to help us find an image to accompany our push notification. Imagine we want to send all our devices a live tile with an image whenever a new item is added to our list. And what’s more we want the image to be something that portrays the text of item inserted.

Enter Bing Search.

image

You can sign up for the Bing Search API here and you get 5,000 searches for free per month. As you might expect, you can invoke the Bing Search API via HTTP.

Combining these two ideas is now pretty straightforward:

// This is your primary account key from the datamarket
// This isn’t my real key, so don’t try to use it! Get your own.
var bingPrimaryAccountKey = "TIjwq9cfmNotTellingYouE6lNMNhFo4xSMkMGs="; // This creates a basic auth token using your account key var basicAuthHeader = "Basic " + new Buffer(":" + bingPrimaryAccountKey).toString('base64'); // and now for the insert script function insert(item, user, request) { request.execute({ success: function() { request.respond(); getImageFromBing(item, sendPushNotification); } }); } // this function does all the legwork of calling bing to find the image function getImageFromBing(item, callback) { var req = require('request'); var url = "https://api.datamarket.azure.com/Data.ashx" + "/Bing/Search/v1/Composite?Sources=%27image%27&Query=%27" + escape(item.text) + "%27&Adult=%27Strict%27&" + "ImageFilters=%27Size%3aMedium%2bAspect%3aSquare%27&$top=50&$format=Json"; req.get({ url: url, headers: { "Authorization": basicAuthHeader } }, function (e, r, b) { try{ var image = JSON.parse(b).d.results[0].Image[0].MediaUrl; callback(item, image); } catch (exc) { console.error(exc); // in case we got no image, just send no image callback(item, ""); } }); } // send the push notification function sendPushNotification(item, image) { getChannels(function(results) { results.forEach(function(result) { push.wns.sendTileWideImageAndText01(result.channelUri, { image1src: image, text1: item.text }, { // logging success is handy during development // mobile services automatically logs failure success: console.log }); }); }); } // this is where you load the channel URLs from the database. This is // really an exercise for the reader based on how they decided to store // channelUrls. See the second push tutorial above for an example function getChannels(callback) { // this example loads all the channelUris from a table called Channel var sql = "SELECT channelUri FROM Channel"; mssql.query(sql, { success: function(results) { callback(results); } }); }

Which resulted in:

9-26-2012 8-49-12 PM

Which is pretty neat. Have fun.

Note: Finding images on the internet is risky, you really don’t know what might show up! Also, I make no statement about the legality or otherwise of using images from bing or other search providers in your own applications. As always, consult the terms an conditions of any services you integrate with and abide by them. Be good.

 
Josh Post By Josh Twist
5:05 AM
27 Sep 2012

» Next Post: BUILD 2012 – the week we discovered ‘kickassium’
« Previous Post: Understanding the pipeline (and sending complex objects into Mobile Services)

Comments are closed for this post.

Posted by Michael @ 10 Oct 2012 5:02 AM
What other modules are available in Mobile Services?

© 2005 - 2014 Josh Twist - All Rights Reserved.