Create charts for a facebook page via open graph and php - facebook

I have created a FB App that grants the following permissions from the user:
1. manage_pages
2. read_insights
By using the app, the user can create a new tab on a page and delete it when this is necessary.
Apart from that, I want to give the option to the user to see some basic stats regarding the page(s) that she creates the tab(s).
For example, I want to retrieve the page views for a certain page for a specific period.
In order to do this I used the following code:
$today = date("Y-m-d");
$until = strtotime($today);
$since = strtotime("2013-08-01");
$pageID = "123";
$page_info = $facebook->api("/$pageID?fields=access_token");
$access_token = $page_info['access_token'];
$params = array(
'access_token' => $access_token,
'since' => $since,
'until' => $until,
);
$insights = $facebook->api("/{$pageID}/insights/page_views/",
"GET",
$params
);
print_r($insights);
The problem is that the result is...somehow empty. More precisely, I receive the following:
Array
(
[data] => Array
(
)
[paging] => Array
(
[previous]=>https://graph.facebook.com/123/insights/page_views/since=1370059200&until=1375329600
[next]=>https://graph.facebook.com/123/insights/page_views/since=1380600000&until=1385870400
)
)
When I use, the same logic to receive insights for my app (without using $token in the $params array), I receive the right data.
In addition to that, I was wondering if there is a way to create charts with this data (directly from FB).
Thx,
Antonis

I managed to solve the problem.
The returning array was empty, because I forgot to check if the user is logged in through facebook...
Regarding the charts, I didn't find any solution directly from facebook, so I used the Charts.js plugin.

Related

How to create post with multiple images on fb api? [duplicate]

Now I posting a single photo to wall like this:
$response = $facebook->api("/$group_id/photos", "POST", array(
'access_token=' => $access_token,
'message' => 'This is a test message',
'url' => 'http://d24w6bsrhbeh9d.cloudfront.net/photo/agydwb6_460s.jpg',
)
);
It works fine, but can I somehow post a multiple photos, something like this:
You can now publish multiple images in a single post to your feed or page:
For each photo in the story, upload it unpublished using the {user-id}/photos endpoint with the argument published=false.
You'll get an ID for each photo you upload like this:
{
"id": "10153677042736789"
}
Publish a multi-photo story using the {user-id}/feed endpoint and using the ids returned by uploading a photo
$response = $facebook->api("/me/feed", 'POST',
array(
'access_token=' => $access_token,
'message' => 'Testing multi-photo post!',
'attached_media[0]' => '{"media_fbid":"1002088839996"}',
'attached_media[1]' => '{"media_fbid":"1002088840149"}'
)
);
Source: Publishing a multi-photo story
You can make batch requests as mentioned here: https://stackoverflow.com/a/11025457/1343690
But its simple to loop through your images and publish them directly.
foreach($photos as $photo)
{
//publish photo
}
Edit: (regarding grouping of photos on wall)
This grouping is done by facebook automatically if some photos are uploaded into the same album.
Currently you cannot create an album in a group via Graph API - it is not supported (as of now), see this bug.
But you can do this - create an album manually, then get the album_id by-
\GET /{group-id}/albums, then use the the code with album_id instead of group_id-
foreach($photos as $photo){
$facebook->api("/{album-id}/photos", "POST", array(
'access_token=' => $access_token,
'name' => 'This is a test message',
'url' => $photo
)
);
}
I've tested it, see the result-
Actually you can upload a multi story photo(I did it using Graph Api and PHP) but the problem comes if you need scheduled this post.Your post is schedule but also it shows on the page's feed.
P.S. I'm using Graph Api v2.9
PHP Code
$endpoint = "/".$page_id."/photos";
foreach ($multiple_photos as $file_url):
array_push($photos, $fb->request('POST',$endpoint,['url' =>$file_url,'published' => FALSE,]));
endforeach;
$uploaded_photos = $fb->sendBatchRequest($photos, $page_access_token);
foreach ($uploaded_photos as $photo):
array_push($data_post['attached_media'], '{"media_fbid":"'.$photo->getDecodedBody()['id'].'"}');
endforeach;
$data_post['message'] = $linkData['caption'];
$data_post['published'] = FALSE;
$data_post['scheduled_publish_time'] = $scheduled_publish_time;
$response = $fb->sendRequest('POST', "/".$page_id."/feed", $data_post, $page_access_token);
$post_id = $cresponse->getGraphNode()['id'];
You will need to upload each photo first with published state to false, and then use the ID's of the unpublished photos to the /me/feed endpoint to schedule the photo. The schedule needs to be within the 24 hours from the time the photos are uploaded as facebook deletes all unpublished photos in 24 hours.
Ref:
https://developers.facebook.com/docs/graph-api/photo-uploads/
There is no way to publish more than one photo in the same graph API call.
See documentation: https://developers.facebook.com/docs/graph-api/reference/user/photos

trying to determine if user is a page admin using FB GraphAPI

I have a page tab app. When the user clicks on the "Go to App" and is sent to my page tab edit url i am trying to determine if they are a page admin or not.
I have tried two different methods. I have tried from the only admin/owner of the page
method 1 used from https://developers.facebook.com/blog/post/2011/09/05/platform-updates--labor-day-edition/
$page_info = $facebook->api("/".$pageID."?fields=access_token");
$pageAccessToken = $page_info['access_token']
$is_admin_url = "https://graph.facebook.com/" . $pageID
. "/admins/" . $FBuser . "?access_token="
. $pageAccessToken;
$response = file_get_contents($is_admin_url);
response is {"data":[]}
I have also tried::
path = '/'.$pageID.'/admins/'.$FBuser;
$params = array(
'app_id' => FB_APP_ID,
'access_token' => $pageAccessToken
);
$is_admin = $facebook->api($path, 'POST', $params);
Although PAGE_ID/admins is a valid request, you need an admin's access_token to see the list. I.e. only admins can see who else is an admin.
What you can do is approach this from the other end by yielding a list of pages that the user is an admin of (using the https://graph.facebook.com/USER_ID/accounts/ data and the manage_pages permission) and search through that list for your application.
However, I would understand if some users would be reluctant to give the manage_pages permission, as it also provides an access token to authenticate as that page, which would be something of a security hole on their part. Unfortunately, there does not seem to be another way to access a list of pages for which that user is an admin.
Simplest way will be signed Request.
A signed_request parameter is POSTed to an application when the app is loaded inside a Page Tab.
You can get a lot of information from signed_request
require '../fb_sdk/facebook.php';
$config = array();
$config['appId'] = '45916xxxxxx';
$config['secret'] = '59caxxxxxx';
$facebook = new Facebook($config);
$facebook->setFileUploadSupport(true);
$signed_request = $facebook->getSignedRequest();
print_($signed_request); will have output like
Array
(
[algorithm] => HMAC-SHA256
[expires] => 1347210000
[issued_at] => 1347203265
[oauth_token] => AAAGhmv67ki8BAAfBwtxxxx
[page] => Array
(
[id] => 192430xxxxxx
[liked] => 1
[admin] => 1
)
[user] => Array
(
[country] => in
[locale] => en_US
[age] => Array
(
[min] => 21
)
)
[user_id] => 10000020xxxxx
)
You can use $signed_request[page][admin] value to determine whether a user is admin of current page, in which your app in loaded in Page Tab. If it's set to 1 then user is admin of the page else not an admin i.e. set to 0.
More About Signed Request
i had some luck using admin_only = true
https://developers.facebook.com/docs/graph-api/reference/user/groups/

Create Facebook event as Page with rGraph API

I am trying to create an event on Facebook on behalf of the page i own with Graph API.
From FB documentation i read that it is done like this:
POSTing name and start_time (other things are optional) to
https://graph.facebook.com/{Page_ID}/events
with proper premissions (create_event, manage_pages)
playing around with this in Graph API Explorer i do get event created but it is done under my own profile rather than Page.
So is it possible to create the event under the Page i own rather than my profile?
PS i double checked the page id so it is not my profile id
PPS I know there are allready many discussions about this here, but unfortunatley i couldnt find a straightforward answer to my question.
So i figured this out myself. I needed to post it with page access token. heres the code
$page_info = $this->fb->api('/' . $page_id . '?fields=access_token');
if (!empty($page_info['access_token'])) {
$path = realpath(APPPATH . '../path/to/img');
$args = array(
'access_token' => $page_info['access_token'],
'start_time' => $start_time,
'description' => $description
'name' => $name,
'location' => $loaction
);
$img = 'img.jpg';
if ($upload) {// if picture is needed
$args['#' . $img] = '#' . $path . '/' . $img;
$this->fb->setFileUploadSupport(true);
}
$res = $this->fb->api("/" . $this->input->post('fb_event'), "post", $args); // should give back event id
}

Add coordinate data to a Facebook Event

Right now, as far as I know, the Facebook Graph API lets you add a location to an event as a string value. Users are able to add location data to events manually though, by specifying a Facebook place or an address, and it looks like Facebook natively uses Bing maps to display the location. Does anyone know if there are any plans to update the API to let developers add location data properly to events?
The API already supports location data.
Facebook will display the map correctly if you specify a location_id which could be the ID of a place page
Here is a code example...
$facebook->setFileUploadSupport(true);
$event = array(
'name' => stripslashes ($name),
'description' => stripslashes ($description),
'start_time' => $start_time,
'end_time' => $end_time,
'privacy_type' => $privacy,
'location_id' => $location_id
);
$event[basename($flyer_file)] = '#' . realpath($flyer_file);
try {
$result = $facebook->api('me/events','post',$event);
} catch (FacebookApiException $e) {
$error = "Facebook Error: $e";
}

Need help with routing in Mojolicious

I have the "Pages" controller with the "show" method and "Auths" controller with the "check" method which returns 1 if user is authenticated.
I have "default" page ("/profile").
I need to redirect to / if the user is authenticated and redirect all pages to / with the authorization form if the user is not authenticated. My code does not want to work properly (auth based on the FastNotes example application): (
auths#create_form - html-template with the authorization form.
$r->route('/') ->to('auths#create_form') ->name('auths_create_form');
$r->route('/login') ->to('auths#create') ->name('auths_create');
$r->route('/logout') ->to('auths#delete') ->name('auths_delete');
$r->route('/signup') ->via('get') ->to('users#create_form') ->name('users_create_form');
$r->route('/signup') ->via('post') ->to('users#create') ->name('users_create');
#$r->route('/profile') ->via('get') ->to('pages#show', id => 'profile') ->name('pages_profile');
my $rn = $r->bridge('/')->to('auths#check');
$rn->route ->to('pages#show', id => 'profile') ->name('pages_profile');
$rn->route('/core/:controller/:action/:id')
->to(controller => 'pages',
action => 'show',
id => 'profile')
->name('pages_profile');
# Route to the default page controller
$r->route('/(*id)')->to('pages#show')->name('pages_show');
It seems you want / to render either a login form OR a profile page. The code above will always show / as login because it hits that route condition first and will never care if you're authenticated or not.
Try a switch in your initial route for / (your default route after the bridge is unnecessary).
my $r = $self->routes;
$r->get('/' => sub {
my $self = shift;
# Check whatever you set during authentication
my $template = $self->session('user') ? '/profile' : '/login';
$self->render( template => $template );
});
A couple of notes on your example:
Its much easier to help debug issues if you use Mojolicious::Lite for examples.
Try using under instead of bridge.
Try using $r->get(..) instead of $r->route(..)->via(..)
Hope this helps.