28 Jun, 2009  |  Written by Jon  |  under Amazon Web Services

This tutorial is part of a series on setting up Scalable Web Hosting with Amazon EC2

To login to our instance, we will use a great Telnet/SSH client named PuTTY. I currently run it on windows and it works very well. The Windows installer is available here. Install the software on your machine.

In our previous tutorial, we generated a key that we saved on our local machine. Before we use PuTTY, we have to convert that key to PuTTY’s format. In the installation pack was a program called “PuTTYgen”. Run this program. Select “Load” from the main screen and find the key that we saved when we were creating our Amazon EC2 instance. Note, the Amazon key ends with the extension .pem, so you will have to switch to show all files *.* Once the key loads, select “Save Private Key”

GenerateKey

You will get a warning about saving the key without a passphrase. Click Yes/OK

Now run the main PuTTY application. In the main Session screen, add the Public DNS for your new Amazon EC2 Instance into the Host/IP Box. You can also name your profile if you want to reuse it

PuTTYHost

Then, in the menu tree on the left, expand “SSH” under “Connection” and select “Auth”.  Click the “Browse” button in the “Private Key File” field and load the key you just created with PuTTYgen.

SelectKey

Now click the “Open” button at the bottom (or you can go back to the “Session” screen to save your configuration first). A SSH command line window will open with a prompt saying “Login As:”. Type “root” and hit enter. If you see something like this, you have successfully logged in!

LoggedIn

28 Jun, 2009  |  Written by Jon  |  under Amazon Web Services

This tutorial is part of a series on setting up Scalable Web Hosting with Amazon EC2

If you have not already done so, you should register for an Amazon EC2 account. Follow the instructions provided to generate and save your login credentials.

For this tutorial, we will use the AWS Management Console. Login to the Management Console. On the home screen, make sure the tab EC2 is selected. Your screen will look something like this (with likely all zeros in the “My Resources” section):

Dashboard

Click on the “Launch Instances” button. You will be presented with series of default machine images.  Choose the “Basic Fedora Core 8″ Image. Note that there is an option that has the LAMP stack (Linux, Apache, MySql, PHP) already configured. For the sake of this tutorial, we are going to do it from scratch. For practical reasons, I like to control my install setup rather than going with pre-configured options anyway.

PickInstance

Now, enter in a name for the key you would like to create, and save it in a secure place on your local machine. We will need it for SSH login purposes later:

MakeKey

Now we will setup basic firewall access for SSH (we will fix the web server and database firewall access later):

ConfigureFirewall

Now, enter 1 for the number of instances, and select Launch!

LaunchInstance

It make take a few minutes for your instance to start up. Once the Instances screen shows a status of  “running”, click on your server to see its configuration details. We are particularly interested in the Public DNS that was assigned. Make a note of this.

PublicDNS

Now we have everything we need to login and manage our server through SSH. Continue on to our next tutorial on “Loging in to an Amazon EC2 Instance Using PuTTY

As you know, Facebook Connect and Facebook Iframe Aps restrict the developer to only using XFBML if the page is being served from somewhere outside of Facebook (as all iframes and connect applications are by definition)

Facebook does make available, however, a handy XFBML tag Fb:serverfbml that allows you to serve up regular FBML inside a Facebook served iframe within your non-FBML facebook application.

The example below shows how the fb:friend-selector FBML tag can be implemented in an iframe application. This example populate a friend selector and display’s that friend’s Facebook UserID when the post button is clicked.


<?php
//Link in library. Note my directory structure may be different
require_once '../fblibrary/facebook.php';

//Authentication Keys
//My Authentication Keys. Sored in $appapikey and $appsecret respectively
require_once 'keys.php';

//Construct the class
$facebook = new Facebook($appapikey, $appsecret);

//Require login
$user_id = $facebook->get_loggedin_user();
if (!$user_id>0) {
	$user_id = $facebook->require_login();
}

//Get the authentication variables
foreach($_GET as $key => $value) {
	if (strpos($key,"fb_sig")!==false) {
		if ($i!=0) $fbvars.= "&";
		$fbvars.= "$key=$value";
		$i++;
	}
}

?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head></head> 

<body> 

<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script> 

	<?=$_GET[friend_sel];?>

	<fb:serverfbml style="width: 500px; height:20px;">

		<script type="text/fbml">

		<form id="addform" action="http://www.keywordintellect.com/facebook/iframeexample/serverfbml.php?<?=fbvars?>">
			<fb:fbml>
				<fb:friend-selector uid="<?=$user_id?>" name="newuid" idname="friend_sel"></fb:friend-selector>
			</fb:fbml>
			<input type="submit" value="Submit"/>
		</form>

		</script>
	</fb:serverfbml>

<script type="text/javascript">  FB.init("<?=$appapikey?>", "xd_receiver.htm"); </script> 

</body>
</html>

This tutorial assumes you already have a basic Facebook IFrame application up and running. If not, see our getting started tutorial.

First, we need a javascript function or library to handle our Ajax requests. To keep it simple, and cross-browser compatible, we use the Prototype Javascript Library. Specifically the version that is hosted and maintained by Google. To implement, add this to your canvas page header:

	<script src="http://www.google.com/jsapi"></script>
	<script>
		// Load AJAX modules
	   	google.load("prototype", "1.6");
	</script>

Next, create a DIV on your page to hold our AJAX enabled content. For example:

<div id="comments">Populating Comments....</div>

We need to create a separate file for the AJAX call to fetch and use to populate the div. So create a new file (I used simpleajax_divcontent.php in my example). Add whatever you want to that file. I used:

<?

//If we don't sleep then the DIV populates too quickly to see anything
sleep(3);

echo "Here are the comments from the Ajax page";

?>

I call that sleep function because the div would update too quickly to even see it otherwise (obviously in a real application you wouldn’t need to use it)

Now, back to our canvas page. Before the closing body tag, add the following Javascript to call the Updater function from the Prototype library. Substitute your file name for my ’simpleajax…’ name.

<script type="text/javascript">
new Ajax.Updater('comments', 'simpleajax_divcontent.php', { method: 'get' });
</script>

You’re done! One note: if you want to make Facebook API or XFBML calls on the page you are calling from the code above, you have to pass the fb_sig GET variables through the url ’simpleajax_divcontent.php?fb_sig=adfafdfafdqaf’ etc. This keeps everything authenticated. See our other post on the topic for more info.

Getting Facebook Developer Application running and libraries installed:

Go to http://developers.facebook.com/ . Click the Green “Get Started”  Button

Click “PHP Client Libraries” on the right side of the page in the gray box. Save the zip file to your local computer. Unzip the contents of “facebook-platform”>>”php” and upload to the folder on your web server that will serve as the root of your Facebook application. FYI, you just need the files in the “php” folder in your root directory.

Install the Facebook developer application at http://www.facebook.com/developers/

Click the “Setup a new application” link in the gray box in the upper right of the developer application homepage

Fillout the application name and submit

Now you are on the edit application settings interface.

Click the “Canvas” tab on the left and change the following:

  • “Canvas Page Url” enter the url you want your application to be displayed under on facebook. I used “iframexample”.
  • Under “Canvas Callback URL”, enter the URL of the applications “homepage” on your server. I used “www.keywordintellect.com/facebook/iframeexample/”.
  • Under “Canvas Settings” click “IFrame”.

Click the “connect” tab on the same settings interface. In the “Connect URL” field enter your Canvas URL (http://www.keywordintellect.com/facebook/iframeexample/ in my case)

Save your settings

Setup your canvas page:

Create a file named “index.php” and put it in the root directory on your webserver for the application “www.keywordintellect.com/facebook/iframeexample/” in my case.

Call the Facebook libraries and authenticate. Note: Replace the app key and secret with the values displayed on your applications settings page withing Facebook. Note: that since I have many aps running, I separated out the Facebook Libraries in a separate directory up one level from my application roots

<?

//Link in library. Note my directory structure may be different
require_once '../fblibrary/facebook.php';

//Authentication Keys
$appapikey = 'REPLACE WITH YOUR KEY';
$appsecret = 'REPLACE WITH YOUR SECRET';

//Construct the class
$facebook = new Facebook($appapikey, $appsecret);

//Require login
$user_id = $facebook->require_login();
?>

Let’s also add in a basic XFBML call to the fb:name tag as well as an API call to get the UIDs of the logged in users friends

<?

// XFBML: Greet the currently logged-in user!
echo "<p>Hello, <fb:name uid=\"$user_id\" useyou=\"false\" ></fb:name>!</p>";

// API: Print out at most 25 of the logged-in user's friends, using the friends.get API method
echo "<p>Friends:";
$friends = $facebook->api_client->friends_get();
$friends = array_slice($friends, 0, 25);
foreach ($friends as $friend) {
  echo "<br>$friend";
}
echo "</p>";

?>

Now, if we were to stop here and run it, the API call would work, but the XFBML would not. We need to set up the page to handle the XFBML. The XFBML documentation is here: http://wiki.developers.facebook.com/index.php/XFBML.

First, you need to create a Cross Domain Communication Channel File. Follow these instructions: http://wiki.developers.facebook.com/index.php/Cross-domain_communication_channel

When that file is created, we then add the following code before and after the PHP XFBML. Note, you need to add your API key and change the path to the Cross Domain Channel File in the last line.

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
</head>
<body>
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>

<? //Insert the PHP XFBML and API PHP code above here ?>

<script type="text/javascript">
	FB.init("YOUR API KEY HERE", "../fblibrary/xd_receiver.htm"); });
</script>

</body>
</html>

Congrats, you are done!

Here is the full index.php file:

<?php
//Link in library. Note my directory structure may be different
require_once '../fblibrary/facebook.php';

//Authentication Keys
$appapikey = 'YOURAPIKEY';
$appsecret = 'YOURAPISECRET';

//Construct the class
$facebook = new Facebook($appapikey, $appsecret);

//Require login
$user_id = $facebook->require_login();
?>

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
	<head>
	</head>
	<body>
		<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>

		<?
			// Greet the currently logged-in user!
			echo "<p>Hello, <fb:name uid=\"$user_id\" useyou=\"false\"></fb:name>!</p>";

			// Print out at most 25 of the logged-in user's friends, using the friends.get API method
			echo "<p>Friends:";
			$friends = $facebook->api_client->friends_get();
			$friends = array_slice($friends, 0, 25);
			foreach ($friends as $friend) {
			  echo "<br>$friend";
			}
			echo "</p>";
		?>

		<script type="text/javascript">
			FB.init("YOURAPIKEY", "../fblibrary/xd_receiver.htm");
		</script> 

	</body>
</html>
9 Jun, 2009  |  Written by Jon  |  under Facebook Development

Facebook has a great tool to debug API requests that is a bit tough to find / under documented. If you add the php code…

$GLOBALS['facebook_config']['debug']=true;

at the top of your page, and then make an api call to users->getinfo for example, then the debug tool outputs the following on your HTML page (inline, in a neat Ajax click to see details type box):

Params:

Array
(
    [uids] => 780432493
    [fields] => uid,first_name,last_name,name,locale,pic_square,profile_url
)

XML:

<?xml version="1.0" encoding="UTF-8"?>
<users_getInfo_response>
  <user>
    <uid>780432493</uid>
    <uid>780432493</uid>
    <first_name>Jon</first_name>
    <last_name>Pastor</last_name>
    <name>Jon Pastor</name>
    <locale>en_US</locale>
    <pic_square>http://profile.ak.facebook.com/v224/904/100/q780432493_3916.jpg</pic_square>
    <profile_url>http://www.facebook.com/profile.php?id=780432493</profile_url>
  </user>
</users_getInfo_response>

SXML:

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [list] => true
        )

    [user] => SimpleXMLElement Object
        (
            [uid] => Array
                (
                    [0] => 780432493
                    [1] => 780432493
                )

            [first_name] => Jon
            [last_name] => Pastor
            [name] => Jon Pastor
            [locale] => en_US
            [pic_square] => http://profile.ak.facebook.com/v224/904/100/q780432493_3916.jpg
            [profile_url] => http://www.facebook.com/profile.php?id=780432493
        )

)

PHP:

Array
(
    [0] => Array
        (
            [uid] => 780432493
            [first_name] => Jon
            [last_name] => Pastor
            [name] => Jon Pastor
            [locale] => en_US
            [pic_square] => http://profile.ak.facebook.com/v224/904/100/q780432493_3916.jpg
            [profile_url] => http://www.facebook.com/profile.php?id=780432493
        )

)

Very helpful for debugging to say the least!

$facebook->require_login() has some gotcha behaviors in iframes that are worth mentioning. Hopefully I will save you some time. Over the course of ripping my hair out, I observed one or more of the following on pages with $facebook->require_login() :

  • Facebook generating a new “auth_token” in the url query string each time I requested a page
  • Pages, other than the canvas page, “breaking out” of the Facebook frame
  • Ajax requests that were returing nothing due to a page redirect

All of the above are due to Facebook not being able to maintain authentication across page requests if the page is simply linked to from inside the iframe. Facebook essentially has to re-direct back after generating new authentication credentials.  If you open up your iframe on the canvas page in a new window, you will see the following Get variables in the URL (an example from my page):

fb_sig_in_iframe: 1
fb_sig_locale: en_US
fb_sig_in_new_facebook: 1
fb_sig_time: 1244518218.1479
fb_sig_added: 1
fb_sig_profile_update_time: 1241618728
fb_sig_expires: 1244606400
fb_sig_user: 780432493
fb_sig_session_key: 2.hvRa_GKzi347TYchGAyWXA__.86400.1244606400-780432493
fb_sig_ss: QGgImUePCmQg5dBx_Mm07A__
fb_sig_ext_perms: auto_publish_recent_activity
fb_sig_api_key: 9c74c62f8c7ed2d5fef13719d0256dcb
fb_sig_app_id: 125523728288
fb_sig: 6350aff72d9b7bd40672a8552047b746

These variables in the URL are critical to maintaining authentication across iframe pages. If you reform this query string and append it to your URLs or Ajax requests, then they will be authenticated and all the above errors will go away. Here is som PHP code to do that:

<?
//build the authentication query string

foreach($_GET as $key => $value) {
	if (strpos($key,"fb_sig")!==false) {
		if ($i!=0) $fbvars.= "&";
		$fbvars.= "$key=$value";
		$i++;
	}
}

//then to link, just use $fbvars to add on to the query string of any link

?>
8 Jun, 2009  |  Written by Jon  |  under Facebook Development

I have been vexed over the past week in trying to develop an i-frame based Facebook application with the lack of resources available to answer some simple questions, fix errors, etc. So I will focus my first posts there. You can follow the category/tag for more updates.

8 Jun, 2009  |  Written by Jon  |  under About

Welcome!

In leading a variety of online businesses over the years, I have come to depend on a myriad of blogs and other resources to challenge my thinking. In an effort to give back, I have started this site. I plan to focus a third on programming, a third on SEO and marketing and a third on strategy/funding/vc. At least that is the intent….we’ll see where we get.

My goal is to blog about something only if the first page of Google search results doesn’t quite do the topic justice…so lots of topics will be skipped. But hopefully my time will be well spent giving back vs. duplicating.

Thanks for reading!
Jon