Introduction
In a previous
article I provided a set of utility functions for connecting your website to Facebook using the Facebook for
Websites API. This article builds and improves upon
the original app and adds some examples of how we can leverage Facebook's Graph API to provide deeper interaction with Facebook.
Background
This article will build on the same code from the previous article that has been refactored into a class object.
What is the Graph API?
The Graph API is Facebook's way of enabling automation of most UI functions based on a REST-ful interface.
The Graph API makes a request to Facebook at a URL that looks like this: http://graph.facebook.com/ID. The ID is the ID of the Facebook object you are working on.
Every object in Facebook has an ID as required by REST. You can find the full set of documentation
here: http://developers.facebook.com/docs/reference/api/.
Using the code
Before you use the code, you must create a Facebook Application and have an application ID and secret code. See the first article for details.
In this article, I'll provide the base patterns for working with Facebook data. The code will implement a consistent way of returning data from Facebook
so when you access user.hometown (for example), it will always return a value or blank. It will not produce an error if the data is not returned by Facebook.
Each function in the new design includes test pages that help verify the function works.
Refactoring the original code
Let's review how the current code differs from the previous article. The main change is that all but a few functions are encapsulated in a class
library named fb_utility. The code block below shows the class structure for fb_utility.
class fb_utility
dim dictKey
dim dictItem
sub Class_Initialize()
dictKey = 1
dictItem = 2
end sub
public function get_page_contents(strURL)
end function
public function post_page(strURL, strData)
end function
public Function NewID()
End Function
public function ksort(byref objDict )
SortDictionary objDict, dictKey
end function
Function SortDictionary(byref objDict, intSort)
End Function
public function parse_access_token( str )
end function
public function parse_expires( str )
end function
end class
This utility class is re-used by just about every other class and function in the Graph API and initial authorization functions.
The basic request pattern
For the most part, every Graph API request does some basic things: make a call to
fb_utility.get_page_contents
which returns a JSON string which
is then converted to a JSON object for reference. The problem with data returned from Facebook is that if a value is blank or null, the property is not returned.
For example: user.hometown might not be populated by the user you are requesting, as a result the JSON string returned by Facebook will not contain a hometown value.
When the JSON string is converted to an object it will not have a hometown property. As a result, attempting to access user.hometown will trigger a VBScript error.
I call it the "sparse data problem".
To solve the sparse data problem, I include a code block in each class that maps from JSON to a VBScript class to provide a reliable interface for each data object.
Below you will find a pattern for a Facebook Data Type Object implemented in a VBScript class. A call to
Load
and passing the Facebook Object ID will get
the JSON string and a call to load_from_json_object
will perform the mapping.
class fb_DTO
dim fbu
dim m_token
dim m_json_str
dim m_graph_url
public property get graph_url()
graph_url = m_graph_url
end property
public property get json_string()
json_string = m_json_str
end property
public property get token()
token = m_token
end property
public property let token(value)
m_token = value
end property
sub Class_Initialize
set fbu = new fb_utility
end sub
sub Class_Terminate
set fbu = nothing
end sub
public sub Load(ID)
dim obj
m_graph_url = "https://graph.facebook.com/" & id & _
"?access_token=" & m_token
m_json_str = fbu.get_page_contents( m_graph_url )
set obj = JSON.parse( m_json_str )
load_from_json_object obj
end sub
public sub load_from_json_object( fb_obj )
on error resume next
on error goto 0
err.clear
end sub
end class
A real world example - Facebook User Object
The next code block builds on the pattern examples and implements a Facebook user object.
class facebook_user
dim m_id
dim m_name
dim m_first_name
dim m_middle_name
dim m_last_name
dim m_gender
dim m_locale
dim m_languages
dim m_link
dim m_username
dim m_third_party_id
dim m_timezone
dim m_updated_time
dim m_verified
dim m_bio
dim m_birthday
dim m_education
dim m_email
dim m_hometown
dim m_interested_in
dim m_location
dim m_political
dim m_favorite_athletes
dim m_favorite_teams
dim m_quotes
dim m_relationship_status
dim m_religion
dim m_significant_other
dim m_video_upload_limits
dim m_website
dim m_token
dim m_json_str
dim m_graph_url
dim fbu
sub Class_Initialize()
m_id = ""
m_name = ""
m_first_name = ""
m_middle_name = ""
m_last_name = ""
m_gender = ""
m_locale = ""
m_languages = ""
m_link = ""
m_username = ""
m_third_party_id = ""
m_timezone = ""
m_updated_time = ""
m_verified = ""
m_bio = ""
m_birthday = ""
m_education = ""
m_email = ""
m_hometown = ""
m_interested_in = ""
m_location = ""
m_political = ""
m_quotes = ""
m_relationship_status = ""
m_religion = ""
m_significant_other = ""
m_video_upload_limits = ""
m_website = ""
set fbu = new fb_utility
end sub
public property get graph_url()
graph_url = m_graph_url
end property
public property get json_string()
json_string = m_json_str
end property
public property get token()
token = m_token
end property
public property let token(value)
m_token = value
end property
public property get id()
id = m_id
end property
public property let id(value)
m_id = value
end property
public property get name()
name = m_name
end property
public property let name(value)
m_name = value
end property
public property get first_name()
first_name = m_first_name
end property
public property let first_name(value)
m_first_name = value
end property
public property get middle_name()
middle_name = m_middle_name
end property
public property let middle_name(value)
m_middle_name = value
end property
public property get last_name()
last_name = m_last_name
end property
public property let last_name(value)
m_last_name = value
end property
public property get gender()
gender = m_gender
end property
public property let gender(value)
m_gender = value
end property
public property get locale()
locale = m_locale
end property
public property let locale(value)
m_locale = value
end property
public property get languages()
languages = m_languages
end property
public property let languages(value)
m_languages = value
end property
public property get link()
link = m_link
end property
public property let link(value)
m_link = value
end property
public property get username()
username = m_username
end property
public property let username(value)
m_username = value
end property
public property get third_party_id()
third_party_id = m_third_party_id
end property
public property let third_party_id(value)
m_third_party_id = value
end property
public property get timezone()
timezone = m_timezone
end property
public property let timezone(value)
m_timezone = value
end property
public property get updated_time()
updated_time = m_updated_time
end property
public property let updated_time(value)
m_updated_time = value
end property
public property get verified()
verified = m_verified
end property
public property let verified(value)
m_verified = value
end property
public property get bio()
bio = m_bio
end property
public property let bio(value)
m_bio = value
end property
public property get birthday()
birthday = m_birthday
end property
public property let birthday(value)
m_birthday = value
end property
public property get education()
education = m_education
end property
public property let education(value)
m_education = value
end property
public property get email()
email = m_email
end property
public property let email(value)
m_email = value
end property
public property get hometown()
hometown = m_hometown
end property
public property let hometown(value)
m_hometown = value
end property
public property get interested_in()
interested_in = m_interested_in
end property
public property let interested_in(value)
m_interested_in = value
end property
public property get location()
location = m_location
end property
public property let location(value)
m_location = value
end property
public property get political()
political = m_political
end property
public property let political(value)
m_political = value
end property
public property get quotes()
quotes = m_quotes
end property
public property let quotes(value)
m_quotes = value
end property
public property get relationship_status()
relationship_status = m_relationship_status
end property
public property let relationship_status(value)
m_relationship_status = value
end property
public property get religion()
religion = m_religion
end property
public property let religion(value)
m_religion = value
end property
public property get significant_other()
significant_other = m_significant_other
end property
public property let significant_other(value)
m_significant_other = value
end property
public property get video_upload_limits()
video_upload_limits = m_video_upload_limits
end property
public property let video_upload_limits(value)
m_video_upload_limits = value
end property
public property get website()
website = m_website
end property
public property let website(value)
m_website = value
end property
public sub LoadMe()
dim strFields
dim obj
m_graph_url = "https://graph.facebook.com/me?access_token=" & _
m_token
m_json_str = fbu.get_page_contents( m_graph_url )
set obj = JSON.parse( m_json_str )
load_from_json_user obj
end sub
public sub Load(ID)
dim strFields
dim obj
m_graph_url = "https://graph.facebook.com/" & _
ID & "?access_token=" & _
m_token
m_json_str = fbu.get_page_contents( m_graph_url )
set obj = JSON.parse( m_json_str )
load_from_json_user obj
end sub
public sub load_from_json_user(fb_obj)
on error resume next
m_id = fb_obj.id
m_name = fb_obj.name
m_first_name = fb_obj.first_name
m_middle_name = fb_obj.middle_name
m_last_name = fb_obj.last_name
m_gender = fb_obj.gender
m_locale = fb_obj.locale
m_languages = fb_obj.languages
m_link = fb_obj.link
m_username = fb_obj.username
m_third_party_id = fb_obj.third_party_id
m_timezone = fb_obj.timezone
m_updated_time = fb_obj.updated_time
m_verified = fb_obj.verified
m_bio = fb_obj.bio
m_birthday = fb_obj.birthday
m_education = fb_obj.education
m_email = fb_obj.email
m_hometown = fb_obj.hometown.name
m_interested_in = fb_obj.interested_in
m_location = fb_obj.location.name
m_political = fb_obj.political
m_quotes = fb_obj.quotes
m_relationship_status = fb_obj.relationship_status
m_religion = fb_obj.religion
m_significant_other = fb_obj.significant_other
m_video_upload_limits = fb_obj.video_upload_limits
m_website = fb_obj.website
on error goto 0
err.clear
end sub
end class
Pulling them all together with the fb_graph_api object
To keep code that uses this library uncluttered, the fb_graph_api
class implements a function that returns a ready made object.
What's in the current library?
I provided everything I'm working on as of this writing, however only some functions are ready for your consumption. The other examples are in alpha mode;
use at your own risk. Here are the working objects and associated graph_api "shortcuts":
Facebook Object Name | Class Name | Graph API Function | Test Page |
User | fb_user | get_user | user_test.asp |
Friends (a list of user objects) | fb_friends | get_friends | friends_test.asp |
Friend | fb_user | get_friend | friend_test.asp |
Album (Photo Album) | fb_album | get_album | album_test.asp |
Photo | fb_photo | get_photo | album_test.asp |
Comment | fb_comment | none, called by other objects. | none |
Like | fb_like | none, called by other objects. Note: this is a like object not a like method. I don't have that working yet. | none |
Graph API Methods
Presently only the post_to_wall
method is implemented.
The test page for wall post is post_wall_test.asp. Presently you can only post to the currently logged-in user's wall.
The post to wall takes the following parameters:
Parameter Name | Description |
Message | The message that you want to display on the wall |
Picture | The URL of a picture to display with the wall post |
Link | The URL that is the target of the link |
Name | The name to display on the link |
Caption | The link caption |
Description | A longer text describing the link |
Points of interest
The DTO classes can be stored in the session because they make use of only VBScript variants and there are no objects (like
scripting.dictionary
) that raise threading model issues.
Conclusion
While the example here does not support the full Graph API, I think you'll be able to wade through any other API data by referencing the examples here.
If you implement another module, post it here and I'll be sure to included it in a new release. I'll release a new version every third month of the year
for the next year. Your feedback, advice, and votes are always appreciated.
History