Setting Facebook Status with Flash (The Hard Way)

Feature image

You may have already checked my post Setting Facebook Status with Flash (The Easy Way). As the name implies, that?s the easy way to prompt a user to update their status. That version basically calls a special Facebook URL from Flash that prompt a user with suggested text in the status window that they can edit before they post. That method is useful for many situations. It's a lightweight and very simple to code.

But why do things the easy way when there is a hard way to do it? The hard way is to make your status setter a true Facebook application. The drawback is that your final SWF will be larger and you'll have to do a bit more work to get it up and running, but you'll have access to many more customization features, like the ability to add graphics, captions, links and more.

An Update (January 21, 2012)

Before you get too far into this post, let me outline a few changes that have been made with the Facebook API since this was originally published.

The Facebook API no longer allows you to pre-populate the 'message' field portion of a user's status. There are still a number of things you can set in a status update though, and you'll learn about this in a subsequent post in this series called Setting Facebook Status with Flash - Version 3. That will serve most people who read this post.

There is still some benefit from understand the process I've gone over below although the original goal of this process is addressed in a simpler fashion in the "Version 3" post I mentioned above. The benefit of this "hard way" method is that it will help you understand the underlying process of making a more robust Facebook application.

One last note about the source files you can download along with this post. They were built when the Flash Facebook API was at version 1.6. At the time I write this update, January 21, 2012, the current version of the Flash Facebook API is 1.8.1. You will need the lastest version of the API from Adobe to have your application function.

The "Hard" Flash version in action

Below is the actual Facebook app. Give it a try so you know what we're building. Pay attention to the dialog boxes as they appear. You'll need to log in with Facebook to post the status update. In a real app, you could make the UX better for sure. We're just talking about how to build this here, so it should be fine for this purpose.

The Flash movie can't be displayed on your device.

What's the deal? If you're reading SuperGeekery, you know your way around a Flash plugin. You've probably got Flash turned off, uninstalled, or maybe you don't have JavaScript turned on. Whatever the case may be, you can see the Flash movie. Go jump on a computer with those things and we're in business again.

What just happened?

If you followed through the entire process, you should have ended up with something like the screenshot below in your own Facebook newsfeed. This screenshot is from my Facebook page after posting with the app.

FB status message set by the SuperGeekery Facebook Status Setter application.

Notice we're actually posting from a Facebook application this time, which includes a large image, the big 75x75 pixel logo, a small 16x16 image plus some other info. We get to add a headline (the app name in blue, which is also a link), a caption area (in this example, it says "You too could be setting your status the hard way."), and a pretty lengthy description text area. There are additional things you can add as well if you read the documentation.

This additional stuff wasn't available in the original version where you simply prompt a URL.

Let's get this started

First thing's first. Download the source files for what we're building here.

Once you have the files, you'll need to set up a Facebook application. Head over to https://developers.facebook.com/. This is the hub of your Facebook developer life. There is a lot of good documentation here that you'll find helpful. Click the My Apps button at the top of the screen to get to the screen where you actually manage your apps.

You may or may not have anything listed here, based on what you've done in the past as a Facebook developer. Click the "Set Up New App" button. Pick a name for your app. (You'll also need to agree to the Facebook Terms of Service to move ahead.)

Click on the Web Site tab on the left hand side of your screen and enter in the Site URL of where the SWF file is going to be be hosted. For example, I've put "http://supergeekery.com" in this area because that's where my file actually resides. I've also filled in "supergeekery.com" in the "Site Domain" area so I can test my app on subdomains of my site.

NOTE: You will need to test your app on a live server. You can't test the file locally because it will fail to authenticate. Every time you make a change to you SWF, you'll need to replace the file on your server, clear your web cache, and reload the page.

When you hit "Save Changes" you'll be back at the home screen for your app. On this screen you'll need the App ID for later, since we'll be using that in this project. We won't be using the App secret, but you should not share that password with others.

Get your Facebook App ID.

Get the SWC

Head over to the Adobe ActionScript 3 SDK for Facebook Platform API home page. Download the GraphAPI_Web_x_x.swc.

Get the correct version of the Flash Facebook SWC.

At the time I write this, we're at version 1.6, so the file name is GraphAPI_Web_1_6.swc. Get whatever the most recent one is. The important thing here is to get the Web version, since what we're building here is on the web. The Examples file on this page is also extremely helpful. You'll see I'm using much of the index.php page they've included in this example zip for embedding the file we're building today.

Start your Flash project and Import the SWC

Open Flash and start a new project. Open the "Publish Settings" for this new file (under the File drop down on a Mac.) Click the "Flash" tab in there and import the SWC file you downloaded. (I keep the SWC in the same folder I save the FLA file in so I can archive the entire folder with the version of the SWC I'm using.)

If you haven't used a SWC before, let me cover how to import that briefly. Under your file drop down, you'll be able to adjust your Publish Settings. You'll need to be publishing a SWF which will make the Flash tab available in this dialog box. Click that Flash tab. Then, next to the Script: ActionScript 3 area, click the Settings button. You'll see something like the shot below.

Set your AS3 settings to import the SWC.

Click the import SWC button and be sure it is added to your list of SWCs for this project.

Digging into the code

I'm not going to go over every bit of the code in this post, but if you look at the ActionScript in the files you downloaded, you'll see that it contains a cornucopia of copious comments. (I love a little alliteration.) I will go over the flow of what's happening hitting on some of the code.

First, import your classes you need.

import flash.events.MouseEvent;
import com.facebook.graph.Facebook;
import flash.display.MovieClip;
import flash.text.TextField;

You have access to the Facebook graph with the SWC you imported.

The Facebook application needs to start with the Facebook init function which takes the App ID that you got earlier when you set up the application on the Facebook Developers "My Apps" page. You'll see that I have the Facebook.init function called within a function called init(). I wait until the very end of the entire code block to start this function. You don't need to do that. I do it for my own organizational purposes.

Facebook.init("YOUR_FB_APP_ID_GOES_HERE", onFBInit);

The Facebook.init function takes 2 parameters. The first is the App ID. Notice that it's in quotes though since it expects a string. Don't just pass in the number by itself. The second parameter is the function that executes once the app hears back from Facebook. You're not logging someone into the application yet with this Facebook.init function. You're simple telling Facebook that you'd like to get an app started up and if Facebook gives you an "ok", you will move on from there. The code I'm not covering but is in your file is basically making button invisible or disabled that shouldn't be visible until the Facebook app is ready for action.

Your Facebook application has started, now what?

Once you get that "ok" from Facebook, the onFBInit function will fire. The name of this function can be anything you want, but it needs to accept 2 parameters, a result object (aka success) and a fail object. A result/success message means that the user who is on this page right now has used this application before AND they have allowed it access AND they are currently logged into Facebook with this browser already. You'll see in the code, the button that posts the status message is turned on and is ready for action.

The thing you're probably more interested in at this point is the lack of success. If you didn't receive a success message you need to log the user in or get them to authorize your app in the first place. You'll see in the 'else' part of this function, the Facebook login/logout movieclip, called "fb_log_button" since it contain both states of the button, is set to the "loggedOut" state. By having that movieclip goto and stop at the frame label "loggedOut" it will show a "log in" graphic. You'll also see that if the user is not logged in, the button for posting a status message is obscured by setting it's alpha to 25% to indicate it is not usable currently.

function onFBInit(result:Object, fail:Object):void
{
	this.fb_log_bt.addEventListener(MouseEvent.CLICK, fbLoginChangeAttempt);
	this.fb_log_bt.buttonMode = true;
	this.fb_log_bt.visible = true;
	this.waitingOnFacebook.visible = false;
	this.submit_fbStatus_bt.visible= true;
	if (result)
	{//already logged in because of existing session
		this.fb_log_bt.gotoAndStop('loggedIn');
		fb_logged_in = true;
		
		this.submit_fbStatus_bt.alpha = 1;
		this.submit_fbStatus_bt.mouseEnabled = true;
	}
	else
	{
		this.fb_log_bt.gotoAndStop('loggedOut');
		fb_logged_in = false;
		this.submit_fbStatus_bt.alpha = .25;
	}

}

Making the Log In and Log Out button work

The fb_log_bt movieclip has a MouseEvent.CLICK event listener added to it in the init() function as well. This function can possible do 2 different things.

If a user is not logged into Facebook, the Facebook.login function is executed. It takes 2 parameters. The first one is a callback function, i.e. what function should be called upon completion of this login attempt. In this case, we're executing the onFBLogin function. The second parameter is an object that is filled with permissions you want your app to have into the user's Facebook profile. This example only asks for a single type of permission, "publish_stream", which allows the app to publish to a users news stream. The more access you ask for, the more likely someone is going to question whether they should allow access. As a best practice, only ask for the permissions you really need. You can see a full list of what permissions you can ask for in the Facebook documentation here.

If a user is already logged in, it will execute the Facebook.logout function. It takes a single parameter, a callback function to execute when it's completed the logout process. The Facebook.logout simply logs a user out of Facebook entirely from the browser they are using. Your app won't see them as a logged in user anymore, but they can click login again and log back in with their Facebook credentials.

function fbLoginChangeAttempt(e:MouseEvent):void
{
	if (! fb_logged_in)
	{
		var opts:Object = { perms:"publish_stream" };
		Facebook.login(onFBLogin, opts);
	}
	else
	{
		Facebook.logout(onFBLogout);
	}
}

After a successful Facebook login or logout

After the Facebook logging attempt, it's back to run of the mill AS3. In the function below, we just change the visibility of several items on the screen and enable the submit button to accept mouse events.

function onFBLogin(result:Object, fail:Object):void
{
	if (result)
	{
		//successfully logged in
		this.fb_logged_in = true;
		this.fb_log_bt.gotoAndStop('loggedIn');
		this.submit_fbStatus_bt.mouseEnabled = true;
		this.submit_fbStatus_bt.alpha = 1;
	}
	else
	{
		// Something didn't go as planned to set the app to the logged out state
		// call the onFBLogout function.
		
		onFBLogout();
	}
}

The onFBLogout function basically does the opposite of the onFBLogin function. There's nothing special about this function. It's just typical visual settings that are being updated.

function onFBLogout(success:Boolean = true):void
{
	// logged out, show log in button
	this.fb_logged_in = false;
	this.fb_log_bt.gotoAndStop('loggedOut');
	this.submit_fbStatus_bt.mouseEnabled = false;
	this.submit_fbStatus_bt.alpha = .25;
}

Submitting a status message to a user's news feed

The status message itself has some simple logic that was covered in the Setting Facebook Status with Flash (The Easy Way) post, so I won't go over how that status message is actually constructed again here. The first part of the showFBUI function is pulled from the easy version as well. In short, it shows an error message if the user hasn't completed selected something from the pull down menu.

The second part of the showFBUI function does some special Facebook magic though, so let's take a close look at it. This function will make a Facebook User Interface dialog box appear on the screen. We want the 'feed' dialog box. We store this method in the variable "methodInput". See the Feed Dialog documentation for full docs on this.

We want to set 6 things for Facebook Dialog box, the message, the caption, the description, the link, the name and the picture. To keep things easier to read, we'll store each piece of the information in its own variable. Note that the picture is a URL path to the picture. We then create an object to hold all of these variables.

Finally, we'll take the methodInput and the data and pass them into the Facebook.ui function which will make the dialog box appear on the user's screen.

function showFBUI(event:MouseEvent):void
{
	if (fbStatusComboBox.selectedIndex == -1)
	{
		showErrorMessage();
	}
	else
	{
		// build your fbStatus as a string
		var myCustomfbStatus:String = fbStatuspart1 + fbStatusComboBox.value + fbStatuspart2;

		// define your caption text
		var theCaption:String = "You too could be setting your status the hard way.";

		// define the descrition text
		var theDescription:String = "Why set your status the easy way? The SuperGeekery FB Status Setter app is a great way of learning how to build a basic Facebook application and it also lets you set your Facebook status. Learn more at SuperGeekery.com";

		// We need to follow the FB docs to tell it what sort of input we are sending to FB
		// We are trying to set the 'feed'
		var methodInput = 'feed';
		
		var thePicture = "http://assets.supergeekery.com/sg_status_setter_icon_75x75.png";
		var theLink = "http://supergeekery.com";
		var theName = "The SuperGeekery FB Status Setter";

		// Create an object that we'll call 'data' and fill it with the actual data we're sending to Facebook
		var data:Object = {
			message:myCustomfbStatus, 
			caption:theCaption, 
			description:theDescription, 
			picture:thePicture, 
			name:theName, 
			link:theLink
			};
			
		Facebook.ui(methodInput, data, showFBUICallback);
	}
}

Embedding your SWF properly in the HTML

This basically completes the Facebook app, but if you've tried embedding this SWF in the HTML page that Flash generates on it's own, you probably are a little frustrated. Since this is a Facebook application, you need to import the Facebook javascript into your HTML page and create a div in your HTML page to give the javascript a hook into the page. (I with the FB javascript created this div on it's own, but I digress.) We'll use swfObject to place the SWF into the HTML. I found it necessary to set the 'wmode' to transparent in my tests. Others who've written about this mention that you need to set the name attribute to the same name as the ID of the div you're placing the SWF. What does that look like? Here's the basic version.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
	<head>	 	
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
		<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>	
	</head>
	<body>
		<div id="fb-root"></div>
		<div id="yourFBFlashApp">
			<h1>You need at least Flash Player 10.0 to view this page.</h1>
			<p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
		</div>  
		<script type="text/javascript">
			var flashvars = {};
					var params = {
						wmode: 'transparent'
					};
					var attributes = {
						name: 'yourFBFlashApp'
					};
			swfobject.embedSWF("setting_fb_status_hard.swf?<? echo(time()) ?>", "yourFBFlashApp", "620", "150", "10.0", null, null, params, attributes) 			
		</script>
	</body>
</html>

Wrap up

Whew! You made it. There's a lot more to keep track of this way, but it offers you a lot more options. If you get your head wrapped around this, you're on your way to making more complex Facebook apps as well.

Did I miss anything? Do you have a better approach? Please let me (and other) know by posting a comment. Good luck with your app!

Comments on this post.

This is very cool. But I can’t get it to work. I never even get the callback from the Init. Is there a way to debug this?! :(

By Krystian Majewski on Jan 20 2012

... and by the way, your sample above doesn’t seem seem to work properly either. After I log in, the post button never turns opaque.

By Krystian Majewski on Jan 20 2012

Krystian, Let me take a look. The biggest problem with building with Facebook is that it is definitely not a ‘make it and forget about it’ programming. The API changes quickly.

By John Morton on Jan 20 2012

Hello Krystian,

I took a look at the files. I republished my SWF using the most recent version of the Flash Facebook API, now at version 1.8.1 and it works again without any change. Have you tried using the version 1.8.1 API file and not the 1.6 version that is included in the source?

By John Morton on Jan 21 2012

Hello John,

thanks for reviewing the case. Yes, the sample above works for me now! However, I was using the newest version in my own code, so that’s not why it wasn’t working for me. At this point, I’m pretty sure it’s the fact that the Sourcode is distributed as a SWC. I’m still using CS3 and although it can use custom SWC, there seems to be no interface for setting them and I can’t find any documentation how to do it. I used the pure sourcode *.as files and although they don’t generate any errors, they just don’t seem to work.

But the issue has resolved itself. I wanted to use the API to pre-populate the status update box. Since that’s not possible anymore, I can’t use the API anyway.

But thank you for your generous patience and the tutorial! You were an enormous help. :)

Cheers
Krystian

By Krystian Majewski on Jan 22 2012

Thanks a million, dead simple post and got it running :) (I was missing the HTML implementation part at all).

By Duminda on Feb 27 2012

Leave Your Comment:

name:

email:

location:

url:

your comment:

Remember my personal information

Notify me of follow-up comments?

Twitter Feed

John Morton talking on Twitter




Meanwhile on Instagram… //

My latest shot from Instagram.
Hazy night in Union Square