Exception when uploading photo with Facebook Graph API - php

I would like to upload a photo to facebook for a user in the default album for an application. This is described under publishing here:
http://developers.facebook.com/docs/reference/api/photo
The method has been answered here: How can I upload photos to album using Facebook Graph API. I am using the following:
$args = array(
'message' => 'Photo Caption',
'image' => '#'.realpath("image.png")
);
$data = $facebook->api('/me/photos', 'post', $args);
However I get the exception "(#324) Requires upload file" when I attempt this. I have a valid session and I have the publish_stream and user_photos permissions. I can retrieve data using the API. The image file is definitely valid because it can be loaded with file_get_contents(realpath("image.png")).
I've tried this solution, using curl, which works perfectly:
Upload Photo To Album with Facebook's Graph API
$args = array(
'message' => 'Photo from application',
'pic.png' => '#'.realpath('pic.png')
);
$tok = $session['access_token']
$url = 'http://graph.facebook.com/'.$album_id.'/photos?access_token='.$tok;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
Compared with Facebook's PHP SDK curl which looks like this (using the same $args and $url):
$ch = curl_init();
$opts = self::$CURL_OPTS;
$opts[CURLOPT_POSTFIELDS] = http_build_query($args, null, '&');
$opts[CURLOPT_URL] = $url;
curl_setopt_array($ch, $opts);
$data= curl_exec($ch);
Why doesn't the PHP version work? Looks like the http_build_query() function is interfering with loading the image. I don't know enough about curl to understand what's going on here.

I'm so glad I went trough the same problem
You have to set the fileUpload param to true !
$facebook = new Facebook(array(
'appId' => $facebookapi_id,
'secret' => $facebookapi_secret,
'fileUpload' => true,
'cookie' => true
));

Facebook have intentionally transformed the POST fields to a GET string using http_build_query() to stop fields beginning with # being used to accidentally or maliciously to upload files. Here's the GitHub issue.
A quick fix for this is to remove the http_build_query() from src/facebook.php in the SDK:
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
Becomes:
$opts[CURLOPT_POSTFIELDS] = $params;
However if you do this you should take action to filter user generated messages that start with #. For example you could add a space to the front of each message.

If you use graph api to upload the photo it will getting the error (#200) User must have accepted TOS.
However if you use old rest api, just changing the url to https://api.facebook.com/method/photos.upload?access_token=xXXXXXXXXXXX if you use above example.

Related

How to send documents for Telegram API with multipart/form-data?

I want to sent documents and photos with the Telegram API. Problem is, that once it's sent, it's cached in on there servers. But if my document changes, I send old versions. For the documentation says:
Pass a file_id as String to send a file that exists on the Telegram
servers (recommended), pass an HTTP URL as a String for Telegram to
get a file from the Internet, or upload a new one using
multipart/form-data
But I'm not sure how to implement this. I tried with the following, sending HTTPHEADER, but it's still sending the cached version :/
function sendPhoto($bot_id,$chat_id,$caption,$disable_notification,$photo_url)
{
$ch = curl_init('https://api.telegram.org/bot'.$bot_id.'/sendPhoto');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$param = array(
'chat_id' => $chat_id,
'caption' => $caption,
'parse_mode' => 'html',
'disable_notification' => $disable_notification,
'photo' => $photo_url
);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($param));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
Can someone help me please ? :)
As you are sending the file/image by its url, telegram would use its cache and will not fetch the image from that particular given url again (same behaviour may happen when you use your browser to see that image or any resource in internet).
If you want to force telegram to not use the cache, you should change the url by giving some query parameters. In that case, the url would be different than your previous url and telegram will fetch the image again. For example use:
$param = array(
//...
'photo' => $photo_url . '?timestamp=' . time()
);

Post message on Facebook with curl

I want to be able for my web site to post a message on the fan page of the website.
So I use this code I found:
<?php
require_once("assets/facebook.php");
$facebook = new Facebook(array(
'appId' => '471898006354908', // Fake
'secret' => 'd2f7fb2dbc0ab7f42bc1c4337ab041b1', // Fake
'cookie' => true
));
$access_token = $facebook->getAccessToken();
echo $access_token;
$msg = "testmsg";
$title = "testt";
$uri = "http://somesite.com";
$desc = "testd";
$pic = "http://static.adzerk.net/Advertisers/d18eea9d28f3490b8dcbfa9e38f8336e.jpg";
$attachment = array(
'access_token' => $access_token,
'message' => $msg,
'name' => $title,
'link' => $uri,
'description' => $desc,
'picture'=>$pic,
'actions' => json_encode(array('name' => $action_name,'link' => $action_link))
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://graph.facebook.com/me/feed');
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);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //to suppress the curl output
$result = curl_exec($ch);
curl_close ($ch);
?>
Each time I execute the page it echoes me something like this:
471898006354908|d2f7fb2dbc0ab7f42bc1c4337ab041b1
But it don't post anything on my fan page ?
Any help please ?
If that is all the code you found, then you are missing one important part: the login process. It´s explained in detail in the docs: https://developers.facebook.com/docs/facebook-login/v2.4
Right now it seems that you are only using an App Access Token, but you need a User Access Token that is authorized with the publish_actions permission. Make sure you understand all the different Tokens, here are some links about those:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/
Don´t forget to read about Login Review too, if you want to go public with your App: https://developers.facebook.com/docs/facebook-login/review
Using your own CURL calls is perfectly fine btw, i would not suggest using the PHP SDK for small projects because that´s just overkill and the PHP SDK uses CURL too. After all it´s just a bunch of PHP Classes. Just make sure you don´t prefill the message parameter, because that´s not allowed according to the platform policy.
Use the Facebook API / SDK.
This is probably not permitted in ToS and actively prevented. They detect the agent and use other means to prevent you accomplishing this with cURL.
Or you need to at least jump through a couple authentication hoops probably to prevent abuse. Check this past post and please close this if you deem your question to be a dupe. Post to a Facebook user's wall with cURL PHP

Instagram API Subscription, how to get post?

I'm working to understand how to get the results of a Instagram Subscription that looks for a specific tag. Ultimately, what I would like to do is as images are posted with the tag I'm looking for add the link to the photo as well as the username to a database.
I was able to create my subscription no problem but now I'm not sure how to get the POST information from the subscription.
Working with two files...subscribe.php and callback.php
subscribe.php
<?php
//ALL YOUR IMPORTANT API INFO
$client_id = 'XXX';
$client_secret = 'XXX';
$object = 'tag';
$object_id = 'taglookingfor';
$aspect = 'media';
$verify_token='';
$callback_url = '(full URL here)/callback.php';
//SETTING UP THE CURL SETTINGS...
$attachment = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'object' => $object,
'object_id' => $object_id,
'aspect' => $aspect,
'verify_token' => $verify_token,
'callback_url'=>$callback_url
);
//URL TO THE INSTAGRAM API FUNCTION
$url = "https://api.instagram.com/v1/subscriptions/";
$ch = curl_init();
//EXECUTE THE CURL...
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);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //to suppress the curl output
$result = curl_exec($ch);
curl_close ($ch);
//PRINT THE RESULTS OF THE SUBSCRIPTION, IF ALL GOES WELL YOU'LL SEE A 200
print_r($result);
?>
callback.php
<?php
if (isset ($_GET['hub_challenge'])){
echo $_GET['hub_challenge'];
}
//This is an update
else {
$myString = file_get_contents('php://input');
$answer = json_decode($myString);
echo $answer;
}
?>
In my callback.php I'm attempting to echo out the results of the json_decode...but that also begs the question how will I catch that echo? Sorry, this might be really silly but how do I catch the moment when the callback.php script is being fired by a new image with the specific tag I'm looking for. As I mentioned what I hope to do is take the info in the $answer and insert some of the info into a database.
I'm new at this so any help would be greatly appreciated.
Thanks a million!!
I feel your pain. Their API isn't the easiest to work with and their documentation leaves lot to be desired. That said, this is what happens:
You send a request to the subscription API endpoint
Instagram sends a response to your callback.php file
The response contains a hub_challenge parameter that you need to echo to confirm your subscription
If it's successful you will get a post to your callback.php with the subscriptionid of your new subscription
Everytime you get a post to your callback.php you need to fire a request to Instagram for their latest media that matches your tag.
i think your callback url is not able to receive any post data, you may try to post something to your callback url
I hope this answer of mine will be helpful to people having similar problem.

Facebook GRAPH API + PHP SDK: get the URL of the large user picture

I'm trying to rewrite a Facebook app (a PHP script embedding a small multiplayer Flash game) from old FBML to new iFrame type and it kind of works:
<?php
require_once('facebook.php');
define('FB_API_ID', '182820975103876');
define('FB_AUTH_SECRET', 'XXX');
$facebook = new Facebook(array(
'appId' => FB_API_ID,
'secret' => FB_AUTH_SECRET,
'cookie' => true,
));
if (! $facebook->getSession()) {
printf('<script type="text/javascript">top.location.href="%s";</script>',
$facebook->getLoginUrl(
array('canvas' => 1,
'fbconnect' => 0,
#'req_perms' => 'user_location',
)));
} else {
try {
$me = $facebook->api('/me');
$first_name = $me['first_name'];
$city = $me['location']['name'];
$female = ($me['gender'] != 'male');
$fields = $facebook->api('/me', array(
'fields' => 'picture',
'type' => 'large'
));
$avatar = $fields['picture'];
# then I print swf tag and pass first_name;city;avatar to it
} catch (FacebookApiException $e) {
print('Error: ' . $e);
}
}
?>
but I think that the call to get the user profile picture causes my script to perform a 2nd CURL fetch, which is probably avoidable? And also I'd like to use the new GRAPH API and not the old REST API - but I'm not sure how to rewrite that call (and I need to get the large and direct user picture).
If you know the user ID, just use:
<img src="http://graph.facebook.com/<UID>/picture?type=large" />
Also note that you can use that URL to retrieve the contents via cURL. If necessary, you can also use cURL to follow the redirects and get the final URL.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,
"http://graph.facebook.com/<UID>/picture?type=large");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
$url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
var_dump($url);
Instead of making two API calls you could use FQL, something like:
$result = $facebook->api(array(
'method'=>'fql.query',
'query'=>'SELECT uid,name,first_name,current_location,sex,pic_big FROM user WHERE uid=me()'
));
Sure the fql.query is not a graph method but still it's the way to use FQL.

Uploading video to old Facebook REST API

I'm having lots of issues with uploading videos.
If I try to use https://api-video.facebook.com I am getting a cURL host not found error, if I use http://api-video.facebook.com I get a message to use https://api-video.facebook.com
If I try to use https://api.facebook.com/restserver.php?method=video.upload I get a 101 error code -
<error_msg>Invalid API key</error_msg>
but the API key works for everything else, statuses, comments, likes, fql for the user?
Heres what I am sending:
access_token=XXXX
api_key=XXXX
call_id=1279204007.6003
description=Description+of+this%3F
format=JSON
title=Title%2C+a+title
v=2.0
sig=XXX
I read in the post on the FB developers forum that splitting the session key by | gives you a correct session key? Is this the same as access_token? I have tried splitting this up with no luck.
Any ideas, or even working code in PHP (!) would be most welcome! Thanks
Try using this code with the FB SDK
require_once 'facebook.php';
$appapikey = 'xxx';
$appsecret = 'xxx';
$facebook = new Facebook($appapikey, $appsecret);
$session_key = 'xxx'; //this is the infinite session_key returned when asking for the offline_access extended permission
$args = array(
'method' => 'facebook.video.upload',
'v' => '1.0',
'api_key' => $appapikey,
'call_id' => microtime(true),
'format' => 'JSON',
'session_key' => $session_key,
'title' => 'My video title',
'description' => 'My video description'
);
ksort($args);
$sig = '';
foreach($args as $k => $v) {
$sig .= $k . '=' . $v;
}
$sig .= $appsecret;
$args['sig'] = md5($sig);
$args["short.wmv"] = '#E:\path\to\short.wmv';
$ch = curl_init();
$url = 'http://api-video.facebook.com/restserver.php?method=facebook.video.upload';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
print_r($data); //returned xml here
I also found a bug report submitted today stating that video uploads have been working and not working sporatically. It could be your code is just fine and facebook's APIs are messing up.
EDIT:
Try the following, it seems to have worked for a few people.

Categories