I’m working on a project where a user wanted to be able to add events to their fan pages on Facebook as well as their personal web page. Since it was an uphill battle to get any useful information on doing this, I thought I’d share a step by step tutorial of how to accomplish this, starting from square one.
Square One: Setting up your App
- Log in to Facebook.
- Go to http://developers.facebook.com/setup/ to set up your app.

- You should now see your app’s information, but just for good measure, go to facebook.com/developers to get to more of your app’s information. You will have to allow the developers app permission. This will be where to go to configure your app’s information or look at stats for it at any later point in time.

Square Two: Create a web page
- Mine is called “addEvent.cfm”
- Add a pointer to your jQuery.js file, wherever that is. Your life will be easier if you embrace jQuery. Statement of fact.
Square Three: Start hooking Facebook in to your site
If you are developing in IE, STOP IT! Download Firefox and bask in its glory. If you don’t already have it installed, be sure to install Firebug extension for Firefox & activate it immediately. It will come in handy for debugging the AJAX you haven’t written yet, as well as any other problem you will ever have.
We’re going to add a login with Facebook button to the page. Luckily, if you can find it, Facebook has you covered. Just copy and paste in as they instruct (remember, you will need the app ID you just created at square 1), load up your page, and viola! you have a login button!
The beauty of the facebook single sign on is that it will go ahead and set a cookie for your site. You can do a dump of the cookie scope and you will see a lovely cookie with a bunch of jibberish, entitled fbs_(your app id).
<cfdump var="#cookie#">
<cfoutput>#cookie.fbs_(your appID)#</cfoutput>
Since this cookie really IS a bunch of gibberish (meaningful, but still gibberish), I decided to create a .cfm file that wrote more useful cookies if a user successfully signed on. Inside of the single sign-on code, we will place an AJAX request that fires to a separate coldfusion page that will write the cookies. There is probably a way to do this without using CF at all, but I didn’t look it up.
FB.init({appId: 'your app id', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.sessionChange', function(response){
if(response.session){
accessKey = response.session.access_token;
fbUid = response.session.uid;
$(document).fillPageOpts();//get the access key and fill in the pages we could post to
$.ajax({//set cookies
url: "setCookies.cfm",
data: {
accessKey: response.session.access_token,
fbUid: response.session.uid,
},
type: "post",
dataType: "json"
});//end ajax
}
else{// The user has logged out, and the cookie has been cleared
$('##error').show();
}
});
And here is our page that assigns the cookies:
<cfoutput>
<cfset frmLen = listLen(form.fieldnames)>
{<cfif structKeyExists(form, "accessKey")>
<cfloop from="1" to="#frmLen#" index="i">
<cfcookie name="#lcase(listGetAt(form.fieldnames, i))#" value="#form[listGetAt(form.fieldnames, i)]#" expires="never">
#lcase(listGetAt(form.fieldnames, i))# : #form[listGetAt(form.fieldnames, i)]#
</cfloop>
</cfif>}
</cfoutput>
You can see it’s very simple, and will return a JSON response.
Because the user could already be signed in, add this to the addEvent page in your script at the top to default to the cookie values:
<cfif structKeyExists(cookie, "accessKey")><!---do we already have a cookie? if so, set our vars accordingly--->
accessKey = '#cookie.accessKey#';
fbUid = '#cookie.fbUid#';
</cfif>
Square Four: Create a form
According to the Facebook Graph API Events Documentation, you will need to send the event’s title, start_time, end_time & access_token in to create a new event. Ok. So let’s make a form that has those in it. I have added a couple of optional parameters to my form as well. you will also notice I have added an “_fb” to the end of each form name. More on this momentarily.
<form name="addEvent" id="addEvent" class="hide" action="##" method="post">
<label for="name">Event Name:</label> <input type="text" name="name_fb" id="eventName" /><br />
<label for="start_time">Start Time:</label> <input type="text" name="start_time_fb" /><br />
<label for="end_time">End Time:</label> <input type="text" name="end_time_fb" /><br />
<label for="location">Location:</label> <input type="text" name="location_fb" /><br />
<label for="venue">Venue:</label> <input type="text" name="venue_fb" /><br />
<label for="privacy">Privacy:</label>
<select name="privacy_fb">
<option value="OPEN">Open</option>
<option value="CLOSED">Closed</option>
<option value="SECRET">Secret</option>
</select><br />
<label for="access_token_fb">Page:</label>
<select name="access_token_fb" id="accessKey">
</select><br />
<input type="button" value="Create Event" id="sendEvent" />
</form>
Excellent. However, all of this is completely useless as it is currently because we are missing a key ingredient: the access_token — and not the access_token for the USER, the access token for the PAGE. This brings us to…
Square Five: Obtaining the page access token & selecting which page to add an event for
This is a very important step, because without it, you will be posting events to YOUR profile, not your PAGE’s profile. First, you will need to have your app request permission to manage pages (not events, like you would think). Luckily, this is stupidly easy. Just add this attribute to your fb:login button, as depicted below:
<fb:login-button perms="manage_pages"></fb:login-button>
Now, when a user logs in using your login button, they will have to allow permission to use your app. This will also give you the right to manage pages on their behalf. Let’s get into that now. First, we need to see what pages the user admins, so we will fire off this AJAX request (note: i made this into a jQuery plugin as it is needed at 2 places on my page):
(function($){
$.fn.fillPageOpts = function(){
$.ajax({//what pages does the user admin?
url: "https://graph.facebook.com/" + fbUid + "/accounts?access_token=" + accessKey,
type: "get",
dataType: "jsonp",
success: function(d, t, x){//loop through each page and add it to the dropdown list
$.each(d.data, function(id, val){
$('##accessKey').append('<option value=\"' + val.access_token + '\">' + val.name + '(' + val.category + ')</option>');
});
}
});//end ajax
$('##addEvent').fadeIn(200);//show the form
}
})(jQuery);
This returns a list of all pages the user can admin, and will give you a list of all of the PAGE’s Access Tokens so you can add events on the page’s behalf, not the user’s. I’m looping through all of the items returned and feeding them in to the form created at Square Four.
Square Six: Adding a handler
At this point, you think you’re locked and loaded, just shoot the form over to FB via AJAX, and you’re set. False. AJAX didn’t remote over so well for me, so I had to create a cfhttp request do do the work for me. I stuck this in a .cfm, although it would probably be better suited for a function in a .cfc. Here is the code:
<cfoutput>
<cfset frmLen = listLen(form.fieldnames)>
<cfhttp method="Post" url="https://graph.facebook.com/events">
<cfloop from="1" to="#frmLen#" index="i">
<cfhttpparam type="formfield" name="#lcase(left(listGetAt(form.fieldnames, i), len(listGetAt(form.fieldnames, i)) -3))#" value="#form[listGetAt(form.fieldnames, i)]#">
</cfloop>
</cfhttp>
#cfhttp.filecontent#
</cfoutput>
The nice thing here is that you will get back a JSON response from facebook that you can use to display a link or whatever to your newly created event. Here’s the jquery to fire this request & handle the return:
$(document).ready(function(){
$('##sendEvent').click(function(){//send the event to FB to get added.
$('##error').hide();
$.ajax({
url: "postToFb.cfm",
type: "post",
dataType: "json",
data: $('##addEvent').serializeArray(),
success: function(d, t, x){
$('##eventsAdded').prepend('<li><a href=\"http://www.facebook.com/event.php?eid=' + d.id +'\&index=1" target=\"_blank\">' + $('##eventName').val() + '</a></li>')
.fadeIn(200);
},
error: function(x, t, e){
$('##error').show();
}
});//end ajax
});
});
Square Seven: Finishing touches
Since we modularized the event sender, we need to go back and call it on page load if the user is already logged in, add to the code you already have:
<cfif structKeyExists(cookie, "accessKey")><!---do we already have a cookie? if so, set our vars accordingly--->
accessKey = '#cookie.accessKey#';
fbUid = '#cookie.fbUid#';
$(document).fillPageOpts();//get the access key and fill in the pages we could post to
</cfif>
Now, I like a little css to make things prettier and easier to use:
<style type="text/css">
.hide{
display: none;
}
.error{
color: #F00;
font-weight: bold;
}
.right{
float: right;
}
#addEventWrapper{
width: 600px
}
#addEventWrapper{
width: 600px
}
#addEvent label{
display: inline-block;
text-align: right;
width: 125px;
}
</style>
And there you have it. Hopefully this will help someone out there!
Let’s look at the complete page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Add a Facebook Event</title>
<style type="text/css">
.hide{
display: none;
}
.error{
color: #F00;
font-weight: bold;
}
.right{
float: right;
}
#addEventWrapper{
width: 600px
}
#addEventWrapper{
width: 600px
}
#addEvent label{
display: inline-block;
text-align: right;
width: 125px;
}
</style>
</head>
<script type="text/javascript" src="http://www.triadwebcrafters.com/lib/js/jQuery.js"></script></head>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<body>
<cfoutput>
<div id="addEventWrapper">
<ul id="eventsAdded" class="right hide"></ul>
<div id="fb-root"></div>
<fb:login-button perms="manage_pages"></fb:login-button>
<div id="error" class="error hide">Error Occurred</div>
<form name="addEvent" id="addEvent" class="hide" action="##" method="post">
<label for="name">Event Name:</label> <input type="text" name="name_fb" id="eventName" /><br />
<label for="start_time">Start Time:</label> <input type="text" name="start_time_fb" /><br />
<label for="end_time">End Time:</label> <input type="text" name="end_time_fb" /><br />
<label for="location">Location:</label> <input type="text" name="location_fb" /><br />
<label for="venue">Venue:</label> <input type="text" name="venue_fb" /><br />
<label for="privacy">Privacy:</label>
<select name="privacy_fb">
<option value="OPEN">Open</option>
<option value="CLOSED">Closed</option>
<option value="SECRET">Secret</option>
</select><br />
<label for="access_token_fb">Page:</label>
<select name="access_token_fb" id="accessKey">
</select><br />
<input type="button" value="Create Event" id="sendEvent" />
</form>
</div>
<script>
var accessKey = '', fbUid = '', pageAccessKey = '';
(function($){
$.fn.fillPageOpts = function(){
$.ajax({//what pages does the user admin?
url: "https://graph.facebook.com/" + fbUid + "/accounts?access_token=" + accessKey,
type: "get",
dataType: "jsonp",
success: function(d, t, x){//loop through each page and add it to the dropdown list
$.each(d.data, function(id, val){
$('##accessKey').append('<option value=\"' + val.access_token + '\">' + val.name + '(' + val.category + ')</option>');
});
}
});//end ajax
$('##addEvent').fadeIn(200);//show the form
}
})(jQuery);
<cfif structKeyExists(cookie, "accessKey")><!---do we already have a cookie? if so, set our vars accordingly--->
accessKey = '#cookie.accessKey#';
fbUid = '#cookie.fbUid#';
$(document).fillPageOpts();//get the access key and fill in the pages we could post to
</cfif>
FB.init({appId: '(your app id)', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.sessionChange', function(response){
if(response.session){
accessKey = response.session.access_token;
fbUid = response.session.uid;
$(document).fillPageOpts();//get the access key and fill in the pages we could post to
$.ajax({//set cookies
url: "setCookies.cfm",
data: {
accessKey: response.session.access_token,
fbUid: response.session.uid,
},
type: "post",
dataType: "json"
});//end ajax
}
else{// The user has logged out, and the cookie has been cleared
$('##error').show();
}
});
$(document).ready(function(){
$('##sendEvent').click(function(){//send the event to FB to get added.
$('##error').hide();
$.ajax({
url: "postToFb.cfm",
type: "post",
dataType: "json",
data: $('##addEvent').serializeArray(),
success: function(d, t, x){
$('##eventsAdded').prepend('<li><a href=\"http://www.facebook.com/event.php?eid=' + d.id +'\&index=1" target=\"_blank\">' + $('##eventName').val() + '</a></li>')
.fadeIn(200);
},
error: function(x, t, e){
$('##error').show();
}
});//end ajax
});
});
</script>
</cfoutput>
</body>
</html>