This is a repost from an earlier post. My earlier blog exploded messily so I am reposting some of my technical posts from the past
Facebook has opened up access to most of their data through their Graph API. I bitch elsewhere about their decision to implement OAuth 2.0, but that should not detract from the fact that this new REST based interface is simple, straightforward, and a breeze to use. The number of requests to parse a user’s feed is not insignificant compared to what is possible with FQL.
For our Kynetx Code Run, we have already done some pretty exciting things with the FB API.
Previously, Kynetx has treated data sources as read-only operations. With this release, we have introduced writes as a user action. The format is similar to the usual get syntax, but it is an action so it needs to be called from the Action part of your rule (use it like you would notify or other actions like: after, before, float…)Facebook calls their data the Social Graph. I may use that term interchangeably with Facebook or the Graph API.
Skip to the examples
Create a Facebook application
The easy way that I did it was to just go to the Facebook Developer page. You will need to accept the FB terms and conditions and name your app. It doesn’t matter what you name your app, but the name will be used by Facebook during the authorization process and for any content that you create through the API.For our purposes, we are only interested in a couple bits of information; however, this does create a real app so you should spend some time filling in profiles, adding logos and generally tarting-up your app.
If you are familiar with OAuth, you know that you need an id and secret for the authorization process. Conveniently for us, Facebook takes us straight to the required information
The Graph API uses the Application ID and Secret as the consumer_key and consumer_secret respectively.
It is important that you do the next step correctly! Set your Facebook application’s Connect URL to http://cs.kobj.net:80/ruleset/fb_callback/ Facebook uses the Connect URL as an additional security measure to make sure developers are not up to something naughty. As part of the OAuth process, KRL tells FB to send a token to a URL on our server (That’s how your user can log in and authorize through Facebook and never give out their username and password). If your Connect URL and the URL that Kynetx provides don’t match, the authorization process will FAIL.
FACebook’s social graph
The Graph API exposes several objects from the social graph. From what I have read on the forums, there are a few objects that were available in the old API or FQL that are not available from the Graph API. I would recommend that you become familiar with what information is available and where to find it. From the Facebook documentation, these are the objects that are availableCreate your Kynetx Application
For KRL, the process of integrating Facebook into your application is the same as the process we use for Twitter and Google. The Twitter documentation is fairly extensive, so I will just hit the highlights.Set up your facebook application information in the META sectionkey facebook { "consumer_key" : "892934849920029", "consumer_secret" : "1a3836d9d025f9e2738bb50976" }
Create first rule to AUTHORIZE your user with Facebookrule auth_app is active { select using ".*" setting () if (not facebook:authorized()) then facebook:authorize(["publish_stream","email","user_photos","read_stream", "user_notes","offline_access","user_about_me","user_notes", "user_photos","user_likes","user_online_presence" ]) with opacity = 1 and sticky = true; fired { last; } }
Let’s examine the authorize command in more detail:
facebook:authorize(["publish_stream","email","user_photos", "read_stream","user_notes","offline_access","user_about_me", "user_notes","user_photos","user_likes","user_online_presence" ])authorize takes as an argument an array of extended permissions. They are separated into two major categories: Publishing and Data. Data is further divided into User and Friends permissions.
Permissions
| Publishing | Data | |
|---|---|---|
| User | Friend | |
| publish_stream | ||
| create_event | read_insights | |
| rsvp_event | read_stream | |
| offline_access | user_about_me | friends_about_me |
| user_activities | friends_activities | |
| user_birthday | friends_birthday | |
| user_education_history | friends_education_history | |
| user_events | friends_events | |
| user_groups | friends_groups | |
| user_hometown | friends_hometown | |
| user_interests | friends_interests | |
| user_likes | friends_likes | |
| user_location | friends_location | |
| user_notes | friends_notes | |
| user_online_presence | friends_online_presence | |
| user_photo_video_tags | friends_photo_video_tags | |
| user_photos | friends_photos | |
| user_relationships | friends_relationships | |
| user_religion_politics | friends_religion_politics | |
| user_status | friends_status | |
| user_videos | friends_videos | |
| user_website | friends_website | |
| user_work_history | friends_work_history | |
| read_friendlists | ||
| read_requests | ||
I suspect that some might be tempted to pile all the permissions into an authorize request. Aside from missing the point of writing context sensitive rules to fulfill specific needs, there is an Internet Explorer limitation which restricts the size of an HTTP query. Just to keep you from piling on permissions, I’m not going to tell you what that limit is.
Despite the permissions the user has authorized, there is often public data which is available regardless of authorization. Do not be misled by a user’s public information into thinking that your app is authorized to request the information; ie: to allow other people to find you in a friend search, your first and last name has public permissions. So anyone who types the URL: https://graph.facebook.com/100001078761602/ will see the information that Kay Netticks has made public.
Connections
Connections are the way that facebook links objects together. Most every object has connections to other objects. This allows a group to have members, photos and a news feed. A status message only has comments. The user object has many, many connections—basically all the various stuff that you can see on your FB home page.Not specifying a connection will return the profile information for the current object.
For convenience, there is a special function facebook:connections() which will tell you what are valid connections for a particular object.
IDs
Almost every object in the Social Graph has an id. Getting information for a particular object is as easy as providing the correct id. If you don’t specify an id, the currently authorized user is used as the default object. Facebook has a special alias for the currently authorized user “me”. KRL doesn’t require you to specify an id, but you may see request urls in your debug statements that use “me” so you should be aware of the meaning.Paging
Several of the Social Graph queries can return multiple items. Facebook provides some paging functions so you have some control over which and how many results are returned.- limit
- offset
- since
- until
Since and until operate like a min and max date respectively. They take a date as an argument, but that date can be formatted according to what the PHP strtotime function allows. That means that ‘2010-04-01’ and ‘yesterday’ are both valid values. The online PHP manual gives these as valid examples:
Valid formats for FBs since and until query parameters"now”
"10 September 2000"
"+1 day”
"+1 week”
"+1 week 2 days 4 hours 2 seconds"
"next Thursday"
"last Monday”
fields
If you are only interested in select fields of a Social Graph object, you may use the fields argument to limit the response to only your desired fields. The argument takes the form:- fields : <string> | <CSV string> | [<string1>,…,<stringN>]
Queries
Query syntax should be familiar to KRL users. There are 5 basic facebook queries which are available in KRL. Each can accept a hash as an argument, though facebook:search is the only function that requires an argument. Not specifying an id, will perform the query in the context of the currently authorized user.facebook:metadata()
- optional
- id :<string>
I debated whether I should provide access to the metadata query. The metadata is designed to allow for introspection. That’s kind of like telling you what know about what you know about an object. It returns profile information, but it also returns preformatted url references to all of the connections that are valid for your object. It’s a good idea, but when you have a token with your metadata request and are defaulting to the currently authorized user (“me”), the urls come pre-configured with the access token attached. That may not make much difference for people who are writing pure javascript implementations of the Social Graph, but KRL is a MUCH more secure environment and I don’t like the idea of leaving that token lying around.facebook:picture()
- optional
- id :<string>
- type : square | small | large
Most all objects have a picture or an icon associated with them. When you make a request for the picture, Facebook returns a redirect to the actual URL. I follow that re-direct and return the actual URL for the picture. This makes a picture call a little bit more complicated so bear that in mind if you are going to do large amounts of picture requests. If it would be more useful, I could include something like a ‘nofollow’ tag so that I just return the location of the redirect, but that is currently not providedfacebook:search()
- required
- type : post | user | page | event | group | home
- q : <string>
- optional
- id :<string>
I haven’t found FB’s search functionality to be terribly robust. As I say to my kids, “You get what you get and you don’t throw a fuss”. If you find that you aren’t getting the results that you think you should, grab the url from the debug and enter it with your browser to see if it’s just bad indexing on FB’s part.facebook:get()
home is a special case where the search will be performed only on the currently authorized users news feed or whomever is specified by the optional id parameter
- optional
- id :<string>
- connection: <string>
- type : <facebook object>
If you would like to follow a connection; ie: get all the comments associated with a post, just provide a “connection” : <value>. If you would like KRL to do some sanity checking, you can use the optional “type” : <object> syntax in conjunction with connection. KRL will check to see if your connection is valid for that type of object. If not, a warning will be printed to your console.facebook:ids()
- required
- ids :<string> | <CSV string> | [<string1..stringN>] | url
This method allows you to get profile information for multiple ids. <string> can be a username or the numeric id (it is not guaranteed that the user will have a username defined).
An optional usage is to provide a URL instead of an id. You can use this to look up or check to see if there is an object already associated to a URL in Social Graph
POSTS
| Connection | Requires* | Arguments |
|---|---|---|
| feed (wall) | <profile id> |
|
| comments | <post id> |
|
| likes | <post id> | |
| notes | <profile id> |
|
| links | <profile id> |
|
| events | <profile id> |
|
| attending (events) | <event id> | |
| maybe (events) | <event id> | |
| declined (events) | <event id> | |
| albums | <profile id> |
|
| photos | <album id> |
|
Here are the objects that you can publish via the Graph API:
Syntax for publishing is very simple, but remember that publishing is an action. In this case, the action is not producing JavaScript, but posting data to the Graph API.
facebook:post()
- required
- connection : <string>
- id: <string>
- optional
- <arg> : <string>
*id is optional when the connection requires a profile id. As in previous cases, if the id is not supplied, it will default to the id of the currently authorized user. The following connections require a profile id: feed, notes, links, events, albums. I would suggest always supplying the id for consistency.
The post method cross checks the connection type with the permitted arguments. If an argument is not associated with the connection, it will just be ignored.
For convenience, there is a special function facebook:writes() which will tell you what are valid argument keywords for a particular connection.
Examples
Request for metadata by idfacebook:metadata({“id” : “100001078761602”});
returns: JSON
Request for metadata for currently authorized userfacebook:metadata();
returns: JSON
Writable fields/allowed parameters for a Facebook objectfacebook:writes(“feed”);returns: Array
Post a message to a user’s feedfacebook:post({"id" : "100001078761602", "connection" : "feed", "message" : "Contactless not, swipe again", "picture" : "https://kynetx-images.s3.amazonaws.com/KynetxLogo273.png", "link" : "http://www.kynetx.com", "name" : "Things I like", "description" : "I am integrated into Facebook!" });
“like” a postfacebook:post({"id" : "641349049_124260134272950", "connection" : "likes"});
Search for these ids and return their profile datafacebook:ids(“ids” : [“100001078761602”,”116360591732083”]);returns: JSON
Search the Facebook Social Graph to see if a URL has an IDfacebook:ids(“ids” : “http://www.kynetx.com”);returns: JSON
Request specific user’s feedfacebook:get({“id” : “100001078761602”, ”connection” : “feed”});
returns: JSON
Request default user’s albumsfacebook:get({”connection” : “albums”});
returns: JSON
Request default user’s home with optional “type” syntaxfacebook:get({”connection” : “home”, ”type” : “user”});
returns: JSON
Request an object by idfacebook:get({”id” : “511048495_446064733495”});
returns: JSON
Request all the messages posted to a specific object (link)facebook:get({“id” : “511048495_446064733495”, ”connection” : “comments”});
returns: JSON
Search the Social Graph for a pagefacebook:search({”type” : “page”, ”q” : “Lehi, Utah”});
returns: JSON
Search the Social Graph for a userfacebook:search({”type” : “user”, ”q” : “Steve Fulling”});
returns: JSON
Get the large picture associated with the currently authorized userfacebook:picture({“type” : “large”});returns: url (string)
Get the picture for an objectfacebook:picture({“id” : “116360591732083”});returns: url (string)
Request for object picture by id and typefacebook:picture({“id” : “100001078761602”, ”type” : “small”});
returns: url (string)
Allowed connections for a Facebook objectfacebook:connections(“page”);returns: Array
facebook:fields()
Allowed fields for a Facebook objectfacebook:fields(“user”);returns: Array
Authorization Action with desired Facebook permissionsfacebook:authorize(["publish_stream","email","user_photos","read_stream"]);
Authorization predicatefacebook:authorized();returns: true or false
limit
Search the Social Graph for a group and limit results to 3facebook:search({"type" : "post", "q" : "bacon", "limit" : 3});
returns: JSON
Search the Social Graph for a user and start with the 20th objectfacebook:search({"type" : "user", "q" : "John Smith", "offset" : 20});
returns: JSON
until
Search the Social Graph for users named who signed up before 2010-05-18facebook:search({"connection" : "feed", "q" : "John Smith", "until" : "2010-05-08"});
returns: JSON
since
Search default user’s news for posts made within last dayfacebook:get({"connection" : "feed", "since" : "yesterday”});
returns: JSON
Get specific fields for the default userfacebook:get({“fields” : [“last_name”,”email”]});
returns: JSON
Due to this elastic recovery, it is high precision machining essential to over-bend the sheet a precise quantity to achieve the specified bend radius and bend angle. The last bend radius will be greater than initially fashioned and the ultimate bend angle will be smaller. The ratio of the ultimate bend angle to the preliminary bend angle is outlined as the springback factor, KS.
ReplyDelete