Posting custom stories to Facebook with batch request - facebook

I have a web application that allows users to post custom stories to their Facebook timeline with the list of fitness exercises they have performed.
The first version is looping through the exercises and calling FP.api for each exercise and it works fine.
Now I would like to make a single call to FB.api with a batch request to speed up the posting and that's where I'm having trouble.
Here is the code with the loop that works fine (exids is an array of numbers):
function postToFB(exids)
{
fbi = 0;
fblength = exids.length;
for (var i = 0; i < fblength; i++)
{
FB.api(
'me/' + vitNamespace + ':perform',
'post',
{
exercise: "http://www.vitalclub.net/scripts/getExforFB.php?exid=" + exids[i],
'fb:explicitly_shared': true
},
function(response) {
...
});
}
}
and here is the code with the batch request that returns an error:
function postToFB(exids)
{
var batcharr = [];
for (var i = 0; i < exids.length; i++)
batcharr.push({ method: 'post', relative_url: 'me/' + vitNamespace + ':perform', body: "exercice=http://www.vitalclub.net/scripts/getExforFB.php%3Fexid%3D" + exids[i] + "&fb:explicitly_shared=true" });
FB.api(
'/',
'post',
{ batch: batcharr, include_headers: false },
function(response) {
...
});
}
The error I get (for each exercise) is the following: The action you're trying to publish is invalid because it does not specify any reference objects. At least one of the following properties must be specified: exercise.
I presume this has to do with the way the body in the batch request is formatted but I cannot find the right way to format it. I have tried using encodeURIComponent on the URL representing the exercise but the error is the same.
Anybody has an idea of what the problem is?
Thanks,
Jean

OK, my bad. It was really a stupid error. I had written the parameter "exercise" in French instead of English (so "exercice" instead of "exercise") and that's where the problem was.
I'm also now using $.param to format the parameters so I now have:
var batcharr = [];
var opts;
for (var i = 0; i < exids.length; i++)
{
opts = { exercise: "http://www.vitalclub.net/scripts/getExforFB.php?exid=" + exids[i], 'fb:explicitly_shared': true };
batcharr.push({ method: 'post', relative_url: 'me/' + vitNamespace + ':perform', body: $.param(opts) });
}
before calling FB.api and it works like a charm!

Related

SharePoint CAML + REST + Paging issue

I suppose I have found another SP bug... but maybe I do something wrong.
I have this POST request:
https://dmsdev/coll/f7c592adcb4c4e5996c2de00d444a94c/_api/Web/Lists/GetByTitle('1')/GetItems?$expand=ContentType&$select=Id,SonarDocId,ContentTypeId,EncodedAbsURL,Modified,ContentType/Name
With body:
{"query":{"ViewXml":"<View><Query><OrderBy><FieldRef Name='Modified'/></OrderBy></Query><RowLimit>50</RowLimit></View>","ListItemCollectionPosition":{"PagingInfo":"Paged=TRUE&p_Modified=2017-08-10T07:25:28"}}}
As you can see I do a CAML query with ORDER BY Modified column and I want to take items starting from the item after the item with some modified date but looks like this is not working... I mean similar request on other SP environment works, and on the other env it is not working... it takes all items starting from the first one after ordering by modified... I have no idea what is wrong :/
You could check my sample test script.
<script type="text/javascript">
function restCallwithCaml(listName, caml,PID) {
/// get the site url
var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
/// set request data
var data = {
"query": {
"__metadata":
{ "type": "SP.CamlQuery" },
"ViewXml": caml,
"ListItemCollectionPosition": {
"PagingInfo": "Paged=TRUE&p_ID=" + PID
}
}
};
/// make an ajax call
return $.ajax({
url: siteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/GetItems",
method: "POST",
data: JSON.stringify(data),
headers: {
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
'content-type': 'application/json;odata=verbose',
'accept': 'application/json;odata=verbose'
}
});
}
function GetItemsPaging() {
var pageLimit = 2;
var pageNumber = 0;
var caml = "<View><Query><Where><Geq><FieldRef Name='ID'/><Value Type='Number'>1</Value></Geq></Where></Query><RowLimit>" + pageLimit + "</RowLimit></View>";
var listName = "ChildB";
restCallwithCaml(listName, caml, pageNumber).done(function (data) {
if (data.d.results.length == pageLimit) {
pageNumber++;
//add to array or display
var PID=data.d.results[data.d.results.length - 1].Id;
alert(PID);
restCallwithCaml(listName, caml, PID).done(function (data) {
//add to array or display
alert(data.d.results[data.d.results.length - 1].Id);
})
}
});
}
</script>
Original thread
The problem was with my understanding of how this whole thing works + time zones
I had to write a paging query eg:
Paged=TRUE&p_ID=10&p_Modified=2018-12-14T18:52:00
So I had to add p_Modified parameter from the last item from the previous page... Additionally this data has to be in UTC, so for example I can execute get query with the time returned by the CAML
https://server/site/_api/web/RegionalSettings/TimeZone/localTimeToUTC(#date)?#date='2018-12-14T11:52:00'
And date returned by this call should be passed in p_Modified.

Facebook api multiple request

I am creating a facebook application generator. And I need to check if the user has currently added the application on this facebook page or not.
In order to do that, i first request facebook api to give a list of his pages. Then i loop through all the pages. And request for apps on each of these pages.
Lastly i compare the appId with the one user just created and displays the display the warning accordingly.
The problem is , when i loop through each of the pageId and request FbApi for subpages, the request response is delayed and the for each loop completes its cycle before the results are fetched from facebook.
Here is my code, which is quite complex... Any ideas to fix the issue is highly appreciated.
FB.login(function (response) {
FB.api('/me/accounts', function (apiresponse) {
var totalPages = apiresponse.data.length;
var pageIndex = 0;
$.each(apiresponse.data, function (pageNumber, pageData) {
var pageAccessToken = pageData.access_token;
var tabPageName = pageData.name;
var tabPageId = pageData.id;
FB.api("/" + tabPageId + "/tabs", function (response) {
var foundApp = false
$.each(response.data, function (index, value) {
var exsistingAppId = (value.id).split("app_").pop();
if (exsistingAppId == fbAppId) {
foundApp = true;
}
});
if (foundApp === true) {
var data = {
PageId: tabPageId,
Url: window.location.href.split("/").pop()
}
$.ajax({
type: "POST",
url: '/facebook/Match',
contentType: "application/json",
data: JSON.stringify(data),
success: function (data) {
if (data == "True") {
$("#addToFacebookModal ul").append("<li><span class='pageTab'><a class='pageTabName' target='_blank' href='https://facebook.com/profile.php?id=" +tabPageId + "'>" +tabPageName + "</a></span><a class='deleteAppFromPageTab' data-id='" +tabPageId + "' data-accessToken='" +pageAccessToken + "'>[x]</a></li>");
alreadyAdded.push(true);
} else {
alreadyAdded.push(false);
}
pageIndex++;
if (pageIndex == totalPages) {
console.log("Total Pages = " + totalPages + ", Looped through = " + alreadyAdded.length);
if (alreadyAdded.indexOf(true) >= 0) {
$("#addToFacebookModal").modal();
} else {
addToFacebook();
}
}
}
});
}
else {
pageIndex++;
}
});
});
});
}, { scope: 'manage_pages' });
Here is pseudocode of what i am doing
var myVariable
-Fb.Api Callback function returns response array
-Loop through the response array
-Get new Response array based on the previous response in that array
-Loop through each item of the new response array and compare it with myVariable.
The problem is that responses are delayed while the loop finishes up before the responses arrive. As i result i cant compare the nested Item with myVariable.
If by "facebook page" you mean a business page / organization page (not a profile), you can get the same information more easily by checking the endpoint '/{{page_id}}/tabs/{{app_id}}.
Replace page_id with the ID of the page you want to check and app_id similarly with your app ID. I don't have working code at the moment, but something like this:
FB.api(
'/' + checkPageID + '/tabs/{{app_id}}',
function (response) {
// Do console.log(response) to figure out how to see if installed or not
}
)
YOu can use fields expansion:
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#fieldexpansion
FB.api('/me/accounts', {fields: 'name, address{city}'},function (response)
{
//do something here.
}

FB.api post to multiple ids at same time

I'm having a little trouble here. I'm not good at javascript and all.
The problem is that I'm trying to post to some Facebook users using FB.api. However, it only works if it's only one friend at a time.
Here's my code:
FB.api({ method: 'friends.get' }, function(result) {
var user_ids="" ;
var totalFriends = result.length;
var randNo = Math.floor(Math.random() * totalFriends);
var numFriends = result ? Math.min(1,totalFriends) : 1;
if (numFriends > 0) {
for (var i=0; i<numFriends; i++) {
user_ids+= (',' + result[randNo]);
randNo ++;
if(randNo >= totalFriends){
randNo = 0;
}
}
}
FB.api(user_ids + '/feed', 'post', { message: txt2send },function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
alert('Post ID: ' + response.id);
}
});
});
The output of user_ids is looking like this: ,10083461349,100082391,19293822
Hope you can help me solve this. And please don't refer me any links to help, trust me, I've tried everything.
Hope you can help me solve this. And please don't refer me any links to help, trust me, I've tried everything.
Yeah, sure. But instead of sticking to what the docs say, you’re trying to invent your own “syntax” – you really think that’s helpful …?
Accessing the Graph API generally works by making HTTP requests to /someid/someendpoint/.
But what you are trying, is to (eventually) make a request to
/,10083461349,100082391,19293822/feed
– which is just complete and utter nonsense. You just can’t access the Graph API listing multiple ids at once.
If you want to post to several user’s feeds, you have to make one API call for each one of these users.

Get Facebook iframe params

If a user clicks 'Accept' on a request, they will see an iframe with my site in it.
The facebook url (that has the iframe), looks something like this:
https://apps.facebook.com/[request_id]/?fb_source=notification&request_ids=[request_ids]&ref=notif&app_request_type=user_to_user&notif_t=app_request
How can i get the 'request_id' from the iframe url??
Is there a method/API for that in the JS library?
If you are using php
you can retrieve request_id by $_GET['request_id'] or $_REQUEST['request_id']
if you are using javascript
This is just one implementation of getting requests parameters in javascript, there are better implementations as well, i stated an example.
var Request = {
parameter: function(name) {
return this.parameters()[name];
},
parameters: function() {
var result = {};
var url = window.location.href;
var parameters = url.slice(url.indexOf('?') + 1).split('&');
for(var i = 0; i < parameters.length; i++) {
var parameter = parameters[i].split('=');
result[parameter[0]] = parameter[1];
}
return result;
}
}
var request_id = parameters['request_id'];
Get url from iframe
document.getElementById("iframe_id").contentWindow.location.href
Hope this is what you require

Can not retrieving friends information using Facebook Graph API

Here is some testing code:
<script>
var movieList = new Array();
var friendList=" ";
var friendCount = 0;
function get_friend_likes() {
FB.api('/me/friends', function(response) {
friendCount = response.data.length;
for( i=0; i<response.data.length; i++) {
friendId = response.data[i].id;
friendList=friendList+(response.data[i].name)+'<br/>';//store names
FB.api('/'+friendId+'/movies', function(result) {
movieList = movieList.concat(result.data); //fetch data to the pool
friendCount--;
document.getElementById('test').innerHTML = friendCount
+ " friends to go ... ";
});//end_FB.api
} //end_for
});//end_FB.api
}
</script>
The problem is: I can get the friends' names and ids successfully with the outer FB.api call, but I can't get '/movies' information in the inner FB.api call. The returned data is empty.
Any insights on this? Thanks a lot!!
According to the User object api documentation you need the "user_likes" permission to get /me/movies and "friends_likes" permission to get friendId/movies.
Have you asked for these permissions?
Not sure how you authenticate your users, but you can do it with the javascript sdk as well:
FB.login(callbackFunction, { scope: "user_likes,friends_likes" });