Skip to content

Instantly share code, notes, and snippets.

@tracend
Last active April 11, 2016 19:08
Show Gist options
  • Save tracend/4710985 to your computer and use it in GitHub Desktop.
Save tracend/4710985 to your computer and use it in GitHub Desktop.
[DEPRECATED] Backbone.js APIs: Facebook Project moved: http://github.com/backbone-api/facebook

Backbone API : Facebook

A simple way to interact with Facebook's Graph API using Backbone.js objects.

Install

bower install backbone.api.facebook

Dependencies

  • Facebook JS: all

Usage

The plugin will try to create a global namespace Facebook that will host all the Models/Views/Collections mirrored from Backbone.API.Facebook

When the web page is loaded, passing the appId and uri for reference in the api requests

Facebook.set({
		appId: 345644234546,
		uri: "namespace"
	});

Most Backbone.js conventions apply using the Facebook namespace.

var friends = new Facebook.Collections.Friends();

var me = new Facebook.Models.Me();

Facebook's UI is treated as the template method for the Views

var post = new Facebook.Models.Post();
var view = new Facebook.Views.Post({ model : post, callback : MyFunction });

Credits

Created by Makis Tracend ( @tracend )

Login/logout inspired by facebook-user.js - Copyright (c) 2010 Christian Bäuerlein

Originally used for havenbase.com

Distributed through Makesites.org

Released under the MIT license

/* Backbone API: Facebook
* Source: https://github.com/backbone-api/facebook
*
* Created by Makis Tracend (@tracend)
* Distributed through [Makesites.org](http://makesites.org)
* Released under the [MIT license](http://makesites.org/licenses/MIT)
*/
// Assuming that Facebook JS lib is loaded...
if( window.FB ) (function(_, Backbone) {
// Constants
var graph = "https://graph.facebook.com"
// Fallbacks
//APP = window.APP || (APP = { Models: {}, Collections: {}, Views: {} });
if( _.isUndefined(Backbone.API) ) Backbone.API = {};
// Base model - mainly used for setup options
Backbone.API.Facebook = new Backbone.Model({
"appId": false,
"uri": false
});
// Namespace definition
Backbone.API.Facebook.Models = {};
Backbone.API.Facebook.Collections = {};
Backbone.API.Facebook.Views = {};
// Helpers
// Sync method
var Sync = function(method, model, options) {
var url = (this.url instanceof Function) ? this.url() : this.url;
var params = {};
// add access token if available
var token = this.getToken();
if( token ){
if( url instanceof Object) { url["access_token"] = token; }
else { url += ( url.search(/\?/) > -1 ) ? "&access_token="+ token : "?access_token="+ token; }
}
//FB.api(url, method, params, function( response ) {
FB.api(url, method, function( response ) {
// save response.paging for later?
// send just the response.data:
var data = response.data || response;
options.success( data );
});
};
var getToken = function(){
// first priority have the local options
if( this.options && this.options.access_token) return this.options.access_token;
// after that the internal token
if( !_.isUndefined( token.get("accessToken") ) ) return token.get("accessToken");
// no token
return false;
}
// Models
// - Main Constructor
var Model = Backbone.Model.extend({
// available options
options : {
access_token : false
},
initialize: function(model, options){
// fallbacks
options = options || {};
this.options = _.extend(this.options, options);
//return Backbone.Model.prototype.initialize.apply(this, arguments);
// auto-fetch if requested...
if( options.fetch ){
this.fetch();
}
},
fetch : function(method, model, options) {
var self = this;
if( this.getToken() ){
// we'll be using the supplied access token
Backbone.Model.prototype.fetch.call( self );
} else {
FB.getLoginStatus(function(response){
if( response.status == "connected" ){
// save token
token.set( response.authResponse );
// continue with request
Backbone.Model.prototype.fetch.call( self );
}
// else try to FB.Login?
});
}
},
sync: Sync,
getToken: getToken
});
//
Backbone.API.Facebook.Models.User = Model.extend({
defaults : {
//installed : true
}
});
Backbone.API.Facebook.Models.Feed = Model.extend({
defaults : {}
});
Backbone.API.Facebook.Models.Post = Model.extend({
defaults : {
method: "feed",
link: "",
picture: "",
name: "",
caption: "",
description: ""
}
});
Backbone.API.Facebook.Models.Page = Model.extend({
defaults : {
method: "oauth",
client_id: false,
redirect_uri: ""
},
isFan: function( uid ){
uid = uid || "me()";
return (new isFan({ id : this.id, uid : uid }) ).fetch();
}
});
Backbone.API.Facebook.Models.Tab = Model.extend({
url: function(){ return graph + "/"+ this.page +"/tabs/app_"+ this.id },
defaults : {},
initialize: function( data, options ){
this.page = data.page;
this.id = Backbone.API.Facebook.get("appId");
}
});
//
Backbone.API.Facebook.Models.Link = Model.extend({
defaults : {
url: window.location.href,
normalized_url: "",
share_count: 0,
like_count: 0,
comment_count: 0,
total_count: 0,
commentsbox_count: 0,
comments_fbid: 0,
click_count: 0
},
url: function(){
return {
method: 'fql.query',
query: "SELECT url,normalized_url,share_count,like_count,comment_count,total_count,commentsbox_count,comments_fbid,click_count FROM link_stat WHERE url ='"+ this.get("url") +"'"
}
},
parse: function( response ){
// error control?
if( response instanceof Array ){
// use only the first item
return response.shift();
} else {
return response;
}
}
});
Backbone.API.Facebook.Models.Login = Model.extend({
defaults : {
method: "oauth",
client_id: false, //fb_appId
//display: "popup",
//response_type: "token"
//redirect_uri: "" //https://apps.facebook.com/'+ fb_uri +'/'
}
});
Backbone.API.Facebook.Models.AddToPage = Model.extend({
defaults : {
method: 'pagetab',
//redirect_uri: '', //https://apps.facebook.com/{{fb_uri}}/
}
});
// Me is an extension of the user
Backbone.API.Facebook.Models.Me = Backbone.API.Facebook.Models.User.extend({
url : graph + "/me",
defaults : {
id : "me"
},
// defaultOptions: {
options : {
auth: false,
// see https://developers.facebook.com/docs/authentication/permissions/
scope: [], // fb permissions
autosync: true, // auto fetch profile after login
protocol: location.protocol
},
oauth: null,
initialize: function(){
var self = this;
FB.Event.subscribe('auth.authResponseChange', function(e){ self.onLoginStatusChange(e) });
return Backbone.API.Facebook.Models.User.prototype.initialize.apply(this, arguments);
},
login: function(callback){
callback = callback || function() {};
FB.login(callback, { scope: this.options.scope.join(',') });
},
logout: function(){
FB.logout();
},
onLoginStatusChange: function(response) {
// only execute once?
if(this.options.auth === response.status) return false;
var event;
if(response.status === 'not_authorized') {
event = 'facebook:unauthorized';
// login logic
} else if (response.status === 'connected') {
event = 'facebook:connected';
// save request for later...
this.request = FB.getAuthResponse();
// copy access token
this.oauth = {
access_token : this.request.accessToken,
expiry : (new Date).getTime() + this.request.expiresIn
};
if(this.options.autosync === true) this.fetch();
} else {
event = 'facebook:disconnected';
}
this.trigger(event, this, response);
this.options.auth = response.status;
}
});
Backbone.API.Facebook.Models.WebPage = Model.extend({
defaults : {
"shares": 0,
"comments": 0,
"type": "website",
"is_scraped": false
},
options: {
},
url: function(){ return "https://graph.facebook.com/?ids="+ this.options.page },
parse: function( data ){
// data arrives in a sub-object with the URL as the key
var model = {};
// - pick the first element regardless of key
for(var key in data ){
model = data[key];
break; // "break" because this is a loop
}
data = model;
return data;
}
});
// Collections
// - Main Constructor
var Collection = Backbone.Collection.extend({
// available options
options : {
access_token : false
},
initialize: function(model, options){
// fallbacks
options = options || {};
this.options = _.extend(this.options, options);
//return Backbone.Collection.prototype.initialize.apply(this, arguments);
// auto-fetch if requested...
if( options.fetch ){
this.fetch();
}
},
fetch : function(method, model, options) {
var self = this;
if( this.getToken() ){
// we'll be using the supplied access token
Backbone.Collection.prototype.fetch.call( self );
} else {
FB.getLoginStatus(function(response){
if( response.status == "connected" ){
// save token
token.set( response.authResponse );
// continue with request
Backbone.Collection.prototype.fetch.call( self );
}
// else try to FB.Login?
});
}
},
sync : Sync,
parse : function( response ){
//console.log("facebook data:", response );
//is uid always the id? apparently...
var data = _.map(response, function( result ){
if( result.uid ){
result.id = result.uid;
delete result.uid;
}
return result;
});
return data;
},
getToken: getToken
});
//
Backbone.API.Facebook.Collections.Friends = Collection.extend({
model : Backbone.API.Facebook.Models.User,
url: function(){
return {
method: 'fql.query',
query: 'Select name, uid from user where is_app_user = 1 and uid in (select uid2 from friend where uid1 = me()) order by concat(first_name,last_name) asc'
}
}
});
Backbone.API.Facebook.Collections.Feed = Collection.extend({
// examples options:
options: {
//access_token : config.facebook.access_token
},
model : Backbone.API.Facebook.Models.Feed,
url: function(){
// creating an object of parameters
var params = {
method: 'fql.query',
query: "select message,description,attachment,created_time from stream where source_id ='"+ this.id +"' limit "+ this.num,
}
// add access token if available
if( this.options.access_token ){
// we'll be using the supplied access token
params["access_token"] = this.options.access_token;
}
return params;
// old...
// check if there is either an id or user set - fallback to 'me'
//var page = this.user || this.id || "me";
//return "/"+ page +"/feed?limit="+ this.num;
},
initialize: function( model, options){
// parameters
this.id = options.id || false;
this.user = options.user || null;
this.num = options.num || 10;
// auto-fetch if requested...
if( options.fetch ){
this.fetch();
}
}
});
// Views
// - Main Constructor
var View = Backbone.View.extend({
template : FB.ui,
initialize: function( options ){
// fallback
options = options || {};
if( options.callback ) this.callback = options.callback;
// load the parent?
//
// fincally, render the view
return this.render();
},
render : function(){
this.template( this.model.toJSON(), this.callback );
// preserve chainability?
return this;
},
callback : function(){
}
});
//
Backbone.API.Facebook.Views.Post = View.extend({
callback : function(response) {
//document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
}
});
Backbone.API.Facebook.Views.Login = View.extend({
initialize: function( options ){
//
this.model = new Backbone.API.Facebook.Models.Login({
client_id: Backbone.API.Facebook.get("appId"), //fb_appId
//redirect_uri: "https://apps.facebook.com/"+ Backbone.API.Facebook.get("uri") +'/'
});
// load the parent?
//
return View.prototype.initialize.call( this, options );
},
callback : function (response) {
if( typeof( response ) != "undefined") {
if(response.session) {
//var user = JSON.parse(response.session);
// save the userid in the form
//$("#entry-form").find("input[name='fbid']").val(user.uid);
top.location.href = this.model.get("redirect_uri");
} else {
// No session
//top.location.href = 'http://facebook.com/';
console.log("no session");
window.location.reload();
}
} else {
// denied access
console.log("denied access");
//top.location.href = tab.host;
}
}
});
Backbone.API.Facebook.Views.AddToPage = View.extend({
initialize: function( options ){
//
this.model = new Backbone.API.Facebook.Models.AddToPage();
// load the parent?
//
return View.prototype.initialize.call( this, options );
}
});
// Internal
// - internal access token
// Note: Always ask for the user_likes permission before calling any of the above to make sure you get a correct result
var Token = Backbone.Model.extend({
});
// - isFan method
// Note: Always ask for the user_likes permission before calling any of the above to make sure you get a correct result
var isFan = Model.extend({
url : function(){
// alternate 'plain' url
// "/"+ this.options.uid +"/likes/"+ this.options.id
return {
method: 'fql.query',
query: 'select uid from page_fan where uid='+ this.options.uid +' and page_id='+ this.options.id
}
},
parse: function( response ){
// check if there is a data response
return { fan : !(_.isEmpty(response.data) ) };
}
});
// init token
var token = new Token();
// alias APP.API
if( typeof APP != "undefined" && (_.isUndefined( APP.API) || _.isUndefined( APP.API.Facebook) ) ){
APP.API = APP.API || {};
APP.API.Facebook = Backbone.API.Facebook;
}
// Shortcut
if(typeof window.Facebook == "undefined"){
window.Facebook = Backbone.API.Facebook;
}
})(this._, this.Backbone);
{
"name": "backbone.api.facebook",
"version": "0.6.0",
"main": ["./backbone.api.facebook.js"],
"dependencies": [ "backbone", "underscore" ]
}
@tracend
Copy link
Author

tracend commented Mar 3, 2013

Note: this gist is now DEPRECATED
Project moved: http://github.com/backbone-api/facebook

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment