I'm generating a Login URL, which works great, but in my case the email permission is mandatory so I need to explain to the user and re-ask the email permission.
Here's how I'm generating the URL:
$fb = new Facebook\Facebook([
'app_id' => fbappid,
'app_secret' => fbappsecret,
'default_graph_version' => 'v2.2',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'user_birthday', 'user_location', 'user_hometown', 'user_relationships']; // Optional permissions
$loginUrl = $helper->getLoginUrl('http://localhost/urbanportal/wifilogin.php?origlink='.$_SESSION['origlink'].'&routerlink='.$_SESSION['routerlink'].'&siteid='.$_SESSION['siteid'], $permissions);
I read that you can pass a third parameter that says you're doing a re-request like so:
$loginUrl = $helper->getLoginUrl('http://localhost/urbanportal/wifilogin.php?origlink='.$_SESSION['origlink'].'&routerlink='.$_SESSION['routerlink'].'&siteid='.$_SESSION['siteid'], $permissions, true);
But I'm getting a "Length of param app_id must be less than or equal to 32" Facebook error, maybe that was for SDK 4.0?
The documentation always seems to navigate me to:
FB.login(
function(response) {
console.log(response);
},
{
scope: 'user_likes',
auth_type: 'rerequest'
}
);
But this is for Javascript SDK...
A quick look in the source code of the SDK reveals that there’s a dedicated method getReRequestUrl for that:
/**
* Returns the URL to send the user in order to login to Facebook with permission(s) to be re-asked.
*
* #param string $redirectUrl The URL Facebook should redirect users to after login.
* #param array $scope List of permissions to request during login.
* #param string $separator The separator to use in http_build_query().
*
* #return string
*/
public function getReRequestUrl($redirectUrl, array $scope = [], $separator = '&')
https://github.com/facebook/facebook-php-sdk-v4/blob/5.0-dev/src/Facebook/Helpers/FacebookRedirectLoginHelper.php#L202
I hope you are aware though that you will not get an email address for every FB user; f.i. they simply might not have one on file with Facebook, so even with the email permission you won’t get an email address.
Related
I would like to know if it's possible to login on Facebook api without a callback URL.
What I want to do is really "simple":
- Login on Facebook.
- Post or Delete on the wall.
- Logout of Facebook.
This is my code for login and post:
$fb = new Facebook\Facebook([
'app_id' => 'xxxx',
'app_secret' => 'xxxx',
'default_graph_version' => 'v2.5',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['publish_actions'];
$loginUrl = $helper->getLoginUrl(null, $permissions);
echo 'Log in with Facebook!';
try {
$accessToken = 'xxxx';
//$accessToken = $helper->getAccessToken();
//echo 'Log in with Facebook!';
$linkData = [
'link' => 'http://www.desarrollolibre.net/blog/tema/50/html/uso-basico-del-canvas',
'message' => $model->value,
];
$response = $fb->post('/feed', $linkData, $accessToken);
$graphNode = $response->getGraphNode();
The problem here is that I have to specify the access token getting directly from developers app, because $accessToken = $helper->getAccessToken() returns nothing to me.
Any help will be appreciate.
You can't "auto-login", you have to implement a proper login process. If you want to automate things (and you really should not autopost, because that is not allowed), you need to store a User Access Token somewhere and use it later. You may want to use an Extended User Token for this, because the default one is only valid for 2 hours. The Extended User Token is valid for 60 days.
More information about Tokens and how to generate them:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/
I have used this code for auto post on my facebook fan page
<?php
// Requires Facebook PHP SDK 3.0.1: https://github.com/facebook/php-sdk/
require ('facebook.php');
define('FACEBOOK_APP_ID',"YOUR-APP-ID");
define('FACEBOOK_SECRET',"YOUR-APP-API-SECRET");
$user = null;
$facebook = new Facebook(array(
'appId' => FACEBOOK_APP_ID,
'secret' => FACEBOOK_SECRET,
'cookie' => true
));
$user = $facebook->getUser(); // Get the UID of the connected user, or 0 if the Facebook user is not connected.
if($user == 0) {
/**
* Get a Login URL for use with redirects. By default, full page redirect is
* assumed. If you are using the generated URL with a window.open() call in
* JavaScript, you can pass in display=popup as part of the $params.
*
* The parameters:
* - redirect_uri: the url to go to after a successful login
* - scope: comma separated list of requested extended perms
*/
$login_url = $facebook->getLoginUrl($params = array('scope' => "publish_stream"));
echo ("<script> top.location.href='".$login_url."'</script>");
} else {
try {
$params = array(
'message' => "Hurray! This works :)",
'name' => "This is my title",
'caption' => "My Caption",
'description' => "Some Description...",
'link' => "http://stackoverflow.com",
'picture' => "http://i.imgur.com/VUBz8.png",
);
$post = $facebook->api("/$user/feed","POST",$params);
echo "Your post was successfully posted to UID: $user";
}
catch (FacebookApiException $e) {
$result = $e->getResult();
}
}
?>
But I need to post on my facebook fan page with my fan page name, this scrpit work so good but this code post on my fan page with my admin account and not like my fan page.
PLZ HELP ME :(
I think you need to take a look to this article carefully, I did it using the steps mentioned there.
Just put you token here:
https://graph.facebook.com/me/accounts?access_token=token
Then you will find the access token for posting as a page.
Hope that helps.
I am trying to get a page access token starting out with just a users access token stored in my database and a page id. So far I have not been using the facebook.php instead just using php's curl_* functions. So far I can send posts to the page (with a hard coded page id) but I want to impersonate the page when doing so.
Can I do this easily without facebook.php, that would be nice as it might save me from feeling like I should rewrite what I've done so far. If not, then how would I get the page access token from the facebook object - remember so far at least I don't store user ids or page ids in my db, just user access tokens and of course my app id and secret.
I've been looking at the example for getting page access tokens but I find it not quite what I need as it gets a user object and in so doing seems to force the user to login to facebook each time, but I stored the user access token to avoid exactly that from happening.
Do I need more permissions than manage_page and publish_stream? I tried adding offline_access but it doesn't seem available anymore (roadmap mentions this).
here is some of my code from my most recent attempt which uses the facebook.php file:
// try using facebook.php
require_once 'src/facebook.php';
// Create our Application instance
$facebook = new Facebook(array(
'appId' => $FB_APP_ID, // $FB_APP_ID hardcoded earlier
'secret' => $FB_APP_SECRET, // $FB_APP_SECRET hardcoded earlier
));
$facebook->setAccessToken($FB_ACCESS_TOKEN );
//got user access token $FB_ACCESS_TOKEN from database
// Get User ID -- why?
$user = $facebook->getUser();
//------ get PAGE access token
$attachment_1 = array(
'access_token' => $FB_ACCESS_TOKEN
);
$result = $facebook->api("/me/accounts", $attachment_1);
foreach($result["data"] as $page) {
if($page["id"] == $page_id) {// $page_id hardcoded earlier
$page_access_token = $page["access_token"];
break;
}
}
echo '<br/>'.__FILE__.' '.__FUNCTION__.' '.__LINE__.' $result= ' ;
var_dump($result); //this prints: array(1) { ["data"]=> array(0) { } }
$facebook->setAccessToken($page_access_token );
// Get User ID, why - re-init with new token maybe?
$user = $facebook->getUser();
//------ write to page wall
try {
$attachment = array(
'access_token' => $page_access_token,
'link' => $postLink,
'message'=> $postMessage
);
$result = $facebook->api('/me/feed','POST', $attachment);
echo '<br/>'.__FILE__.' '.__FUNCTION__.' '.__LINE__.' $result= ' ;
var_dump($result);
} catch(Exception $e) {
echo '<br/>'.__FILE__.' '.__FUNCTION__.' '.__LINE__.' $e= ' ;
var_dump($e); /*this gives : "An active access token must
be used to query information about the
current user." */
}
die;
Thanks
PS: I hardcoded the user id and started calling
$result = $facebook->api("/$user_id/accounts", $attachment_1);
and I still get an empty result.
PPS: The Graph API Explorer does not show my fan pages either even though my account is set as the Manager. My attempts to post work but show as being from my account rather than from the page.
PPPS: made a little progress by adding permissions on the graph explorer page to get an access token that way but that doesn't help as I need to the the access token programmatically. When a user with many fan pages logs in to my site I want to show them the list of their facebook fan pages to choose from. In practice aren't the permissions just granted on the app?
PPPPS: the list of permissions on my app now stands at : email, user_about_me, publish_actions
and
Extended Permissions:
manage_pages, publish_stream, create_note, status_update, share_item
do I need more? when I try now I still fail to get anything from the call to:
$facebook->api("/$user_id/accounts", $attachment_1);
Px5S: DOH!!! I see now that I was neglecting to add the manage_pages permissions to my call for a user access token when my scripts first get one and store it in the DB. But when I reuse that new access token I still get the error : "An active access token must be used to query information about the current user." So, can't such tokens be reused? Aren't they long term? will read more stuff...
Here is my functioning code, still messy but seems to work, note the scopes on the first $dialog_url, and please feel free to mock my code or even suggest improvements :
function doWallPost($postName='',$postMessage='',$postLink='',$postCaption='',$postDescription=''){
global $FB_APP_ID, $FB_APP_SECRET;
$APP_RETURN_URL=((substr($_SERVER['SERVER_PROTOCOL'],0,4)=="HTTP")?"http://":"https://").$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'?returnurl=1';
$code = $_REQUEST["code"];
$FB_ACCESS_TOKEN = getFaceBookAccessToken( );
$FB_ACCESS_TOKEN_OLD = $FB_ACCESS_TOKEN;
//if no code ot facebook access token get one
if( empty($code) && empty($FB_ACCESS_TOKEN) && $_REQUEST["returnurl"] != '1')
{
// if( $_REQUEST["returnurl"] == '1') die;
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=".$FB_APP_ID."&redirect_uri=".$APP_RETURN_URL."&scope=publish_stream,manage_pages";
header("Location:$dialog_url");
}
if( empty($FB_ACCESS_TOKEN) ){
if($_REQUEST['error_code'] == '200'){
return null;
}else if (!empty($code)){
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$FB_APP_ID."&redirect_uri=".urlencode($APP_RETURN_URL)."&client_secret=".$FB_APP_SECRET."&code=".$code;
$access_token = file_get_contents($token_url);
$param1=explode("&",$access_token);
$param2=explode("=",$param1[0]);
$FB_ACCESS_TOKEN=$param2[1];
}else{
return null;
}
}
if(!empty($FB_ACCESS_TOKEN) && $FB_ACCESS_TOKEN_OLD != $FB_ACCESS_TOKEN) {
setFaceBookAccessToken( $FB_ACCESS_TOKEN);
}
$_SESSION['FB_ACCESS_TOKEN'] = $FB_ACCESS_TOKEN;
$page_name = '';
$page_id = getFaceBookPageId(); //from db
if(empty($page_id ) ) return null;
//in case there are multiple page_ids separated by commas
if(stripos($page_id, ',') !== false ){
$page_ids = explode(',', $page_id) ;// = substr($page_id, 0, stripos($page_id, ','));
}
$result = null;
foreach($page_ids as $page_id){
$page_id = trim($page_id);
if( !empty($FB_ACCESS_TOKEN)){
//get page_id
require_once 'src/facebook.php';
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => $FB_APP_ID,
'secret' => $FB_APP_SECRET
));
$facebook->setAccessToken($FB_ACCESS_TOKEN );
//------ get PAGE access token
$page_access_token ='';
$attachment_1 = array(
'access_token' => $FB_ACCESS_TOKEN
);
$result = $facebook->api("/me/accounts", $attachment_1);
if(count($result["data"])==0) {
return null;
}
foreach($result["data"] as $page) {
if($page["id"] == $page_id) {
$page_access_token = $page["access_token"];
break;
}
}
//------ write to page wall
try {
$attachment = array(
'access_token' => $page_access_token,
'link' => $postLink,
'message'=> $postMessage
);
$result = $facebook->api('/me/feed','POST', $attachment);
} catch(Exception $e) {
return null;
}
} //end if( !empty($FB_ACCESS_TOKEN))
}//end foreach
return $result; }
Now, I wonder if I can send the same message to several pages at once ...
Yup, just by looping over the ids, see above, it now supports multiple page ids.
And unless someone wants to contribute to the code - there's lots of ways it can be improved - I'm done.
I am using Zend Gmail Oauth 1.0 for implementing login with Gmail feature.
After successful authentication, how can I get authenticated user's profile, specifically user's unique gmail id? Here is the code:
$THREE_LEGGED_SCOPES = array('https://mail.google.com/',
'https://www.google.com/m8/feeds');
$options = array(
'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
'version' => '1.0',
'consumerKey' => $THREE_LEGGED_CONSUMER_KEY,
'consumerSecret' => $THREE_LEGGED_CONSUMER_SECRET_HMAC,
'callbackUrl' => getCurrentUrl(),
'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken',
'userAuthorizationUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken',
'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken'
);
if ($THREE_LEGGED_SIGNATURE_METHOD == 'RSA-SHA1') {
$options['signatureMethod'] = 'RSA-SHA1';
$options['consumerSecret'] = new Zend_Crypt_Rsa_Key_Private(
file_get_contents(realpath($THREE_LEGGED_RSA_PRIVATE_KEY)));
} else {
$options['signatureMethod'] = 'HMAC-SHA1';
$options['consumerSecret'] = $THREE_LEGGED_CONSUMER_SECRET_HMAC;
}
$consumer = new Zend_Oauth_Consumer($options);
/**
* When using HMAC-SHA1, you need to persist the request token in some way.
* This is because you'll need the request token's token secret when upgrading
* to an access token later on. The example below saves the token object
* as a session variable.
*/
if (!isset($_SESSION['ACCESS_TOKEN'])) {
if (!isset($_SESSION['REQUEST_TOKEN'])) {
// Get Request Token and redirect to Google
$_SESSION['REQUEST_TOKEN'] = serialize($consumer->getRequestToken(array('scope' => implode(' ', $THREE_LEGGED_SCOPES))));
$consumer->redirect();
} else {
// Have Request Token already, Get Access Token
$_SESSION['ACCESS_TOKEN'] = serialize($consumer->getAccessToken($_GET, unserialize($_SESSION['REQUEST_TOKEN'])));
header('Location: ' . getCurrentUrl(false));
exit;
}
} else {
// Retrieve mail using Access Token
$accessToken = unserialize($_SESSION['ACCESS_TOKEN']);
}
near as I can tell you can't.
Gmail doesn't have an api just a read only feed.
However if you want that feed the scope url is:
https://mail.google.com/mail/feed/atom/
There are some api's for working with gmail accounts in the context of Google Apps.
I've setup a script which allows users to post messages to a fan page on Facebook. It all works but there's one small issue.
The Problem:
When the post is added to the page feed it displays the posting user's personal account.
I would prefer it to show the account of the page (like when you're admin of the page it says it came from that page). The account I'm posting with have admin rights to the page, but it still shows as a personal post.
HTTP POST
$url = "https://graph.facebook.com/PAGE_ID/feed";
$fields = array (
'message' => urlencode('Hello World'),
'access_token' => urlencode($access_token)
);
$fields_string = "";
foreach ($fields as $key => $value):
$fields_string .= $key . '=' . $value . '&';
endforeach;
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
curl_close($ch);
To post as Page not as User, you need the following:
Permissions:
publish_stream
manage_pages
Requirements:
The page id and access_token (can be obtained since we got the required permissions above)
The current user to be an admin (to be able to retrieve the page's access_token)
An access_token with long-lived expiration time of one of the admins if you want to do this offline (from a background script)
PHP-SDK Example:
<?php
/**
* Edit the Page ID you are targeting
* And the message for your fans!
*/
$page_id = 'PAGE_ID';
$message = "I'm a Page!";
/**
* This code is just a snippet of the example.php script
* from the PHP-SDK <http://github.com/facebook/php-sdk/blob/master/examples/example.php>
*/
require '../src/facebook.php';
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => 'app_id',
'secret' => 'app_secret',
));
// Get User ID
$user = $facebook->getUser();
if ($user) {
try {
$page_info = $facebook->api("/$page_id?fields=access_token");
if( !empty($page_info['access_token']) ) {
$args = array(
'access_token' => $page_info['access_token'],
'message' => $message
);
$post_id = $facebook->api("/$page_id/feed","post",$args);
} else {
$permissions = $facebook->api("/me/permissions");
if( !array_key_exists('publish_stream', $permissions['data'][0]) ||
!array_key_exists('manage_pages', $permissions['data'][0])) {
// We don't have one of the permissions
// Alert the admin or ask for the permission!
header( "Location: " . $facebook->getLoginUrl(array("scope" => "publish_stream, manage_pages")) );
}
}
} 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(array('scope'=>'manage_pages,publish_stream'));
}
// ... rest of your code
?>
Here the connected $user is supposed to be the admin.
Result:
More in my tutorial
As far as I know, all you have to do is specify a uid (that is, the page's ID) in your call to stream.publish
EDIT
Have a look at impersonation
Because the is the only relevant posting in the google results for "facebook graph won't post to page as page" I want to make a note of the solution I found. You need an access token with manage_pages permissions. Then call
https://graph.facebook.com/<user_id>/accounts?access_token=<access_token>
This will list all the pages the user has access to and will provide the access tokens for each. You can then use those tokens to post as the page.
The Graph API expects the parameter page_id (The Object ID of the Fan Page) to be passed in as an argument to API calls to get the events posted in a Fanpage wall. Not mentioned anywhere in the official Graph API documentation, but it works. I have tested it successfully with the Official PHP SDK v3.0.1
The required application permissions would be create_event and manage_pages
An Example would look something like this:
//Facebook/Fan Page Id
$page_id = '18020xxxxxxxxxx';
//Event Start Time
$next_month = time() + (30 * 24 * 60 * 60);
//Event Paramaeters
$params = array(
'page_id' => $page_id, // **IMPORTANT**
'name' => 'Test Event Name',
'description' => 'This is the test event description. Check out the link for more info: http://yoursite.com',
'location' => 'Kottayam, Kerala, India',
'start_time' => $next_month
);
$create_event = $facebook->api("/$page_id/events", "post", $params);
The answer lies with acquiring a permission of "manage_pages" on the FB:login button, like so:
<fb:login-button perms="publish_stream,manage_pages" autologoutlink="true"></fb:login-button>`
When you get those permissions, you can then get a structured list back of all the pages the logged-in user is an Admin of. The URL to call for that is:
https://graph.facebook.com/me/accounts?access_token=YourAccessToken
I HATE the Facebook documentation, but here is a page with some of the information on it: https://developers.facebook.com/docs/reference/api/
See the 'Authorization' and 'Page Login' sections in particular on that page.
A great resource to put all of this together (for Coldfusion Developers) is Jeff Gladnick's CFC on RIA Forge: http://facebookgraph.riaforge.org/
I added the following UDF to Jeff's CFC if you care to use it:
<cffunction name="getPageLogins" access="public" output="true" returntype="any" hint="gets a user's associated pages they manage so they can log in as that page and post">
<cfset var profile = "" />
<cfhttp url="https://graph.facebook.com/me/accounts?access_token=#getAccessToken()#" result="accounts" />
<cfif IsJSON(accounts.filecontent)>
<cfreturn DeserializeJSON(accounts.filecontent) />
<cfelse>
<cfreturn 0/>
</cfif>
</cffunction>
What this returns is a structure of all the pages the logged-in user is an Admin of. It returns the page NAME, ID, ACCESS_TOKEN and CATEGORY (not needed in this context).
So, VERY IMPORTANT: The ID is what you pass to set what page you are posting TO, and the ACCESS_TOKEN is what you pass to set who you are POSTING AS.
Once you have the list of pages, you can parse the data to get a three-element array with:
ID - ACCESS_TOKEN - NAME
Be careful though, because the Facebook ACCESS_TOKEN does use some weird characters.
Let me know if you need any additional help.
You must retrieve access_tokens for Pages and Applications that the user administrates.
The access tokens can be queried by calling /{user_id}/accounts via the Graph API.
More details:
https://developers.facebook.com/docs/facebook-login/permissions/v2.0 -> Reference -> Pages
This is how I do it with PHP SDK 4.0 and Graph API 2.3:
/**
* Posts a message, link or link+message on the page feed as a page entity
*
* #param FacebookSession $session (containing a page admin user access_token)
* #param string $pageId
* #param string $message - optional
* #param string $link - optional
*
* #return GraphObject
*/
function postPageAsPage( $session, $pageId, $message = '', $link = '' ){
// get the page token to make the post request
$pageToken = ( new FacebookRequest(
$session,
'GET',
"/$pageId" . "?fields=access_token"
))->execute()->getGraphObject();
return ( new FacebookRequest(
$session,
'POST',
"/$pageId/feed",
array(
'access_token' => $pageToken->getProperty( 'access_token' ),
'message' => $message,
'link' => $link,
)
))->execute()->getGraphObject();
}