1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Building OpenSocial Apps- P3 pptx

50 281 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Building OpenSocial Apps
Định dạng
Số trang 50
Dung lượng 387,73 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Writing the requestSendMessage CodeNow that we’ve defined our requestSendMessagefunction, let’s plug it into our Tic-Tac-Toe app and try it out.The following example function wraps reque

Trang 1

// Update the UI for the failures for(var i = 0; i < failure.length; i++){

clicked = current_list.list_dom["myspace.com:" + failure[i]];

if(clicked) clicked.style.backgroundColor = "red";

} } } }

So, there is a lot going on here.The callback for requestShareAppis especiallyimportant.The first thing that really happens is that the various types of errors aretrapped, and an error message is displayed if one is found

If there was no error, we cycle through the list of currently selected users, revert thebackground of the corresponding div tags to white, and reset the list.There are now twopossibilities: the user either canceled the pop-up or hit Send If the pop-up was canceled,there’s no more work to do If the pop-up wasn’t canceled, the user must have hit the Sendbutton, so we need to figure out who the actual recipients were.We do this by accessing theresponseValuesobject in the ResponseItemthat’s passed back to us.responseValuescontains two arrays: One,success, contains the list of users who were successfully sent aninvite.The other,failure, contains the list of users who had an error occur when theinvite was sent Both arrays contain the integer IDs of the specified users

There are a couple of things to note when accessing the success and failure arrays

First, users who already have the app installed won’t get the invite, but neither will theyshow up in either array Second, the IDs in the array are integers, so they don’t exactlymatch the IDs that are sent by the API (in the format "myspace.com:6221")

Back to the function at hand.We extract the successandfailurearrays and loopthrough them.We turn the background color of all the successful recipients to green,and that of all the failures to red.You’ll notice that we have to append "myspace.com:"

to the beginning of each ID so it matches up with the IDs we fetched from the API

It may be useful to add a More button to your app, something like “Select Random20” that will randomly select 20 of the user’s friends.This will help encourage users toshare the app with a larger group of friends; turning 20 clicks into one click makes itmuch easier for your users

Using opensocial.requestSendMessage to Send Messages and Communications

Let’s examine how opensocial.requestSendMessageworks.The requestSendMessagefunction provides a number of ways for apps to communicate with users

MySpace supports the following message types:

n Send Message:a private one-to-one message that will arrive in the user’s MailCenter in-box

n Comment:a public one-to-one message that will appear on the user’s Profilepage in the Comments section

Trang 2

n Bulletin:a one-to-many message that will appear in the Bulletins module of each

of the user’s friends’ Home pages

n Blog:a one-to-many message that will appear on a MySpace user’s Blog

n Profile:not a message per se; allows an app to edit/update the user’s Profile.Thefollowing Profile sections can be edited and are chosen by the user in a drop-down menu:

About MeI’d Like to MeetInterestsEdit Artist ProfileMovies

TelevisionBooksHeroesDefining requestSendMessage

opensocial.requestSendMessagehas the following signature:

opensocial.requestSendMessage = function(recipients, message, opt_callback, opt_params)You probably noticed that the signature for opensocial.requestSendMessageisvery similar to that of opensocial.requestShareApp.The big difference is that you’reallowed to define only one recipient ID at a time; the container will reject an array ofIDs Similar to requestShareApp, however, are opt_callback, which is the functionthat’s invoked when the pop-up modal has closed, and opt_params, which is unused

n Types that support a message title are Send Message, Comment, Bulletin, and Blog

The title doesn’t support any HTML markup

n All of the message types support a message body All support some HTML markup

in the body.Tags like <div>, <script>, and <span> are stripped out, but tags like

<a>, <img>, <b>, and <em> are allowed

When creating the opensocial.Messageobject, you need to specify the opensocial.Message.Field.Typeproperty; this specifies which of the message types

Using opensocial.requestSendMessage to Send Messages and Communications 75

Trang 3

will be sent.Table 5.1 shows the list of supported types and the opensocial.Message.

Field.Typefields to which they correspond

Profile and Blog are MySpace-specific extensions and not in the OpenSocial spec,which is why they’re namespaced a little differently In the code that follows, we’ll showyou how to make use of the message types when using requestSendMessage

Writing the requestSendMessage CodeNow that we’ve defined our requestSendMessagefunction, let’s plug it into our Tic-Tac-Toe app and try it out.The following example function wraps requestSendMessageand isuseful if you want to use requestSendMessagein multiple places throughout your app:

function rsmWrapper(id, subject, body, type, callback){

var param = {};

param[opensocial.Message.Field.TYPE] = type;

param[opensocial.Message.Field.TITLE] = subject;

var message = opensocial.newMessage(body, param);

opensocial.requestSendMessage(id, message, callback);

}Note that the function is fairly similar to the requestShareAppwrapper.This function just requires two additional parameters to construct the opensocial.Messageobject:subjectandtype.The typeparameter corresponds to one of the

opensocial.Message.Field.Typevalues found in Table 5.1

Now that we have our requestSendMessagewrapper, we can make use of it in theapp by creating different types of messages A fairly simple and effective type of message

is a bulletin; it is a one-to-many message that gets blasted out to all the user’s friends

function rsmBulletin(){

var this_app = opensocial.getEnvironment().currentApplication;

var profile_link = this_app.getField(MyOpenSpace.Application.Field.PROFILE_URL);

var image_link = this_app.getField(MyOpenSpace.Application.Field.ICON_LARGE);

Table 5.1 Supported Message Types Message Type Value of opensocial.Message.Field.Type Send Message opensocial.Message.Type.PRIVATE_MESSAGE Comment opensocial.Message.Type.PUBLIC_MESSAGE Bulletin opensocial.Message.Type.NOTIFICATION Blog MyOpenSpace.PostTo.Targets.BLOG Profile MyOpenSpace.PostTo.Targets.PROFILE

Trang 4

var subject = "Social Tic-Tac-Toe is Here!";

var body = "Hey everyone! I' m playing TTT online with my friends, come";

body += "<a href='" + profile_link + "'>play a game</a> with me!";

body += "<center><img src='" + image_link + "'/></center>";

rsmWrapper(opensocial.IdSpec.PersonId.VIEWER, subject, body, opensocial.Message.Type.NOTIFICATION, rsmBulletinCallback);

}Since bulletins don’t use any template messaging, we have to generate all the links ourselves.To do this, we make use of the instance of a MyOpenSpace.Applicationobject for this app.When an app is rendered, the MySpace platform pushes down ascript-accessible representation of the app’s information.This object may be accessedfrom the environment with the call

opensocial.getEnvironment().currentApplicationSpecific data that may be found in this object includes:

1 App ID, accessed via the field enum MyOpenSpace.Application.Field.ID

2 Name, accessed via the field enum MyOpenSpace.Application.Field.Name

3 Profile URL, accessed via the field enum MyOpenSpace.Application.Field.

opensocial.getEnvironment().currentApplication.getField(

MyOpenSpace.Application.Field.NAME);

Here we use the app’s Profile URL and the large icon to generate the bulletin sage Some of the supported HTML tags are also used for the body.Then the wrapperfunction is called and voilà! We’ve sent our first message!

mes-Bulletins are great for getting the word out to a large audience, but they lack a sonal touch In our Tic-Tac-Toe app, one user can challenge another user to a game

per-Using opensocial.requestSendMessage to Send Messages and Communications 77

Trang 5

var image_link = this_app.getField(MyOpenSpace.Application.Field.ICON_LARGE);

var subject = "I challenge you to a TTT duel!";

var body = "Hey" + name + "! You've been challenged to ";

body += "a game of Tic-Tac-Toe, click <a href='" + profile_link + "'>";

body += "here</a> to accept the challenge!<center>";

body += "<img src='" + image_link + "' /></center>";

rsmWrapper(id, subject, body, opensocial.Message.Type.PRIVATE_MESSAGE, rsmMessageCallback);

}This code is fairly similar to the bulletins code.We use the MyOpenSpace.

Applicationobject to generate a message and then invoke the wrapper.There is alsosome app-specific code in this function that determines the ID and name of thechallenged user; this ID is sent into the wrapper while the name is used to personalize themessage Adding a person’s name to a message is an old trick that helps the message seem

a little less like a form letter

Callback in requestSendMessageThe callback for requestSendMessageworks the same as requestShareApp An errorcould be generated before the modal dialog is shown; otherwise the value 1, 0, or ⫺1 isreturned

Trang 6

Let’s take a look at one quick example:

function rsmMessageCallback(response){

var div = TTT.Tabs.getCurrentContainer().firstChild;

if(response && !response.hadError()){

if(0 === response.getData()){

div.innerHTML += "challenge cancelled ";

} else if(1 === response.getData()){

div.innerHTML = "challenge sent!";

} } else{

log("Oops, there was an error, try refreshing the page!");

} }First we check for an error If one was found, we display an error message asking theuser to refresh the page

Most errors that occur with the messaging system are intermittent and can be fixed with

a refresh If there was no error, a simple message is displayed reaffirming the user’s action

Getting Your App Listed on the Friend Updates with opensocial.requestCreateActivity Basics

On every user’s MySpace Home page there is a module that displays the user’s FriendUpdates.These updates are a feed and might include information like “John added a newphoto,”“Mary and John are now friends,” or “Susan installed the Tic-Tac-Toe

application.”These updates are ordered by date, and the newest information is alwaysdisplayed on top

When an app creates an activity, the activity appears in this feed.That makes any appactivity a one-to-many message that will appear in the Friend Updates feed for each ofthe user’s friends.With activities, applications can define numerous custom messages thatwill appear in a user’s Friend Updates

Activities can be created only from the app’s Canvas surface, but they’re a great way toembed your app into a user’s MySpace experience and promote your application at thesame time

Defining opensocial.requestCreateActivity

opensocial.requestCreateActivityhas the following signature:

opensocial.requestCreateActivity = function(activity, priority, opt_callback)This means it’s a function that must include an activity (opensocial.Activity), apriority (opensocial.CreateActivityPriority) setting for the request, and

Getting Your App Listed on the Friend Updates 79

Trang 7

Note

At the time of this writing, opensocial.CreateActivityPriority is not being checked

or used by MySpace You’ll notice in the code that follows that we always pass in a value

of high (opensocial.CreateActivityPriority.HIGH) as opposed to low (opensocial.CreateActivityPriority.LOW).

If you have opensocial.CreateActivityPriority in your code and MySpace starts making use of it, the behavior of your app may be affected, so it’s good to keep this in mind should your app suddenly start doing something

Let’s take a quick look at how OpenSocial defines the priorities:

High:If the activity is of high importance, it is created even if this requires askingthe user for permission.This might cause the container to open a user flow that navi-gates away from your gadget

Low:If the activity is of low importance, it is not created if the user has not givenpermission for the current app to create activities.With this priority, the

requestCreateActivitycall never opens a user flow

Using the Template System to Create ActivitiesOne of the most important elements of creating and raising activities is the templatesystem In fact, it’s so important that it needs to be explained before we start looking atcode Unlike messages, which are completely defined and passed into the function asstatic text, activities make use of a custom template system Basically, you create atemplate for your activities’ messages and the variables are resolved at runtime.Templatesmust be used for activities Every template must have a title containing up to a

maximum of 160 visible characters Each template may also optionally specify a bodyhaving up to 260 visible characters

Your message template is based on a text string with some optional variables (whichyou may occasionally hear referred to as “tokens”) thrown in.These variables arereplaced by real data once the activity is raised A basic activity’s message might looksomething like this:

"Susan installed Tic-Tac-Toe on: ${date}."

When the template is run, you’ll specify that ${date}will be replaced with a stringcontaining the current date and time So, if you give the variable ${date}a value like

“September 28, 2010,” the resulting message would read

“Susan installed Tic-Tac-Toe on: September 28, 2010.”

Data Types

In our first example, the ${date}variable was a string However, you can also specifythe data type of a variable.The two currently available data types are Literal and Person

Trang 8

For example, let’s say we have a template where the variable ${opponent}is of typePerson It might look like this:

"You've been bested at Tic-Tac-Toe by ${opponent}."

To get this template message to display correctly, you need to pass in the opponent’suser ID For example, if we pass in the string "6221"(Tom’s ID) for our ${opponent}

variable, our message would read

“You’ve been bested at Tic-Tac-Toe by Tom.”

The word Tom would then link to Tom’s Profile.

Reserved Variable NamesThere are a number of variables that are reserved (see Table 5.2), but the most interestingone is ${sender} This is because ${sender}is actually a required variable in yourtemplate title, meaning you’ll be using it a lot

The variable ${sender}is a Person-type variable, which means it’s replaced by theViewer’s name and Profile link For example, let’s say we changed our template to read

"${sender} raised this event, making ${sender} the Viewer!"

If Susan were to raise an event with that variable, the resulting message would read

“Susan raised this event, making Susan the Viewer!”

Getting Your App Listed on the Friend Updates 81

Table 5.2 Reserved Variable Names

${subject} Replaced with a link to the Viewer’s Profile

and the Viewer’s display name as the corresponding text

${subject.DisplayName} Replaced by the Viewer’s display name

(no link)

${subject.ProfileUrl} Replaced by the Viewer’s Profile URL

${variable_name.Count} Used when variables are aggregated and

where variable_name is the name of a

Trang 9

But if her arch-nemesis,Tom, raised the event, the message would read

“Tom raised this event, making Tom the Viewer!”

In each instance the Viewer’s information is used for the ${sender}variable

AggregationWhen a user has a large number of applications, and friends who like applications, theuser’s feeds can get crowded with information and updates Because of this, activity feedsare aggregated If a user has five friends all playing Tic-Tac-Toe and raising activities forthe app, all of those activities are aggregated into a single feed entry for Tic-Tac-Toe

For example, let’s create a new message template and see what would happen whenit’s raised multiple times Let’s start with a new template:

"${sender} is playing Tic-Tac-Toe with ${opponent}."

In this example we’d want to aggregate the ${opponent}variable (you can learnhow to specify aggregated variables by skipping ahead to the section on using the

Template Editor) The first time I raise the event, my opponent’s ID is "6221"(Tom,again!).The resulting message reads

“Susan is playing Tic-Tac-Toe with Tom.”

If Susan raises the event again, this time challenging her friend Matt to a game, theresulting message reads

“Susan is playing Tic-Tac-Toe with Tom and Matt.”

And if Susan raises the event a third time, but this time challenging Tila Tequila to abattle of Tic-Tac-Toe, the resulting message would read

“Susan is playing Tic-Tac-Toe with Tom, Matt, and Tila!”

Now that’s a game I would like to see Notice that not only does the templating tem keep aggregating your message feeds, it also makes them grammatically correct by

sys-adding commas and the word and.

Body and Media Items

We have variables and data types, but there’s more to a message template than that

What about pictures and the message itself? That’s where body and media items comeinto play

The body is similar to a template’s title, but it’s optional and can hold more ters If you include a body, it displays on the second line under your specified title

Trang 10

Media items can be any picture on MySpace that’s accessible to the Viewer InChapter 3, Getting Additional MySpace Data, we fetched a list of the Viewer’s photos,displayed them on the page, and allowed the player to select one for a custom board back-ground If a custom background is selected, it is used as a media item in any raised activity

You’re allowed to include a maximum of three media items in a message template Allwill be rendered on the second line of the message

Using the Template Editor to Create TemplatesNow that you know how templates work, you’re ready to create some new templates foryour app.To do this, you’ll use the Template Editor tool found on your My Apps page

Under each application there is a tool entitled Templates (Figure 5.6); click it to be taken

to your Templates page (shown in Figure 5.7)

Click on Create Template to create new templates for your app.This will take you tothe template creation screen

From this screen (Figure 5.8) you can edit existing templates or create a new one

Let’s look at an existing template for our Tic-Tac-Toe application

Getting Your App Listed on the Friend Updates 83

Figure 5.6 Screen shot of My Apps S Templates link

Figure 5.7 Screen shot of an existing Templates list

Trang 11

On the individual Template screen, you can see all of the pertinent template tion Under Content you’ll find the template’s name and unique identifier along withthe title and the body.There are also separate tabs for Single Form instances (when justone activity is raised) and Aggregate Form instances (multiple activities are raised)

informa-Under Variables, you can add and specify data types and even test values for each ofyour variables Below this section are sample media items that you can use to test howthey’ll appear when you preview or run your template

To test your template, click the Preview Template button.This creates a preview ofyour template in the bottom portion of the screen using the test data you indicatedunder Variables and Media Items

You’ll also be provided with sample JavaScript code that can be used to raise theevent.You can actually just cut and paste this code into your app to begin raising activi-ties, but you’ll most likely want to customize it (see “Raising the Event” in the follow-ing section)

If you’re satisfied with your template, click the Save Template button to save yourtemplate for later use

Once your template is saved, you can switch it from development status to live status

To do this:

1 Go back to your Templates page

2 Click the Publish button next to the template you want to make live

3 Click OK when prompted

From your Templates page you can also delete or edit an existing template

Figure 5.8 Screen shot of the Templates screen

Trang 12

Using opensocial.requestCreateActivityNow that we understand what opensocial.requestCreateActivitylooks like andhow to construct a template, let’s actually use the function

Raising the EventThe template we’re using for our activity is the following:

${subject} has started a game of

var media_item_array = [ media_item ];

// Insert the array into the parameters param[opensocial.Activity.Field.MEDIA_ITEMS] = media_item_array;

Getting Your App Listed on the Friend Updates 85

Trang 13

}First, the activity template is defined as "x_and_y_started_game".This is theunique identifier for the desired template and can be found in the Template Editorunder Template Name.

The template variables are then given actual values; the ${opponent}variable isassigned the value of the ID of the opponent, and the ${params}variable is assigned aJSON object.This is an example of how you might use different template messages fortracking purposes, since here we’re saying the user got to the Canvas page from an activ-ity Meanwhile, the two variables correspond to the list of variables in the TemplateEditor under Variables

The next block of code attaches a media item to the activity A couple of things tonote here: First, the media item URI must conform to an API-style URI and not a reg-ular old URL, such as www.example.com/my_picture.jpg.The best way to get these APIURIs is through the API itself, as we do here in the app

In our code we fetch the list of photos for a user and save those values into a list

When a photo is selected, we match it to the correct entry in the list and parse out theURI.This URI is accessed from the MyOpenSpace.Photoobject using the

MyOpenSpace.Photo.Field.PHOTO_URI.The second thing to note is that an activity requires an array of media items So, even

if you have only one media item, make sure to stick it in an array

Once all the parameters are set up, the opensocial.Activityobject is created andit’s passed into requestCreateActivity

Note

What are we doing there with the custom parameters in the template? Well, custom values can

be passed into an app’s Canvas surface by appending an "appParams" key to the query string.

So, for example, by appending &appParams={"hello"%3A"goodbye"%2C"from"%3A"act"}

to the end of the Canvas URL, we pass the JSON object { "hello" : "goodbye", "from" :

"act" } into the app.

These values can be picked up inside the Canvas by doing the following:

gadgets.views.getParams().hello;

gadgets.views.getParams().from;

In this case, the first line resolves to "goodbye" and the second to "act".

Trang 14

Using Activity Callbacks to Combat Permission-Denied ErrorsUh-oh! Permission denied? It turns out that a separate permission is required to raise anactivity for a user If this permission isn’t set, the container blocks the request and returns

an error So that’s that, I guess Oh well, better luck next time…

Not necessarily;opensocial.requestPermissionto the rescue again! In a methodsimilar to one used in Chapter 3, Getting Additional MySpace Data, where we requestedpermission to fetch photos, we can request permission here to raise an activity:

function raiseActivityCallback(response) { // Check for an error

// Some other error log("Oops, there was an error, try refreshing!");

} } }

If there was an error, we first check whether it was a permissions error If so, we ify why we want the permission and which permission we want Again, don’t forget tostick the MyOpenSpace.Permissionobject into an array or it will be rejected OncerequestPermissionis closed, it will invoke the specified callback function Let’s take alook at it:

Getting Your App Listed on the Friend Updates 87

Trang 15

Very simple; if no new permissions were granted, the response has an error No errormeans the permission has been granted, so retry the activity.This is a great way toensure that the activity is sent while also providing a nice flow for the user

Sending NotificationsThe fourth and final way to communicate with your users is the app notification

Notifications are great for turn-based games as they are a quick and easy way to letplayers know when it’s their turn in the game.This is exactly how we use them in ourTic-Tac-Toe app It’s also highly regarded because it’s the only message type that doesn’trequire the user’s confirmation

When using notifications, you have to watch that you’re not spamming yourusers.You could be shut down, or worse, you’ll annoy your user base and loseinstalls But, if you keep it reasonable, notifications are a great way to increase userengagement

When a user gets a notification, he or she gets an indicator on the Home page saying

a new notification has arrived Clicking on the indicator takes the user to the MailCenter, where he or she will see the message in the notification folder Each notificationcan have zero to two buttons to allow the user to take some action In our Tic-Tac-Toeapp, we tell users it’s their turn and provide one button to take them back to the Canvaspage to play the game

Notifications are a MySpace-specific extension, but they are patterned afterrequestCreateActivity, so the code should be somewhat familiar Let’s take a look atwhat that means:

// Wrap requestCreateNotification function rsmNotification(recipient, game_id){

// Create the body text var body = "Hi ${recipient}, it's now your turn";

body += "in <a href='${canvasUrl}'>Tic-Tac-Toe</a>!";

// Create the button that links to the Canvas var url1 = MyOpenSpace.NotificationButton.UrlTypes.CANVAS;

var params1 = { "game_id" : game_id, "recipient" : recipient };

var text1 = "Take Your Turn!";

var button1 = MyOpenSpace.newNotificationButton(url1, text1, params1);

// Create the button that links to the app's Profile var url2 = MyOpenSpace.NotificationButton.UrlTypes.APP_PROFILE;

var text2 = "Check out Tic-Tac-Toe";

var button2 = MyOpenSpace.newNotificationButton(url2, text2);

var param = {};

Trang 16

param[MyOpenSpace.Notification.Field.MEDIA_ITEMS] = mediaItemArray;

var notification = MyOpenSpace.newNotification(param);

MyOpenSpace.requestCreateNotification(

recipient, notification, rsmNotificationCallback);

}Notifications use a built-in template, similar to requestShareApp However, only thevariables ${recipient}and${canvasUrl}are available, and you’ll need to use theactivities-style variable format ${variable_name}, as opposed to the

requestShareAppstyle of [variable_name].The button is defined by a MyOpenSpace.NotificationButtonobject.This objecthas three fields:

n MyOpenSpace.NotificationButton.URL

n MyOpenSpace.NotificationButton.PARAMS

n MyOpenSpace.NotificationButton.TEXTTheURLcan be one of two values:MyOpenSpace.NotificationButton.

UrlTypes.CANVASorMyOpenSpace.NotificationButton.UrlTypes.

APP_PROFILE.You probably won’t want to take your users back to your app Profile, especially con-sidering that only users who have installed the app receive notifications Here, we want

to take the user back to the Canvas instead

ThePARAMSfield allows us to define custom parameters that are sent into the Canvaspage In our Tic-Tac-Toe app, we append three custom parameters—essentially creating atracking parameter.This parameter is used to let us know that a user came to the Canvasfrom a notification, what action the user wants to take, and which game the user wants

to play

Once the button is created, we’re ready to create the MyOpenSpace.Notificationobject itself.We assign the body text first, using MyOpenSpace.Notification.Field.BODY,and then add the button using MyOpenSpace.Notification.Field.BUTTONS.The buttonhas to be placed in an array, so if you have more than one button, you’d add each one to thearray Omitting the BUTTONSparameter or passing in an empty array would just attach nobuttons to the message

Sending Notifications 89

Trang 17

Notifications use the permission MyOpenSpace.Permission.VIEWER_SEND_

NOTIFICATIONS You may want to use opensocial.hasPermission (followed possibly by opensocial.requestPermission) to check that permission before attempting to send the message See Chapter 3 to learn how to check and request permissions.

SummaryThe primary source of growth for most apps is friend-to-friend advertising A userinstalls the app and then invites a few friends, or a posting appears in the Friend Updatesfeed with a link to the app Either way, the app developer has written various activities,messages, and invitations as a way of advertising and seeding the application

It’s important to remember that while these tools must be used, they should never beabused An app that’s spammy will quickly annoy users, leaving you with few installs and

a declining user base

Trang 18

In this chapter we’ll add two different features to our app that are dependent onexternal server communications Each feature will use a different technique.We willmake use of existing services on the Web to create a “mashup”-style app.

Communication with your own servers, and securing those channels, will be coveredwhen we discuss other styles of applications

Communicating with External Servers

What Is an External Server?

An external server is any server whose DNS address does not resolve to the same top-level domain as the main hosting page The Web browser imposes multiple security constraints when dealing with an external server, particularly with regard to cookies and XMLHttpRequest (XHR) calls.

In the case of apps, an external server can also be considered any server that is not under the control of MySpace The two notions are close enough to be interchangeable for most discussions in this book.

The main MySpace top-level domain is myspace.com, but all apps are hosted in the domain msappspace.com, also referred to as a “jail domain” since it restricts apps’

access to the parent page via the same-origin policy regarding source domains.

Trang 19

OpenSocial recognizes that it can’t be all things to all people In fact, it’s designed to bejust some things to all people—namely, an API for exposing social information.To thatend it really is designed for use in external applications and mashups

There are a multitude of techniques for communicating with external servers If allyou are doing is referencing static content, there are almost no constraints If you want to

do something a little more dynamic, like invoke a Web service, things are a little morecomplicated

As we said before, static content on external servers has very little in the way of straints So long as you use a fully qualified address, the image file will resolve from anyserver.This is a common technique for large Web sites.They make use of a contentdelivery network, or CDN A CDN may be simple or complex A simple CDN justoffloads the bandwidth that would be used to serve static content from the dynamic appservers, leaving more bandwidth and processing power for handling dynamic requests

con-Most browsers also throttle the number of concurrent connections back to a singledomain, so this technique allows the browser to download more files at once; thereforethe page loads faster

Dynamic content is another story.There are a handful of well-established techniquesfor creating dynamic content, some legitimate, some nefarious.We’ll cover the well-established techniques here and touch on the nefarious ones in Chapter 13,Performance, Scaling, and Security

Mashups

Origin of Mashups

A mashup is a Web site or Web application that seamlessly combines content from more than one source into an integrated experience The first mashups were simply hackers reverse-engineering the map APIs from companies like Yahoo! and MapQuest to make interesting overlays, such as laundromats near you Over time, the mashup was recog- nized as not cannibalizing business but being a new business and application model in the Web 2.0 universe.

While direct information is cloudy, the term mashup itself is likely derived from a tice in music where two different-source music tracks are combined, often through digital manipulation, to create something entirely new An example of this would be mixing Madonna’s “Like a Virgin” vocals over heavy drum and bass instrumentals

prac-Mashups are a combination of one or more services in a new way to make a new service

or product that is different from the original

As companies have recognized the value of allowing external parties to use their ices and infrastructure, the number of open APIs catering to mashup-style applicationshas proliferated widely Several new business models have emerged, allowing larger

Trang 20

Adding a Feed Reader to Our App 93

providers to leverage their services and infrastructure for new revenue streams byproviding so-called cloud services to third parties.This is in sharp contrast to thereaction to what we’ll call “proto-mashups” from the early days of the Web Back then itwas common practice for preportal aggregation sites to either deep-link to buried serv-ices within another site (for example, linking to buying concert tickets via TicketMasterfrom a band review site) or completely hijack a competitor’s content by using framesets

to make their site look like the competitor’s

Pitfalls of Deep Linking

A number of court cases have resulted in deep linking being declared illegal The decisions were largely based on the fact that the deep linker/framer (utilizing site) used the content for commercial gain without the consent of the content generator (service site) The practical reasoning is that the utilizing site was using the service site as a nonconsenting content provider and bypassing the service site’s advertising to show the utilizing site’s own ads This was a contentious issue for some time—so contentious, in fact, that the W3C felt the need to publish a paper arguing that deep linking should be legal since that is one of the major ways information interacts on the Web In practice, deep linking has been difficult to prosecute A cease-and-desist letter has been the action of choice for any company attempting to protect its content, and it has usually been successful.

Almost every major Internet player has some sort of open API to cater to mashup applications Content feeds continue to be a major component As we transition to “Web 2.5/3.0,” consisting of cloud services and user-generated content, a number of new APIs are also emerging More obvious and pedestrian applications come in the form of hosted databases (like Amazon’s SimpleDB service) and various app-hosting services.

Among the newer services are those that help spread the reach of user-generated tent across the Web, like Google’s Blogger Data API, Digg’s user ratings, and MySpace’s own PostTo endpoints.

con-Adding a Feed Reader to Our AppWe’ll now extend our app by adding a feed reader.This feature allows your users tonever have to leave their game to keep up with the latest happenings on the Web In theinterest of theatrics, we’ll do this as a contrasting implementation in three parts.We’ll add

a standard set of feeds for the user to select from.Then we will demonstrate three ent implementations using makeRequest:

differ-n Manual display using the FEED content type

n Manual display using the DOM content type

n Raw text response of the feed with TEXT content type

Trang 21

ptgOverview of gadgets.io.makeRequest

The call gadgets.io.makeRequestis the standard way for apps to call out to an nal server.This is the only officially supported technique for making external server calls

exter-in the OpenSocial specification It is also the only technique that is allowed on all threesurfaces

AmakeRequestcall is a powerful and flexible wrapper on top of theXMLHttpRequest(XHR) object built into all modern browsers.The makeRequestcallwraps a batching mechanism on top of the XHR request and hides the ugly implemen-tation details If you have a special, well-known data type, it also provides several conven-ience formatters that will preprocess the response.You as the developer only need tosupply a callback function that receives the response and does something useful with it

As you may have gleaned,makeRequestuses the same underlying communicationmechanism as all the built-in OpenSocial endpoints.The difference is that themakeRequestcall is designed to handle external server communication In order to getaround the same-origin policy applied to all XHR calls, the call to an external server isbounced off a proxy server that lives within the msappspace.com jail domain

The proxy is a resource shared by all apps on MySpace As such, MySpace imposessome throttling restrictions on the number of requests an app may make within a certaintime period Particularly bad or sloppy apps have been known to take the proxy downentirely in the early days of the MySpace Open Platform Now these apps are morelikely to be suspended if they start adversely affecting the proxy servers’ performance

Even with this policy, the proxy is subject to slowed responses during peak load hours

All the OpenSocial REST endpoints support both XML and JSON return formats, with JSON being the default and the format used within the JavaScript client library The term REST stands for Representational State Transfer The REST endpoints and how to use them are discussed at length in Chapter 9, External Iframe Apps.

XHR may be used synchronously or asynchronously, but most implementations are asynchronous since asynchronous implementations don’t cause the page to stop func- tioning during communication and generally deliver a better user experience.

Trang 22

Adding a Feed Reader to Our App 95

ThemakeRequestcall may be invoked as follows:

gadgets.io.makeRequest(url, callback, opt_params)where url indicates the URL of the service being invoked,callback is a functionthat is invoked when the data is received, and opt_paramsis an optional object hash

of parameters to the request By default, this call issues a GETrequest to urland invokes the function callbackwith the unprocessed raw text in the data response

As we alluded to before,makeRequestis more than just a wrapper on top of anXHR request It provides many optional parameters that, depending on what kind ofdata service you are invoking, can prove extremely useful.These parameters can specifythings like content preprocessing, security authorization, raw headers, and a specificHTTP method

For reference, optional parameters to gadgets.io.makeRequestare specified inTable 6.1 All optional keys are enum values from the enum gadgets.io.

RequestParameters In general, the string specified in the “Key” column will work,but it is good programming practice to use the enum value For example, the keyAUTHORIZATIONis specified as gadgets.io.RequestParameters.AUTHORIZATION

Table 6.1 Option Parameters to gadgets.io.makeRequest*

AUTHORIZATION The type of authentication to use in the request; can be one of

gadgets.io.AuthorizationType.NONE, gadgets.io.AuthorizationType.SIGNED, or gadgets.io.AuthorizationType.OAUTH CONTENT_TYPE The type of content you want to treat the response as; can be

one of gadgets.io.ContentType.DOM, gadgets.io.ContentType.FEED, gadgets.io.ContentType.JSON, or gadgets.io.ContentType.TEXT GET_SUMMARIES If the content is a feed, whether to retrieve the summary fields

for the feed, can be either true or false (default).

HEADERS Headers to pass along in the request; should be an object

containing key/value pairs corresponding to the headers to

be sent to the server; for example, {

"Content-Type" : "application/atom+xml",

"Accept-Language": "en-us"

}

Trang 23

retrieve; should be specified as a number (the default at the time of this writing is 3).

POST_DATA If the method is a POST, the data to pass to the other server

Data can be passed to the MySpace container either as an object containing key/value pairs or as an encoded string The OpenSocial specification currently states that data should be only a string, but the MySpace OpenSocial container still honors both the object and the string format.

Example as an object:

{ data1 : "test", data2 : 123456 }

Example as a string:

data1=test&data2=123456

In order to convert simple objects to a string, you may make use

of either the utility method gadgets.io.encodeValues or gadgets.json.stringify.

REFRESH_INTERVAL How long in seconds the response from this request should be

kept in the container’s cache; should be specified as a number The default interval is one hour, but this is subject

to the browser and container’s cache implementation.

*Reprinted from Google (http://code.google.com/apis/opensocial/articles/makerequest-0.8.html) and used according to terms described in the Creative Commons 2.5 Attribution License

(http://creativecommons.org/licenses/by/2.5/) Find the latest specification at www.opensocial.org or http://wiki.opensocial.org/index.php?title=Gadgets.io_(v0.9).

Response StructureThe response that is returned as a parameter to the callback method is a JSON objectand follows a predictable structure.This structure includes error messages, raw response,security information, and processed data.Table 6.2 identifies the properties of themakeRequestresponse object

Trang 24

The actual content of the datafield varies depending on the CONTENT_TYPEspecified in the initial request In the case of a TEXTcontent type request, the value ofdatais the raw text response and matches the value of the textfield For all othercontent types, it is some sort of JSON object representation of the data

Handling JSON ContentMySpace disallows the use of an evalstatement, so the only two ways to process JSONdata are by calling gadgets.json.parseor by using makeRequest.The

CONTENT_TYPEparameter must be set to gadgets.io.ContentType.JSONfor theresponse text to be processed as JSON

When a makeRequestcall is made with the JSON content type, the parsed JSONobject is placed in the response dataproperty.The content of the textproperty is theraw, unevaluated JSON text.This method works on any app surface (Home, Profile, orCanvas)

On the Canvas surface, only you can use a JSONP request to get JSON data(discussed later in this chapter in the section “Overview of JSONP”)

Handling Partial HTML ContentWhen making a request for partial HTML content to be rendered directly into the page,your best bet is to use the default TEXTformat (gadgets.io.ContentType.TEXT).Since the raw HTML is written directly into the innerHTMLof some element on thepage, no processing is needed.This technique is analogous to Ruby on Rails’s partials orusing the Ajax.Updater from the Prototype JavaScript library

Handling RSS Feed ContentRSS feeds can be directly processed in the makeRequestcall by specifying aCONTENT_TYPEofgadgets.io.ContentType.FEED.When this is done, themakeRequestresponse contains a processed JSON object that represents the feed.Thiscan also be used in conjunction with the GET_SUMMARIESparameter to includesummaries in the feed request

Adding a Feed Reader to Our App 97

Table 6.2 MySpace-Supported makeRequest Response Object Properties Key Description

data Parsed/processed data if a CONTENT_TYPE other than

gadgets.io.ContentType.TEXT is specified errors Array of any errors that occurred when making the request, typically request

errors, for example, 404 or 500 text Raw text of the response; useful if you are performing partial content

rendering, as is common when using Ruby on Rails

Trang 25

Once you have the content loaded into the data DOM object, you are able to use thefull DOM API in all its glory Statements like the following may be used to select nodes:

response.data.getElementsByTagName("item");

This can prove to be very useful when dealing with proprietary APIs Even on occasion

a well-known data type must be handled this way if the provider is not well conforming

This allows you as the developer to write more robust code, if you have a need

Another way in which this is useful is when applying XSLT transforms to the XMLfor display If you wish to look further into this technique, it involves using the followingmethods (depending on your browser):

n DOMDocument.transformNode()(Internet Explorer)

n XSLTProcessor.importStylesheet()andXSLTProcessor.transformToFragment()functions (Firefox and Safari)Creating the XSLT object can be a little cumbersome because of browser compatibil-ity issues Maintaining the transforms can be problematic as in-browser debugging toolsare poor at best and there are some minor implementation differences between browsers

It is not impossible, but we leave it to the reader to explore this technique

“User’s Pick” Feed ReaderOur mashup example is a user-driven feed reader.The user can pick a feed from ourmarket-tested and carefully peer-reviewed (read: random) drop-down list of availablefeeds.The user can then choose to do a one-time read or have the list refreshperiodically, à la PointCast Network

Setup and Design of the Feed ReaderThis is a simple reader.The user can pick one of a preselected list of RSS source feedsfrom a drop-down.The user can also choose to have the feed continuously updated byselecting a check box

The first step is building the UI for our feed reader It will consist of a drop-downlist, a format (content type) radio button selector, an action button, and a display surface

Ngày đăng: 24/12/2013, 06:17

w