ASP (VBScript)
From Facebook Developers Wiki
Contents |
[edit] Craig Bovis
This is a class I have written for interfacing with FaceBook from Canvas pages. Requires MD5.asp class by Chris Read (http://chris.brimson-read.com.au/?page_id=7)
v1.2 (2007/07/23)
- Added a SendNotificationRequest method for simple calling of the facebook.notifications.sendRequest method.
- Added a Form method. This returns the value of a posted form item by key. If the item was specified as an array in your FBML then a Variant() will be returned otherwise a string will be returned.
- Added a IncludeCSS method. This allows you to easily embed CSS from an external file into your FBML.
- Added a FQLQuery method for executing an FQL statement and retrieving the results.
- Added a SetProfileFBML method for easily setting the profile FBML of a user.
- Added a SetRefHandle method for easily setting the content of an fb:ref by handle.
- Added a RequireInstall method which redirects the user to your install page if they have not installed the app.
- Added a SuccessMessage method which produces a standard FBML success tag with the specified message.
- Added a ErrorMessage method which produces a standard FBML error tag with the specified message.
- Added a Redirect method which writes a standard FBML redirect to the response causing your page to redirect when called.
- Moved the API version into a constant.
- Now using the faster REST server.
v1.1 (2007/06/30)
- Added the ability to quickly reference InCanvas, ApplicationInstalled & UserID variables passed to your canvas page by Facebook
- Change the field lookup to check both GET & POST. Some users have reported that Facebook switches between which one is used.
- API calls now use ServerXMLHTTP and make a POST request
- Data is encoded properly when passed to the API. This fixes problems with passing FBML etc. as parameters.
- The CallID is now based off of a Timestamp (plus an incremented integer since we might make multiple requests per second)
[edit] Facebook.asp
<%
' FaceBook ASP Class v1.2
' Developed by Craig Bovis
'-----------------------------
'
' This class is designed to allow you to interface with facebook applications via a Canvas page
' It provides simple methods for authenticating the canvas request and making calls to the Facebook API
CONST REST_URI = "http://api.facebook.com/bestserver.php"
CONST FB_PARAM_PREFIX = "fb_sig"
CONST FB_API_VERSION = "1.0"
Class FaceBook
Public SecretKey
Public ApiKey
Public SessionKey
' Public properties for accessing information passed across to this callback from Facebook
Public Property Get InCanvas
InCanvas = (Request(FB_PARAM_PREFIX & "_in_canvas") = "1")
End Property
Public Property Get ApplicationInstalled
ApplicationInstalled = (Request(FB_PARAM_PREFIX & "_added") = "1")
End Property
Public Property Get UserID
UserID = Request(FB_PARAM_PREFIX & "_user")
End Property
' This allows you to call a facebook method (e.g. facebook.profile.getFBML) with the specified parameters
' You do not need to pass in the following parameters as they are appended automatically,
' - session_key
' - api_key
' - call_id
' - v
Public Function CallApiMethod(strMethod, oParams)
oParams("method") = strMethod
Dim oXMLHTTP
Set oXMLHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP")
oXMLHTTP.Open "GET", GenerateRequestURI(oParams), False
oXMLHTTP.Send()
Set CallApiMethod = oXMLHTTP.ResponseXml
End Function
Public Sub Redirect(strURI)
%>
<fb:redirect url="<%= strURI %>" />
<%
End Sub
Public Function ErrorMessage(strMsg)
ErrorMessage = "<fb:error message=""" & strMsg & """ />"
End Function
Public Function SuccessMessage(strMsg)
SuccessMessage = "<fb:success message=""" & strMsg & """ />"
End Function
Public Function RequireInstall()
If (Request.Form("fb_sig_added") = "0") Then
%>
<fb:redirect url="http://www.facebook.com/apps/application.php?api_key=<%= ApiKey %>" />
<%
End If
End Function
Public Function SetRefHandle(handle, fbml)
Dim oParams
Set oParams = Server.CreateObject("Scripting.Dictionary")
oParams.Add "handle", handle
oParams.Add "fbml", fbml
Set SetRefHandle = CallApiMethod("facebook.fbml.setRefHandle", oParams)
End Function
Public Function SetProfileFBML(uid, fbml)
Dim oParams
Set oParams = Server.CreateObject("Scripting.Dictionary")
oParams.Add "markup", fbml
If (Not IsNull(uid)) Then oParams.Add "uid", uid
Set SetProfileFBML = CallApiMethod("facebook.profile.setFBML", oParams)
End Function
Function FQLQuery(query)
Dim oParams
Set oParams = Server.CreateObject("Scripting.Dictionary")
oParams.Add "query", query
Set FQLQuery = CallApiMethod("facebook.fql.query", oParams)
End Function
Public Sub IncludeCSS(strPath)
Dim oFSO
Set oFSO = Server.CreateObject("Scripting.FileSystemObject")
If (oFSO.FileExists(Server.MapPath(strPath))) Then
Dim oFile
Set oFile = oFSO.OpenTextFile(Server.MapPath(strPath))
%>
<style type="text/css">
<%= oFile.ReadAll() %>
</style>
<%
Call oFile.Close()
End If
End Sub
' This property returns whether or not the request made to your page was from FaceBook
Public Property Get RequestIsValid
Dim strItem, oRequestParams
Set oRequestParams = Server.CreateObject("Scripting.Dictionary")
For Each strItem In Request.Form
If (Left(strItem, Len(FB_PARAM_PREFIX)) = FB_PARAM_PREFIX And Not strItem = FB_PARAM_PREFIX) Then
oRequestParams(Mid(strItem, Len(FB_PARAM_PREFIX & "_") + 1)) = Request.Form(strItem)
End If
Next
RequestIsValid = (GenerateSig(oRequestParams) = Request.Form("fb_sig"))
End Property
Public Function Form(strKey)
If (Len(Request.Form(strKey)) > 0) Then
Form = Request.Form(strKey)
Else
If (Len(Request.Form(strKey & "[0]")) > 0) Then
Dim arrKey()
Redim arrKey(0)
Do While Len(Request.Form(strKey & "[" & Ubound(arrKey) & "]")) > 0
arrKey(Ubound(arrKey)) = Request.Form(strKey & "[" & Ubound(arrKey) & "]")
Redim Preserve arrKey(Ubound(arrKey) + 1)
Loop
Redim Preserve arrKey(Ubound(arrKey) - 1)
Form = arrKey
End If
End If
End Function
Public Function SendNotificationRequest(to_ids, req_type, content, image, boolInvite)
Dim oParams
Set oParams = Server.CreateObject("Scripting.Dictionary")
oParams.Add "to_ids", to_ids
oParams.Add "type", req_type
oParams.Add "content", content
oParams.Add "image", image
oParams.Add "invite", LCase(boolInvite)
Set SendNotificationRequest = CallApiMethod("facebook.notifications.sendRequest", oParams)
End Function
Private Sub Class_Initialize()
If (Len(Request(FB_PARAM_PREFIX & "_api_key")) > 0) Then ApiKey = Request(FB_PARAM_PREFIX & "_api_key")
If (Len(Request(FB_PARAM_PREFIX & "_session_key")) > 0) Then SessionKey = Request(FB_PARAM_PREFIX & "_session_key")
End Sub
' This generates a facebook REST uri for the passed in parameters
Private Function GenerateRequestURI(oParams)
If (Len(SessionKey) > 0) Then oParams("session_key") = SessionKey
If (Len(ApiKey) > 0) Then oParams("api_key") = ApiKey
If (Len(GetUniqueCallID()) > 0) Then oParams("call_id") = GetUniqueCallID()
oParams("v") = FB_API_VERSION
GenerateRequestURI = REST_URI & "?"
Dim strItem
For Each strItem In oParams.Keys
GenerateRequestURI = GenerateRequestURI & strItem & "=" & Server.UrlEncode(oParams(strItem)) & "&"
Next
GenerateRequestURI = GenerateRequestURI & "sig=" & GenerateSig(oParams)
End Function
' This creates a signature of the supplied parameters
Private Function GenerateSig(oParams)
Set oParams = SortDictionary(oParams)
Dim strSig, strItem
For Each strItem In oParams
strSig = strSig & strItem & "=" & oParams(strItem)
Next
strSig = strSig & SecretKey
Dim oMD5
Set oMD5 = New MD5
oMD5.Text = strSig
GenerateSig = oMD5.HexMD5
End Function
' SortDictionary function courtesy of MSDN
Private Function SortDictionary(objDict)
Dim strDict()
Dim objKey
Dim strKey,strItem
Dim X,Y,Z
Z = objDict.Count
If Z > 1 Then
ReDim strDict(Z,2)
X = 0
For Each objKey In objDict
strDict(X,1) = CStr(objKey)
strDict(X,2) = CStr(objDict(objKey))
X = X + 1
Next
For X = 0 to (Z - 2)
For Y = X to (Z - 1)
If StrComp(strDict(X,1),strDict(Y,1),vbTextCompare) > 0 Then
strKey = strDict(X,1)
strItem = strDict(X,2)
strDict(X,1) = strDict(Y,1)
strDict(X,2) = strDict(Y,2)
strDict(Y,1) = strKey
strDict(Y,2) = strItem
End If
Next
Next
objDict.RemoveAll
For X = 0 to (Z - 1)
objDict.Add strDict(X,1), strDict(X,2)
Next
End If
Set SortDictionary = objDict
End Function
' Returns a unique CallID. Uses an application incrementer & a timestamp since VBScript only allows
' us to generate a timestamp accurate to 1 second. We may make multiple calls per second so this would not be unique!
Private Function GetUniqueCallID()
If (Len(Application("FB_CallID")) = 0) Then Application("FB_CallID") = 1
GetUniqueCallID = TimeStamp() & Application("FB_CallID")
Application("FB_CallID") = Application("FB_CallID") + 1
End Function
' Returns a timestamp accurate within 1 second
Private Function TimeStamp()
TimeStamp = Year(Now()) & Month(Now()) & Day(Now()) & Hour(Now()) & Minute(Now()) & Second(Now())
End Function
End Class
%>
[edit] Fahrzin Hemmati
I'm new to ASP, so I may have used inefficient objects or a workaround for something I didn't know. I'm developing this as part of a company, so I'm not allowed to post the whole thing. Instead, I'm only posting what the guy below has posted, but fixed.
Changelog:
- Uses POST instead of GET. Useful for setFBML and other non-URL-safe functions
- Uses a newer XMLHTTP object with fewer bugs/limitations.
- Allows multi-application use through initialize functions (class_initialize can't take parameters??)
- GenerateRequestURI handles auth.getSession correctly
- Helper methods to deal with XML, errors and unix time.
- example function auth_getSession(auth_token)
You will need a whole separate class that handles other things if you want this class to be useful at all. I basically "translated" from the official PHP client into ASP, but there will be many troubles since PHP is, in my opinion, such a better language than ASP. You will hate the lack of simple_xml in ASP.
[edit] RestClient.asp
Also requires the CMD5.asp by Chris Read (http://chris.brimson-read.com.au/?page_id=7)
<!--#include file="fb-md5.asp"-->
<%
CONST REST_URI = "http://api.facebook.com/restserver.php"
CONST FB_PARAM_PREFIX = "fb_sig"
Class FaceBookRestClient
private parser
private use_params
'Sample function
public function auth_getsession(auth_token)
response.write("auth_getsession"&auth_token)
use_params.removeall
use_params.add "auth_token",auth_token
result=callapimethod("facebook.auth.getSession",use_params)
parser.loadxml(result)
if instr(result,"error_response")<>0 then
handle_error parser
response.write "<br>getsession FAILED???<br>"
set auth_getsession=nothing
else
set to_ret = server.createobject("scripting.dictionary")
sessionkey=parser.documentelement.getElementsByTagName("session_key").item(0).firstchild.nodevalue
set docu=parser.documentelement
to_ret.add "session_key",node_value(docu,"session_key")
response.write sessionkey&":::"&node_value(docu,"uid")&"<br>"
to_ret.add "uid",node_value(docu,"uid")
expire=node_value(docu,"expires")
if expire=0 then
to_ret.add "expires","never"
else
to_ret.add "expires",unix2asp(expire)
end if
set docu=nothing
set auth_getsession=to_ret
set to_ret=nothing
end if
end function
public function unix2asp(unix)
unix2asp = DateAdd("s", unix, "01/01/1970 00:00:00")
end function
private sub handle_error(rootnode)
response.write "Error "&node_value(rootnode,"error_code")&": "&node_value(rootnode,"error_msg")&"<br>"
end sub
private function node_value(rootnode,tagname)
node_value=rootnode.getElementsByTagName(tagname).item(0).firstchild.nodevalue
end function
Public ApiKey
Public SessionKey
Public SecretKey
' This allows you to call a facebook method (e.g. facebook.auth.getSession) with the specified parameters
' You do not need to pass in the following parameters as they are appended automatically,
' - session_key
' - api_key
' - call_id
' - v
Public Function CallApiMethod( strMethod, oParams )
oParams( "method" ) = strMethod
Dim oXMLHTTP
Set oXMLHTTP = Server.CreateObject( "MSXML2.ServerXMLHTTP" )
oXMLHTTP.Open "POST", REST_URI, False, "", ""
oXMLHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oXMLHTTP.Send(GenerateRequestURI( oParams))
CallApiMethod = oXMLHTTP.ResponseText
Set oXMLHTTP = Nothing
End Function
' This property returns whether or not the request made to your page was from FaceBook
Public Property Get RequestIsValid
Dim strItem, oRequestParams
Set oRequestParams = Server.CreateObject( "Scripting.Dictionary" )
For Each strItem In Request.Form
If ( Left( strItem, Len( FB_PARAM_PREFIX ) ) = FB_PARAM_PREFIX And Not strItem = FB_PARAM_PREFIX ) Then
oRequestParams( Mid( strItem, Len( FB_PARAM_PREFIX & "_" ) + 1 ) ) = Request.Form( strItem )
End If
Next
RequestIsValid = ( GenerateSig( oRequestParams ) = Request.Form( "fb_sig" ) )
set oRequestParams = nothing
End Property
'Call for initializing
Public Sub Initialize(api_key,secret_key)
ApiKey = api_key
SecretKey = secret_key
End Sub
Public Sub Initialize2(api_key,secret_key,session_key)
ApiKey = api_key
SecretKey = secret_key
SessionKey = session_key
End Sub
Private Sub Class_Initialize()
set parser = Server.CreateObject("Microsoft.XMLDOM")
set use_params = server.createobject("Scripting.Dictionary")
end sub
private sub Class_Terminate()
set parser = nothing
set use_params = nothing
end sub
' Creates the content for a POST to the REST server
Private Function GenerateRequestURI( oParams )
If ( Len( Application( "FB_CallID" ) ) = 0 ) Then Application( "FB_CallID" ) = 100005
'For auth.getSession (only function to not use session_key?)
if oParams("session_key")="none" then
oParams.remove "session_key"
else
oParams( "session_key" ) = SessionKey
end if
oParams( "api_key" ) = ApiKey
oParams( "call_id" ) = Application( "FB_CallID" )
oParams( "v" ) = "1.0"
'This is useless for POSTs.
' GenerateRequestURI = REST_URI & "?"
Dim strItem
For Each strItem In oParams.Keys
GenerateRequestURI = GenerateRequestURI & strItem & "=" & Server.UrlEncode(oParams(strItem)) & "&"
Next
GenerateRequestURI = GenerateRequestURI & "sig=" & GenerateSig( oParams )
Application( "FB_CallID" ) = Application( "FB_CallID" ) + 205
End Function
' This creates an signature of the supplied parameters
Private Function GenerateSig( oParams )
Set oParams = SortDictionary( oParams )
Dim strSig, strItem
For Each strItem In oParams
strSig = strSig & strItem & "=" & oParams( strItem )
Next
strSig = strSig & SecretKey
Dim oMD5
Set oMD5 = New MD5
oMD5.Text = strSig
GenerateSig = oMD5.HexMD5
End Function
'Wrapper of generatesig for cookies
public function generatesig_cookies(cookies)
set dict=server.createobject("scripting.dictionary")
for each item in cookies
dict.add item,cookies(item)
next
generatesig_cookies=generatesig(dict)
set dict=nothing
end function
' SortDictionary function courtesy of MSDN
Private Function SortDictionary(objDict)
Dim strDict()
Dim objKey
Dim strKey,strItem
Dim X,Y,Z
Z = objDict.Count
If Z > 1 Then
ReDim strDict(Z,2)
X = 0
For Each objKey In objDict
strDict(X,1) = CStr(objKey)
strDict(X,2) = CStr(objDict(objKey))
X = X + 1
Next
For X = 0 to (Z - 2)
For Y = X to (Z - 1)
If StrComp(strDict(X,1),strDict(Y,1),vbTextCompare) > 0 Then
strKey = strDict(X,1)
strItem = strDict(X,2)
strDict(X,1) = strDict(Y,1)
strDict(X,2) = strDict(Y,2)
strDict(Y,1) = strKey
strDict(Y,2) = strItem
End If
Next
Next
objDict.RemoveAll
For X = 0 to (Z - 1)
objDict.Add strDict(X,1), strDict(X,2)
Next
End If
Set SortDictionary = objDict
End Function
End Class
%>
