Facebook comment ID issue
I am using FBML's fb:comments plugin on a Facebook app (which, although it's described as "legacy" on the Facebook developer site, seems to be the only way to get proper Facebook comment integration on a Canvas app? Please let me know if I'm wrong, it seems navi开发者_C百科gating the open ocean is easier than navigating the Facebook documentation). I'm also using the JavaScript SDK to subscribe to the comment.create
event so I can keep track of who is commenting on my pages. Easy enough, and this seems to work to an extent, but while I have the following code:
FB.Event.subscribe('comment.create', function(response) {
console.log(response);
});
This returns a nice JSON object including the following nugget:
commentID: "10150576473610309"
Great! I have a comment ID. So now I go to the Facebook graph API to get a bit more information about this comment (I want the text, author, etc.), so I issue the following in PHP because, according to the Facebook docs, everything on Facebook has a unique ID, and just hitting up the Graph API with this ID will give you some sweet info.
file_get_contents('http://graph.facebook.com/10150576473610309');
Oh no! This returns false. This is strange. So I check the API for all the comments relating to a specific page, and this gives me a list of the comments...but the ID of the one I just added is different, now it's in the format:
"id": "10150576473610309_20003210"
What is this additional underscore and number?! Calling the graph API with this comment ID gives me the comment info! Where and how (and why?) did this new ID come about? (Of course I tried the Facebook dev forum but it seems asking my mouse the same question would have achieved similar results).
Edit 13/06/2014: Be careful, the username field is now deprecated (thanks @Cyril-n)
Thanks to Jonathan & Tarmo I developped a mixed approch :
FB.Event.subscribe('comment.create',
function(response) {
var commentQuery = FB.Data.query("SELECT text, fromid FROM comment WHERE post_fbid='"+response.commentID+"' AND object_id IN (SELECT comments_fbid FROM link_stat WHERE url='"+response.href+"')");
var userQuery = FB.Data.query("SELECT name FROM user WHERE uid in (select fromid from {0})", commentQuery);
FB.Data.waitOn([commentQuery, userQuery], function() {
var commentRow = commentQuery.value[0];
var userRow = userQuery.value[0];
console.log(userRow.name+" (id: "+commentRow.fromid+") posted the comment: "+commentRow.text);
});
}
);
With this you get all the info needed on the last comment posted.
PS: there is a field named 'username' in the table comment ( http://developers.facebook.com/docs/reference/fql/comment/ ) but it doesn't really seem to work (it says username "Anonymous user" when it isn't anonymous... that's why I used the second query to get the user info)
This is now the preferred way to get the comments from a comment box:
http://developers.facebook.com/blog/post/490
Anyway, about your question. I've found that facebook adds an id whenever they launch a new platform. For example, the id of an object for FQL, graph api, and old REST API are all different. To see this in action look at a photo in an album. All those ids separated by an underscore are: The graph api id, the FQL aid, the photo graph api unique id, and some additional ids are possible, depending on who uploaded it. Those mysterious numbers that get added after your comments are just some kind of comment counter for your application, or a group of applications, basically useless.
So, from my experience mixing facebook platforms is always a bad idea, involving a lot of experimentation and hacks. If it's possible always use a singe platform, the graph api is the best bet right now.
If you just need to query the comment body and author, then you can use the FQL api. You need to query both the comment and link_stat tables.
SELECT text, fromid FROM comment
WHERE post_fbid=#{commentID}
AND object_id IN
(SELECT comments_fbid FROM link_stat WHERE url="#{href}")
The commentID
and href
variables should be available to you from the comment.create callback.
The voted up answer simply refers to a way using the graph api to get all comments for a page. Still left with the same problem, you don't know what the comment id is for the comment most recently left.
My basic pattern was to solve it server side - after the create comment event on the server side I retrieve all comments for the page, then I check for any comment ids that have not been stored and store that. I don't, however, have the need to directly associate the users action to this.
Faced same problem! That numbers looks like sort of timestamp, or so...
Nothing about that at http://developers.facebook.com/docs/reference/api/Comment/
It's possible to grab some last comments for page by event (limit as described http://developers.facebook.com/docs/reference/api/ ) but as temporary workaround.
So I'm looking for solution too.
Solved this with an ugly and bit fragile hack, but it works. Here are the basic steps:
- subscribe to comment.create
- download list of comments from '/comments/?ids=PAGE_URL&limit=10000'
- take the last comment and assume it's the correct one
Example Code:
FB.Event.subscribe('comment.create', function() {
var href = document.location.href;
FB.api('/comments/?ids=%s&limit=1000'.format(href), function(comments) {
if (comments[href] && comments[href].data) {
var comment = _(comments[href].data).last();
jQuery.post('/events/comment', {
comment_id : comment.id,
message : comment.message
});
}
});
});
This has a race condition that many user's might be commenting at the same time and things will probably get mixed up.
Another possible problem might be the paging of comments, I hope limit 10000 causes it to not page for a while.
Third problem is that this list might be huge and could take a while to download.
This example uses jQuery and Underscore.js in addition to Facebook JS SDK.
Olivier's answer is very elegant and complete, I find it overly involuted though. As stupid as it is on facebook's part to give a json "response" object where the "commentID" value has no correnspondence whatsoever to a real reference, since the last element of the "data" array in graph api response is the newest comment, then you can just fetch, in PHP, the last element with the end() function on the "data" subarray in the JSON response.
EDIT: On second thought, Olivier's approach is great, because it does let you build a permalink out of the commentID value. By selecting the "id" field of the commentdata, and ignoring everything else, you have the volatile code that is contained in the permalink url in the form "id_comments_fbid".
EDIT: Olivier's method does not trigger for replies to existing comments, since those are addressed by selecting "comments" and not by the given query.
精彩评论