Nested pagination in facebook graph api while using php-sdk-v4 - facebook-graph-api

I am trying to get all users who likes a specific post on a feed. I am using facebook/php-sdk-v4 . There is no problem on getting next page for feed. However when I use next function to get next users who liked that post in inner loop it gives
Error:Caused by: Facebook\Exceptions\FacebookAuthenticationException
Subfields are not supported by feed.
In FacebookRequest.php I disabled appsecret_proof, maybe it is related to this security issue. If I don't disable, it gives now invalid appsecret_proof despite v5.0 sdk already generates appsecret_proof internally at the line 70 of Facebook\Authentication\AccessToken.php.
Without appsecret_proof I am able to request but in some cases like batch query or loops I think there is a need for appsecret_proof. However, it generates that code itself and it gives invalid error. I don't know what to do.
$fb = new Facebook\Facebook([
'app_id' => '60...
]);
$feed = $graphNode->getField('feed')
while(true) {
foreach ($feed->all() as $key1 => $post) {
if ($likes = $post->getField('likes')){
while(true) {
if (!($likes = $fb->next($likes))) break;
}
}
}
if (!($feed = $fb->next($feed))) break;
}

Related

Google Actions SDK "Error: Unauthorized, Your client does not have permission to the requested URL" caused by use of conv.user.storage

I'm trying to convert an existing Alexa app to Google Actions wherein I need to implement session and persistent data values. My understanding from https://developers.google.com/assistant/conversational/df-asdk/save-data is that conv.data and conv.user.storage are intended for this purpose. However, making any attempt to assign values to either results in the error "Error: Unauthorized, Your client does not have permission to the requested URL", and also a reference to the offending key which points to this in the firebase console log: https://us-central1-hello-world-e37ec.cloudfunctions.net/cf-p7ROQlBMjQId9Cws6XdJBA-name. Similar issues here in stackoverflow seem to indicate that I need to grant the appropriate function to all users, but I don't know which function is being called. I'm new to Google Actions, so apologies if I'm overlooking something obvious. Code is very similar to the example offered on google's doc.
const {conversation} = require('#assistant/conversation');
const functions = require('firebase-functions');
const app = conversation();
...
app.handle('status', async conv => {
conv.overwrite = false;
if (conv.user.verificationStatus === 'VERIFIED') {
conv.user.storage = {};
conv.user.storage.sum = 69;
conv.add(`Alright, I'll store that for next time. See you then.`);
} else {
conv.add(`I can't save that right now, but we can add ` +
`new numbers next time!`);
}
});
I found the answer for this issue. Appears that I was not in the correct area of documentation for the "conversation" object/app. Correct method is described here: https://developers.google.com/assistant/conversational/webhooks#read_and_write_storage.
Using my example
app.handle('status', async conv => {
conv.overwrite = false;
if (conv.user.verificationStatus === 'VERIFIED') {
conv.session.params.sum = 69; //within session
conv.user.params.sum = 100; //across sessions
conv.add(`Alright, I'll store that for next time. See you then.`);
} else {
conv.add(`I can't save that right now, but we can add ` +
`new numbers next time!`);
}
});

'Content-Length: 0', Javascript, XMLHttpRequest, Django REST API

I wish I can find some assistance with my code.
I have set up a Database on mySQL, and connected it to Django REST. Those both work as expected, and I can access the REST with Firefox REST Client with it returning the correct tables from the database.
I have started working for user interface with html and javascript and I have encountered a problem I am unable to solve. I am a student, and this is part of my school work, but unfortunately my teachers are unavailable at the moment due summer vacations and I am eager to continue my project. Hence I am askin for Your assistance.
As I have tested the Django REST through Firefox REST Client, I am sure the database and REST service is not at fault so here we come to my code.
I seem to be able to get connection to the REST Service, giving me code 200 and state 4 (pictures linked underneath)
ReadyStateChange + ReadyState console.logs
Picture 2 shows that my GET request gets stuck on OPTIONS, instead of executing the correct request.
200 OPTIONS
However I am unable to pull data out, giving me 'Content-Length: 0'.
Originally I thought the issue would be cross-domain request problem until my fellow student said he does not think it is, however he was unable to find solution for my code either.
I am trying to find reason and workaround for this error, and if you guys do have idea why this is happening I would deeply appriciate your help!
Here is my code:
<div id="demo"></div>
<script>
loadData() //function kutsu
function loadData(){
if (window.XMLHttpRequest) {
// code for modern browsers
xmlhttp = new XMLHttpRequest();
} else {
// code for old IE browsers
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "http://127.0.0.1:8000/vamkrs/";
xmlhttp.open("GET", url, true);
xmlhttp.withCredentials = true;
xmlhttp.setRequestHeader("Authorization", "Basic " + btoa("username:password"));
xmlhttp.send();
setTimeout(xmlhttp.onreadystatechange = function() {
console.log(this.status);
console.log(this.readyState);
if (this.readyState == 4 && this.status == 200) {
var myData = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myData.responseText(); }
},1500);
/*
xmlhttp.onreadystatechange = function(){
console.log(this.status);
if (this.readyState == 4 && this.status == 200) {
var myData = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myData.responseText();}
}; */
}
</script>
Ps. Sorry, English is not my native language so some spelling mistakes might have been made
Pss. First time posting here, I apologize if mistakes were made on the post

Google Directory API - batch add members to a group

I am using the Google Admin SDK to create, update and delete mailing lists (aka groups).
Everything works fine so far and I can create a new group and add members to it. But: Every adding of a member takes about 1s so I was thinking of a batch request to add several users to a group at once.
In the Google Admin interface it is easy to add several users at once but I didn't find any way to implement this via the API.
Is there a way to do so or do I have to loop through every user?
This works but takes a lot of time if I have to do it for every single user:
$service = new Google_Service_Directory($this->getGoogleClient());
$user = new Google_Service_Directory_Member();
$user->setEmail('test#test.com');
$user->setRole('MEMBER');
$user->setType('USER');
$service->members->insert($group_id, $user);
finally I found a solution on my own: The Admin SDK comes with a Batch class :)
To get batch requests working these steps are necessary:
When initiating the Google Client add the following line to the code
$client->setUseBatch(true);
then you can initiate the batch object
$batch = new Google_Http_Batch($client);
a little modification on the code posted above brings me to this code
foreach($arr_users as $user)
{
$userdata = new Google_Service_Directory_Member();
$userdata->setEmail($user);
$userdata->setRole('MEMBER');
$userdata->setType('USER');
$batch->add($service->members->insert($temp_list_name, $userdata));
}
finally you have to execute the request which is done by this line:
$client->execute($batch);
that's all and it works perfectly
While using the method of Christian Lange I was getting this error -
Argument 1 passed to Google\Client::execute() must implement interface Psr\Http\Message\RequestInterface, instance of Google\Http\Batch given,
So I used this instead
$client->setUseBatch(true);
$service = new Google_Service_Directory($client);
$batch = $service->createBatch();
foreach ($emails as $email)
{
$user = new Google_Service_Directory_Member(array('email' => $email,
'kind' => 'member',
'role' => 'MEMBER',
'type' => 'USER'));
$list = $service->members->insert($key, $user);
$batch->add($list);
}
$resultsBatch = $batch->execute();

facebook pagination next url giving empty set of friend list

i am using following code to get all my friends ,but it gives only 5 friends in data and next pagination link,i have 22 friends but when i click on next pagination gives empty array data
FB.api('/me/friends/?access_token=CAACEdEose0cBAIgrQyQs6DaApZAwDCpSub2WHKXaU3inS1QPvcep24avZCoVpyYcHoWgZBltVdFKbKy8UokU6x2JXGEgeDcRu3C3sM2dEZCuzQIsbZALFGPcamyRqR5ZA4VE8c0U2KNcKNar5qVzo9ToAr6BQatoJKd4dIiXg3dqoS4RLlszQjfm3Yf66XxtKxPyIHEDhudQCLgBZCcINLlucERa4ZBf9a8ZD',function(response) {
console.log(response);
if (response && !response.error) {
var nextPage = response.paging.next;
FB.api('v2.1/248176728710033/friends?limit=10&access_token=CAACEdEose0cBAIgrQyQs6DaApZAwDCpSub2WHKXaU3inS1QPvcep24avZCoVpyYcHoWgZBltVdFKbKy8UokU6x2JXGEgeDcRu3C3sM2dEZCuzQIsbZALFGPcamyRqR5ZA4VE8c0U2KNcKNar5qVzo9ToAr6BQatoJKd4dIiXg3dqoS4RLlszQjfm3Yf66XxtKxPyIHEDhudQCLgBZCcINLlucERa4ZBf9a8ZD&offset=10&__after_id=enc_AeysBhpBnD6OYeeb4OHHT4qPay7GeUF8OUqNU7PcF3HilkONx4E5EXzymARn2J3u7msA2J4PqjbJyyCE51vHJCOX',function(resp){
console.log(resp);
});
}
//
});
It is not possible to get ALL friends anymore, see my answer in this thread: how to get a list of all user friends (not only who use the app)?
If you still get friends who aren´t using your App, it could be because your App was created before end of April 2014. In that case, it´s a v1.0 App. Your are using /me/friends without a version tag in the first call, but with a version tag in the second call. Also, use /me instead of that id (248176728710033).

How to get Expiration Date of access token in Facebook SDK for Unity

I am using parse sdk for backend management for my game. For user signup/login parse api ask for parameter tokenExpiration. I have no idea how to get it from facebook unity sdk.
https://www.parse.com/docs/unity_guide#fbusers-signup
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(accessToken, userId, tokenExpiration);
Got this problem solved by myself using debug_token. Here is the right code on how to do it.
FB.API("/debug_token?input_token="+FB.AccessToken+"&access_token="+FB.AccessToken,Facebook.HttpMethod.GET, AccessTokenCallback);
function AccessTokenCallback(response:String){
Debug.Log(response);
var access = JSON.Parse(response);
Debug.Log("Token Expiration is: "+access["data"]["expires_at"].Value);
}
If you will print the response it will give you a JSON with all information about the access token and you can take whatever info you need about an access token.
Open FacebookAccessTokenEditor.cs and replace original line 81:
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}]";
by these two:
string getExpiresAt = ",{\"method\":\"GET\", \"relative_url\":\"debug_token?input_token="+accessToken+"\"}";
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}"+getExpiresAt+"]";
Then open FacebookEditor.cs and in method MockLoginCallback, just before line 220:
isLoggedIn = true;
insert the following lines:
var tokenData = (Dictionary<string, object>)MiniJSON.Json.Deserialize(responses[2]);
var expiresAt = (long)((Dictionary<string, object>)tokenData["data"])["expires_at"];
accessTokenExpiresAt = FromTimestamp((int)expiresAt);
also, add the missing function FromTimestamp which you can copy from AndroidFacebook.cs or IOSFacebook.cs or jus copy from here:
private DateTime FromTimestamp(int timestamp)
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timestamp);
}
Finally, you can call the parse method like you do on IOS or Android or Web:
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(FB.UserId, FB.AccessToken, FB.AccessTokenExpiresAt);
Note: As I have worked on the code, I am not sure of the original line numbers, but I think they are correct. Also, this does not reflect the best coding practices, but since it is used only in a debug context, they're good enough for me.