Facebook on/off social reading in app - facebook

I try social plugin "Recommendations Bar" and it works. It has a built-in function to activate and deactivate the social reading function.
I want to enable this function in my simple app with "read" publish_actions.
I don't want to use cookies or session var to do this, it's a wrong way.
Users have to choose in which article on/off the social reading and change his preference on the fly.
User login with:
scope="publish_actions, email"
I know:
$facebook->api("/me/permissions");
$facebook->api("/me/news.reads?limit=10");
and I can post reads:
FB.api('/me/news.reads',
'post',
{ 'article': 'xxxxxx',
'access_token': 'xxxxx' },
function(response)
and delete it:
FB.api(id, 'delete', function(response)
Any idea for API call to enable/disable social reading function?
How to set publish_actions permission value to 0/1 for the users having app installed?

I dont want to use cookies or session var to do this, it's a wrong way.
Right, the user’s profile would be a better place to save this, so that he doesn’t have to make that decision again next time he visit’s your site.
How to set publish_actions permission value to 0/1 for the users having app installed?
You can’t revoke permissions via app. And I can’t see why you would want to. If a user disabled social reading on your site (which you save in their profile, preferably), then just don’t post anything on their behalf.

Related

Facebook SDK: client_pages call returns "PENDING" even though permissions were granted

We need to be able to create ads (programmatically) for our clients' pages.
We connect the app to Facebook on the client side, thusly:
FB.init({
appId,
autoLogAppEvents: true,
xfbml: true,
version: 'v8.0',
});
FB.login(response => {
console.log('FB.login ', response);
}, {
scope: 'ads_management,pages_show_list,business_management,pages_manage_ads',
return_scopes: true
});
The "ads_management" scope results in the user being presented with a dialog allowing him to select pages for which he wishes to grant our app permission to advertise.
So far, so good.
Now, our current understanding is that, in order to use this permission, we need to:
curl
-F "page_id=<PAGE_ID>"
-F "permitted_tasks=['ADVERTISE']"
-F "access_token=<ACCESS_TOKEN>"
"https://graph.facebook.com/v8.0/<BUSINESS_ID>/client_pages"
The <ACCESS_TOKEN> in question here is one that we have obtained for our business's app-scoped system user, from here
https://business.facebook.com/settings/system-users/100053095133371
The <BUSINESS_ID> is ours, namely this one: 211256229451447
<PAGE_ID> is the ID of the end user's page: 101848131661824
Unfortunately, the response we get is :
{"access_status":"PENDING"}
It seems that this response indicates that the end user is meant to approve this request manually. This is strange, as the user has already approved the ads_management scope on connecting his account (see above). It seems that he is now required to approve access for the business (not the app this time?) manually, using the Facebook web interface.
So, what are we doing wrong here? How can we obtain permission to advertise for the user's page?
Note that our support request to FB has been summarily closed without resolution, which is fairly normal.
https://developers.facebook.com/support/bugs/3349788308467923/

Re-asking for declined facebook permissions

What would be the proper way of re-asking user permissions? I am specifically interested in pages_show_list. There FB gives the user a list of pages to select from. Assuming the user would not have selected all of them at first run, i might want to show the list once again at some point of application lifecycle. How would i do that?
I found calling
FB.login(statusChangeCallback, {scope: 'pages_show_list', return_scopes: true})
would not do the trick as it would simple confirm the user has already linked fb to app as You've previously linked [AppName] to Facebook. There is a way to go Edit and then modify a list, but unlikely user would understand to do that.
A second option i came across is to revoke the permission first
FB.api('/me/permissions/pages_show_list', 'DELETE', function(){
FB.login(statusChangeCallback, {scope: 'pages_show_list', return_scopes: true})
});
but then, what would happen to the pages i have check at first run? I assume they would be revoked and access tokens would become obsolete.

Generate access token Instagram API, without having to log in?

So I am building a restaurant app and one of the features I want is to allow a user of the app to see photos from a particular restaurant's Instagram account.
And I want a user to be able to see this without having to login to their Instagram account, so they shouldn't even need an Instagram account for this to work.
So I have read this answer How can I get a user's media from Instagram without authenticating as a user?
And I tried what it said and used the client_id(which I recieved when I registered my app using my personal Instagram account), but I still get an error back saying :
{
meta: {
error_type: "OAuthAccessTokenException",
code: 400,
error_message: "The access_token provided is invalid."
}
}
The endpoint I am trying to hit is :
https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]
So do I absolutely need an access token for this to work(and thus have to enforce a user to log in) ?
If I do, then is there way to generate an access token somehow without forcing the user log in?
I believe there is a way around this, as the popular dating app Tinder has this desired functionality I am looking for, as it allows you to see photos from people's Instagram account without having to log in! (I have just verified this 5 minutes ago!)
Any help on this would be much appreciated.
Thanks.
Edit April 2018: After facebook privacy case this endpoint is immediately put out of service. It seems we need to parse the JSON embedded in <script> tag directly within the profile page:
<script type="text/javascript">window._sharedData = {"activity_counts":...
Any better ideas are welcome.
You can use the most recent link
GET https://www.instagram.com/{username}/?__a=1
to get latest 20 posts in JSON format. Hope you put this to good use.
edit: other ways aren't valid anymore:
https://www.instagram.com/{username}/media/
Instagram used to allow most API requests with just client_id and without access_token, the apps registered back in the day still work with way, thats how some apps are able to show instagram photos without user login.
Instagram has changes the API specification, so new apps will have to get access_token, older apps will have to change before June 2016.
One way you can work around this is by using access_token generated by your account to access photos. Login locally and get access_token, use this for all API calls, it should not change, unless u change password,if it expires, regenerate and update in your server.
Since the endpoints don't exist anymore I switched to a PHP library -
https://github.com/pgrimaud/instagram-user-feed
Installed this lib with composer:
composer require pgrimaud/instagram-user-feed "^4.0"
To get a feed object -
$cache = new Instagram\Storage\CacheManager();
$api = new Instagram\Api($cache);
$api->setUserName('myvetbox');
$feed = $api->getFeed();
Example of how to use that object -
foreach ($feed->medias as $key => $value) {
echo '<li><img src="'.$value->thumbnailSrc.'"></li>';
}

Security of feed posting

Using JavaScript SDK, it is possible to wall post with user's consent. Since It can be done entirely on client side, how to prevent someone to post something to their wall on behalf of my application, tampering with fields the fields like "picture", "link", "caption" and "description"?
Edit for the bounty:
Bragging is an essential part of any game, including online games. In my web game I want to enable users to brag on Facebook when they win, but I don't want them to be able to forge some post and send via my application, what would allow them to brag without actually winning. They may only publish something via my application if I actually allow them to do (I can only imagine some way to ensure this by using some authenticated server side API).
Facebook's Feed Dialog allows developers to prompt users if they want to publish something in their wall, and I well could use it to publish the user's winning story. The problem is that that API is entirely client-side, and can be used via Javascript SDK or just by forging an URL. I was able to forge a post in the name of my application by just filling the fields in an URL, like this given example:
https://www.facebook.com/dialog/feed?
app_id=123050457758183&
link=https://developers.facebook.com/docs/reference/dialogs/&
picture=http://fbrell.com/f8.jpg&
name=Facebook%20Dialogs&
caption=Reference%20Documentation&
description=Using%20Dialogs%20to%20interact%20with%20users.&
redirect_uri=http://www.example.com/response
The problem is that I was unable to forge such request for an existing application, like Robot Unicorn Attack : Evolution. Thus, either 1) I don't know how to forge a request to this application and that is still possible and there is no safety or 2) it is possible to prevent client side exploitation of the Facebook's API, and I don't know how to do this on my application.
So, for the bounty sake, I will consider a proper answer either 1) some proof that it is always possible to forge a post on behalf of some application, and by that I would require a way to post whatever I want on behalf of Robot Unicorn Attack : Evolution, or 2) a way to prevent users to forge feed posts on behalf of my application, in a way I can no longer do it without having server-side only information.
If you want to post anything on behalf of Robot Unicorn Attack : Evolution do the following:
0) Make sure you have added the app.
1) Using Chrome, go to https://s.adultswim.com/games3/fb-game-files/robotunicornattackevolution-sec/index.html (this URL was located by inspecting the action of the form tag above the iframe of the content on the canvas page)
2) Open Developer Tools
3) In the Console paste this:
FB.ui({
method: 'feed',
name: 'There is no security',
link: 'https://developers.facebook.com/docs/reference/dialogs/',
picture: 'http://fbrell.com/f8.jpg',
caption: 'I can post whatever i want',
description: 'Dialogs provide a simple, consistent interface for applications to interface with users.'
},
function(response) {
if (response && response.post_id) {
alert('Post was published.');
} else {
alert('Post was not published.');
}
});
4) Hit enter and see the dialog pop up on the page
1) some proof that it is always possible to forge a post on behalf of
some application, and by that I would require a way to post whatever I
want on behalf of Robot Unicorn Attack : Evolution,
You have already done that. Keep Self proof. Hence proved.
2) a way to prevent users to forge feed posts on behalf of my
application, in a way I can no longer do it without having server-side
only information.
feed posts need is an application id, which cannot be hidden. So as long as you have an application - anyone may post on its behalf . (according to me.)

How to specify Extended Permissions in the JS SDK Auth request

UPDATED TO BE MORE CLEAR (hopefully :)):
Related to this page, specifically the SSO section: http://developers.facebook.com/docs/authentication/
You've got the option Facebook says to use either that facebook connect button (whatever connect means nowdays with Facebook is a grey fog to me now) or just roll your own image as a button and on click call FB.Login().
So I tried the facebook button route which lead me to a complete brick wall. I mean I can get it working, auth, login, all that but I have no clue how to pass extended permissions through this entire process with the button:
window.fbAsyncInit = function () {
FB.init({ appId: facebookApplicationID, status: true, cookie: true, xfbml: true });
FB.Event.subscribe('auth.sessionChange', function (response) {
...rest of code
Ok, how do I attach extended permissions to this call? Of course you can do it easily if using Login() but why doesn't facebook show any examples or state whether the perms parameter exists in terms of placing it somewhere in this process of using that button!
related links: http://forum.developers.facebook.com/viewtopic.php?pid=248096#p248096
I don't even know why they have that button in here when it looks to me like most everyone is just simply calling Login() inside the Init. I assume then calling Login() still manages the SSO in terms of cookie, etc.?
Is anyone using this button or are you just going with FB.Login() ?
I'm running this in an iframe on our own hosted website...not embedding code into the facebook site itself (which I believe is called canvas right?).
RTFM. Yes, I mean friendly.
Right below the Single Sign-on section is the Account Registration Data section and I've copy-pasted this from there.
<fb:login-button perms="email,user_birthday"></fb:login-button>
Not exactly sure what you are trying to accomplish here. If you want to get information about your user or take actions on their behalf on Facebook, you need the user to tell Facebook it's okay to do so (this only needs to happen once) which is why you need to you call FB.login as described here: http://developers.facebook.com/docs/reference/javascript/FB.login.
FB.login(function(response) {
if (response.session) {
if (response.perms) {
// user is logged in and granted some permissions.
// perms is a comma separated list of granted permissions
} else {
// user is logged in, but did not grant any permissions
}
} else {
// user is not logged in
}
}, {perms:'read_stream,publish_stream,offline_access'});
They need to enter in their password to prove it's really them to authorize your app. If you need extended permissions, the second parameter in FB.login allows you to do this.
If the user is already logged in to Facebook (for example in another tab) then there's no need to log in and the login screen should be skipped. If the user is both logged in an has already authorized your app then there's no need to call FB.login.
You check check the user's login status (and permissions) with FB.getLoginStatus: http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus before deciding whether or not to call FB.login.