Feb 10, 2010

Publish post to facebook Wall (News feeds) from actionscript

This article shows two ways how to make publish to stream Wall (News feeds) from flash facebook application or game:

  • Publish post to stream with no user actions (using Stream.publish)
  • Publish to stream from rendered Feed form (using Facebook.streamPublish)

1. Publish to stream using Stream.publish method

You can find detailed description of this method here http://wiki.developers.facebook.com/index.php/Stream.publish

That is very detailed description and I only want to show how to use it from actionscript 3.
Most probably you use actionscript facebook API client libraries from here.
When I have found description of Sream.publish method on page above and understood that I need to use it (without feed form rendering) I couldn't find any appropriate actionscript method in documentation. Only digging of client library source code helped me to find PublishPost class that allows calling Stream.publish method.

Here is example how to use this method from actionscript 3:

private function publishToStream():void{
var message:String = "Stream.publish example";
var attachment:Object = {media: [{
type: "image",
src: "http://novacoders.com/design/img/logo.gif",
href: "http://novacoders.com/"
}]};
var actionLinkData:ActionLinkData = new ActionLinkData();
actionLinkData.href = "http://novacoders.com/services/flashdevelopment/";
actionLinkData.text = "Flash games development";
var post:PublishPost = new PublishPost(message, attachment, [actionLinkData], fbook.uid);
post.addEventListener(FacebookEvent.COMPLETE, onPublish);
var call:FacebookCall = fbook.post(post);
}

private function onPublish(e:FacebookEvent):void{
if(e.error!=null){
// fbook.grantExtendedPermission("publish_stream");
trace("Publish to stream: " + e.error.errorMsg);
}else{
trace("Publish to stream: onPublish " + e.data);
}
}


2. Publish to stream from feed form using Facebook.streamPublish method

to be continued

Feb 8, 2010

Verify whether flash swf file is loaded from Facebook

This article describes how to verify that Flash object was loaded from Facebook web page.

There are official detailed instructions on facebook page you can find here:
http://wiki.developers.facebook.com/index.php/Fb:swf

Here are main points:

For security, this technique does not embed your secret key in your Flash app:
  1. Get all the parameters whose names start with fb_sig. (Do not include the fb_sig parameter itself.) In Flex use Application.application.parameters to do this.
  2. Strip the fb_sig_ prefix from all parameters.
  3. Create a string of the form param1=value1param2=value2param3=value3, etc., sorted by the names (not the values) of the parameters. Note: Do not use ampersands between the parameters.
  4. Separately pass this string and the fb_sig parameter itself to your server, where your secret key is stored.
  5. On your server, append your application secret key to the string that was passed in. The following is returned: param1=value1param2=value2param3=value3myappsecret
  6. On your server, create an MD5 hash of this string.
  7. On your server, compare the generated hash with the fb_sig parameter that was passed in. If they are equal, then your Flash object was loaded by Facebook.

After reading that article, many developers try to use fb_sig_ parameters which are listed here
and it doesn't work.
The right way to generate string from point 3 above is to use all parameters with prefix "fb_sig_" because those can be changed anytime by facebook.

Here is Actionscript 3 code that implements this technique:

private function encodeFlashVarsString(parameters:Object):String{
var keyArray:Array = new Array();
for (key in parameters) {
keyArray.push(key);
}
keyArray = keyArray.sort();
var hashString:String = "";
while (keyArray.length > 0) {
var key:String = keyArray.shift();
if (key != "fb_sig" && key.substring(0, 6) == "fb_sig") {
var param:String = parameters[key];
hashString += key.substr(7) + "=" + param;
}
}
return hashString;
}

You can acces parameters from loaderInfo field of stage or other MovieClips. For example:
parameters = stage.loaderInfo.parameters;


Now, you need to send generated hash string to your server where it will be merged with Facebook Application Secret Key and MD5 hash should be calculated. Then you need to compare MD5 code with fb_sig parameter to determine if swf file was loaded and run from Facebook page. So, don't forget to send "fb_sig" parameter to the server as well.

Here is server side java code that makes MD5 hash calculation and compares result with result received from client side.


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* Check if client application run from facebook page
* @param paramsString String generated on client side
* @param appSecretKey Your application's secrete key
* @param resHashString String we should receive after paramsString MD5 hash calculation
* @return true if swf file was loaded from Facebook page
*/

public static boolean checkHashString( String paramsString,
String appSecretKey,
String resHashString
) {
if(paramsString == null || resHashString == null){
return false;
}
try {
String srcString = paramsString + appSecretKey;
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] src = srcString.getBytes();
byte[] res = md5.digest(src);
String resStr = new BigInteger(1, res).toString(16);
return resStr.equals(resHashString);
} catch (NoSuchAlgorithmException ex) {
System.out.println("md5 exception:"+ex.getMessage());
}
return false;
}


Hope it is helpful article :)