经典 ASP 和 Facebook Graph API





5.00/5 (12投票s)
在前一篇文章的基础上,我们现在深入研究 Facebook Graph API 并提供一些有用的函数。
引言
在上一篇文章中,我提供了一组实用函数,用于通过 Facebook for Websites API 将您的网站连接到 Facebook。本文在前一篇应用的基础上进行改进,并添加了一些示例,说明如何利用 Facebook 的 Graph API 提供更深入的 Facebook 交互。
背景
本文将基于上一篇文章中已重构为类对象的相同代码。
什么是 Graph API?
Graph API 是 Facebook 基于RESTful 接口实现大多数 UI 功能自动化的方式。
Graph API 向 Facebook 发送请求,URL 类似于:http://graph.facebook.com/ID。ID 是您正在处理的 Facebook 对象的 ID。Facebook 中的每个对象都根据 REST 的要求具有 ID。您可以在此处找到完整的文档:http://developers.facebook.com/docs/reference/api/。
使用代码
在使用代码之前,您必须创建一个 Facebook 应用程序并拥有应用程序 ID 和密钥。有关详细信息,请参见第一篇文章。
在本文中,我将提供处理 Facebook 数据的基本模式。代码将实现一种一致的方式来返回 Facebook 数据,以便当您访问 user.hometown(例如)时,它将始终返回一个值或空值。如果 Facebook 未返回数据,也不会产生错误。新设计中的每个函数都包含有助于验证函数是否正常工作的测试页面。
重构旧代码
让我们回顾一下当前代码与上一篇文章的不同之处。主要的变化是,除了少数几个函数之外,所有函数都封装在一个名为 fb_utility 的类库中。下面的代码块显示了 fb_utility 的类结构。
''************************************************************
'' A summary of the fb_utility class as found in fb_app.asp
''************************************************************
class fb_utility
dim dictKey
dim dictItem
'' Initialize the fb_utility class
sub Class_Initialize()
'' Initialize KSort values
dictKey = 1
dictItem = 2
end sub
'' get the contents of a web page, include
'' validation that the user is logged in
public function get_page_contents(strURL)
end function
'' Some Facebook API functions require a post
'' this function handles the post request
public function post_page(strURL, strData)
end function
'' Generate a GUID
public Function NewID()
End Function
'' KSort is not required for the new oAuth
'' however you might find it useful
public function ksort(byref objDict )
SortDictionary objDict, dictKey
end function
'' Sort dictionary is called by the ksort function
Function SortDictionary(byref objDict, intSort)
End Function
'' gets the access token from the return
'' authentication request made to Facebook
public function parse_access_token( str )
end function
'' Parses the expires value from the return data
'' provided after an oAuth request to Facebook
'' I have yet to figure out how to make use of this
public function parse_expires( str )
end function
end class
这个实用工具类被 Graph API 和初始授权函数中的几乎所有其他类和函数重用。
基本请求模式
在大多数情况下,每个 Graph API 请求都会执行一些基本操作:调用 fb_utility.get_page_contents
,它返回一个 JSON 字符串,然后将该字符串转换为 JSON 对象以供引用。Facebook 返回的数据存在一个问题,即如果某个值为空或 null,则不会返回该属性。例如:您请求的用户可能没有 hometown 信息,因此 Facebook 返回的 JSON 字符串将不包含 hometown 值。当 JSON 字符串转换为对象时,它将没有 hometown 属性。结果,尝试访问 user.hometown 将触发 VBScript 错误。我称之为“稀疏数据问题”。
为了解决稀疏数据问题,我在每个类中都包含了一个代码块,该代码块将 JSON 映射到 VBScript 类,从而为每个数据对象提供一个可靠的接口。
下面您将找到一个用 VBScript 类实现的 Facebook 数据类型对象的模式。调用 Load
并传递 Facebook 对象 ID 将获取 JSON 字符串,调用 load_from_json_object
将执行映射。
'' Copy and paste the template below for each new Facebook DTO class
'' A Facebook DTO
class fb_DTO
'' **
'' ** Declare Variables
'' **
'' Default Variables for properties
dim fbu '' Facebook utility object
dim m_token ''
dim m_json_str ''
dim m_graph_url ''
'' Default Internal Variables
'' Object Type Specific Variables
'' **
'' ** property exposure
'' **
'' Default Properties
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
'' Object Type property exposure
'' initialization
sub Class_Initialize
set fbu = new fb_utility
end sub
'' termination
sub Class_Terminate
set fbu = nothing
end sub
'' **
'' Implementation
'' **
'' Load object by id
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
'' map your properties here
on error goto 0
err.clear
end sub
end class
真实世界示例 - Facebook 用户对象
接下来的代码块基于模式示例,并实现了一个 Facebook 用户对象。
''**************************************************************************
'' Copyright 2012 Larry Boeldt
'' Class: facebook_user V1.0 2012-01-26
'' Author: Larry Boeldt - lboeldt@scs-inc.net; larry@boeldt.net
''
'' Description:
'' Facebook user object
''
''**************************************************************************
class facebook_user
dim m_id '' The user's Facebook ID
dim m_name '' The user's full name
dim m_first_name '' The user's first name
dim m_middle_name '' The user's middle name
dim m_last_name '' The user's last name
dim m_gender '' The user's gender: female or male
dim m_locale '' The user's locale
dim m_languages '' The user's languages
dim m_link '' The URL of the profile for the user on Facebook
dim m_username '' The user's Facebook username
dim m_third_party_id '' An anonymous, but unique identifier for the user;
'' only returned if specifically requested via the fields URL parameter
dim m_timezone '' The user's timezone offset from UTC
dim m_updated_time '' The last time the user's profile was updated;
'' changes to the languages, link, timezone, verified,
'' interested_in, favorite_athletes, favorite_teams,
'' and video_upload_limits are not not reflected in this value
dim m_verified '' The user's account verification status, either true or false (see below)
dim m_bio '' The user's biography
dim m_birthday '' The user's birthday
dim m_education '' A list of the user's education history
dim m_email '' The proxied or contact email address granted by the user
dim m_hometown '' The user's hometown
dim m_interested_in '' The genders the user is interested in
dim m_location '' The user's current city
dim m_political '' The user's political view
dim m_favorite_athletes '' The user's favorite athletes; this field
'' is deprecated and will be removed in the near future
dim m_favorite_teams '' The user's favorite teams; this field
'' is deprecated and will be removed in the near future
dim m_quotes '' The user's favorite quotes
dim m_relationship_status '' The user's relationship status: Single,
'' In a relationship, Engaged, Married, It's complicated,
'' In an open relationship, Widowed, Separated, Divorced,
'' In a civil union, In a domestic partnership
dim m_religion '' The user's religion
dim m_significant_other '' The user's significant other
dim m_video_upload_limits '' The size of the video file and the length
'' of the video that a user can upload; only returned
'' if specifically requested via the fields URL parameter
dim m_website '' The URL of the user's personal website
dim m_token ''
dim m_json_str ''
dim m_graph_url ''
dim fbu '' Facebook utility object
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
''**************************************************************************
'' Copyright 2012 Larry Boeldt
'' Function: load_from_json_user V1.0 2012-01-26
'' Author: Larry Boeldt - lboeldt@scs-inc.net; larry@boeldt.net
'' Parameter(s):
'' fb_obj - The facebook object as returned from JSON.parse
''
'' Description:
'' This function attempts to safely assign all user parameters from a
'' fasebook object so that you can consistently address the properties in
'' your code without concern about errors resulting from properties that
'' are missing in the return json object
''**************************************************************************
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
使用 fb_graph_api 对象将它们整合在一起
为了保持使用此库的代码整洁,fb_graph_api
类实现了一个返回现成对象的函数。
当前库中有哪些内容?
截至本文撰写时,我提供了我正在处理的所有内容,但只有一些函数已准备好供您使用。其他示例处于 alpha 模式;风险自负。以下是可用的对象和相关的 graph_api “快捷方式”。
Facebook 对象名称 | 类名 | Graph API 函数 | 测试页面 |
用户 | fb_user |
get_user |
user_test.asp |
Friends (用户对象列表) | fb_friends |
get_friends |
friends_test.asp |
Friend | fb_user |
get_friend |
friend_test.asp |
Album (相册) | fb_album |
get_album |
album_test.asp |
Photo | fb_photo |
get_photo |
album_test.asp |
注释 | fb_comment |
无,由其他对象调用。 | none |
例如 | fb_like |
无,由其他对象调用。注意:这是一个点赞对象,而不是点赞方法。我还没有实现那个。 | none |
Graph API 方法
目前仅实现了 post_to_wall
方法。
墙面帖子(post to wall)的测试页面是 post_wall_test.asp。目前只能发布到当前登录用户的墙面。
发布到墙面(post to wall)需要以下参数
参数名称 | 描述 |
Message | 您想在墙面上显示的消息 |
图片 | 要与墙面帖子一起显示的图片的 URL |
链接 | 作为链接目标的 URL |
名称 | 要在链接上显示的名称 |
标题 | 链接的标题 |
描述 | 更长的文本,描述链接 |
关注点
DTO 类可以存储在会话(session)中,因为它们只使用 VBScript 变量,并且没有任何(如 scripting.dictionary
)会引发线程模型问题的对象。
结论
虽然这里的示例不支持完整的 Graph API,但我认为您可以参考这里的示例来处理任何其他 API 数据。如果您实现了另一个模块,请在此处发布,我一定会将其包含在新版本中。我将在未来一年中每三个月发布一个新版本。您的反馈、建议和投票始终受到赞赏。
历史
- 发布版本 1。