I'm writing a Facebook iframe/canvas app and would like to give users the ability to invite friends to install this app. Currently I am using Facebook's PHP-SDK for logging in the users and all interaction with Facebook. The only things I can find about implementing the invite friends dialog either relate to FBML, which has bee deprecated; or the requests dialog: https://developers.facebook.com/docs/reference/dialogs/requests/ . The latter seems to require the use of Facebook's Javascript SDK, which has its own methods for login.
Is the JS SDK my only option, and if so, how can I use this without forcing my users to have to login again?
first approach:
function newInvite(){
var receiverUserIds = FB.ui({
method : 'apprequests',
message: 'Come on man checkout my applications.',
},
function(receiverUserIds) {
console.log("IDS : " + receiverUserIds.request_ids);
}
);
//http://developers.facebook.com/docs/reference/dialogs/requests/
}
Second Approach:
<?php
include_once "fbmain.php";
if (isset($_REQUEST['ids'])){
echo "Invitation Successfully Sent";
echo '<pre>';
print_r($_REQUEST);
echo '</pre>';
echo "<b>If you need to save these user ids then save these to database <br />then redirect user to the apps.facebook.com/yourapp url</b>";
$string = "<script type='text/javascript'>top.location.href='{$fbconfig['appBaseUrl']}'; </script>";
echo "Use the following javascript code to redirect user <br />";
echo htmlentities($string, ENT_QUOTES);
}
else {
?>
<fb:serverFbml style="width: 500px;">
<script type="text/fbml">
<fb:fbml>
<fb:request-form
action="<?=$fbconfig['baseUrl']?>/invite.php"
target="_top"
method="POST"
invite="true"
type="Demo Application Learning API"
content="Checkout this demo application and learn iframe base facebook application development. <fb:req-choice url='<?=$fbconfig['appBaseUrl']?>' label='Accept' />"
>
<fb:multi-friend-selector
showborder="false"
actiontext="Checkout this demo application">
</fb:request-form>
</fb:fbml>
</script>
</fb:serverFbml>
<?php } ?>
third approach(using PHP-SDK):
$app_id = "YOUR_APP_ID";
$canvas_page = "YOUR_CANVAS_PAGE_URL";
$message = "Would you like to join me in this great app?";
$requests_url = "http://www.facebook.com/dialog/apprequests?app_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page)
. "&message=" . $message;
if (empty($_REQUEST["request_ids"])) {
echo("<script> top.location.href='" . $requests_url . "'</script>");
} else {
echo "Request Ids: ";
print_r($_REQUEST["request_ids"]);
}
?>
Yes - currently the FB JS requests dialog is the only way. And your users won't need to authenticate with your app - in fact they won't need to authenticate with it all. I have a jsfiddle example with code you can look at, but all you need to specify is your app id.
currently (as of v2.3) there is no way for canvas app's that are not games to invite users.
Can non-game app use FB apprequests dialog in FB v2
Related
Is this scenario possible?
Customer goes to my website, wants to download a PDF technical document that interests them, they click the Download button and a Facebook share window appears to log them in to share it to Facebook. Once they click Share and it is posted on their wall then the download begins?
Many thanks.
Ian
UPDATE
According to a Facebook new policy, this act is not allowed. Use it at your own risk. I hold no responsibilities for using this.
Yes, using the JavaScript SDK, it provides a response (it doesn't anymore)
We will create an if statement to see if the response has a post_id if yes show the download link else do something else (alert the user, maybe?)
DEMO (API 2.0) (not working; revision required)
DEMO (API 2.7) working Rev#63
HTML
<div class="container">
<div>
<p>This file is locked, to unlock and download it, share it</p>
<p class="hidden">Thanks for sharing, the file is unlocked and ready for download</p>
<p class="hidden">In order to download this file, you need to share it</p>
</div>
<a class="fsl fsl-facebook" href="#" id="facebook-share">
<span class="fa-facebook fa-icons fa-lg"></span>
<span class="sc-label">Share on Facebook</span>
</a>
<a class="fsl content-download" href="#" id="download-file">
<span class="fa-download fa-icons fa-lg"></span>
<span class="sc-label">Download File</span>
</a>
</div>
JavaScript (jQuery)
$('#ShareToDownload').on('click', function(e) {
e.preventDefault();
FB.ui({
display: 'popup',
method: 'share',
href: location.href,
},
/** our callback **/
function(response) {
if (response && response.post_id) {
/** the user shared the content on their Facebook, go ahead and continue to download **/
$('#ShareToDownload').fadeOut(function(){ $('#downloadSection').fadeIn() });
} else {
/** the cancelled the share process, do something, for example **/
alert('Please share this page to download this file'):
}
});
});
UPDATE
With the release of API version 2.0 the Feed dialog was deprecated and replaced with the new modern Share Dialog so the above code uses the new Share Dialog
Thank you, works perfect! I Didn't know how to get the download link from a JSON file, so I did it slightly different, maybe not that safe.
Add this to the section where the response is checked
$.post('optimus.php', { 'fieldname' : 'download', 'value' : 'yes'});
Made a new page where the session is set (optimus.php)
<?php
session_start();
$_SESSION[$_POST['fieldname']] = $_POST['value'];
?>
Download.php contains the following code
<?php
session_start();
if($_SESSION['download'] == "yes"){
session_destroy();
$file = 'file.zip';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
} else {
echo "You didn't share, or you already downloaded the file";
}
?>
So, when the user shared something, the $_SESSION['download'] is set to yes. Download.php checks if it's yes and when it is the download is automatically started. Also, the session is destroyed so they can only download once.
I am trying to create a non-expiring page token that I can use on my site to make posts on my Facebook page. According to scenario 5 in this document I should be able to do this:
https://developers.facebook.com/roadmap/offline-access-removal/
My problem is that when I generate the page tokens, they expire in 1 hour.
What I am doing is using this code to display my user access token when I login. I think this is the same token provided by graph api explorer, but I am unsure.
require '../src/facebook.php';
$facebook = new Facebook(array(
'appId' => 'app_id',
'secret' => 'app_secret',
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
if ($user) {
$logoutUrl = $facebook->getLogoutUrl( array(
'scope' => 'read_stream,publish_stream,publish_actions,manage_pages,email,user_checkins',
));
} else {
$loginUrl = $facebook->getLoginUrl();
}
echo $loginUrl;
$me = $facebook->api('/me');
?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<title>php-sdk</title>
</head>
<body>
<h1>php-sdk</h1>
<?php if ($user): ?>
Logout
<?php else: ?>
<div>
Login using OAuth 2.0 handled by the PHP SDK:
Login with Facebook
</div>
<?php endif ?>
<h3>PHP Session</h3>
<pre><?php print_r($_SESSION); ?></pre>
<?php if ($user): ?>
<h3>You</h3>
<img src="https://graph.facebook.com/<?php echo $user; ?>/picture">
<h3>Your User Object (/me)</h3>
<pre><?php print_r($user_profile); ?></pre>
<?php else: ?>
<strong><em>You are not Connected.</em></strong>
<?php endif ?>
</body>
</html>
I then use that token in this graph api command:
https://graph.facebook.com/me/accounts?access_token=<access_token>
This gives me a list of all my pages and apps and their respective page/app tokens.
I then take the page token I want to use and check with the Facebook Access Token Debugger and it shows it has an expiration of 1 hour. So I use the following command to try and exchange it for a 60 day token as described in the first URL i posted:
https://graph.facebook.com/oauth/access_token?client_id=client_id&client_secret=client_secret&grant_type=fb_exchange_token&fb_exchange_token=access_token
The command just gives me the error: "message": "An unknown error has occurred.","type": "OAuthException", "code": 1.
I then thought maybe because my user access token is not long lived, it wont generate a long lived page token. So I used my user token with the same command to extend it and it just returns the same token back with the expiration not extended.
Can anyone offer some insight as to what I am doing wrong and how I can create this non-expiring page token?
Read the instructions again carefully - based on your description you're:
Getting a short user token
Getting a short page token from /me/accounts
Attempting to extend the short page token
What you should be doing is:
Getting a short user token (if client side auth)
Exchanging that for a long user token (or you'll already have a long user token if you used the server side oauth flow)
Using the long user token to retrieve the (long) page access token
I'm trying to build an app that lets users vote in 4 different categories,
I want to save the User id so that I can make sure someone can only vote once.
I know you can get the user id when a user interacts with the tab, I've read something about fb_sig_profile_user but I don't know how to use this.
I've read a little about this on the facebook dev page but it isn't very clear.
If I understand correctly you can get the user id after a user clicks on something and the facebook tab does an ajax call.
Then at that moment you can grab the user id but I don't know how.
I have many Facebook page tabs that require the Facebook user id to ensure no duplicate entries are made for one user. What you have to do is step up a Facebook app. Configure it as a Page Tab app and put it on your Facebook page. Once it is there, then you do a Facebook login popup asking for user permissions. After that, you can use the SDK to query the current user to get their ID (or you can decode the signed_request form post parameter that facebook posts to your tab app). You can also do similar things in non-page tab apps wether it is a standalone website or a iFramed canvas app.
Facebook will make a POST request to your app with a signed_request parameter which, after you decode as described in the docs, will yield a hash of information such as the user's country.
If the user has authorized your app, then that same parameter will contain additional information such as the user's Facebook id.
//use this to get facebook user id
<?php session_start();?>
<?php require 'src/facebook.php';
$app_id = "your_app_id";
$app_secret = "your_secret_key";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret
));
$canvas_page = "https://www.facebook.com/page_name/app_appid"; //this is you facebook app url
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo $data["user_id"];
$_SESSION['fbuser']=$data["user_id"];
}
?>
I am attempting a test app to learn on facebook. I am using this code from the facebook developer page:
<?php
$app_id = "YOUR_APP_ID";
$canvas_page = "YOUR_CANVAS_PAGE_URL";
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
?>
When I run this I get:
Message: Undefined index: signed_request
I am using this in Codeigniter. I have no idea if that matters.. When I run this it uses the $auth_url and return:
http://mydomain.com/responsepage?code=biglongstring
so I know I am getting to facebook and getting something...
In that string url returned is a variable named "code." I tried to change the $_REQUEST object to look for "code" but it gives the same error.
It does redirect me back to my response page after it briefly displays the error because the "user_id" element is empty. It is empty because signed_request is not present in the url sent back.
What am I doing wrong? It should go to facebook, ask for me to allow the app, display the user_id. For some reason the signed_request just isn't there.
Thank you.
EDIT: I'm looking at this again. Where does it ever actually go out and use that URL?
EDIT: If I use the $auth_url manually, pasting it in the address of the browser it redirects back to my response page with no problem. Of course, I did not see a variable named signed_request, just "code" so I don't know what's going on.
Okay it seems that you are using your Canvas URL in the $canvas_page variable which is wrong. You need to use the Canvas Page which is something like: http://apps.facebook.com/appnamespace
This way, your app will open inside the iframe and Facebook will be able to send you the signed_request
Make sure that you have "signed_request for Canvas" enabled in settings->advanced->migrations
Then you should get the signed_request via $_POST.
Twitter offers a dead simple method for prepoulating someones status for posting. Specifically, its as easy as http://twitter.com/?status=message .
I am looking for a similar method to use for facebook. Unfortunately, all I can find are like buttons and similar, which don't fit my need (the content we want posted does not have its own page). Is there any method on facebook to easily set someones status?
It sounds like you just want a simple way to share content onto Facebook. Facebook is deprecating the Share Button, but still seems to support direct URL calls to the Share page:
http://www.facebook.com/sharer/sharer.php?u=cnn.com&t=great+news+site
So, create a link that opens your URL in a new window, like in this Javascript:
window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(myUrl)+'&t='+encodeURIComponent(myTitle),'sharer','toolbar=0,status=0,width=626,height=436');
You mention prefilling it with default text. I believe Facebook explicitly forbids this now. They say this in the Feed Dialog page, which should pretty much cover their policy for the Sharer page too:
This field will be ignored on July 12, 2011 The message to prefill the text field that the user will type in. To be compliant with Facebook Platform Policies, your application may only set this field if the user manually generated the content earlier in the workflow. Most applications should not set this.
This used to work at https://www.facebook.com/connect/prompt_feed.php?message=woot
But nolonger does.
In Facebook, to post to a certain user's profile you need the following:
The user to authenticate/authorize your application
You ask for an extended permission to be able to post to his wall (publish_stream in this case)
Capture the user id and use it to post whatever you want
Now doing the is easy and can be done in different ways, let's take the PHP-SDK example page and modify it:
<?php
/**
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
require '../src/facebook.php';
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => '191149314281714',
'secret' => '73b67bf1c825fa47efae70a46c18906b',
));
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
// Login or logout url will be needed depending on current user state.
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$loginUrl = $facebook->getLoginUrl(
'scope' => 'publish_stream'
);
}
// This call will always work since we are fetching public data.
$naitik = $facebook->api('/naitik');
?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<title>php-sdk</title>
<style>
body {
font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
}
h1 a {
text-decoration: none;
color: #3b5998;
}
h1 a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<h1>php-sdk</h1>
<?php if ($user): ?>
Logout
<?php else: ?>
<div>
Login using OAuth 2.0 handled by the PHP SDK:
Login with Facebook
</div>
<?php endif ?>
<h3>PHP Session</h3>
<pre><?php print_r($_SESSION); ?></pre>
<?php if ($user): ?>
<h3>You</h3>
<img src="https://graph.facebook.com/<?php echo $user; ?>/picture">
<h3>Your User Object (/me)</h3>
<pre><?php print_r($user_profile); ?></pre>
<?php else: ?>
<strong><em>You are not Connected.</em></strong>
<?php endif ?>
<h3>Public profile of Naitik</h3>
<img src="https://graph.facebook.com/naitik/picture">
<?php echo $naitik['name']; ?>
</body>
</html>
Now I changed the following from the original example:
$loginUrl = $facebook->getLoginUrl(array(
"scope" => "publish_stream"
));
Now that the user granted your application the right permission you can post to his wall, refer to this answer to get you started.