Retrieving batch FB reactions from multiple posts - facebook

I managed to return the first page of my posts with some details including its ID with:
api = 'https://graph.facebook.com/v3.2/me'
key = 'secret'
payload = {'fields':'''
posts{permalink_url,created_time,admin_creator,message}'''
, 'access_token':key}
r = requests.get(api, params = payload)
In the FB Graph API documentation, you can do an API call like this /{object-id}/reactions, so now with the ID, getting the reactions is possible. But I need to get the reaction counts by type, so after some research, I find out that I will be able to chain the calls like below.
reactions.type(LIKE).limit(0).summary(1).as(LIKE),
reactions.type(LOVE).limit(0).summary(1).as(LOVE),
reactions.type(WOW).limit(0).summary(1).as(WOW),
reactions.type(HAHA).limit(0).summary(1).as(HAHA),
reactions.type(SAD).limit(0).summary(1).as(SAD),
reactions.type(ANGRY).limit(0).summary(1).as(ANGRY),
reactions.type(THANKFUL).limit(0).summary(1).as(THANKFUL)
Fine now everything is working, but after a pause, I realized that no way in FB will allow me to run those calls for each post especially after I get all the posts IDs since the beginning and sure enough it does not.
So there's this thing about batching as well where I tried to do, where I stacked multiple IDs;
fields=id,reactions.type(PRIDE).limit(0).summary(1),reactions.type(LIKE).limit(0).summary(1)&ids=id1,id2
but I get this instead;
"message": "Syntax error \"Field reactions specified more than once. This is only possible before version 2.1\"
From here it is quite clear to me that FB does not allow specifying a field more than once but just doing reactions.limit(0).summary(1) just returns the total reactions, how am I able to retrieve the reactions from each post without having to bust the API. It gets more confusing as the APIs constantly change throughout time and now we have v3.2 and most of the methods I have researched on SO does not apply anymore.

Related

Why is wordpress API sending back unpredictable results?

When using wordpress API, I'm sending the following request:
/posts?_embed=wp:featuredmedia&_fields=link,title,featured_media,date,description,_links,_embedded&categories[]=415&per_page=1
In reality, there are no posts under category 415, so I would expect the result to be an empty array. The problem is that I end up with an actual result which is a single post that belongs to another category.
I also noticed that changing things in the query params (I've tried removing one of the _fields params, removing the _embed I'm passing leads to different results being fetched. Any ideas if this has to do with the way I'm using the endpoint?

Determine the proper REST API method

I have the following functionalities in my API:
Getting a user by their name
Getting a user by their ID
Getting a user, or if it doesn't exist create one
Getting multiple users by their ID
Currently I'm handling the two first functionalities with a GET request, and the third with a POST request. I could use a GET request for getting multiple users, but sending potentially hundreds of IDs through a query parameter seems like the wrong approach, as I would get a very long URL. I could also use a POST request to send the long list of IDs through its body, but I doubt a POST request is meant for this purpose.
What method would be appropriate to use for the last one?
I see 2 possible ways here:
Get all users and do your filtering post response.
Get a range of IDs, which resumes to only 2 parameters, the lower and the upper limits of the interval. (If this satisfy your needs)
Behaving the way you described and avoiding long URLs in the same time will not work together.

Get Facebook page like count for OpenGraph v2.10

I can't get Facebook to return the page like count, the response provided does not match what the API states. According to the docs, the following URL:
https://graph.facebook.com/v2.10/<page-id>/likes?access_token=<access-token>&summary=true
should return a JSON response with a summary key that provides the like count in the corresponding hash. The problem is the response never contains the summary key, but it does contain the data and pager keys as specified in the docs.
I'm certain my access token is valid and my page ID are correct.
I've also tried to get the page_fans metric from the page insights via the following URL, but it simply returns an empty data object.
https://graph.facebook.com/v2.10/<page-id>/insights/page_fans?access_token=<access-token>
Is there another way to go about retrieving the like count for a page or any particular reason that the requests would succeed, but be missing the relevant data?
Facebook Doc Links:
https://developers.facebook.com/docs/graph-api/reference/v2.10/object/likes
https://developers.facebook.com/docs/graph-api/reference/v2.8/insights
UPDATE
I was able to retrieve the count by using this Graph API call:
https://graph.facebook.com/v2.10/<page-id>?access_token=<access-token>&fields=engagement
As New Hand pointed out, you can get the key directly, without going through the engagement field using the following:
https://graph.facebook.com/v2.10/<page-id>?access_token=<access-token>&fields=fan_count
Do you mean to get the fan_count?
Please try this:
https://graph.facebook.com/v2.10/<page-id>?access_token=<access-token>&fields=fan_count

Limit Number of Posts coming from /feed Facebook Graph API

When I use /{page_id}/feed?access_token=xxxx, this give me all the posts on the page, both by user and page. I want to limit and control the posts. I want to put constraints like:
Timestamp (that is to get posts after a particular timestamp)
Post id (to get post after a particular post)
Since getting all the posts from feed is irrelevant and in-effective. Is there any way to accomplish this ?
You can use
GET /{page_id}/feed?limit={nr_of_posts_to_return}&since={timestamp}
to be able to limit the number of results and specify the starting timestamp. Have a look at the reference here:
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.0#paging
For your second Use Case you'd need to use the Batch API imho, because with a single Graph API request you can't filter on specific Posts. Instead, you need to use the Batch API to split this in two queries as described here:
https://developers.facebook.com/docs/graph-api/making-multiple-requests/#operations
The request would then look like this:
curl \
-F 'access_token={your_access_token}' \
-F 'batch=[{ "method":"GET","name":"get-post","relative_url":"{your_post_id}?fields=created_time"},{"method":"GET","relative_url":"{your_page_id}/feed?since={result=get-post:$.created_time}&limit={nr_of_posts_to_return}"}]' \
https://graph.facebook.com/
In Graph Explorer, you have to change the HTTP method to Post, then add a new field called batch. Leave the URL blank so far. Paste this as batch value:
[{ "method":"GET","name":"get-post","relative_url":"​293088074081904_400071946716849?fields=created_time"},{"method":"GET","relative_url":"293088074081904/feed?since={result=get-post:$.created_time}&limit=1"}]
This works at least for me.
For others looking for a solution, it appears the 'since' done at the 'comment' and 'reply' levels are ignored. Which means this is not a solution for me.
The query Tobi provided will provide all the posts after the first 'since' but every comment and reply in those posts, regardless of that you set their 'since' to.
Further to this, if you wish to search for new comments , regardless of the age of the post, this fails as well. For example:remove the first 'since' and change to limit=1000 and only request comments as a fields using 'since' , this will return the last 1000 posts and all comments for all of those 1000.
That said, thank you Tobi for your time and showing me how to get everything I need in a single function call. I may experiment parsing the complete recordset every time. ( maybe too much traffic though!)

HasMany RESTfull (or anti-RESTfull) Design?

So I've been reading a lot on RESTfull design - specifically dealing with resources.
Taking the canonical example of Users, Posts, and Comments, with relationships as:
Users ---(hasMany)---> Post ---(hasMany)---> Comment
One may initially think to expose something like:
GET /users GET /posts GET /comments
POST /users POST /posts POST /comments
GET /users/id GET /posts/id GET /comments/id
PUT /users/id PUT /posts/id PUT /comments/id
DELETE /users/id DELETE /posts/id DELETE /comments/id
But then, say I want all Comments of a certain Post made by a particular User. I'd need to do something like:
GET /users/id
> someUser
> var postIds = someUser.posts()
GET /posts?id=<postIds[0]>&id=<postIds[1]>&...
> somePosts
> **application user inspects posts to see which one they care about**
> var postOfInterest = somePosts[x];
> var postId = postOfInterest.id;
GET /comments?id=postId
> someComments (finally)
Suppose though I only care about a Post or Comment in the context of it's owner. Suppose a different resource structuring which may (or may not?) be more natural:
GET /users
POST /users
GET /users/id
PUT /users/id
DELETE /users/id
GET /users/id/posts
POST /users/id/posts
GET /users/id/posts/id
PUT /users/id/posts/id
DELETE /users/id/posts/id
GET /users/id/posts/id/comments
POST /users/id/posts/id/comments
GET /users/id/posts/id/comments/id
GET /users/id/posts/id/comments/id
GET /users/id/posts/id/comments/id
Which to me, is probably a better representation of what the resources are. Then all I need is:
GET /users/id/posts
> somePosts
> **application user inspects posts to see which one they care about**
> var postOfInterest = somePosts[x];
> var postId = postOfInterest.id;
GET /users/id/posts/postId/comments
> someComments
This just seems more like navigating a file system than the previous method - but I don't know if its RESTfull at all (perhaps this is what REST was trying to get rid of) because in order to access a Comments resource, I need to know which User and which Post it belongs to. But the former requires 3 requests, while the latter requires just 2.
Thoughts?
Quite a bit of what is good REST is opinion but I would say your second approach is generally more "RESTful".
Basically you do want hierarchy in REST API and filesystem like navigation instead of query parameters. This is especially so if you follow HATEOS like API as someone can navigate your API.
In your second example it's important to have both GET /users/id and GET /users/id/posts so that when a request for the user's info is made it doesn't include all it's posts (or their IDs) too. And the second request will return their posts too. Often users have thousands of posts in a forum.
The disadvantage is that the api user always has to know the author of the post for which it wants to get comments. He'd essentially make a "give me that user and give me his/hers posts" request to your server which means that your server will make a query for that user and then select his posts. Instead it's much more convenient for both your user and your server to have separate requests - "give me that user", "give me that post" and "give me that comment". This means that you have to store separately users, posts and comments and for each post/comment store the id of it's author so that you can make selection of posts/comments by their author ("give me posts by this user", or simply "give me this post")
I would personally go with this variant of requests
GET user
GET post
GET comment
...
For every request I'd implement a where clause which will give the user of my api more options to make a specific selection. For example GET posts where userId='myID'. It can be implemented with url query parameters like http://myapi.mydomain.com/post?userId=user1 or inside the header. It will return a list of posts for that user. You can also have where clause for the post's ID - http://myapi.mydomain.com/post?id=123 which will return only this post. Note that for the first case - when you fetch a list of posts - you can only return some kind of short info for the posts (like id, author, summary...) and require an additional request to post?id=id for the full post content.
Having this implementation would give you at least two advantages:
the user of the api needs to know only one id to get some info - postID to get a post's content/comments, userId to get all posts/comments for that user
the selection is done on the server so less data is transfered over the network meaning faster responses (and potentially less costs for final users if they are on a mobile plan or something)
In my opinion this implementation giveс you loosely coupled objects (user, post, comment) and more flexible queries