Skip to content

Instantly share code, notes, and snippets.

@baygross
Created March 31, 2012 19:56
Show Gist options
  • Save baygross/2267893 to your computer and use it in GitHub Desktop.
Save baygross/2267893 to your computer and use it in GitHub Desktop.
Easy Koala (FB) integration with Rails 3
#
# app/views/shared/_fbinit.html.erb
#
<div id="fb-root"></div>
<!-- Facebook -->
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '<%= Facebook::APP_ID %>',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
channelUrl : '<%= Facebook::CALLBACK_URL %>/channel.html',
xfbml : true // parse XFBML
});
// logout if FB flag is set
if ( typeof(FB_LOGOUT_FLAG) != 'undefined' )
FB.logout( function(response){ location.href = "/"; } );
// Browser-specific hacks to make FB Connect more reliable
$.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase());
if ($.browser.chrome || $.browser.msie) {
FB.XD._origin = window.location.protocol + "//" + document.domain + "/" + FB.guid();
FB.XD.Flash.init();
FB.XD._transport = "flash";
} else if ($.browser.opera) {
FB.XD._transport = "fragment";
FB.XD.Fragment._channelUrl = window.location.protocol + "//" + window.location.host + "/";
}
};
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
#
# /app/controllers/application_controller.rb
#
before_filter :load_user
def load_user
#set facebook + session vars
@fb_oauth = Koala::Facebook::OAuth.new
@fb_graph = Koala::Facebook::API.new # can only access public datam, temporary.
session[:fb_id] ||= @fb_oauth.get_user_from_cookies(cookies)
begin
#if user is logged in
if session[:fb_id]
#Grab their access token, and upgrade the graph object
if @fb_oauth.get_user_info_from_cookies(cookies)
token = @fb_oauth.get_user_info_from_cookies(cookies)["access_token"]
@fb_graph = Koala::Facebook::API.new( token )
end
#load existing user from DB if possible
@current_user = User.where( :facebook_id => session[:fb_id] ).first
#otherwise create new user
if !@current_user
fb_obj = @fb_graph.get_object( session[:fb_id] )
@current_user = User.newFromFB( fb_obj )
end
end
rescue Koala::Facebook::APIError
#User cookie is stale, so don't act like they are logged in
session.clear
end
end
#
# /public/channel.html
#
<script src="http://connect.facebook.net/en_US/all.js"></script>
#
# /assets/javascript/[controller].js
# [ whatever javascript file is associated with the above view... ]
#
/*----------------------------------------------------------------------------------------
Splash Page
------------------------------------------------------------------------------------------*/
$(document).ready( function() {
//Facebook Login Code
fb_connect($("#fb_login"), loginSuccess);
});
function loginSuccess() {
alert("logged in successfully, hooray!");
}
function fb_connect(obj, success_function) {
var click_fn = function() {
$(this).find("span.button-text").html("Logging you in...");
FB.login( function(response){
console.log(response);
if (response.status === "connected") {
success_function.call(obj);
} else {
// user is not logged in
$(this).find("span").html("Connect with Facebook");
alert('Facebook login failed, please try again!');
}
}, {scope:''} // add PERMISSIONS HERE
// via: https://developers.facebook.com/docs/authentication/permissions/
);
}
$(obj).click(click_fn);
}
#
# /assets/stylesheets/[controller].css.scss
# [ whatever scss file is associated with the above view... ]
#
#fb_connect{
width: 208px;
margin-left: auto;
margin-right: auto;
margin-top: 30px;
}
#privacy_info {
color: #888;
font-size: 11px;
margin-top: 15px;
a{
color: #888;
&:hover{
text-decoration:underline;
}
}
}
.facebook-button {
height: 46px;
width:160px;
display: block;
background: transparent image-path("facebook-lg-f.png") no-repeat top left;
padding-left: 48px;
cursor: pointer;
.button-text {
display: block;
padding: 15px 7px 17px 5px;
background: transparent image-path("facebook-lg-r.png") no-repeat top right;
color: #888;
}
}
#
# config/facebook.yml
# [ sign up for an app at facebook.com/developers ]
#
development:
app_id:
secret_key:
callback_url:
production:
app_id:
secret_key:
callback_url:
#
# don't forget to run bundle install :)
#
gem 'koala'
#
# /app/views/controller/index.html.erb
# [ whatever file you want to add FB login to ]
#
<div id='fb_connect'>
<div id='fb_login' class='facebook-button large'><span class='button-text'>Login!</span></div>
<p id='privacy_info'>Questions? Read our <a href='/privacy'>Privacy Policy</a></p>
</div>
<!-- FB partial settings -->
<%= render :partial => 'shared/fbinit'%>
#
# config/initializers/koala.rb
#
module Facebook
CONFIG = YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env]
APP_ID = CONFIG['app_id']
SECRET = CONFIG['secret_key']
CALLBACK_URL = CONFIG['callback_url']
end
Koala::Facebook::OAuth.class_eval do
def initialize_with_default_settings(*args)
case args.size
when 0, 1
raise "application id and/or secret are not specified in the config" unless Facebook::APP_ID && Facebook::SECRET
initialize_without_default_settings(Facebook::APP_ID.to_s, Facebook::SECRET.to_s, Facebook::CALLBACK_URL.to_s)
when 2, 3
initialize_without_default_settings(*args)
end
end
alias_method_chain :initialize, :default_settings
end
#
# /app/models/user.rb
#
def self.newFromFB(fb_user)
user = User.new
user.facebook_id = fb_user["id"]
user.name = fb_user["first_name"] + " " + fb_user["last_name"]
user.age = self.age_from_bday_string(fb_user["birthday"])
user.gender = fb_user["gender"]
user.save
user
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment