Using FB PHP API to post status update to news feed - php

I run a music search engine, I already use basic Facebook intergration, like the like button, but my next aim is to create deeper intergration,
I'm aiming that when a user searches for something($q which I set as a cookie $_COOKIE['q'] ), a status update will appear, saying what they searched for and a link to my site.
I can allow a user login to facebook through JavaScript but I presume I would need to do it the PHP way.
I need to use PHP, as, after the user gives permission, I would like it that the user isn't pestered again. I have the Facebook PHP SDK and have created an app on Facebook. Online tutorials haven't really helped and i'm still on square 1, even though my PHP is okayish.
I would really appreciate if anyone gave me some guidelines/ ideas or helped code it.
Thanks in advance!
Niall

Well What you need to do is relatively easy. I think you already have the right java script for this but I'll add that in aswell, just incase!
Okay! First we need to add the php script at the top of your page that gets the information if the user has logged-in to their facebook:
define('FACEBOOK_APP_ID', 'YOUR APP ID');
define('FACEBOOK_SECRET', 'YOUR APP SECRET');
function get_facebook_cookie($app_id, $application_secret) {
$args = array();
parse_str(trim($COOKIE['fbs' . $app_id], '"'), $args);
ksort($args);
$payload = '';
foreach ($args as $key => $value) {
if ($key != 'sig') {
$payload .= $key . '=' . $value;
}
}
if (md5($payload . $application_secret) != $args['sig']) {
return null;
}
return $args;
}
$fbcookie = get_facebook_cookie(FACEBOOK_APP_ID, FACEBOOK_SECRET);
$fb_access_token = $fbcookie['access_token'];
I'm presuming you know about the app ID and secret etc etc... fill those out under the define section.
Next we need to add a couple of things into the html for the javascript login:
FB.init({appId: 'YOUR APP ID AGAIN', status: true,
cookie: true, xfbml: true});
FB.Event.subscribe('auth.login', function(response) {
window.location.reload();
});
That goes into your body script.
The next part is the facebook login button:
?fb:login-button perms="publish_stream,offline_access" onlogin="window.location.reload(true);" autologoutlink="true"? ?/fb:login-button?
(the question marks are the <> symbols as these conflict with the coding symbols in Stackoverflow)
Now you may wonder about the need for offline access. That's easy... I wonder about that too! lol I'm not 100% sure why that occurs but I think it's my webserver (a tad odd it is) so try it without offline permissions first and if that doesn't work then add it back in.
So that's all you have to do for the login aspect and posting aspect is a curl script:
$url = "https://graph.facebook.com/me/feed";
$ch = curl_init();
$attachment = array( 'access_token' => '' . $fb_access_token . '',
'message' => "just searched " . $q . " at http://domain.com",
);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
$result= curl_exec($ch);
curl_close ($ch);
So did you see what I did? don't forget to add if statements depending on your website layout etc etc so that users don't keep posting "i just searched at http:// domain.com" lol although that would spark that human curiosity ;) due to no searching being done thus $q=NULL and thus it'll still send nothing lol so maybe ad an if statement for when you have a query lol :P (Yes i know I added a space in the url from my 'print' version however stackoverflow is picky about how many url's I can post v_v" lol).
Please ask me if you need me to explain an other parts any further.
Good luck and happy searching!
Jon

Related

How do I send info to this API using cURL and PUT?

I am working with an API that is documented here: https://cutt.ly/BygHsPV
The documentation is a bit thin, but I am trying to understand it the best I can. There will not be a developer from the creator of the API available before the middle of next week, and I was hoping to get stuff done before that.
Basically what I am trying to do is update the consent of the customer. As far as I can understand from the documentation under API -> Customer I need to send info through PUT to /customers/{customerId}. That object has an array called "communicationChoices".
Going into Objects -> CustomerUpdate I find "communicationChoices" which is specified as "Type: list of CommunicationChoiceRequest". That object looks like this:
{
"choice": true,
"typeCode": ""
}
Doing my best do understand this, I have made this function:
function update_customer_consent() {
global $userPhone, $username, $password;
// Use phone number to get correct user
$url = 'https://apiurlredacted.com/api/v1/customers/' . $userPhone .'?customeridtype=MOBILE';
// Initiate cURL.
$ch = curl_init( $url );
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt( $ch, CURLOPT_USERPWD, $username . ":" . $password );
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Data to send
$data = [
"communicationChoices" => [
"communicationChoiceRequest" => [
"choice" => true,
"typeCode" => "SMS"
]
]
];
$json_payload = json_encode($data);
print_r($json_payload);
// Set other options
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($json_payload)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
// Execute the cURL request
$response = curl_exec($ch);
// Check for errors.
if( curl_errno( $ch ) ) :
// If an error occured, throw an Exception.
throw new Exception( curl_error( $ch ) );
endif;
if (!$response)
{
return false;
} else {
// Decode JSON
$obj = json_decode( $response );
}
print_r($response);
}
I understand that this is very hard to debug without knowing what is going on within the API and with limited documentation, but I figured asking here was worth a shot anyway.
Basically, $json_payload seems to be a perfectly fine JSON object. The response from the API however, is an error code that means unknown error. So I must be doing something wrong. Maybe someone has more experience with APIs and such documentation and can see what I should really be sending and how.
Any help or guidance will be highly appreciated!
before you test your code, you can use the form provided on the API Documentation.
when you navigate to API > Customers > /customers/{customerId} (GET), you will see a form on the right side of the page (scroll up). you need to provide the required values on the form then hit Submit button. you will surely get a valid data for communicationChoices based on the result from the Response Text section below the Submit button.
now, follow the data structure of communicationChoices object that you get from the result and try the same on API > Customers > /customers/{customerId} (PUT) form.
using the API forms, you may be able to instantly see a success or error from your input (data structure), then translate it to your code.

Retrieving Facebook / Google+ / Linkedin profile picture having email address only

What I need
I need to automatically find & download profile picture for user knowing his email address only. Originally, I focused on Facebook considering the amount of people actively using it. However, there seem to be no direct support from their API anymore.
There was similar question here:
How to get a facebook user id from the login email address which is quite outdated and current answers there are "it's deprecated" / "it's not possible"...
EDIT: I've found even better question: Find Facebook user (url to profile page) by known email address (where it is actually explained why and since when this feature isn't supported)
There must be a way...
What makes me think that this should be possible is that Spokeo is somehow doing it:
http://www.spokeo.com/email-search/search?e=beb090303%40hotmail.com
There are some services / APIs offering this kind of feature:
Clearbit
Pipl
...but I haven't found anything free.
Alternatives
If there is some workaround or different approach than using Facebook's API to achieve this, I would like to know. If Facebook is really completely hopeless here, then combination of these: Google+, Linkedin and/or Gravatar could do.
My first (original) attempt:
Once you have Facebook's username or user ID, it's easy to build URL to download the picture. So I was trying to look for Facebook's user IDs using emails with the /search Graph API:
https://graph.facebook.com/search?q=beb090303#hotmail.com&type=user&access_token=TOKEN
which unfortunatelly always ends with "A user access token is required to request this resource."
Using FB PHP API + FB App ID & Secret
I've also tried this: at first I retrieve access_token using app ID and secret and then I'm trying to use it as a part of /search request with curl:
function post_query_url($url, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
function get_query_url($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
function get_retrieve_app_access_token($app_id, $secret) {
$url = 'https://graph.facebook.com/oauth/access_token?client_id='.$app_id.'&client_secret='.$secret.'&grant_type=client_credentials';
$res = get_query_url($url);
if (!empty($res)) {
$tokens = explode('=', $res);
if (count($tokens) == 2)
return $tokens[1];
}
return null;
}
function post_retrieve_app_access_token($app_id, $secret) {
$url = 'https://graph.facebook.com/oauth/access_token';
$data = 'client_id='.$app_id.'&client_secret='.$secret.'&grant_type=client_credentials';
$res = post_query_url($url, $data);
if (!empty($res)) {
$tokens = explode('=', $res);
if (count($tokens) == 2)
return $tokens[1];
}
return null;
}
function get_id_from_email($email, $accessToken) {
$url = 'https://graph.facebook.com/search?q='.urlencode($email).'&type=user&access_token='.$accessToken;
$res = get_query_url($url);
if (!empty($res)) {
return $res;
}
return null;
}
echo 'Retrieving token...<br>';
$token = post_retrieve_app_access_token('MY_APP_ID', 'SECRET');
echo 'Retrieved token: ' . $token . '<br>';
echo 'Retrieving user ID...<br>';
$id = get_id_from_email('beb090303#hotmail.com', $token);
echo 'Retrieved ID: ' . $id . '<br>';
outputs something like:
Retrieving token...
Retrieved token: 367458621954635|DHfdjCnvO243Hbe1AFE3fhyhrtg
Retrieving user ID...
Retrieved ID: {"error":{"message":"A user access token is required to request this resource.","type":"OAuthException","code":102}}
Other info
Since it's asking for "user access token", I've also tried to go to Facebook's Graph Explorer: https://developers.facebook.com/tools/explorer/
let it generate access token for me and queried:
search?q=beb090303#hotmail.com&type=user&debug=all
That one ends with:
{
"error": {
"message": "(#200) Must have a valid access_token to access this endpoint",
"type": "OAuthException",
"code": 200
}
}
...so Facebook seems kinda hopeless here.
That's exactly why Gravatar exists and why people use Gravatar, users know which public profile image they bind to which e-mail address and they know where to change it.
Your app can have the possibility for users to upload their own profile image and fallback to Gravatar.
If you just try to extract an image from Facebook or Google+, it might freak your users out and it will also be harder for them to know where your service got the profile image from.
Using Gravatar in PHP it is as simple as this:
<?php
$email = "email#server.com";
$default = ""; // absolute url to default image goes here or leave empty for default gravatar image
$size = 200;
$grav_url = "http://www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?d=" . urlencode($default) . "&s=" . $size;
header("content-type: image/jpeg");
echo file_get_contents($grav_url);
?>
Apart from that, you can also use Facebook and/or Google+ as external login providers where users can grant your application access to their profile information.
There was a bug: Can't search for user by email after July 2013 Breaking Changes that has been closed as "By Design" with official response:
"The ability to pass in an e-mail address into the "user" search type was removed on July 10, 2013. This search type only returns results that match a user's name (including alternate name)" ~ Joseph Tuấn Anh Phan (Facebook Team)
so probably no direct support from Graph API.
I've tried Graph API Explorer where you can try to play with some FQL too (just need to select version 2.0 as newer versions are not supported anymore), unfortunately query like:
SELECT uid, name FROM user where email = 'some.email#gmail.com'
gives:
"error": {
"message": "(#604) Your statement is not indexable. The WHERE clause must contain
an indexable column. Such columns are marked with * in the tables linked from
http://developers.facebook.com/docs/reference/fql ",
"type": "OAuthException",
"code": 604
}
and reference for table user shows that only uid and third_party_id can be used in WHERE.
You should need access token as well as Facebook id of the user. without knowing them cannot get their profile pic
I think Spokeo might have an agreement with Facebook to access the data? I would not be surprised.
Anyway, if you are on a profile you can maybe search for profile_id in the HTML. It's a hack, not sure if it works.
You could always allow people to comment by logging in with their g+/facebook/whatever account (requires you to do something OpenID-like, though); if they've logged in, you should be able to get the facebook uid.
Also, there's something called libravatar, which allows people to associate pictures with their OpenID or email address (and which falls back to gravatar if they haven't configured anything specifically for libravatar); using that should give you more photos than if you stick to "just" gravatar.

Check if the user is a fan of my facebook page?

I used to use the flowing code to check if the user is a fan of my page or not while he is on my facebook page. Now I want to check if the user is a fan of my facebook page while he is on my WEBSITE.
<?php
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["page"]["liked"])) {
echo "You are not a fan!";
} else {
echo "Welcome back fan!";
}
?>
I read through the facebook documentation, but I was not able to find suitable answer.
Help ?
I do not want to deal with any application permissions with facebook. How can I approach this through only php ?
You will not get page details if visiting application not in Page Tab.
You may achieve that with simple FQL query to page_fan table (knowing the id of the Facebook Page of course):
SELECT uid, page_id FROM page_fan WHERE uid=me() AND page_id=PAGE_ID
Or by querying Graph API for likes connection of user object:
https://graph.facebook.com/me/likes/PAGE_ID
Both of those ways require user_likes permission granted by user.
To get the same details for user's friends ask for friends_likes permission and substitute me/me() with friend id.
Update: (just to describe what you asked in comments)
There are cases that requiring user_likes may be unnecessary due to nature of flow, if you only need to know that user will/need to like some URL and/or Facebook Page.
You may do so by subscribing (FB.subscribe) to edge.create event which will be triggered once user will like the page (for un-like there is edge.remove event).
Beware that this is only reliable in cases user didn't liked that content before since edge.create only fired on time of user's action.
A better approach to the problem is:
// to generate user access token after the user is logged in
$USER_ACCESS_TOKEN = $facebook->getExtendedAccessToken();
$isFan = curl("https://api.facebook.com/method/pages.isFan?format=json&access_token=" . $USER_ACCESS_TOKEN . "&page_id=" . $FACEBOOK_PAGE_ID);
function curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}

facebook access_token request return NOTHING

it's been 5 days that I'm stuck in the implementation of a simple fb login and I'm banging my head like a motherf***r. anyways.
I'm at the point that I'm trying to set the accessToken by hand.
like shown in this post.
https://github.com/facebook/php-sdk/issues/418#issuecomment-2605012
the only problem is that the oauth/access_token call returns nothing
and I'm guessing that it's a pretty messed up behaviour.
this is the snippet I use to make the call
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".FB_APPID."&redirect_uri=".urlencode($curUrl)."&client_secret=".FB_APPSECRET."&code=".$_GET['code'];
log_to_file("curPageURL: ".$token_url);
$response = file_get_contents($token_url);
log_to_file("resp: ".$respone);
the log_to_file is a custm method that logs the taken message in a file so that I can have the log situation in a tail -f scenario.
what happens here is that the log "resp: ". returns nothing at all.
did anyone face the same problem?
thx in advance. this thing is driving me insane.
and I can officially state that the fb sdk is the most buggy and worse-documented service
I've ever used.
Facebook has the most badly-documented API in the world. I remember the time I used it and couldn't help swearing all the time ! :) Here is a piece of pseudo-code that did work for me. It gains permission from a user to post a link on his wall. I'm just posting it so that maybe you can take some hints and make your code work:
<?php
//A function for cURL operations.
function callFb($url)
{
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true
));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$url = "https://graph.facebook.com/oauth/access_token?client_id=<your_client_id>&redirect_uri=".urlencode("<the_url_where_the_user_is_redirected_after_granting_permission>")."&client_secret=<your_client_secret>";
/* Get access token. */
$access_token = callFb($url);
/* Parse the result to get access token */
$access_token = substr($access_token, strpos($access_token, "=")+1, strlen($access_token));
/* Save access token, if you want to for future.*/
mysql_query("INSERT INTO fb_auth_tokens (id,auth_token) VALUES('$_GET[id]','$auth_token')");
/* Post to users wall */
$apprequest_url = "https://graph.facebook.com/me/feed";
$mymessage="Hello World !";
$parameters = "?access_token=" . $access_token . "&message=" .
urlencode($mymessage) .
"&link=".urlencode("<link_that_you_want_to_post>").
"&description=<description_of_the_link>".
"&method=post";
$myurl = $apprequest_url . $parameters;
$result = callFb($myurl);
// Thy shall be done. :)

Amazon.com MWS Integration

I am currently developing a very basic site which will, at this time, simply display order information from Amazon's Marketplace.
I have all of the MWS Security Credentials.
I have downloaded and reviewed, with much confusion, the PHP Client Library.
I am kind of new to PHP but I feel like I can handle this project.
I need to know how to install and access information from this API. I feel like I've tried everything. Amazon does not supply enough information to get this going. They make it sound like it takes 5 or 6 easy steps and you can access your information; this is not true.
Is there a detailed tutorial on MWS? I need as much information as possible. If you can help me out, maybe outline the steps required to get it going, that would be very appreciated!!!! I'm pulling my hair out over this. Thanks again
A rough file to get you started. This is taken from several pages, including this one from #Vaidas. I don't have links yet, sorry. My only contribution is to put this together in one place.
None of the PHP code Amazon supplied worked for me out of the box. I'm assuming you have XAMPP with cURL or an equivalent environment. This code SHOULD work out of the box to get you started on what needs to happen. Just plug in your credentials.
<?php
$param = array();
$param['AWSAccessKeyId'] = 'YourAccessKeyID';
$param['Action'] = 'GetLowestOfferListingsForASIN';
$param['SellerId'] = 'YourSellerID';
$param['SignatureMethod'] = 'HmacSHA256';
$param['SignatureVersion'] = '2';
$param['Timestamp'] = gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
$param['Version'] = '2011-10-01';
$param['MarketplaceId'] = 'YourMarketplaceID';
$param['ItemCondition'] = 'new';
$param['ASINList.ASIN.1'] = 'B00C5XBAOA';
$secret = 'YourSecretKey';
$url = array();
foreach ($param as $key => $val) {
$key = str_replace("%7E", "~", rawurlencode($key));
$val = str_replace("%7E", "~", rawurlencode($val));
$url[] = "{$key}={$val}";
}
sort($url);
$arr = implode('&', $url);
$sign = 'GET' . "\n";
$sign .= 'mws.amazonservices.com' . "\n";
$sign .= '/Products/2011-10-01' . "\n";
$sign .= $arr;
$signature = hash_hmac("sha256", $sign, $secret, true);
$signature = urlencode(base64_encode($signature));
$link = "https://mws.amazonservices.com/Products/2011-10-01?";
$link .= $arr . "&Signature=" . $signature;
echo($link); //for debugging - you can paste this into a browser and see if it loads.
$ch = curl_init($link);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/xml'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo('<p>' . $response . '</p>');
print_r('<p>' . $info . '</p>');
?>
Please note that it is VITAL to have the
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
line, at least in my case. CURL was working fine for any page except for the MWS page (it was just giving me a blank page with -1s in the info, and it took me most of a day to figure out I needed that line. It's in the MWS forums somewhere.
For good measure, here's a link to MWS ScratchPad.
Once I get a better handle on working with MWS maybe I'll do a tutorial. Or someone who is better at HTML and has a need for more of the features could do it.
in case you still didn't figure out how to do this, follow these steps
read the Developer Guide
read the Reports API Reference
RequestReport with some ReportType that will return order data (page 51 or so, look the reports api reference)
you can test this with the MWS Scratchpad
you can also post to the Amazon MWS community forum to get additional help
you can even write to the Amazon Tech Support
hope this helps you and other users.
Amazon provides some great sample code at https://developer.amazonservices.com/. I've successfully used their code for my PHP applications.
I agree. It was a nightmare to figure out the MWS API.
Some changes to #Josiah's method to make it work for other marketplaces:
Line:
$sign .= 'mws.amazonservices.com' . "\n";
Change to: your correct MWS endpoint. List here http://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html - it'll match your marketplace ID, which could be something like this:
$sign .= 'mws-eu.amazonservices.com' . "\n";
and UK marketplace ID for UK site.
Line:
$link = "https://mws.amazonservices.com/Products/2011-10-01?";
Again, change the start of the url in line with above.
This'll probably give you straight text output in a browser (view source for xml). For XML visible output (easier for checking) do this:
Add an XML content type line to top of file:
header('Content-type: application/xml');
Then comment out:
echo($link);
and
print_r('<p>' . $info . '</p>');
Implementing MWS is easy if you follow the right steps:
1-Download the codebase library from the https://developer.amazonservices.com/ as per your preferred language.
2-Set your seller mws credentials in config.php file under sample folder so that same can be used while running the specific file under the sample folder like: RequestReportSample.php and set the report type and endpoint url for specific seller domain.
3- You can then check submitted request status from scratchpad.
4- You can use GetReportSample file to get the order report data and use the same as per your need.
You can follow the reference as well http://prashantpandeytech.blogspot.com/2015/03/mws-amazon-marketplace-web-service-api.html

Categories