Manage Facebook Page tab apps via Open Graph API? - php

I have been investigating the Facebook Open Graph API. There is a "manage pages" extended permission which allows publishing to a user's Facebook Page news feed/wall via "impersonation". This is nice functionality, but is there anything more you can do through the API?
Specifically, I would like to be able to Add or Remove a "Tab" application from a user's Page via the API. Right now it's complicated to guide a user through the process of adding a tab app to their business (or Place) Facebook Page, and it would be AWESOME if they could just grant my app permission and I could add the app for them with the API.
Basically I am wondering if the API allows for true "page management", or just posting to the Page.
Anyone have any experience with this?
Is the best I can do pointing them to the "add.php" page with the "page" GET variable (e.g. http://www.facebook.com/add.php?api_key=xxxx&pages=1&page=xxxxxx)? This works OK for ADDING a tab application, but there is nothing at all to help them REMOVE an application from their Page so far as I know.
Thanks!

It is worth noting now, for anyone viewing this question (which is celebrating it's 1st birthday!), that Facebook significantly upgraded their API functionality back in July 2011. You can now Add, Remove, Rename, Reorder and set tabs as Default via the Open Graph API. The blog post is here:
https://developers.facebook.com/blog/post/524/
And the official documentation is here:
https://developers.facebook.com/docs/reference/api/page/#tabs
What Facebook does NOT have yet is a new API method for creating new tab apps, or for changing the tab icon. This is a big step though!
UPDATE: There is bug on the new bug tracker to follow about creating apps in the API if you want to follow it and see what they do: http://developers.facebook.com/bugs/295627350461318

There's a way to do it via the API. We finally got it to work, after many hours of sweat and tears :)
You can add a tab to a page without leaving your app. Here's a snippet of code that we used for that. We get a list of pages that a user manages, show them in a drop down and ask them to select what page they want to add our "my agent profile" tab to.
And the final product looks something like this - http://www.facebook.com/pages/Jennifer-Anderson-Real-Estate-Agent/185071901564573?sk=app_253956901293839
protected void btnAddTab_Click(object sender, EventArgs e)
{
if (ddlPage2.SelectedIndex >= 0)
{
FaceBookPages page = FaceBookPages.LookupByPageID(long.Parse(ddlPage2.SelectedValue));
if (page == null)
throw new NPlaySysException("FaceBookPages is null.");
AnalyticLog log = new AnalyticLog();
log.EventID = FBCommon.Events.AddAgentAppTabID;
log.UserID = UserID;
log.EventTime = DateTime.Now;
log.Update();
string result = FacebookSvc.AddTab(Web.AgentAppID, "me", page.AccessToken);
if (result.Equals("true"))
{
FaceBookPages.UpdateAgentProfileAdded(page.PageID, true);
List<FaceBookPages> notTabbedPages = FaceBookPages.LookupAgentProfileNotAddedByUserID(UserID);
imgStep3.ImageUrl = StepDoneImagePath;
divStep3.Attributes["class"] = StepDoneCssClass;
phStep3.Visible = false;
Step3Done = true;
btnCloseStep3.Visible = false;
if (notTabbedPages.Count > 0)
btnEditStep3.Visible = true;
else
btnEditStep3.Visible = false;
}
else
{
lblErrorAddTab.Text = "Failed to add your profile to page.";
Web.EmailError(string.Format("FacebookSvc.AddTab Failed. result={0}<br />UserID={1}<br />PageID={2}", result, UserID, page.PageID));
}
}
}

Yes, the best you can do is direct them to the add.php url. You can't do anything to help them remove the app.
The good news is that the user used to have to go through the add process AND physically decide to "enable" the tab by finding it in the tab dropdown on the page. Facebook has recently changed that and it seems that the tab is now immediately enabled after a user adds the app to their page.
As for "has_added_app" that works... sorta. It will tell you if the app is added to the page, but it won't tell you if the tab is enabled. For example, a user can disable the tab but still technically have the app installed on the page. Therefore "has_added_app" will return true even though the tab isn't actually visible.

Related

Using Facebook API (via Symfony) leads to multiple post on my Page wall

I've got a problem while auto-posting my blog articles on Facebook. I've been looking everywhere on the web to find a solution but it seems I'm the only one to face this problem.
Here are all the informations:
I am using Symfony 3 for my blog
I save a "publicationDate" ($article->getPublicationDate()) to postpone article publication and a "hasBeenSentOnSocialNetworks" (($article->getIsOnline()) boolean to know if it has been sent on Twitter and Facebook wall
I've set a controller action to check if there is any article to set online.
When the controller is called, I get a list of offline articles (publicationDate < now AND getIsOnline == false)
Each of them is then pushed on social networks, thanks to the great bundle of Martin Georgiev (https://github.com/martin-georgiev/social-post-bundle)
Finally, I flush $article->setIsOnline(true) to avoid posting every time, once it's done.
Everything works just fine as Twitter publish my articles and Facebook too. My database saved isOnline = true.
With OVH I can only run CRON task every hour. The CRON task does the job perfectly with only 1 post published on social networks for every article. My CRON is calling a file that use curl to open the page of the controller that handles the publication.
But to have better reaction time, I've tried adding an event in Symfony so that every time a page is loaded, it checks if there are articles to publish on social networks. This worked fine, excepted I had 2 articles posted on Twitter and about 20-30 on Facebook... I've tried everyting : kernel.response, kernel.controller, kernel.request and I've made a "return;" if the event is not MASTER_REQUEST. No success.
Then I've decided to use twig to call the controller opened by my CRON task. I have added at the bottom of my base.html.twig a "{{ render(controller(....)) }}". It works fine for Twitter with only one post. But on Facebook it sends dozen of time the same publication.
I'm kinda lost. It's been days now that I am trying to fix that. Any help or advice would be appreciated! Thanks :)
My controller action:
$repository = $this->getDoctrine()->getRepository(Article::class);
$articles = $repository->findAllOfflineArticles();
foreach ($articles as $article) {
$content = $article->getSocialContent();
if($content == null){
$content = $article->getTitle();
}
$link = $this->get('router')->generate('article_show', array('slug' => $article->getSlug()), UrlGeneratorInterface::ABSOLUTE_URL);
// Post on social networks
$message = new \MartinGeorgiev\SocialPost\Provider\Message($content, $link);
$this->get('social_post')->publish($message);
//
$article->setIsOnline(true);
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
}
---------------- EDIT 1 ----------------
Thanks to #AhmetGunes for opening my eyes. I've been looking for the error everywhere in my code and I have tried so many different things that my understanding of the situation was blurred. It seems the problem was just as the following:
public function findAllOfflineArticles(){
return $this
->createQueryBuilder('a')
->where('a.isPublished = :is_published')
->andWhere('a.isValidated = :is_validated')
->andWhere('a.isOnline <= :is_online')
->andWhere('a.publicationDate <= :now')
->setParameter('now', new \Datetime())
->setParameter('is_published', true)
->setParameter('is_validated', true)
->setParameter('is_online', false)
->orderBy('a.publicationDate', 'ASC')
->getQuery()
->getResult()
;
}
The problem was obvious, despite I don't really understand how it was working this way.
The query was fetching ->andWhere('a.isOnline <= :is_online')
I corrected this big mistake :->andWhere('a.isOnline = :is_online') and got only one post on facebook!
However, why didn't Doctrine told me there was a problem with my request? How come the script wasn't launching again once isOnline was set to true ?
---------------- EDIT 2 ----------------
The correction worked properly two times. But now it's back as before. Exactly 28-29 publications on Facebook. I'm definitively exhausted of this. This is driving me crazy.

invalid parameter in posting offer to facebook api

I have problem with posting offer to page (which I am admin) via facebook api. It'is work, when I post feed to this page, but not for offers. This always return me FacebookSDKException with message : Invalid parameter. I use PHP (Laravel framework), but I think it does not matter on the language I use. I use this code:
try {
$response = $fb->post('/' . $page_id . '/offers' , $offerData, (string) $request->access_token
);
} catch (\Facebook\Exceptions\FacebookSDKException $e) {
return response()->json(['error'=>$e->getMessage(),
], 200);
}
where my "$request->access_token" is page access token. And in my "$offerData" I have this fields:
$offerData =[
'claim_limit'=>8,
'expiration_time'=>\Carbon\Carbon::now()->addDays(10)->toDateTimeString(),
'message'=>"bbb",
'title'=>"ascvc",
'coupon_required'=>false,
'image_url'=>'...',
'published'=>true,
'reminder_time'=>\Carbon\Carbon::now()->addDays(5)->toDateTimeString(),
// 'scheduled_publish_time'=>5
];
I also try do this by curl (not by first code) and by curl it returns similar error message.
"{"error":{"message":"Invalid parameter","type":"OAuthException","code":100,"error_subcode":1528104,"is_transient":false,"error_user_title":"Check Your Admin Permission Level","error_user_msg":"Only some admins of your Page are able to create and edit offers. Talk to the person responsible for your Page about your admin permission level.","fbtrace_id":"..."}}"
It looks that there is problem with permissions but at login to facebook I set this permissions:
['manage_pages', 'pages_show_list', 'email',
'user_hometown', 'publish_actions', 'user_photos', 'publish_pages']
I have no idea where is problem. I must to tell you that feeds on same page works fine, but not offers. Can you help me, please?
Take a look at the newer /nativeoffers endpoint; that should be a cleaner path through this one.
https://developers.facebook.com/ads/blog/post/2016/08/30/offer-ads-apis/

Soundcloud get track ID from link (PHP)

Okay, so I'm using php to post soundcloud widgets on my website(no need to explain why and how because thath's not wath's important)
Here is my code:
if (strpos($post['link'], 'soundcloud.com') !== FALSE)
{
echo "<iframe width=\"500\" height=\"150\" scrolling=\"no\" frameborder=\"no\"
src=\"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/".$trackID."&color=ff6600&auto_play=false&show_artwork=true\"></iframe>";
}
My variable $post['link'] outputs the soundcloud link in this form https://soundcloud.com/alex-oancea/best-thing-about-you-original
What I would like to do is get the track's id from the link and declare it as $trackID because as you can see in my code(in the src="" part), the widget uses the track's ID
I have looked into the soundcloud API and many other threads on this site but I didin't find how to do this or how to write the code...
Thanks in advance!
Check http://developers.soundcloud.com/docs#resolving
You can click the PHP button on the example and get a good way of getting a track ID:
<?php
require_once 'Services/Soundcloud.php';
// create a client object with your app credentials
$client = new Services_Soundcloud('YOUR_CLIENT_ID');
// a permalink to a track
$track_url = 'http://soundcloud.com/forss/voca-nomen-tuum';
// resolve track URL into track resource
$track = json_decode($client->get('resolve', array('url' => $track_url)));
Now $track->id is your track ID.
Just be aware you need the SoundCloud API for this, and you'll probably have to register your app with SoundCloud to use the service. I have not had personal experience with any of this so I can't provide any information about those processes.
If you experiment on your local machine (xampp in your case), you CANNOT make it work, beause the 'REDIRECT_URL' cannot be anything else but a valid link to a hosted domain. The API just does not accept (for the good reason) url's containing "localhost" or or "192.168.x.x"-style url's. This is simply because the API really sends info to the 'REDIRECT_URL' and it needs to be able to reach it.
You need to get in touch with your hosting provider and setup a "live" dev environement.
Assuming you are using the php-soundcloud from the mptre's Github:
Check https://developers.soundcloud.com/docs#resolving (and even the '/resolve' indicated in the 'see also' section).
You can get a good way of getting a track ID by this way:
<?php
require_once 'Services/Soundcloud.php';
// create a client object with your app credentials
$client = new Services_Soundcloud('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET');
// a permalink to a track
$track_url = 'http://soundcloud.com/forss/voca-nomen-tuum';
// resolve track URL into track resource
$track = json_decode($client->get('resolve', array('url' => $track_url), array(CURLOPT_FOLLOWLOCATION => true)));
// display all the information from that track resource
var_dump($track);
Now $track->id is your track ID.
?>
Just be aware you need the SoundCloud API for this, and you have to register your app with SoundCloud to use the service (Register your app).
Another information is that Webservers where a basedir restriction is set and/or safe mode is active don't allow the CURLOPT_FOLLOWLOCATION = true option. Here is a workaround for these webservers in the Soundcloud.php file.

Joomla Backend Login Component

I'm currently trying to get a custom component working to log a user into the backend given their username and password. I realize the inherent security problems this may present, but I would really like an answer to this problem I've been struggling with. Here is the code in my controller.php:
function execute() {
$credentials = array( 'username' => $this->username,
'password' => $this->password );
$options = array();
$options['group'] = 'Public Backend';
$options['autoregister'] = false;
$options['action'] = 'core.login.admin';
$app =& JFactory::getApplication('administrator');
$result = $app->login($credentials, $options);
echo $result;
}
All the documentation that I've read says that this should work (even though it is not exactly kosher to perform admin tasks--like logging into the backend--from a non-admin context). Any idea on what I'm not getting?
EDIT: I forgot to mention which Joomla version I'm using: 2.5.14
I think you need to pay attention to the Joomla authentication/login/authorization flow and user flow which are managed via user and authentication plugins. From what you say it sounds like you will still be using the Joomla user table, is that right? So in that case the Joomla user plugin should work.
Assuming that is true you want to make an authentication plugin. This plugin will be checked along with the joomla authentication plugin and any other authentication plugins you may have running (e.g. remember me/cookie login).
I don't totally understand what you are trying to do (and you haven't said what version of Joomla you are on, which makes a difference in this case), for example do you really want to login to the full back end or do you just want to show some screens the way the insert image plugin does? If on Joomla 3 you might want to look at the Google Summer of Code project for bringing some admin to the front end (called com_services for now). That student also has an http login plugin you could look at. https://github.com/Buddhima/Joomla-HttpLogin-plugin

reading posts from a specific fanpage

I'm running in circle with this problem so I submit it here.
I have created a facebook fanpage and a website for my mother to promote her music. Since she is quite used to facebook I decided that instead of creating a whole backoffice, the website would simply display the fanpage's posts, photos and events. I do this with simple calls to
$data= $fb->api('/'.PAGE_ID.'/posts?fields=id');
for example (or 'notes', 'events'...). The problem is that I have to use a specific access token that I get from my own 'me/accounts/' permissions. From time to time (say every month) I have to go to the Graph API Explorer, get that token, and save it in the website config.
I'm wondering if I couldn't generate that access token server-side on my website, but I can't seem to make it happen. the facebook PHP SDK can't acces my api('/accounts') graph results unless I'm the authentified user (obviously), and a call to api(PAGE_ID.'?fields=access_token') only returns the page's ID.
What Am I doing wrong? can the facebook php sdk make api calls on my behalf (independently of users)?
More info : I created the fanpage, and a simple app called feed reader, with *manage_pages* permission. I'm the only user that authorized that app, and I don't want the user on the website to have to login (why should they? it's my fanpage, why would I need their *manage_page* permission?).
To be honest I kinda feel that public posts sould be public in the graph api too, but I'm sure there is a reason.
To be honest I kinda feel that public posts sould be public in the graph api too, but I'm sure there is a reason.
You can get to any users public posts like so:
Note: this assumes you are using the PHP SDK here http://developers.facebook.com/docs/reference/php/
$facebook = new Facebook(
array(
'appId' => 'fb_app_id',
'secret' => 'fb_secret',
)
);
$url = '/' . 'fb_username' . '/posts?fields=id,name,created_time,message,story,type&limit=10'; // you might need to screw with this some
$page = $facebook->api($url);
while(count($page['data']) > 0)
{
foreach($page['data'] as $fb_post)
{
// USE THEM DATAS
}
// Keep retrieving next pages until spent
$url_parts = parse_url($page['paging']['next']);
$url = '/' . 'fb_username' . '/posts?' . $url_parts['query'];
$page = $facebook->api($url);
}
this is an example from: https://github.com/fyaconiello/WP_Social_Network_Posts/ which pulls FB posts in and saves em as WP posts. It was written to answer a different question.

Categories