After digging in one recent evening to figure out how to build a Facebook Canvas application using NetCommunity, it became clear to me that we needed a way to write REST based custom code in BBNC. One NetCommunity 5.5 patch later and now we can and so can you!
 
Introducing Custom Handlers to the NetCommunity API, enabling full control over the request/response model of a NetCommunity web site.

Add to this the ability to access any Blackbaud API (e.g. RE, BBEC, FE, EE and BBNC)  from a custom handler and watch the Faces turn...  

Here's the idea

You want to write a Facebook Canvas application that a Facebook user can add to their Facebook profile that surfaces content in Facebook that comes from your NetCommunity site.  Examples of content might be your headlines, annual campaign progress, event calendars, photos, or maybe a poll. Because it comes from NetCommunity the content could actually originate from any Blackbaud product accessible to NetCommunity such as current volunteer opportunities from The Raiser's Edge, or a teacher's assignments from The Education Edge.   Another one of those "the possibilities are endless" concepts.
 
If you've dug into using the Facebook API you've probably come to realize that there are two basic approaches to integrating with Facebook:
  1. Accessing Facebook data from your external application - this is what the new NetCommunity v5.5 Social Networking components do, allowing a NetCommunity user to access her Facebook stuff like Friends and Photos, from within the Social Networking parts of a NetCommunity site.
  2. Running a Facebook Canvas application inside of Facebook -this is a hole different donut. This is an application that sits within Facebook that a user can add to his or her Facebook Profile. Hundreds of Facebook Canvas applications, just called Applications in Facebook, have been written and published to the Facebook Application Directory. Whether you want to track your golf scores or throw an octopus at someone, its all there.  This is the kind of Facebook integration we're going to talk about and how I'm going to demonstrate writing REST based custom request handlers with the NetCommunity Platform API.

Facebook Application Development and FBML

I'm not going to rehash the Facebook API documentation here but you'll need to understand the basics before anything else I'm about to say will make any sense.  So I'll try and explain it in a nutshell.
 
<nutshell>
 
Facebook applications are rendered in Facebook pages by using a special version of HTML called FBML. FBML incorporates most of the standard HTML tags and adds a bunch of its own. The Facebook specific tags are used to define Facebook data and UI elements such as the current user's name <fb:name> or a textbox for selecting from your list of friends <fb:friend-selector>.
 
As a Facebook Application developer, your job is to provide the FBML for your application to Facebook. The code to generate your FBML must sit on your server. Repeat: the code to generate your application's FBML must sit on your server. When you have an application that you want added to Facebook, you must install it on Facebook, which essentially means you are telling Facebook where on your server it can get your FBML from. You do this by giving Facebook a URL (from your server) that when called, coughs up valid FBML. Once you've installed the application on Facebook and published it to the Facebook Application Directory, Facebook users can find it and add it to their profile.
 
</nutshell>
 
Remember, the goal is to use my NetCommunity site to cough up my FBML. Since I can write custom code on my NetCommunity site that can access NetCommnunity and maybe some Raiser's Edge data this seems like a good plan if I want to show some relevant info in real time.
 
But there's one small problem. 
 
Facebook wants FBML and FBML has a certain syntax that prohibits certain HTML tags like <head> or <body>. So I can't just write a NetCommunity Custom Part that spits out FBML and put it on a NetCommunity page and give that URL to Facebook, because a NetCommunity page contains all kinds of HTML tags not acceptable as FBML.
 
I also can't pull this off using a NetCommunity Custom Web Method since, while those have access to all the RE data I want, they also don't return valid FBML, since they're .Net Web Service methods that return a SOAP-like kind of XML.
 
So, what I need is a way to write custom code on my NetCommunity server that can be called when a request for a given URL comes in to my server. This custom code must be able to answer the request with its own custom response. A response whose content it has complete control over, content that in this case is valid FBML only, not a web page and not a web service.
 
One NetCommunity 5.5 patch later and we're in business:  Introducing Custom Handlers to the NetCommunity Open Platform.
 
Custom Handlers are classes that you can write that get their own unique NetCommunity URL that they can respond to, fulfilling my lifelong dream to add REST support to NetCommunity.

Getting a little REST

The web is built on the concept of REST (Representational State Transfer) and REST is not limited to the web. Without getting too far into the weeds or getting too philosophical, in its very basic terms, and as far as its application to the web is concerned, REST is the model of making a web request and getting an appropriate response. REST keeps it simple. It defines the underlying concept that by just specifying a URL I can get a response that is appropriate for my task. For example:
  • Your web browser uses REST to request and retrieve an HTML page from a Web Server URL
  • The Raiser's Edge windows application uses REST to request a Donation Data Object from a NetCommunity Web Service URL
  • Facebook uses REST to request FBML from my custom handler URL.
While these three examples depict request and responses of different data formats they share the common concept. In the first two examples, additional technologies are stacked on top of REST to enhance the experience, for the tools, the developer, and the end user. For example web servers and browsers pile HTML on top so, each end of the conversation knows what to expect in the request/response conversation. Web Services pile SOAP and XML on top to provide for transferring strongly typed data elements, eliminating bugs for the programmer and improving programming efficiency, and so on.
 
But the third example is much simpler. No additional technology or methodology is added to the mix. Just a request to a URL and some plain text (that just happens to be FBML is the response). When you hear the term RESTful API flying around the blogoshere these days it most commonly refers to this simplest form, where advanced technologies are not piled on. It's also worth noting, that without the added (although usually beneficial) noise of piled on technologies, simple RESTful APIs are very portable across all of the different technologies that make up the web, allowing LINUX systems to talk to Windows systems and iPhones to talk to ATM machines, at their most basic levels.
 
Another point worth mentioning, is that REST does not always mean you are asking for something. You can just as easily be making a request to do something. Something to think about when you consider you have all of the Blackbaud APIs at your disposal...  

Writing a Custom Handler

Ok, so that's enough rest. How do you create a Custom Handler?
 
In keeping with NetCommunity API tradition, you write a class for your handler that inherits from BBNCExtensions.CustomHandlers.CustomHandler. All you need to do is override the ProcessRequest sub, which is handed the asp.net HttpContext for the request. The context contains, among several other useful things, the Request and Response objects. If you've done any ASP.net coding you know what these are.
 
You will use the Request object to inspect the request, looking for query string parameters or posted form fields that your handler may be expecting. You will use the Response object to write out a response.
 
Here's a simple FBML example:
 
    Public Overrides Sub ProcessRequest(ByVal context As System.Web.HttpContext)
 
        'default response
        Dim sResponse As String = "<div>Hello World</div>"
 
        With context.Response
            'spit it out
            .ContentType = "text/plain"
            .Write(sResponse)
        End With
 
    End Sub
 

Calling a Custom Handler

So how do you call this handler? What's its URL?
 
First, you compile your project and deploy it to the \NetCommunity\bin folder of your installation. The URL to your handler will then have this format:
 
 
My project (and its built assembly) is called FacebookSample and this handler class is HelloWorldFbml so I will end up with an assembly called FacebookSample and type HelloWorldFbml so my handler's actual URL will be:
 
 
I've installed this handler on Labs so click it and see what you get. Go on. Try it.
 
If you want to pass parameters to your handler you can just tack them on the end of the URL, like this:
 
 
My handler code can then inspect the Context.Request.QueryString("foo") item to get the value "bar". Standard Asp.net stuff. Consumers of your handler can also POST form elements to your handler, in which case you would look to Context.Request.Form("foo") for that value. Again, common Asp.net stuff. Facebook uses GETs and POSTs to call your URLs, so consult the Facebook API docs for what to expect and when.
 
Cool trick: Don't like that really long ugly URL? NetCommunity 5.5 added a wicked Friendly Url feature. Essentially you can create as many Friendly URLs as you like, mapping them to site pages or explicit full URLs. So in my sample I've created a Friendly URL called:
 
 
that maps to my handler's full url.  Click it. Go on. I know you want to. Friendly Urls have lots of interesting uses, maybe I'll talk about them some more some other time.
  

Something a Little More Useful 

So that's the basic principal. We now have a way to cough up some FBML from some custom code. But wouldn't it be nice to have access to stuff from my custom handler?
 
Enter the API property.
 
Just like custom parts, custom handlers have an API property that gets you access to all the things exposed in the NetCommunity API, so you can easily get to RSS feeds, Documents, Part data, and lots more.  You'll see some of that action in my sample.
 
Also, since you have a reference to BBNCExtensions you can call your Custom Web Methods that you can write for the RE7Service, where you have access to just about everything from the Raiser's and Education Edge. There's also nothing stopping you from banging on other Blackbaud APIs (like the BBEC Infinty platform) while you're in there.

Facebook Sample

Now that you understand the how, lets take a look at a sample facebook application.  As we've seen, we can create code that runs on our NetCommunity server that can respond to a web request by spitting out some FBML. And we know that we can tell Facebook that we have this application that it can find at our custom handler URL.
 
When we setup the Facebook Application in Facebook, we have to provide three very important pieces of info:
  • A Callback URL
  • A Canvas Page URL
  • A Profile Tab URL
The functions of each are not very well documented, but lots of trial and error later and I think I can explain it. In the setup for the application in Facebook you'll see a form like this:
 
 
The Callback URL is a URL on your NetCommunity site that will return the FBML for the application's canvas page.  The canvas page is the home page for your application, seen when someone runs your application on Facebook.  Facebook will call this URL to get your FBML which it then uses to build the Facebook page. In our case, this will be a URL to a Custom Handler on our NetCommunity site that coughs up some FBML.
 
The Canvas Page URL is essentially just a friendly name URL to your callback URL. Anyone entering this URL in a browser will be taken to the Facebook page that shows your application's canvas page (and again, Facebook will use your callback URL to get your FBML)
 
Profile Tab URL is a separate URL, also on your NetCommunity site that coughs up the FBML for what your application will show on its Tab in the Facebook user's profile.  You'll notice that the first part of this URL is the canvas page URL. So how does a URL that start's with apps.Facebook.com equate to something (a custom handler) on your NetCommunity site? 
 
It works like this:
 
When Facebook wants your canvas page, it calls your Canvas page URL (or Callback URL since they are really the same thing)
 
When Facebook is ready to call for your Profile Tab FBML, it builds a real URL by combining your Canvas URL (which is really your Callback URL) with the Profile Tab URL, so if
 
 
then
 
Following this pattern, Facebook will assume all links within your FBML will be relative to the canvas url in this fashion. It took me a long time to figure this out. That's really why I needed some rest.
 
Now here's the cool part. Friendly URLs in NetCommunity 5.5 can be nested like this  (e.g. labs.Blackbaud.com/canvas/profile) so its easy to define URLs to point to our FBML custom handlers that Facebook will be happy with.
 
So, on the NetCommunity side we will create two friendly URLs to point to our two handlers, one for the Canvas page and one for the Canvas/Profile page.
 
The FBML Custom Part
 
Knowing that I need to create some interesting FBML to show as my application, I kicked around some ideas for what might be a cool sample. I wanted something useful but I also wanted to play with FBML a little. I started with a handler that I hard-coded to spit out my Facebook profile name, standard Hello World stuff.
 
It worked.
 
That was cool.
 
Seeing my FBML on Facebook was cool but hard-coding the FBML wasn't. I needed a better way to edit some FBML and see it show up on Facebook without having to continuously recompile the custom handler assembly and deploy it to the Labs server.
 
Enter the FBML Custom Part. This part's job is to provide a place to edit and store some FBML on the NetCommunity Server, that I can access from Facebook via a custom handler. This part's editor simply offers a big text area to edit some FBML, saving the texbox contents to the part's content.  It doesn't render any content if you place it on a NetCommunity page, but that's OK because this content is FBML that we want to render over on Facebook. With a place to edit and store FBML on my NetCommunity server, I now just needed to create a custom handler (GetFBML) that can open one of these FBML parts and spit back the FBML it contains. 
 
One nice new feature of the v5.5 API is the ability to get the content from any custom part using the API and since all custom handlers have access to the API this became trivial with code like this:
 
'locate the FBML part that holds the fbml to return
Dim oPart As FBMLContent
oPart = Me.API.Parts.LoadCustomContentFromPartId( _
CInt(context.Request.QueryString("partid")), GetType(FBMLContent))
If oPart IsNot Nothing Then
    sResponse = oPart.FBML
    ...
 
Take a look at the sample code and see that the FBML custom part stores a FBMLContent object as its content, which has a string property FBML that contains my edited FBML. Since I can create as many FBML parts on my site as I want, my handler supports a Query String parameter called partId that is the id of the FBML part who's FBML I want to get.  So assuming I created an FBML part with partid 616, the URL to call the handler to get its FBML would be:
 
 
Using Friendly URLs in NetCommunity, I created http://labs.Blackbaud.com/netcommunity/canvas and set it equal to this hander. I gave this friendly URL to Facebook as my callbackURL and viola, when Facebook goes to load my canvas page, it calls my handler, which loads and returns to FBML from my custom part whose id is 616. I can now go edit my custom part on NetCommunity, change the FBML, save it, and refresh my Facebook page in my browser and see the change.
 
Wicked.
 
With this pattern working, I created another FBML part instance that contained the FBML for my Profile Tab page which can use the same handler, with a different partid parameter:
 
 
and created this friendly URL for that and set it in Facebook as the Profile Tab URL for my app:
 
 
Copyright Life is GoodLife is good.
 
That's probably good for this installment. In my next post, maybe we can take a deeper dive into some useful examples of using the FBML custom part and associated Custom Handler. Before we go let's do a quick review of what we've covered:
  1. Custom Handlers, new in 5.5 API, these NetCommunity components you can write yourself, live on the NetCommunity server and can handle any custom request and response in any way you desire.
  2. Custom Handlers are built on the simple REST concept
  3. Facebook canvas apps live on your server which must be able to respond to requests for FBML, Facebook's markup language.
  4. You can write NetCommunity custom handlers to spit out FBML
  5. NetCommunity custom code can access NetCommunity, Raiser's Edge, Education Edge, Blackbaud Enterprise, etc. APIs
  6. The FBML custom part gives you a place to write, edit, store, and retrieve FBML on your NetCommunity server.
  7. Put it all together and you can build a Facebook Canvas Application that has access to all things Blackbaud, via NetCommunity.
  8. Maybe next time around I'll show you some cool Blackbaud things I surfaced in Facebook.
 

Appendix

 
This last section contains some more details on using the sample code. 
  

Installing and Using the Sample

 
Here are the basic steps to get up and running:
  1. In NetCommunity
    • Download and build the source code
    • Make sure the BuildEvents script in the solution will copy all the files to the right place on your NetCommunity Server
    • Add the FBML Custom Part type to NetCommunity
    • Create two FBML parts and put some FBML in them. One for the app's canvas and one for its profile tab.
    • Create two Friendly Urls in NetCommunity that point to the custom handler - one for the app's canvas and one for its profile tab. 
  2. In Facebook:
    • Setup the Facebook Sample application using the Developer Application
    • Add the Facebook Sample to your Facebook Profile to see your FBML show up!

Download and Build the Source

The solution files and all the code for this are in the attached download for this article. As usual, just make sure you update the reference to BBNCExtensions to point to yours, and update the Build Events commands (in the Solution's Compile Properties) to deploy the files to your NetCommunity folders. Do that, and the solution should build and deploy no problem.  If you are building on a different machine than your BBNC install and need to deploy the files manually this is what you need to know:
  • The FacebookSample.dll needs to go the the \NetCommunity\Bin folder
  • All the .ascx files will go to \NetCommunity\Custom\FacebookSample (create folder if nec.)

Add the FBML Custom Part to NetCommunity

The sample contains one Custom Part which we'll cover in detail, but you'll need to install it to NetCommunity first. In the Administration/Custom Parts gallery click the New Custom Part and fill out the form like this: