Facebook, как проверить, понравилась ли пользователю страница и показывать контент?
Я пытаюсь создать приложение iFrame для Facebook. Приложение должно сначала показать изображение, и если пользователю понравится страница, он получит доступ к некоторому контенту.
Я использую RoR, поэтому я не могу использовать SDK Facebook PhP.
Вот мой iFrame HTML, когда пользователю не понравилась страница:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<style type="text/css">
body {
width:520px;
margin:0; padding:0; border:0;
font-family: verdana;
background:url(repeat.png) repeat;
margin-bottom:10px;
}
p, h1 {width:450px; margin-left:50px; color:#FFF;}
p {font-size:11px;}
</style>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
</head>
<body>
<div id="container">
<img src="welcome.png" alt="Frontimg">
</div>
И, если пользователю понравилась страница:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<style type="text/css">
body {
width:520px;
margin:0; padding:0; border:0;
font-family: verdana;
background:url(repeat.png) repeat;
margin-bottom:10px;
}
p, h1 {width:450px; margin-left:50px; color:#FFF;}
p {font-size:11px;}
</style>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
</head>
<body>
<div id="container">
<img src="member.png" alt="Frontimg">
<p>You liked this page</p>
Ответы
Ответ 1
ОБНОВЛЕНИЕ 21/11/2012
@ALL: Я обновил пример, чтобы он работал лучше и учитывал замечания от Chris Jacob и FB Best practices. Посмотрите рабочий пример здесь
Привет Итак, как и было обещано, это мой ответ, используя только javascript:
Содержимое ТЕЛА страницы:
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId : 'YOUR APP ID',
status : true,
cookie : true,
xfbml : true
});
</script>
<div id="container_notlike">
YOU DONT LIKE
</div>
<div id="container_like">
YOU LIKE
</div>
CSS:
body {
width:520px;
margin:0; padding:0; border:0;
font-family: verdana;
background:url(repeat.png) repeat;
margin-bottom:10px;
}
p, h1 {width:450px; margin-left:50px; color:#FFF;}
p {font-size:11px;}
#container_notlike, #container_like {
display:none
}
И, наконец, javascript:
$(document).ready(function(){
FB.login(function(response) {
if (response.session) {
var user_id = response.session.uid;
var page_id = "40796308305"; //coca cola
var fql_query = "SELECT uid FROM page_fan WHERE page_id = "+page_id+"and uid="+user_id;
var the_query = FB.Data.query(fql_query);
the_query.wait(function(rows) {
if (rows.length == 1 && rows[0].uid == user_id) {
$("#container_like").show();
//here you could also do some ajax and get the content for a "liker" instead of simply showing a hidden div in the page.
} else {
$("#container_notlike").show();
//and here you could get the content for a non liker in ajax...
}
});
} else {
// user is not logged in
}
});
});
И что он делает?
Сначала он входит в FB (если у вас уже есть ИД пользователя, и вы уверены, что ваш пользователь уже зарегистрирован в facebook, вы можете обойти логин и заменить response.session.uid
на YOUR_USER_ID (например, из вашего приложения rails)
После этого он делает запрос FQL в таблице page_fan
, и смысл в том, что если пользователь является фанатом страницы, он возвращает идентификатор пользователя и в противном случае возвращает пустой массив, после этого и в зависимости от результаты его показывают div или другой.
Также здесь есть рабочая демонстрация: http://jsfiddle.net/dwarfy/X4bn6/
В качестве примера используйте страницу coca-cola, попробуйте пойти и как/в отличие от страницы кока-колы и запустите ее снова...
Наконец, некоторые связанные документы:
FQL page_fan table
FBJS FB.Data.query
Не стесняйтесь, если у вас есть вопрос.
Приветствия
ОБНОВЛЕНИЕ 2
Как указано кем-то, для работы javascript требуется jQuery, но вы можете легко удалить его (он используется только для document.ready и show/hide).
Для document.ready вы можете обернуть свой код в функцию и использовать body onload="your_function"
или нечто более сложное, как здесь: Javascript - как определить, загружен ли документ (IE 7/Firefox 3), чтобы заменить документ готовым.
И для показа и скрытия вещей вы можете использовать что-то вроде: document.getElementById("container_like").style.display = "none" or "block"
и для более надежных методов кросс-браузера см. здесь: http://www.webmasterworld.com/forum91/441.htm
Но jQuery так просто:)
UPDATE
Относительно комментария, который я разместил здесь ниже, есть некоторый код ruby для декодирования "signed_request", который facebook POST на ваш URL-адрес CANVAS, когда он выводит его для отображения внутри facebook.
В вашем контроллере действий:
decoded_request = Canvas.parse_signed_request(params[:signed_request])
И тогда это вопрос проверки декодированного запроса и отображения одной или другой страницы. (Не уверен в этом, мне неудобно с ruby)
decoded_request['page']['liked']
И вот связанный класс Canvas (из библиотека rubbraph fbgraph):
class Canvas
class << self
def parse_signed_request(secret_id,request)
encoded_sig, payload = request.split('.', 2)
sig = ""
urldecode64(encoded_sig).each_byte { |b|
sig << "%02x" % b
}
data = JSON.parse(urldecode64(payload))
if data['algorithm'].to_s.upcase != 'HMAC-SHA256'
raise "Bad signature algorithm: %s" % data['algorithm']
end
expected_sig = OpenSSL::HMAC.hexdigest('sha256', secret_id, payload)
if expected_sig != sig
raise "Bad signature"
end
data
end
private
def urldecode64(str)
encoded_str = str.gsub('-','+').gsub('_','/')
encoded_str += '=' while !(encoded_str.size % 4).zero?
Base64.decode64(encoded_str)
end
end
end
Ответ 2
Вам нужно написать небольшой PHP-код. Когда пользователь в первый раз щелкнет вкладку, вы можете проверить, нравится ли ему эта страница или нет. Ниже приведен пример кода
include_once("facebook.php");
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => FACEBOOK_APP_ID,
'secret' => FACEBOOK_SECRET,
'cookie' => true,
));
$signed_request = $facebook->getSignedRequest();
// Return you the Page like status
$like_status = $signed_request["page"]["liked"];
if($like_status)
{
echo 'User Liked the page';
// Place some content you wanna show to user
}else{
echo 'User do not liked the page';
// Place some content that encourage user to like the page
}
Ответ 3
Вот рабочий пример, который является вилкой этого ответа:
$(document).ready(function(){
FB.login(function(response) {
if (response.status == 'connected') {
var user_id = response.authResponse.userID;
var page_id = "40796308305"; // coca cola page https://www.facebook.com/cocacola
var fql_query = "SELECT uid FROM page_fan WHERE page_id="+page_id+" and uid="+user_id;
FB.api({
method: 'fql.query',
query: fql_query
},
function(response){
if (response[0]) {
$("#container_like").show();
} else {
$("#container_notlike").show();
}
}
);
} else {
// user is not logged in
}
});
});
Я использовал метод FB.api(JavaScript SDK) вместо FB.Data.query, который устарел.
Или вы можете использовать Graph API, как в этом примере:
$(document).ready(function() {
FB.login(function(response) {
if (response.status == 'connected') {
var user_id = response.authResponse.userID;
var page_id = "40796308305"; // coca cola page https://www.facebook.com/cocacola
var fql_query = "SELECT uid FROM page_fan WHERE page_id=" + page_id + " and uid=" + user_id;
FB.api('/me/likes/'+page_id, function(response) {
if (response.data[0]) {
$("#container_like").show();
} else {
$("#container_notlike").show();
}
});
} else {
// user is not logged in
}
});
});
Ответ 4
Для JavaScript-кода для обработки рендеринга необходимо использовать некоторые изменения, основанные на симпатии пользователя или не понравившейся странице, на которую Facebook перешел на авторизацию Auth2.0.
Изменить довольно просто: -
сеансы должны быть заменены на authResponse и uid с помощью userID
Кроме того, учитывая требование кода и некоторые проблемы, с которыми сталкиваются люди (включая меня) вообще с FB.login, использование FB.getLoginStatus является лучшей альтернативой. Он сохраняет запрос к FB в случае входа пользователя в систему и аутентификации вашего приложения.
Обратитесь к разделу "Ответ и сеанс" для получения информации о том, как это может сохранить запрос на сервер FB. http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
Проблемы с FB.login и его исправлениями с использованием FB.getLoginStatus.
http://forum.developers.facebook.net/viewtopic.php?id=70634
Вот приведенный выше код с изменениями, которые сработали для меня.
$(document).ready(function(){
FB.getLoginStatus(function(response) {
if (response.status == 'connected') {
var user_id = response.authResponse.userID;
var page_id = "40796308305"; //coca cola
var fql_query = "SELECT uid FROM page_fan WHERE page_id =" + page_id + " and uid=" + user_id;
var the_query = FB.Data.query(fql_query);
the_query.wait(function(rows) {
if (rows.length == 1 && rows[0].uid == user_id) {
$("#container_like").show();
//here you could also do some ajax and get the content for a "liker" instead of simply showing a hidden div in the page.
} else {
$("#container_notlike").show();
//and here you could get the content for a non liker in ajax...
}
});
} else {
// user is not logged in
}
});
});
Ответ 5
С Javascript SDK вы можете изменить код, как показано ниже, это должно быть добавлено после вызова FB.init.
// Additional initialization code such as adding Event Listeners goes here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
alert('we are fine');
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
alert('please like us');
$("#container_notlike").show();
} else {
// the user isn't logged in to Facebook.
alert('please login');
}
});
FB.Event.subscribe('edge.create',
function(response) {
alert('You liked the URL: ' + response);
$("#container_like").show();
}
Ответ 6
Здесь есть статья, описывающая вашу проблему.
http://www.hyperarts.com/blog/facebook-fan-pages-content-for-fans-only-static-fbml/
<fb:visible-to-connection>
Fans will see this content.
<fb:else>
Non-fans will see this content.
</fb:else>
</fb:visible-to-connection>