Instagram Graph API: Media Thumbnail URL - facebook-graph-api

I'm using the Instagram Graph API in a business account, and almost everything works just fine. I have created a WordPress port of the Facebook SDK, and the function that retrieves the media items looks like this (part of a class, the $fb object is already authenticated using the default_access_token in the class constructor):
public function get_media( $business_account_id = '', $limit = 15 ) {
$limit = absint( $limit );
try {
$response = $this->fb->get( "/{$business_account_id}?fields=media.limit({$limit}){media_url,caption,thumbnail_url,permalink}" );
return $response->getDecodedBody();
} catch ( \Facebook\Exceptions\FacebookResponseException $e ) {
return $e->getMessage();
} catch ( \Facebook\Exceptions\FacebookSDKException $e ) {
return $e->getMessage();
}
}
The fields I'm requesting, as you can see, are: media_url, caption, thumbnail_url and permalink. The API responds with all the fields except for thumbnail_url:
array(2) {
["media"]=>
array(2) {
["data"]=>
array(15) {
[0]=>
array(4) {
["media_url"]=>
string(91) "https://scontent.xx.fbcdn.net/..."
["caption"]=>
string(356) "[...]"
["permalink"]=>
string(40) "https://www.instagram.com/p/.../"
["id"]=>
string(17) "..."
}
...
}
["paging"]=>
array(2) {
["cursors"]=>
array(2) {
["before"]=>
string(123) "..."
["after"]=>
string(122) "..."
}
["next"]=>
string(438) "https://graph.facebook.com/v2.10/..."
}
}
["id"]=>
string(17) "..."
}
I get the same response using the Graph API Explorer, which makes me think is something related to my app, maybe permissions (currently manage_pages and instagram_basic), a special setting or a bug (I don't think so, but just in case...).
What am I missing?

Update 2021
The docs have been updated and the old link doesn't work anymore; here's the new link:
https://developers.facebook.com/docs/instagram-basic-display-api/reference/media/#fields
The wording has been updated to indicate that the thumbnail_url field is only available on VIDEO Media.
Original Answer
Looks like the thumbnail_url is available on video IG Media objects only. My solution is to process the images with PHP to generate resized versions of the media objects and cache them so I don't have the regenerate them on every request.

This answer found a way to get thumbnails with the permalink field. https://stackoverflow.com/a/61945051/5698913

Related

Stuck on 'Ads API Access Level:development'

I try to have an app that can pause/resume my adset (accounts owned by myself).
I get no error message(or anything) output when requesting this
$adset = new AdSet($adsetid);
$adset->campaign_status = AdSet::STATUS_ACTIVE;
try{
$adset->updateSelf();
} catch (RequestException $e) {
$response = json_decode($e->getResponse()->getBody(), true);
var_dump($response);
}
But I see that the adset status did not change.
Now, I do see that the Marketing API, Settings section shows me that the API access Level is development and the app doesn't have Ads management standard access.
When I check permissions at App review > Permissions and features it shows 'Standard access' and 'ready to use'. (however not 'Active')
And at the same time my request count and error rate in the past 30 days are acceptable.
I don't understand what is missing to make it work. Can anyone help me out?
The code I have shown in my question was based on the code I copied from the Facebook marketing API documentation.
Strangely when I simulated my request using the Graph API Explorer and hit the "Get code" button it will suggest you a different code.
When I used that code instead of the code of the marketing API docs it did seem to work just as expected.
This code worked as opposed to the code from the docs:
$adsetid = "YOUR ADSET ID";
$access_token = "YOUR ACCESS TOKEN";
try {
$response = $fb->post(
'/'.$adsetid,
array (
'fields' => 'status',
'status' => 'ACTIVE'
),
$access_token
);
} catch(FacebookExceptionsFacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
$graphNode = $response->getGraphNode();

Blocking SOME but not all endpoints in Wordpress rest api

I am creating a REACT app that uses wordpress as a backend through the rest API. I am using the Simple-JWT-Login plugin to handle the register, login, authentication, and it works perfectly.
I want to block non-logged in users from accessing the /wp/v2/posts endpoint. I know I can do this by doing something like:
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
}
if ( ! current_user_can( 'edit_posts' ) ) {
return new WP_Error( 'rest_not_admin', 'You are not entitled to view that.', array( 'status' => 401 ) );
}
return $result;
});
However that blocks all endpoints, including ?rest_route=/simple-jwt-login/v1/auth and ?rest_route=/simple-jwt-login/v1/users which are the ones from the Simple-JWT-Login plugin used for registering and authenticating users. Therefore users end up in a catch 22 whereby they can't login unless they are already logged in!
Is there a way of modifying the above code to block just the wp/v2/posts/ endpoint, or, alternatively, of effectively whitelisting the registering and authenticating endpoints?
Many thanks for any ideas!
Have searched on here and elsewhere but can't find a solution.
You could always check for the url before showing the error with $_SERVER['REQUEST_URI'] but that might become a pain to add all your allowed urls in a if check.
I like to use apache_request_headers with preg_match to check for a Bearer Token and if the current request has the correct bearer token, show the results. Otherwise you would throw a error. I can't guarantee its 100% safe or the correct way to do it but it works pretty well for a super basic simple system.
Something like the below code might work for someone:
add_filter("rest_authentication_errors", function ($result) {
if (!empty($result)) {
return $result;
}
$headers = apache_request_headers();
$matches = array();
$currentToken = "PUT YOUR BEARER TOKEN HERE";
$pattern = $currentToken."/i";
preg_match('/Bearer '. $pattern, $headers['Authorization'], $matches);
if(isset($matches)){
$token = $matches[0];
if($token == 'Bearer ' . $currentToken){
return $result;
} else {
return new WP_Error( 'no_auth_found', 'You are not currently logged in.' , array( 'status' => 401));
}
}
});

client send json and retrieve it in server

Now I'm bulding game by UNITY3D. I want to send json file to server to store it in database I build server by php with Yii Framework, i have problem with send data in client [UNITY3D] and retrieve it in server [Yii]. Please help me.UNITY3D code: I want to send 'name' -> to server
var url = "http://localhost:8888/TPP/index.php/site/saveName";
var form = new WWWForm();
form.AddField( "player", "Henry" );
var download = new WWW( url, form );
print(download);
yield download;
if(download.error) {
print( "Error downloading: " + download.error );
return;
} else {
// show the highscores
Debug.Log(download.text);
}
In Yii, i tried to get data in request
public function actionSaveName() {
if(isset($_POST['name']) {
echo $_POST['name'];
} else {
echo "nothing";
}
}
Is that right?
The unity part is fine, but in yii you'll have to check for $_POST['player'] instead of $_POST['name'] because according to the AddField() documentation, the first parameter is the name of the generated form element.
If you want to have it as name then you'll have to change AddField as : form.AddField("name", "Henry");

Facebook OAuthException: (#1)

I have a few applications which upload image to user profile. A few hours ago all applications were working fine but now when uploading is requested, it gives this error
Fatal error: Uncaught OAuthException: (#1) An unknown error occurred thrown in applications/fb-sdk/facebook.php on line 543
I'm using the following code to publish image.
$FILE = "images/$image";
$args = array('message' => 'My msg ');
$args['image'] = '#' . realpath($FILE);
$data = $facebook->api('/'.$uid.'/photos', 'post', $args);
Is it because of some policy change or some new feature?
I have all the permissions like upload is set to true and application takes permission to upload file.
P.s: when the application is used 2nd time, it works fine.
You need to verify if the user is logged in AND has the permissions to post on wall. We're going to do that with a TRY/CATCH with a call to the user.
$userId = $facebook -> getUser();
if ($userId) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$userId = NULL;
error_log($e);
}
}
$app_permissions = array(
'scope' => 'publish_stream'
);
$logoutUrl = $facebook->getLogoutUrl();
$loginUrl = $facebook->getLoginUrl($app_permissions);
If the user is not logged in OR has authorized the app, you'll need to redirect him via header redirect or with a link.
if ($userId){
//Then you can call the facebook api
$data = $facebook->api('/'.$uid.'/photos', 'post', $args);
//... ...
}
That's the easiest way i've found.
EDIT : This question on stack has helped me : Facebook PHP SDK Upload Photos
No, the error is caused by the system cannot get the image file. Facebook will not allow the empty image field appear in the api. So it return Fatal error: Uncaught OAuthException: (#1) --- although it does not relate to the OAuth and OAuthException.

Facebook Graph API Photo Upload Image ID

brand new here.. I've looked everywhere, couldn't find an answer.. :/ Hopefully someone here can help me out. I'm using the graph api to upload a photo, and tag the user in it. This is currently working great. I would like to show the user the image, in the album, so I need the image id to generate the url. I cannot figure out how to do this!! Below are the lines of code that upload/tag the photo, to my app's album. What do I need to do to get this image id? Thanks a lot! -Tim
$user = $facebook->getUser();
function post_image($facebook, $user,
$image_path){
try{ $tag = array(
'tag_uid' => $facebook->getUser(),
'x' => 0,
'y' => 0
);
$tags[] = $tag;
$image = array(
'message'=> 'Your Banner Photo', 'tags' => $tags,
);
$facebook->setFileUploadSupport(true);
$image['image'] = '#'.realpath($image_path);
$facebook->api('/me/photos', 'POST', $image);
echo "";
return true;
}catch(FacebookApiException $e){
echo $e;
return false;
} }
Sadly, you have to do it as a separate query. You have to get the users galleries (first graph API call). then find the gallery ID you want and request the photos (second graph API call) then parse through the photos to find the one you want. Finally you have to request that photo.
-------------------Update:---------------------------
I'm not a very proficient php developer, but i use facebook api all the time with javascript or actionscript. The basic premise is to call the graph api, and it will return a json object of the result. Use getFile or Curl to load the graph api responses.
You can test your graph api calls here:
https://developers.facebook.com/tools/explorer/?method=GET&path=663032752
so try and walk that through from the graph api. Get the user galleries, then get the photos, then get the one you want.
To get the albums, call
"https://graph.facebook.com/me/albums?access_token="._accessToken;
To get the photos in an album you call it using:
https://graph.facebook.com/"._albumID."/photos?access_token="._accessToken;
And then to get the individual photo you would get the photo's ID property and call that.
sometihng like:
"https://graph.facebook.com/".your_photo_id;
I think using CURL is a good approach, but I'm weak on php, so use what you are comfortable with.
You have the photo ID in facebook API response, if it is uploaded successfully:
$result = $facebook->api('/me/photos', 'POST', $image);
echo $result['id'];