Filtering results from edge /[pageId]/posts - facebook

I would like to show the latest N Facebook posts on my website.
I am using this simple code:
var FB = require('fb')
FB.api('/flourandfire/posts', 'get', { fields: [ 'message', 'picture' ], access_token: '1694494XXXXXXXX|1ba36298123bbf9689942fXXXXXXXXXX' },
function (res) {
if (!res || res.error) {
console.log(!res ? 'error occurred' : res.error)
return
}
console.log(res)
})
However, I need to be able to have some kind of filtering, since there is "noise" in the feed due to the direct link with Instagram (which results in short posts with a picture, that I do NOT want to include in the website's feed)
I basically need to somehow "differentiate" specific posts, which will then placed on the site.
I could fetch 100 posts and filter myself based on a specific tag (like #pub; however, there is the risk of having lots of Instagram posts, more than 100, and end up with ZERO posts on the website.
How would you solve this issue?

There is no official filtering, i would do it like this:
Get N entries by setting the limit parameter to N
Filter them on your own
If there are less than N elements after filtering, use another API call to get more items
Repeat from Number 2
Just an idea though, you could also increase the initial limit - but it would usually result in a slower API call so be careful with that.

Related

GitHub Api: User followers - paging?

I am playing with some Javascript and Github API, and I've came to one problem.
Each time, when I try to call for followers of any user who has followers, the callback that I get from the server shows only 30 users. For example:
https://api.github.com/users/vojtajina/followers - 30 followers
and user followers from original website:
https://github.com/vojtajina/followers - 1,039 followers
My questions is - what is going on? There is no 'next page' in the callback from the server. How can I get all of his/hers followers in the callback?
The max number of items per page is 100, so using the per_page=100 querystring parameter will increase the result to have 100 users per page:
https://api.github.com/users/vojtajina/followers?per_page=100
Using the page querystring parameter, you have control to pagination. For example, to get the second page, you should add page=2:
https://api.github.com/users/vojtajina/followers?per_page=100&page=2
If you want to get all the followers you have to iterate the pages until you receive an empty array.
If you want to use this into a Node.js / JavaScript (on client) app, you can use gh.js–a library I developed which handles this:
var GitHub = require("gh.js");
var gh = new GitHub({
token: "an optional token"
});
gh.get("users/vojtajina/followers", { all: true } function (err, followers) {
console.log(err || followers); // do something with the followers
});

Graph API: event's RSVP check

I'm currently trying to get an idea of getting Facebook's RSVP for an event, but really stuck on that part:
as I see now, to get user's RSVP I have to make three requests with the following logic:
request eventID/attending/userID ->
if "data" array count == 0 ->
request eventID/maybe/userID ->
if "data" array count == 0 ->
request eventID/declined/userID
else -> means user didn't make any choice previously.
So here it looks like I have to make 3 requests to facebook's graph api to get users's RSVP for a single event.
The question is if there is any way to get an RSVP status for an event doing a single request?
I'm using the latest Facebook SDK and the latest graph api.
Many thanks in advance.
So the best solution here so far is:
one request to /eventID/attending/userID
one request to /eventID/maybe/userID
one request to /eventID/declined/userID (if needed to know if the event invitation was declined)
Call to eventID/attending(maybe/declined)/userID lets us filter rsvp to single user, so we avoid downloading and processing a large amount of data here.
After call you have two options:
If result is true, you get the following response:
{
"data": [
{
"name": "Oleskii Poplavlen",
"id": "10204715567996406",
"rsvp_status": "attending"
}
]}
If result is false, you get the following response:
{
"data": []
}
So while you still have to make multiple requests to get user's RSVP to event, you can avoid downloading loads of other users's rsvps.
Hope that helps someone!
I can get you started to do it in 2 calls:
FB.api('/'+ event_id + '?fields=id,attending{rsvp_status},maybe{rsvp_status}', function(event_response){
// here you should make a call to check if the user has the event and if so get the rsvp_status
FB.api('/'+ user_id + '/events?fields=id,rsvp_status', function(user_response){
// check if user has event, then log the rsvp_status
if(user_response.id == event_response.id) {
console.log(user_response.rsvp_status);
} else {
console.log("user is not going");
});
});
I have not tested this but I've been playing around with this API for quite a while now. This could be an answer to do it in 2 calls, not in 1 unfortunatly.
The first call doesn't need the 'attending' and 'maybe' fields but it's usefull to test with.

How to best get around CouchDB's non-RDBMS limitations

We have two document 'types': Post and User:
Typical post:
{
"_id": "3847345345",
"Schema": "Post",
"Text": "Hello World! This is a post!",
"IsFeatured": true,
"UserID": "12345345345234234"
}
Typical user:
{
"_id": "12345345345234234",
"Schema": "User",
"Username": "georgepowell"
"PostIds": ["3847345345","5135345345","9987453236", ... ]
}
On a web page that displays a Post, the Username for that post (plus whatever other changable information about that user) is displayed alongside the post. Similar to SO:
This is a typical example of a situation where an SQL JOIN would be perfect, but of course CouchDB doesn't support anything like that. Instead we could make a view that indexes both User documents and Post documents on a Post's _id. Like this:
function(doc) {
if (doc.Schema = 'Post') {
emit([doc._id, 0], null);
} else if (doc.Schema = 'User') {
foreach (string id in doc.PostIds) // not javascript I know. shhh
emit([id, 1], null);
}
}
which works well, as we can efficiently retrieve all the information we need given a single Post's _id.
However, if I want to create a view that lists all the posts where IsFeatured == true along with all the user data, I get stuck!
function(doc) {
if (doc.Schema = 'Post' && doc.IsFeatured) {
emit([doc._id, 0], null);
} else if (doc.Schema = 'User') {
foreach (string id in doc.PostIds)
emit([id, 1], null); // I can't check if the post is featured!
}
}
Have I reached the limit of CouchDB for relational data? or is this kind of indexing possible in CouchDB?
Since it is a different technology there are trade-offs. And sometimes although things look like they will take more resources (an extra request) in the short-run it can be inconsequential, and in the long-run may give significant scalability, if you need that sort of thing.
CouchDB can handle a lot of different "databases" at the same time, which you can think of as different model spaces. So with the same running instance of CouchDB you could have /users and /posts. This requires absolutely no additional work on the part of configuration or performance of CouchDB.
This can make your map code more straight forward as you then don't need to have the 'Schema' field and be incorporating it into every map function.
Also, you can (and should) have multiple different map/reduce pairs in a given design view. This is important because if you have two different document "Schema"s emit(doc.id, doc.val) how can you tell which is which for reduce purposes.
A more CouchDB idiomatic way to look at your data would be that you don't save the post_ids on the user. Just the UserID on the Posts, then have a map something like the following for Posts:
(doc) ->
emit([doc.user_id, doc.isFeatured], null);
emit([doc.isFeatured, doc.createdAt], doc.user_id);
Then a request to the view API with arguments like ?start_key=['12345345345234234']&end_key=['12345345345234234',{}] would get all their posts.
Where one with ?key=['12345345345234234', 1] would just get their featured posts.
The second emit also gives you ability to quickly get all of the posts that are featured across the whole system sorted by date -- with who made them if you want that data, without getting the whole of the posts sent down the pipe.

Facebook Graph API : get larger pictures in one request

I'm currently using the Graph API Explorer to make some tests. That's a good tool.
I want to get the user's friend list, with friends' names, ids and pictures. So I type :
https://graph.facebook.com/me/friends?fields=id,picture,name
But picture is only 50x50, and I would like a larger one in this request.
Is it possible ?
As described in this bug on Facebook, you can also request specific image sizes now via the new API "field expansion" syntax.
Like so:
https://graph.facebook.com/____OBJECT_ID____?fields=picture.type(large)
The best way to get all friends (who are using the App too, of course) with correct picture sizes is to use field expansion, either with one of the size tags (square, small, normal, large):
/me/friends?fields=picture.type(large)
(edit: this does not work anymore)
...or you can specify the width/height:
me/friends?fields=picture.width(100).height(100)
Btw, you can also write it like this:
me?fields=friends{picture.type(large)}
you do not need to pull 'picture' attribute though. there is much more convenient way, the only thing you need is userid, see example below;
https://graph.facebook.com/user_id/picture?type=large
p.s. type defines the size you want
plz keep in mind that using token with basic permissions, /me/friends will return list of friends only with id+name attributes
You can set the size of the picture in pixels, like this:
https://graph.facebook.com/v2.8/me?fields=id,name,picture.width(500).height(500)
In the similar manner, type parameter can be used
{user-id}/?fields=name,picture.type(large)
From the documentation
type
enum{small, normal, album, large, square}
Change the array of fields id,name,picture to id,name,picture.type(large)
https://graph.facebook.com/v2.8/me?fields=id,name,picture.type(large)&access_token=<the_token>
Result:
{
"id": "130716224073524",
"name": "Julian Mann",
"picture": {
"data": {
"is_silhouette": false,
"url": "https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/15032818_133926070419206_3681208703790460208_n.jpg?oh=a288898d87420cdc7ed8db5602bbb520&oe=58CB5D16"
}
}
}
You can also try getting the image if you want it based on the height or width
https://graph.facebook.com/user_id/picture?height=
OR
https://graph.facebook.com/user_id/picture?width=
The values are by default in pixels you just need to provide the int value
I researched Graph API Explorer extensively and finally found full_picture
https://graph.facebook.com/v2.2/$id/posts?fields=picture,full_picture
P.S. I noticed that full_picture won't always provide full size image I want. 'attachments' does
https://graph.facebook.com/v2.2/$id/posts?fields=picture,full_picture,attachments
Hum... I think I've found a solution.
In fact, in can just request
https://graph.facebook.com/me/friends?fields=id,name
According to http://developers.facebook.com/docs/reference/api/ (section "Pictures"), url of profile's photos can be built with the user id
For example, assuming user id is in $id :
"http://graph.facebook.com/$id/picture?type=square"
"http://graph.facebook.com/$id/picture?type=small"
"http://graph.facebook.com/$id/picture?type=normal"
"http://graph.facebook.com/$id/picture?type=large"
But it's not the final image URL, so if someone have a better solution, i would be glad to know :)
You can specify width & height in your request to Facebook graph API: http://graph.facebook.com/user_id/picture?width=500&height=500
You can size it as follows.
Use:
https://graph.facebook.com/USER_ID?fields=picture.type(large)
For details: https://developers.facebook.com/docs/graph-api/reference/user/picture/
From v2.7, /<picture-id>?fields=images will give you a list with different size of the images, the first element being the full size image.
I don't know of any solution for multiple images at once.
I got this error when I made a request with picture.type(full_picture):
"(#100) For field 'picture': type must be one of the following
values: small, normal, album, large, square"
When I make the request with picture.type(album) and picture.type(square), responses me with an image 50x50 pixel size.
When I make the request with picture.type(large), responses me with an image 200x200 pixel size.
When I make the request with picture.width(800), responses me with an image 477x477 pixel size.
with picture.width(250), responses 320x320.
with picture.width(50), responses 50x50.
with picture.width(100), responses 100x100.
with picture.width(150), responses 160x160.
I think that facebook gives the images which resized variously when the user first add that photo.
What I see here the API for requesting user Image does not support
resizing the image requested. It gives the nearest size of image, I think.
In pictures URL found in the Graph responses (the "http://photos-c.ak.fbcdn.net/" ones), just replace the default "_s.jpg" by "_n.jpg" (? normal size) or "_b.jpg" (? big size) or "_t.jpg" (thumbnail).
Hacakable URLs/REST API make the Web better.
rest-fb users (square image, bigger res.):
Connection myFriends = fbClient.fetchConnection("me/friends", User.class, Parameter.with("fields", "public_profile,email,first_name,last_name,gender,picture.width(100).height(100)"));
I think that as of now the only way to get large pictures of friends is to use FQL. First, you need to fetch a list of friends:
https://graph.facebook.com/me/friends
Then parse this list and extract all friends ids. When you have that, just execute the following FQL query:
SELECT id, url FROM profile_pic WHERE id IN (id1, id2) AND width=200 AND height=200
200 here is just an exemplary size, you can enter anything. You should get the following response:
{
"data": [
{
"id": ...,
"url": "https://fbcdn-profile-a.akamaihd.net/..."
},
{
"id": ...,
"url": "https://fbcdn-profile-a.akamaihd.net/..."
}
]
}
With each url being the link to a 200x200px image.
I have the same problem but i tried this one to solve my problem. it returns large image.
It is not the perfect fix but you can try this one.
https://graph.facebook.com/v2.0/OBJECT_ID/picture?access_token=XXXXX
try to change the size of the image by changing the pixel size from the url in each json object as follows :
for example I change s480x480 to be s720x720
Before :
https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-xfp1/t1.0-9/q71/s480x480/10454308_773207849398282_283493808478577207_n.jpg
After :
https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-xfp1/t1.0-9/q71/s720x720/10454308_773207849398282_283493808478577207_n.jpg
JS styled variant.
Just set enormous large picture width and you will get the largest variant.
FB.api(
'/' + userId,
{fields: 'picture.width(2048)'},
function (response) {
if (response && !response.error) {
console.log(response.picture.data.url);
}
}
);
You can use full_picture instead of picture key to get full size image.
Note: From Graph API v8.0 you must provide the access token for every UserID request you do.
Hitting the graph API:
https://graph.facebook.com/<user_id>/picture?height=1000&access_token=<any_of_above_token>
With firebase:
FirebaseUser user = mAuth.getCurrentUser();
String photoUrl = user.getPhotoUrl() + "/picture?height=1000&access_token=" +
loginResult.getAccessToken().getToken();
You get the token from registerCallback just like this
LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
FirebaseUser user = mAuth.getCurrentUser();
String photoUrl = user.getPhotoUrl() + "/picture?height=1000&access_token=" + loginResult.getAccessToken().getToken();
}
#Override
public void onCancel() {
Log.d("Fb on Login", "facebook:onCancel");
}
#Override
public void onError(FacebookException error) {
Log.e("Fb on Login", "facebook:onError", error);
}
});
This is what documentation says:
Beginning October 24, 2020, an access token will be required for all
UID-based queries. If you query a UID and thus must include a token:
use a User access token for Facebook Login authenticated requests
use a Page access token for page-scoped requests
use an App access token for server-side requests
use a Client access token for mobile or web client-side requests
We recommend that you only use a Client token if you are unable to use
one of the other token types.

Facebook replies empty array on API call for posts

I have a problem with API call on Facebook Graph API. This API call (with the php-sdk):
$posts = $facebook->api('/me/posts?since=2010-1-1&until=2010-3-31T23:59:59');
returns empty array, that looks like this using var_dump : { ["data"]=> array(0) { } }
If I modify the call like this:
$posts = $facebook->api('/me/posts?since=2010-1-1');
it returns the right posts. If I modify it like this:
$posts = $facebook->api('/me/posts?until=2010-3-31');
It returns empty array again. However, this
$posts = $facebook->api('/me/posts?until=2010-12-31');
works fine (but for different posts, than I want).
All of the above, with "statuses" or "links" instead of "posts", return non-empty array.
What is going on?
I think you are hitting infamous 5000 limit. Facebook acts like if you always have only latest 5000 records. So if your 5000th entry from top was newer than 2010-3-31 it won't return anything for /me/posts?until=2010-3-31 query.
Run /me/posts query and look at the bottom item. Facebook won't return anything older than it no matter what extra query parameters you supply (undocumented feature).