Welcome Developers!
It's hard to believe another year has passed. As such, it's time for another State of the Union for OpenSocial. OpenSocial has grown and changed quite a bit over the last year. No longer is it just a platform for a few social networks to allow third-party games. OpenSocial has continued to evolve into uses as a general purpose integration framework. It's seen broad adoption in the Enterprise by the likes of IBM, Oracle, Jive Software, and many others. Myspace has also open sourced large pieces of our OpenSocial platform as Project Negroni.
Come join us and many others at the OpenSocial State of the Union on May 12th (just after Google IO). It's going to be held at the Google San Francisco office. Looking forward to seeing you there. Register for OpenSocial SOTU
We are preparing to roll out our implementation of encrypted user id’s announced in late December: Protecting Myspace User IDs
This will affect ALL IFRAME based applications.
The two easiest solutions are to either grab the Opensocial token from the IFRAME URL and make a call to: http://api.myspace.com/1.0/people/@me/@self?opensocial_token= or the decryption method outlined in the previous blog post: Protecting Myspace User IDs
This will be permanently enabled in 30 days. Please have your code adjusted no later than Monday, April 18th, 2011.
We're always moving to bring more value and improve the experience of working with the Myspace Developer Platform to you, our developers. As we've upgraded our APIs to support OAuth 2.0 we've also been looking at the experience of developing experiences that leverage the Myspace platform outside the walls of Myspace.
The current off-site login tools, collectively known as Myspace ID, are just too complicated and have too many similar options. Currently we support two different off-site login mechanisms through MySpace ID and our MySpace ID SDKs:
As we roll out our OAuth 2.0 support, that's going to add a third login option - OAuth 2.0 client login. Time and again our developers have shown us that what they want is to validate users in order to leverage their social graph data through our rich API catalog. The best solution to this problem is OAuth Login. In order to focus on delivering the best experience to our developers, we're going to phase out support for OpenID login from Myspace ID so we can focus solely on OAuth login solutions moving forward.
OpenID support will continue to function for a time period in order to allow our developers time to transition to using OAuth login. If you are currently using one of the Myspace ID SDKs, this should be a relatively simple matter; the SDKs currently include support for both OAuth login and OpenID login. In the coming months we will be removing OpenID support from the SDKs in order to eliminate confusion and retiring OpenID support.
In the mean time, you are encouraged to explore and transition to OAuth login, enjoy the simpler implementation, cleaner interface, and mobile device support. Happy coding!
The OpenSocial 1.0 spec brought some interesting changes to the Myspace platform, but one often overlooked piece of the 1.0 pie is the new simplified JavaScript API.
One of the major complaints about the legacy JavaScript API found in OpenSocial version 0.8, which lives in the opensocial namespace, is that it is very verbose. Let’s take a look at an example; the snippet below shows how you would fetch a list of 100 friends in a 0.8 app:
function fetchFriends(){ var request = opensocial.newDataRequest(); var params = {}; params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER; params[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1; var idspec = opensocial.newIdSpec(params); params = {}; params[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1; params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100; request.add(request.newFetchPeopleRequest(idspec, params), FRIEND_KEY); request.send(outputFriends);}
The new API, which lives in the osapi namespace, is a little more succinct. Let’s take a look at a code snippet that has the exact same functionality only rewritten to use the osapi API:
function fetchFriends() { osapi.people.getViewerFriends({ 'count': '100', 'startIndex': '1' }).execute(outputFriends);}
You can plainly see the difference. The first example has 16 lines of code and uses 519 characters, the second example has 6 lines and 127 characters. As we all know, the less code the better: it’s easier to read and understand and less bugs will be introduced. The osapi API also has a very jQuery-like feel to it, which more and more developers are becoming used to.
When it comes to parsing the response the osapi API has further simplified things. Let’s say that after we execute the request above we want to access the first friend’s thumbnail URL. First let’s see how it’s done in the legacy API:
var pic = response.get("friends").getData().asArray()[0].getField(opensocial.Person.Field.THUMBNAIL_URL);
And now in the osapi API:
var pic = response.result.entry[0].thumbnailUrl;
A large difference to be sure.
Now that we’ve seen the benefits of the osapi API let’s talk about what it can and can’t do in relation to the legacy API. In terms of accessing and manipulating data (fetching friend lists, updating app data, creating albums, etc) the two APIs have the same functionality. Any data you can access or manipulate using the legacy API can be done with the osapi API.
Outside of data access you’ll still need to use the opensocial or gadgets namespace for most everything else. The osapi API just simplifies data access. So, for example, to share the app you’ll still need to do something like this:
function rsa(friend_array){ var body = "Hey [recipient]! [sender] wants you to "; body += "add [app]. It's way awesome!"; var reason = opensocial.newMessage(body); opensocial.requestShareApp(friend_array, reason, rsaCallback);}
And to resize the height of the app when it loads, you’ll still need to do something like this:
function resize(){ gadgets.window.adjustHeight();}gadgets.util.registerOnLoadHandler(resize);
So how exactly does the new API work? The best place for technical documentation is the official spec. This first link introduces the osapi namespace and describes how to batch and send requests and handle errors:
http://opensocial-resources.googlecode.com/svn/spec/1.0/Core-Gadget.xml#osapi
This next link describes the different services that are defined in the spec and how to use them. Keep in mind that Myspace doesn’t support everything in the spec and we also define some services that aren’t in the spec — more on this later.
http://opensocial-resources.googlecode.com/svn/spec/1.0/Social-Gadget.xml#JavaScriptAPIReference
Because the osapi API uses the same JSON input and output as the REST API, it can be useful to take a look at that spec as well:
http://opensocial-resources.googlecode.com/svn/spec/1.0/Social-API-Server.xml#services
Finally, probably the quickest way to start using osapi is to use a sample app we have developed:
http://www.myspace.com/games/play/195871
The app lists all of the services that Myspace currently supports along with all the available parameters that can be specified. Simply click the service you want to use and fill in all the parameters you want. At this point you can click one of the three buttons:
Let’s look at an example. Say you want to find the viewer’s first five friends that don’t have the app installed. To make this happen just follow these steps:
The desired parameters are now entered in (see Figure 1). At this point you can make sure the request will do what you think it will do by executing it and checking the results (see Figure 2).
Once you’re satisfied that you’re getting the correct data you can click Generate Sample Code to see what the code would look like.
The sample code can now be copied and pasted into your app.
Note: you can see that a function named myCallback is passed in as a parameter to the execute() function. You’ll need to define this myCallback function to correctly handle the callback from the request. If you don’t do this you’ll get an error. You may or may not want to rename myCallback to something more appropriate.
You can play around with all the functionality that the osapi API provides and take away some custom sample code that you can pop right into your app, hopefully you’ll find it useful.
Happy coding!Chad Russell
For reference the complete code of the two sample apps that were used to test the code in the article are below.
1.0 app
<Module xmlns:os="http://ns.opensocial.org/2008/markup" > <ModulePrefs title="MiscTest1.0" description="A test app"> <Require feature="opensocial-1.0"/> <Require feature="opensocial-templates"/> </ModulePrefs> <Content type="html" view="canvas"><button onclick="rsa(FRIEND_ARRAY)">share</button><div id="output"></div> <script type="text/javascript">//<![CDATA[var FRIEND_KEY = "friends";var FRIEND_ARRAY;function fetchFriends() { osapi.people.getViewerFriends({ 'count': '20', 'startIndex': '1' }).execute(outputFriends);}function outputFriends(response){ var friends = response.result; if(!friends.error){ var friend_array = friends.entry; FRIEND_ARRAY = []; for(var i = 0; i < friend_array.length; i++){ writeToOutput(friend_array[ i ].displayName); FRIEND_ARRAY.push(friend_array[ i ].id); } } else{ writeToOutput(friends.error.code + " -- " + friends.error.message); } gadgets.window.adjustHeight();}function rsa(friend_array){ var body = "Hey [recipient]! [sender] wants you to "; body += "add [app]. It's way awesome!"; var reason = opensocial.newMessage(body); opensocial.requestShareApp(friend_array, reason, rsaCallback);}function rsaCallback(response){ // 0 is cancel // 1 is send // -1 is error var data = response.getData().result;}function resize(){ gadgets.window.adjustHeight();}function writeToOutput(msg){ document.getElementById("output").innerHTML += msg + "<br />";}gadgets.util.registerOnLoadHandler(fetchFriends);gadgets.util.registerOnLoadHandler(resize);// ]]></script> </Content></Module>
0.8 app
<button onclick="rsa(FRIEND_ARRAY)">share</button><div id="output"></div><script type="text/javascript">var FRIEND_KEY = "friends";var FRIEND_ARRAY;function fetchFriends(){ var request = opensocial.newDataRequest(); var params = {}; params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER; params[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1; var idspec = opensocial.newIdSpec(params); params = {}; params[opensocial.DataRequest.PeopleRequestFields.FIRST] = 1; params[opensocial.DataRequest.PeopleRequestFields.MAX] = 20; request.add(request.newFetchPeopleRequest(idspec, params), FRIEND_KEY); request.send(outputFriends);}function outputFriends(response){ var friends = response.get(FRIEND_KEY); if(!response.hadError()){ var friend_array = friends.getData().asArray(); FRIEND_ARRAY = []; for(var i = 0; i < friend_array.length; i++){ writeToOutput(friend_array[ i ].getDisplayName()); FRIEND_ARRAY.push(friend_array[ i ].getId()); } } else{ writeToOutput(friends.getErrorCode() + " -- " + friends.getErrorMessage()); } gadgets.window.adjustHeight();}function rsa(friend_array){ var body = "Hey [recipient]! [sender] wants you to "; body += "add [app]. It's way awesome!"; var reason = opensocial.newMessage(body); opensocial.requestShareApp(friend_array, reason, rsaCallback);}function rsaCallback(response){ // 0 is cancel // 1 is send // -1 is error var data = response.getData();}function resize(){ gadgets.window.adjustHeight();}function writeToOutput(msg){ document.getElementById("output").innerHTML += msg + "<br />";}gadgets.util.registerOnLoadHandler(fetchFriends);gadgets.util.registerOnLoadHandler(resize);</script>
Hello. We just wanted to give the development community a heads-up on two changes to our legacy REST APIs we will be making to the platform in the coming weeks. Neither will require any changes on your part. The goal of the changes is to make sure developers have a consistent experience accessing the legacy (v1/v2) REST endpoints with the current OpenSocial 1.0 APIs.
The first change we are making is to reuse the code to compute and validate OAuth digital signatures that exists in the OpenSocial 1.0 APIs, in the legacy v1/v2 REST endpoints. OAuth signed requests should work consistently regardless of what endpoint you are requesting.
The second change is related to privacy bugs in the legacy endpoints. The legacy endpoints will now perform the same permissions checks as the OpenSocial 1.0 APIs. For example, profile requests in v1/v2 will check the same user permissions that the OpenSocial person endpoint does. You should expect the legacy endpoints to work the same as the current OpenSocial 1.0 endpoints, but we highly encourage you to code to the OpenSocial 1.0 endpoints and consider the legacy REST APIs deprecated.
Again, developers should not have to make any changes to continue using the Myspace Developer Platform, but we just wanted to let you know what’s coming. As always, please let us know if anything seems incorrect or needs improving. We’d love to hear from you.
Thanks,ToshDev ManagerMyspace Developer Platform
As we continue to evolve our developer platform and to create an environment that most effectively empowers the developer community while at the same time protects the privacy of our users, Myspace is enacting a number of new initiatives related to data security within our application platform. We also wanted to discuss briefly some of the actions we've taken over the past month to enforce our Developer Terms of Use, which -- as we've said publicly -- prohibit the passing of any user information, including user IDs, to third parties without the consent of our users.
We determined that a handful of developers had intentionally disclosed user IDs to a single data broker in violation of our Terms. We promptly suspended the applications who were engaged in this activity. We also demanded that the data broker who received user IDs delete all such information, and it agreed to do so.
We have been working to come up with both better methods to enforce our Terms, and also mechanisms to allow developers to provide great apps without the need to share Myspace user IDs with third parties.
Initially, we are introducing the following initiatives with the goal of providing the best possible environment for developers while ensuring we protect the privacy of our users.
Below are technical changes that developers will need to make in order to ensure they are not inadvertently passing user IDs to third parties.
Encrypt Myspace User IDs
We are working to eliminate any trace of the user ID from the URL in cases where it's not strictly necessary. For apps that are rendered from an external server via an IFrame, we will begin encrypting the user ID in a way that only the app can recover the user ID. Specifically, the user ID will be encrypted with AES 256 using the specific app's private OAuth consumer secret as the encryption key. Starting on January 21, 2011, apps will need to change over from using the unencrypted user ID to using the encrypted user ID, at which time we will completely eliminate sending the bare user ID as a query parameter. The sample code provided below (in C#) shows developers how to encrypt Myspace user IDs using their app's consumer secret key.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Web;
// 128 bit iv
private static readonly byte[] iv = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // this is the IV we will be using
/// <summary>
/// Decrypts url and base64 encoded string
/// </summary>
/// <param name="encodedCyperText">cyphertext</param>
/// <returns>plaintext</returns>
public static string Decrypt(string encodedCyperText)
{
byte[] csBytes = Convert.FromBase64String(consumerSecret);
// generate a 256 bit key
SHA256CryptoServiceProvider sha = new SHA256CryptoServiceProvider();
byte[] cryptoKey = sha.ComputeHash(csBytes);
// setup encryptor params
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = iv;
aes.Key = cryptoKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// url decode, base64 decode the cypher text to byte array
byte[] cypherBytes = Convert.FromBase64String(HttpUtility.UrlDecode(encodedCyperText));
// decrypt
MemoryStream memStream = new MemoryStream();
CryptoStream decryptStream = new CryptoStream(memStream, aes.CreateDecryptor(), CryptoStreamMode.Write);
decryptStream.Write(cypherBytes, 0, cypherBytes.Length);
decryptStream.FlushFinalBlock();
byte[] decodedBytes = memStream.ToArray();
return Encoding.UTF8.GetString(decodedBytes);
Use Anonymous Identifiers
We have developed a two-phased solution to address the practical need to share anonymous unique identifiers with legitimate third parties. The first phase will utilize an anonymous and unique 32 bit integer matching the same specifications as the Myspace user ID. All developers are required to switch over to this solution prior to January 21, 2011.
Here is how to access the anonymous ID via Myspace javascript container for on-site apps:
opensocial.Container.get().params_["thirdPartyId"]
External Iframe apps came pull this value from the querystring:
third_party_id
In addition to this interim solution, we are working on a long term solution that will be based on industry standards. Anonymous unique identifiers will not be consistent across applications and will consist of a cryptographic secure token. This will prevent the creation of a global lookup table. We do understand the need for consistent anonymous unique IDs across applications for fraud prevention purposes and we will provide mechanisms for authorized parties to be able to link these IDs together across the platform.
We encourage you to review our Developer Terms of Use and if you have any questions, feedback, or are unsure if your app complies or not, please contact us at DeveloperRelations@myspace-inc.com.
We now have a Facebook page dedicated to the Myspace developer community. In addition to our blog, twitter, and newsletter, this is another great place to find news, updates, and events about our platform.
Aligned with our continued efforts of communicating with the developer community about events and changes to our platform, we're expanding and discovering new and additional ways of addressing developers. We want to assure that you are provided details in the quickest and most convenient way, allowing you to make any necessary adjustments and updates to your game(s) on Myspace.
Emails are good - phone calls are better, but what's most often the greatest way of communicating? FACE to FACE. We're always interested in having developers come work with us directly in our office. We want to work side by side to ensure that your game is using our best practices, including key viral channels. If you're interested in working with us, check out our Myspace Labs program for more information. Also, if you're interested in signing up for our developer newsletter, email us or click the button to sign up at the bottom of our developer site.
For the next 1-2 days we'll be conducting some tests on the user homepage app modules on the new Myspace, so don't be alarmed if traffic patterns to your games from that source are irregular during this test. For users who a) have the new Myspace and b) have app modules on their homepage, we'll be testing adding prominently placed links to recently played games at the top of a user's homepage, and then removing the app modules. This test will last 1-2 days so you might see some changes in your games' traffic patterns. We are continually looking into better ways for users to discover the games that they love. We are exploring adding more prominent links and bookmarks to games that appear towards the top of the page, rather than a user having to scroll down the page to see an app module. More to come on that soon!
Thanks to everyone who attended our first ever live webcast for developers. There were a lot of really great questions. For those of you that weren't able to make it, don't worry, you can watch it at your leisure here. The first few seconds got cut off during recording, but you don't miss much.
We're excited about the new Myspace, and what it means to the games. If we didn't have a chance to answer your questions, feel free to email us at DeveloperRelations@Myspace-inc.com.
So check out our webcast for more info! http://vivu.tv/portal/archive.jsp?flow=395-535-6814&id=1288908323616 Also, if you'd like to be whitelisted on the new site, sign up here.
Join the event here: http://vivu.tv/portal/Join?flow=395-535-6814
Our live webcast will feature a personal introduction of the new Myspace from Mike Macadaan, our VP of User Experience & Design. Manu Rekhi, GM of Games, will then walk through the changes to games and how they will impact developers. Developers can use the group chat functionality to ask questions to Mike and Manu.
Thursday, November 04, 2010, 3:00 - 4:00 PM PDT
Agenda:
3:00pm - 3:15pm: The new Myspace - Presented by Mike Macadaan - VP, User Experience & Design
3:15pm - 3:30pm: Changes to games - Presented by Manu Rekhi - General Manager, Games
3:30pm - 4pm: Q&A
More details found at http://myspacedeveloperplatform.eventbrite.com
Myspace and The BitSource are hosting the Erlang Factory Lite conference on Nov 7th at the Myspace Beverly Hills headquarters. The event will be free to attend and will run from 11am - 4pm. The Erlang Lite meeting aims to bring people together and share thoughts and ideas while growing the community within the LA area and give you the chance to present and share with the community.
Speakers confirmed so far are Ulf Wiger, CTO of Erlang Solutions, Kresten Krab Thorup, Chief Architext and Co-founder of EOS Trifork and Robert Virding, one of the creators of Erlang and stars of Erlang The Movie.
For more information, please visit the conference page at http://www.erlang-factory.com/conference/ErlangFactoryLiteLA. Registration for this event is free and required. You can register here.
The new Myspace is here, and we couldn't be more excited. We're placing the focus on showcasing games more. Users have more ways than ever to discover popular and relevant games and see what their friends are playing. Check out Manu's blog for details on how the new site impacts games and developers.
Please join our live webcast to get a personal introduction to the new Myspace from Mike Macadaan, our VP of User Experience & Design. Manu Rekhi, GM of Games, will also walk through the changes to games and how these changes will positively impact developers.
Here are the details (you can also check them out here):
Date: Thursday, November 04, 2010 from 3:00 PM - 4:00 PM (PT)
Join the Event here: http://vivu.tv/portal/Join?flow=395-535-6814
Webcast Meeting Requirements:
Hardware:
- 2GB RAM or higher
- Dual core processor with 2.0 GHz or higher
- Wired network connection with 1Mbps Up link and 1Mbps Down link
Software:
- Flash 10.1 should be installed
- Java 1.5 or later
Suggested Browsers: IE8 & FF 3.6
Hope you can make it!
At MySpace we take the privacy of our users seriously. As we continue to improve the privacy controls and permissions being presented to our users we will be applying these upgraded permission controls to both the newer OpenSocial 1.0 REST APIs and the older APIs used for 0.7/0.8 apps (sometimes called v1/v2 APIs).
What does this mean for you? Your code will not need to change. You may experience a change in the amount of data returned by some of these endpoints as we make these changes. When an app has explicitly requested and been granted permissions, there should be no change in the amount of data returned.